SafeTP 導入記録?

何故 SafeTP? > セキュアなftpだから。

このページに来た方は、たぶんここに書くことをしたいというのが目的だと思いますので、特にここは読み飛ばして構いません。
ずばりftpはコントロール部とデータ部のコネクションが全て平文なため、中継点のパケットをのぞかれたら一発でパスワードとかファイルとかを盗まれてしまいます。
それって非常に怖いので、セキュアなコネクションを実現させるために、SSLとかSSHの様に暗号化したいものです。
そういうわけでサーバの導入が簡単で、かつクライアントからのftpの操作が透過的なsafetpdを導入したいわけです。

SafeTPの仕組みは?

SafeTPのサイトのsftpd - The SafeTP Daemon の説明を見てください。
クライアントは、今まで使用しているftpクライアントが使用可能で、そのクライアントがftpサーバにアクセスしようとすると、ローカルのSafeTPクライアントがパケットを受け取って書き換えて(間違っているかも)、サーバにコネクションを要求します。
サーバに一般のftpが動いている場合、ローカルのSafeTPは普通のftpで接続します。
サーバにsafetpdが動いている場合、safetpdがそのパケットを受け取って認証して、別のftpdとコネクションします。(safetpdが動いているサーバと、ftpdが動いているサーバは別サーバでもOK。ただし、safetpdとftpd間のコネクションは平文でのコネクションとなります。)

要するに、Client[FTP Client<->Local SafeTP Client]<->Server[SafeTPD<->ftpd]という感じなわけです。

注意

このページは、私の理解した(って言っても、ざーっと説明読んだ感じ、、、)範囲内で作っていますので、内容に関して保証できません。
また、使っているSafeTPDのバージョンは、クライアントは2.0(Windows)、サーバは1.46(Linux)を元に書きます。以降のバージョンの参考になる保証はありませんので注意して下さい。
正確な説明は、SafeTPの本家をよく読んでください。

safetp をサーバにインストール

ここで使用するサーバの環境は以下の通りです。 上記のうち、OS, ProFTPD, ucspi-tcp, daemontoolsのインストール/設定は適切に出来ているものとします。
また、GMPもちゃんとインストールしてください。
RedHatの場合、gmp-***.rpmというのがあると思いますのでそれを使っても動くはずです。(とりあえず、私はgmp-3.1.1-2k.rpmとgmp-2.0.2.tar.gzで、動作を確認しました)
あと、当たり前ですが、m4も必要です。gccやg++,c++なども必須です。

上記が完了していた後に行うべきことは、 です。

safetpのmake/copy

すべて、シェルはbashでユーザはrootで作業しました。
bash# cd [sftpd.tar.gzをダウンロードしたディレクトリ]
bash# tar -zvxf sftpd.tar.gz
bash# cd sftpd-1.46(ソースのディレクトリ)
bash# ./configure
bash# make
bash# make check
で、うまくいくはずなんですが、./configure時に`libgmp.a'が見つからないといいます。
そこで `libgmp.a' は、kondaraでは /usr/lib/libgmp.a にありますので、ln -s /usr/lib/libgmp.a でsafetpのソースディレクトリにリンクをおきます。
これで、./configureは行くと思いますが、、、
make時に `gmp_si.cpp' のコンパイル時にエラーを吐きます。
私はC言語の知識が無いためさっぱりわからず、ウェブページを探してもちんぷんかんぷん(っていうか検索の仕方が悪いのか、ほとんど引っかからない)で理解が無理っぽいので、とりあえずエラーメッセージをよく見てみました。
そうしたら、undefined reference to mpz_***というエラーが多発したのでmpz_***がみつからないのか、、と思って`gmp_si.cpp'のソースを見てみたら、どうやらincludeするはずの`gmp.h'が見つからないようだったので `gmp.h'を探してsafetpdのソースディレクトリで ln -s /usr/include/gmp.h をやった後に、`gmp_si.cpp' の 7行目あたりの #include "gmp.h" を #include "./gmp.h" にしてあげました。
そうしたらコンパイルできました。(これでいいのか?)
(2001/11/23: FreeBSDマシンにも入れましたが、コンパイルのエラーの`エ'の字もでませんでした。gmakeが古いっては言われたので、更新しましたが、、、)

で、コンパイルが終了したら、safetpをインストールします。
私は、全て個々にやっていきたかったので設定用スクリプトをあえて使わず、以下のようにしました。
カレントディレクトリが、safetpのソースディレクトリとします。
bash# mkdir [safetpのバイナリを置くディレクトリ]
bash# chmod 755 [safetpのバイナリを置くディレクトリ]
bash# cp sftpd sftpc viewkey makekeys addent [safetpのバイナリを置くディレクトリ]

safetpユーザの作成

safetpは、root権限で動かすべきではなく、特定のアカウントで動くべきです。
safetpのデーモン(sftpd)自体は、サーバ上のファイルを直接触るわけではなく、ftpサーバからのを転送するだけですので、sftpd自体は特定のユーザのファイル全てを操作できる権限は必要ないのです。

私は、以下のようにしました。
/etc/groupに safetp:x:GID: を追加
/etc/passwdに safetp:x:UID:GID:SafeTP:[safetpのバイナリを置くディレクトリ]:/bin/false を追加

ユーザの追加に関しては、個人個人のポリシーがあると思いますので、あんまり強い権限でなければ何でもいいとは思いますが、、、

ユーザーの追加後、以下の行動を忘れてはいけません。
chown -R safetp.safetp [safetpのバイナリを置くディレクトリ]
これでユーザの作成は終了です。

鍵の作成

sftpdでは、暗号化にDSAを使用しますので公開鍵と秘密鍵を作る必要があります。
鍵は、通常 ~safetp 内に置きます。

鍵を作ります。

bash# cd ~safetp
bash# ./makekeys 0 1024
  ↑最初の引数の0はElGamal暗号化の鍵の長さ、後の1024はDSAの鍵の長さです。
    長さ0は鍵を作成しないと同じ意味です。
    ElGamalはサーバ側では使用しませんので0
    DSAはサーバ側で使用しますので設定できる最大値の1024
    を指定します。(詳しくは ./makekeys を引数なしで実行してみてください)

Part of SafeTP's countermeasures against interception attacks
....
Enter an identifying string (80 chars maximum):
moko.cry.jp (WATANABE) <=テキトーにドメインとか、名前とか入れてください。
....
SafeTP will now generate your new security keys.
....
try moving the mouse or typing into another console window.
Entropy progress: [..        ] <=ここが`.'でいっぱいになるまで、
テキトーなタイミングでキーボードを押したりマウスを動かします。
(それを元に鍵が作られるっぽいです)

creating DSA keys with 1024 bits...
Time used to create DSA key:     0.0700 sec
Verifying DSA keys
server name: moko.cry.jp (WATANABE) [11/xx/2001]
Verified.
上記で終了。

私の環境では、/tmp/root 内に鍵ファイルが作成されていたので、それを~safetp内に移動します。
カレントディレクトリ ~safetp
bash# mv /tmp/root/DSA ./
bash# mv /tmp/root/randomSeed ./

クライアントで使用するので、公開鍵の部分をテキストファイルに変換します。
bash# ./viewkey DSA/public.key > DSA/public.key.text

今まで、rootで作業をしたので全ての所有者,グループが、rootになっているため、所有者,グループをsafetpユーザに変更します。
bash# chown -R safetp.safetp ~safetp
パーミッションを確認します。私の環境では以下のようになっています。
pwd:~safetp
700 DSA (DSAディレクトリ内は、所有者以外は閲覧不可)
600 DSA/private.key
644 DSA/public.key (DSAディレクトリが見えないので意味なし?)
644 DSA/public.key.text (これは、どこにおいてもいい気がするけど)
755 addent (なんだ?)
755 makekeys (鍵を作る)
600 randomSeed (DSAの鍵の種?)
755 sftpc (クライアント?)
755 sftpd (デーモンプログラム)
755 viewkey (鍵をテキストに変換)

デーモン設定

sftpdは、単独で動かすこともできますが、inetdで動かすことが望ましいみたいです。
でも、私はtcpserver派ですので、tcpserverを使用してやってみます。
また、デーモンがダウンしないようにdaemontoolsを使用します。

テキトーなディレクトリを作成。
ここでは、/usr/service/ に、safetpd というディレクトリを作成して、そこで作業をしてみます。
bash# mkdir /usr/service/safetpd
bash# cd /usr/service/safetpd

ここに、run という名前のファイルを作成します。
私は以下のようなスクリプトを書きました。
multilogでログをとるつもりで書いていますのでその部分のスクリプトもお忘れ無く(ここでは書きません。)

#!/bin/sh
exec env - PATH="/usr/local/bin:[safetpのディレクトリ]:$PATH" \
tcpserver -vHR -u safetp -g safetp \
[-x "rules.cdb" \] <= tcprulesでcdbファイルを作成している場合のみ。
IPaddr Port \ <= ListenするIPアドレス(全てのネットワークに対しての場合は0)とPort[ftpは通常21]を書きます。
sftpd -f[IPaddr:][Port] \ <= IPaddr,Portには、ProFTPDが起動しているIPアドレス,ポートを指定します。
ただし、IPアドレスを省略すれば、自分自身を指します。
(私の環境では、グローバルIPを使用されたので、気持ち悪いから127.0.0.1を指定しました。)
-sc -y[safetpのディレクトリ] 2>&1 <= 通常は~safetpを指定します。

bash# chmod 744 run

multilogでログを取る場合のみ(上記のスクリプトの`2>&1'を削除します。決して&にしてはいけません。)
bash# chmod +t .

サービスを起動
bash# ln -s /usr/service/safetpd /service
上記の中で、sftpdの引数を知っておく必要があると思いますので、一応書いておきます。
間違っているかもしれませんので、詳しくはオフィシャルの情報を読んでください。

sftpd:

ProFTPDは、もう外部から普通のftpで接続しないとわかっている場合は127.0.0.1で起動するようにしましょう。
tcpserverでの起動例:
tcpserver -vHR -c 5 -u 0 -g 0 127.0.0.1 2121 proftpd &
127.0.0.1の2121番ポートをListenします。
この場合、sftpdの-fでは、`-f127.0.0.1:2121'を指定します。
私はProFTPDもdaemontoolsで動かしてますが、、、
一応、これでサーバ側の設定は完了です。私はもっといろいろ自分でカスタマイズしてますが。

safetpをクライアントにインストール

OSは、Windows2000を使っていますので、それを前提に書きます。
http://safetp.cs.berkeley.edu/safetpc.htmlから、Windows用クライアントをゲットしてきます。
私は、Version2.0を使用しています。
インストールは、簡単にすすみます。

監視ポートの設定

SafeTP Managerを起動して、StatusタブのAdvanced Settingsをクリックします。
SafeTP Manager
Miscellaneous OptionsのRecognized FTP Portsに、サーバのsftpdがListenしているポート番号を追加します。
Add Port
公開鍵の追加を行いますので、まだSafeTP Managerは終了しないで下さい。

公開鍵の追加

まあ、テキトーなFTPクライアントを使って、接続してみればわかりますが、自動的に公開鍵は追加されますので、無視してFTPを使っても構いません。
一応、ここでは、問題が発生しないように手動で追加する方法を書いておきます。
SafeTP ManagerのServer KeysタブのAddボタンをクリックします。
Server NameにIPアドレスを、Keyにサーバの~safetp/DSA/public.key,textの変な文字の羅列をコピーして、SafeTP ManagerのKeyにペースとします。
key
Key: DSA/public.key
--------------------------------
変な文字の羅列
変な文字の羅列
変な文字の羅列
--------------------------------
Branding: moko.cry.jp (WATANABE) [11/xx/2001]
Sha:      16進数の羅列
--------------------------------
--------------------------------

SafeTP Managerの、Checksum:には、Shaと同じ文字の羅列が記載されます。
Branding:には、Branding: と同じ文字が記載されます。
その後、OKを押してください。終了です。

最後に

かなり説明下手ですので、わかりにくかったかもしれませんが、とりあえず、上記のを自分用に変更にすれば動くはずです。
プラットホームがLinuxでしかもディストリがKondaraっていう当たりが??かもしれませんが、とりあえず、うちでは動作しています。
ただ、データチャネルが暗号化・非暗号化にかかわらずレスポンスが遅いので、詳しく調べています。
え?早いけど。っていう方は、どういう構成か教えていただけないでしょうか。。。
(会社のFreeBSDとVineLinuxでは早い...何でだろうね。大体検討は付いてるけど)

あー、これでFTPがセキュアになった、良かったなぁ。やっぱ、セキュアってサイコーだねー!

どうせ、誤りがありそうだから、これから何度ページを訂正することか、、、

※誤りがありましたら、お気軽にメールにてつっこんでください。
(11/23) by 2001- (C) Watanabe Keiji <<Send Mail>>