proftpの暗号化(TLS/SSL)
FTPの暗号化の種類
ftpだと丸見えなので、暗号化をかけようと思う。ftpの暗号化には主に2つある。
- SFTP
- FTPS
SFTPというのはSSH上にFTPをのせるやり方である。ポートもデフォルトだとTCPの22番のみを使用する。基本的にSSHをインストすれば使用できる。クライアントはWinSCPとかFileZillaとかが使える。
今回使用するのはこれ。FTP Over SSLである。仕組みはFTP同様でコントロールコネクションとデータコネクションの2つのTCPを使用する。単純にFTPを暗号化していると思えばよい。
FTP Over SSLの種類
FTP Over SSLにはExplicitとImplicitの2種類がある。違いは以下である。
- Explicit
- Implicit
Explicitとはコントロールコネクションの認証時に暗号化を始める。
Implicitとはいきなり暗号化を始める。通常990番ポートを使用する。
Implicitの方がよさげに見えるが、proftpdではExplicitしか対応していない。理由としてはSSLサポートをするのに、新しいポートを使うのはもったないらしい。あまり詳しくないので、興味があるなら本家サイトを読んでくれ。
ルータの問題点
条件
こんな条件で、こんなことがしたい
- サーバはNAT配下にある
- ルータはFTPをサポートしている
- TLS/SSLを使いたい
- 通常のFTPも使いたい
ここで問題なのが「ルータはFTPをサポートしている」である。通常のFTPをやるのなら問題ないが、SSL/TLSをやる場合に問題がでてくる。ルータのサポート仕様によって異なると思うが、一般的には以下の動きをすると思う。
ルータとFTP
ルータはNAPT(IPマスカレード)と同じ処理をFTPに行う。つまり、ルータは内部LANにいるサーバのFTP通信を監視し、PassiveやPORTコマンドで指定されてくるアドレスをローカルIPからグローバルIPに変換し、さらにポート番号も変換を行う。
このルータの動作事態には問題が無いのだが、FTPとTLS/SSLの両方を行う場合には問題が生じる。TLS/SSLを行うということはFTPに暗号化が掛かる、ルータがアドレスやポート変換ができなくなってしまう。つまりはNAT内のLANにいる場合にはサーバかもしくはクライアントトでローカルIPをグローバルに変換しなくてはならない。proftpdのPassiveでは「MasqueradeAddress」でアドレスの変更ができ、「PassivePorts」でポート番号を限定できるので、それをルータに設定すれば使用ができる。PORTモードを行うならクライアントがNAT内にいるならグローバルIPを設定して行う必要がある。つまりクライアントソフトウェアに依存することになる。基本Passiveになってしまうだろう。
問題
上記のproftpdの設定を行うと通常のFTPで問題が生じる。内部にいるサーバからグローバルIPで送信がくる為、クライアントからPassiveのデータコネクションをルータが受け取った際に、グローバルIPで受け取っている為に内部サーバへ転送ができなくなる。これで通信ができなくなってしまう。そうなった場合には以下のいずれかを選択しなくてはならない。また、FTPSのPORTモードはクライアントの環境にかなり依存し、殆どの環境では使用ができないと思うのでPassiveのみと考える。
- そもそも外部からはFTPSのみにする。
- 外部からのFTPはPORTにし、FTPSはPassiveにする。
- FTPSについてクライアント側でアドレス変換を行う。
結局はクライアントで対応するきゃないかな
「FTPSについてクライアント側でアドレス変換を行う。」を使う。FTPも使いたいけど、PORTのみにするとクライアントの場所によっては使用できない可能性もあるし、FTPSは特定ユーザのみ使用するのでクライアントソフトを限定してもOKだと思うからだ。
サーバ設定
基本的な設定はproftpでファイル転送のページを見てくれ。それとSSL/TLSなので証明書を使用する。おれおれ証明書のページも必要であれば参考に。
PassivePorts 54321 54351 MaxInstances 30 <IfModule mod_tls.c> TLSEngine on TLSLog /var/log/proftpd/tls.log TLSProtocol SSLv23 TLSRSACertificateFile /etc/ssl/Server/cert.pem TLSRSACertificateKeyFile /etc/ssl/Server/private.pem TLSVerifyClient off </IfModule>
「PassivePortsでポート番号を指定し、ルータでも該当ポートをサーバへ向けとく。これで通常のFTPはルータでポート変換されるが、FTPSは暗号化が掛かるため、ルータで転送させる。自宅のルータは60000以上を使用するみたいなので、これ以外のポートを指定しといた。また、「MasqueradeAddress」でアドレスを指定できるが、これをやると通常のFTPが使用できなくなるので設定しない。
クライアント設定
FTPはどんなFTPでも可能だが(FFFTPを使用する場合には、デフォルト設定だとNLSTを使用するのでLISTに変更する必要が有り)、FTPSを使用する場合にはサーバのローカルアドレスが通知されてしまう為、クライアント側でグローバルIPに変更する必要がある。これはSmartFTPというソフトが可能である。ホストで設定でこの機能を有効にしよう。(あとで詳細な説明を追記します・・・)