mod_sftpでProFTPDをSFTPサーバとして動かす

ProFTPD 1.3.2からmod_sftpというモジュールが添付されており、SFTPサーバになれる機能がオプションで追加されています。
これまでmod_tlsによりProFTPDが標準でサポートしていたFTPS(FTP over SSL/TLS)は対応するクライアントが限られていたり何かと癖が強かったのですが、このモジュールを有効にしてビルドするとより広く使われているSFTPによるセキュアな接続を提供できるようになります。

以下では僕が実際に試したビルドの手順とSFTPを有効にする設定例を紹介します。
mod_sftpにはとても親切なドキュメントがあるので、詳しくは本家のサイトを参照して下さい。

ビルドとインストール

本家(http://www.proftpd.org/)から落としてきたソースを展開し、おきまりの手順でmakeします。
SFTPを有効にするために./configure時に--with-modules=mod_sftpを指定します。公式ドキュメントは--enable-opensslしていますが必須ではないようです。

$ wget ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.3a.tar.gz
$ tar zxf proftpd-1.3.3a.tar.gz
$ cd proftpd-1.3.3a
$ ./configure --prefix=/opt/proftpd --sysconfdir=/etc/opt/proftpd --with-modules=mod_sftp
$ make
# make install

この例では僕の趣味で--prefix=/opt/proftpd --sysconfdir=/etc/opt/proftpdしています。
既にProFTPDを別の方法で入れている場合は干渉しないように気をつけましょう。

SFTPサーバの設定

設定ファイル(proftpd.conf)に以下のSFTP関連の設定を追加します。公式ドキュメントに倣ってVirtualHostで設定します。
SFTPで接続できるだけでただのVirtualHostなので、もちろんGlobalセクションの設定は受け継がれます。

まずSFTPEngine onでSFTP接続を受け付けるようにします。
SFTPLogはSFTP接続に関わるログの保存先を指定します。ここではprefix=/opt/proftpdだと仮定して指定しています。
Portディレクティブでこの例ではポート2222番を専用の待ち受けポートとしています。
SFTPHostKeyにはsshdで使っているホスト鍵を指定します。少々気持ちが悪いですがサーバに接続する際にホスト鍵が違うと警告を出すのを避けるためです。

<IfModule mod_sftp.c>
<VirtualHost x.x.x.x>
    SFTPEngine on
    SFTPLog /opt/proftpd/var/log/sftp.log

    Port 2222

    SFTPHostKey /etc/ssh/ssh_host_rsa_key
    SFTPHostKey /etc/ssh/ssh_host_dsa_key
</VirtualHost>
</IfModule>

あとはproftpdを実行すればSFTP接続を受け付けるデーモンが起動します。

# proftpd

なおnオプションをつけるとフォアグラウンドで動きます。

# proftpd -n
ProFTPDのアクセス制御を併用する

SFTPが有効なVirtualHostであってもProFTPD独自の認証機能やアクセス制御がそのまま利用できます。

この例ではmod_auth_fileを使って/etc/opt/proftpd/ftpasswdファイルに書かれたユーザだけがログインできるよう認証を行うようにしています。

AuthOrder mod_auth_file.c

<VirtualHost x.x.x.x>
    ...

    AuthUserFile /etc/opt/proftpd/ftpasswd
</VirtualHost>

こういった設定の中でも特に需要がありそうなchrootの設定もこのとおり手軽に実現できます。これでホームディレクトリより上は見られません。

<VirtualHost x.x.x.x>
    ...

    DefaultRoot ~
</VirtualHost>

また例えばLimitディレクティブでSITE_CHMODを無効にすればパーミッションを変更できなくなります。またSFTPだけにあるコマンド(例えばSYMLINK)もLimitディレクティブで制限できます。

<VirtualHost x.x.x.x>
    ...

    <Limit SITE_CHMOD>
        DenyAll
    </Limit>
    <Limit SYMLINK>
        DenyAll
    </Limit>
</VirtualHost>
通常のFTPを無効にする

LimitディレクティブでサーバすべてのLOGINを無効にした上で、SFTPEngine onのVirutalHostだけLOGINを有効にする方法がドキュメントのFAQで紹介されていました。

<Limit LOGIN>
    DenyAll
</Limit>

<VirtualHost a.b.c.d>
    <Limit LOGIN>
        AllowAll
    </Limit>

    SFTPEngine on
    ...
</VirtualHost>

フォーラムではVirtualHost外(server configコンテキスト)でPort 0にする方法も紹介されていました。

Port 0

http://forums.proftpd.org/smf/index.php/topic,3840.0.html

ただこんな回りくどいことをしなくても、単にserver configコンテキストでSFTPEngine onにしても良いと思うのですが、VirtualHostを使った方が何かメリットがあるんでしょうか。

おわりに

SFTPはsshdのサブシステムとして提供されるのが主で、SFTPだけを単独で提供するにはシステムのユーザを作成した上で特殊なシェルを指定するなど設定を工夫する必要がありました。

このProFTPDのmod_sftpは、シェルの利用は許可せずにファイル転送機能のみを提供するのはもちろん、mod_auth_file等の認証モジュールでProFTPD独自の認証を行うことができ、ProFTPDの機能そのままにchrootや各種ディレクティブによるアクセス制御まで簡単に行えます。

セキュアなFTPだけが必要なシチュエーションは限られていそうではありますが、使い方によっては便利そうですね。