目次

sftpのchroot

ftp接続のみを許可したユーザについて、アクセスを特定のディレクト以下に制限する、つまり、そのディレクトリより上にあるディレクトリ/ファイルを参照できないようにする、という制限を課すことがあります。この制限を課すことを”chrootさせる”と言い、設定は(さほど)面倒なものではありません。
さて。同様の制限をsftpについて実現しようとすると、これがなかなかに難しいことになります。とりあえず考えつくのは、OpenSSHに対し、sshログインした時点でchrootさせてしまう機能を追加するパッチを適用して運用する、というものです。
しかしこのやり方にはひとつ欠点が。それは(リンク先を参照していただければ判りますが)chrootされたディレクトリ以下に、sftpが動作するために必要な環境を整える、つまり適切なディレクトリを作成していくつかのコマンドやライブラリを配置する必要がある、ということです。chrootさせたいユーザごとにその作業を行う必要があるわけですから、これはやはり、なかなかに大変です。

で、ここからが本題。この問題をスマートに解決するパッチを坂元英紀さんが[FreeBSD-users-jp 88822]として投稿されていたので、それについて取り上げてみる次第。
このパッチの造りですが、投稿(上記参照)で坂元さんが述べておられるよう、基本的に「ftpdのchroot処理をsftp-serverにも取り入れてみた」というかたちになっています。ですので、コードの検証にほぼ問題はないと考えられ、安心して使える可能性は高いといえましょう。
また、上記”chrootパッチ with OpenSSH”に比べ、chroot空間内にコマンドやライブラリを配置する必要がなく、簡単に環境を構築できます。環境作成にかかる手間を考えれば、これは大きな利点だと言えるでしょう。

それでは以下で、実際に環境を作ってみましょう。

sftp-serverの再構築

上記のメーリングリストアーカイブからパッチを取得します。念のため、こちらにもコピーを用意しておきます。
まずこのパッチを、FreeBSDのソースツリーに適用します。簡単のため、すべてのソースが/usr/src以下に展開されているものとしましょう。
なお、今回検証で試用したのは6.1-RELEASEでしたが、[FreeBSD-users-jp 88822]では「5.4-RELEASE用のパッチ」とされていますし、現行の5.x/6.xでは同じように使えるかと思います。

まず、以下のようにしてパッチを取得してソースツリーに適用、環境変数”SFTP_CHROOT=yes”を設定1)して、sftp-serverをビルド・インストールします。

% fetch http://www.drive.ne.jp/iMA/attach/FreeBSD-users-jp/88822/sftp-patch
( fetch -o sftp-patch 'http://sahiro.org/wiki/_media/tech:sftp-patch.diff?id=tech%3Asftp_with_chroot&cache=cache')
% cd /usr/src
% sudo patch -p0 < /where/sftp-patch
% cd secure/libexec/sftp-server
% sudo env SFTP_CHROOT=yes make
...
% sudo env SFTP_CHROOT=yes make install
...

"sftpで接続してきたときに"chrootさせる設定

sftp-serverの再構築が終わったところで、設定に移ります。設定方法については、坂元さんが[FreeBSD-users-jp 88823]にてまとめられています。
具体的にはテキストファイル/etc/ssh/sftpchrootを作成して、chrootさせたいユーザのユーザ名を(1ユーザ1行で)書き込めばOKです。たとえばユーザsahiroとsftponlyがsftpでログインしてきたときにホームディレクトリにchrootさせたいときは、次のように記述するだけです。

sahiro
sftponly

また、ユーザ名のあとをタブか空白で区切って、次のように書くことも出来ます。

sahiro          public_html
sftponly        /var/sftp

この場合、sahiroは${HOME}/public_htmlに、sftponlyは/var/tmpにchrootされます2)
坂元さんが書かれているように、このあたりの拡張書式はftpchroot(5)と互換です。詳しくは、ftpchroot(5)のマニュアルを参照してください。

ログイン方法をsftpのみに限定する

さて、このままだとまだ問題があります。sftpでログインしてきたときはchrootされるようになってものの、普通にsshログインしてしまえばchrootされません。つまり、scpやrsyncを使って普通に(sftpでログインしたときには扱うことが出来ない)ファイルを取得したり、置いたりできるわけです。そもそも、シェルログインができる時点でそれ以前の問題なわけです。
ということで、ここまでの作業を活かすためには”chrootさせたいユーザはsftp以外の方法ではログインできないようにする”という対策が必要になります。ここで出てくるのが、scponlyというシェルです。FreeBSDであればportsのshells/scponlyからインストールできます。

% cd /usr/ports/shells/scponly
% sudo env WITH_SCPONLY_SFTP_LOGGING=yes make install
From scponly 4.2, scp & WinSCP compatibilities are not
enabled by default.  To enable those compatibilities,
define WITH_SCPONLY_SCP and/or WITH_SCPONLY_WINSCP,
respectively.

You can enable chroot functionality by defining WITH_SCPONLY_CHROOT.

===>  Extracting for scponly-4.6
...
Updating /etc/shells
===>   Compressing manual pages for scponly-4.6
===>   Registering installation for scponly-4.6
%

ここで環境変数”WITH_SCPONLY_SCP=yes”を設定しては”いけま”せん。scpが使えるようになってしまうと、上記のようにchrootが意味をなさなくなるからです。
こうしてインストールされるシェル/usr/local/bin/scponlyをユーザのログインシェルに設定すれば、そのユーザはsftpによるログインしかできなくなります。
こうして当初意図したように、ftp同様のchrootによる制限を課したsftpアクセスを許可するユーザを作成する、ことができました。

余談になりますが、sftpログインのための認証には、公開鍵認証を使うのがよいでしょう。sftpを使って~/.ssh/authorized_keysの置き換えを行うだけでログインに使用する鍵ペアの変更を実現することができます。
パスワード認証を利用する場合は、別途パスワード変更のためのインターフェイスを用意する必要があるでしょう。ウェブインターフェイスとしてCGIを自作するのも手ですが、Userminを使うのが簡単でしょうか。


表紙に戻る

1) [FreeBSD-users-jp 88822]では/etc/make.confに”SFTP_CHROOT=yes”を記述していましたが、ここではコマンドラインで環境変数を設定するという、別の方法を例示しています。
2) あくまで、sftpでログインした場合にだけ、ということに注意してください。