#SFTPでchrootしても他のアカウントが見える
chrootしているのだから他のアカウントが見えることはない。そう思ってました。しかし実際にやってみると見えてしまうのです。パーミッションの設定次第では、他のアカウントのファイルにアクセスも可能です。
SFTPのchrootの設定方法をググるとたくさんページが見つかるのですが、この問題を解決する方法を書いているブログは見つけられませんでした。今回その対策方法を見つけたので、こちらに残していきたいと思います。もし他に良い解決策がありましたらご指摘いただけると嬉しいです。
前提とする環境
CentOS 6および7。
#SFTPの困った仕様
SFTPでchrootするには、chrootするディレクトリのオーナーがroot:rootでなくてはなりません。(しかもパーミッションは755?) たとえば /home/hogehoge と /home/hugahuga という2つのユーザーにchrootしたSTFPでアクセスできるようにするには、/home をchrootするディレクトリとして指定しなければなりません。
そうすると /home 以下にはhogehogeとhugahugaという2つのディレクトリがあるので、SFTPでログインするとこの2つのフォルダが現れてしまいます。パーミッション次第ではアクセスもできてしまうんですよね。パーミッションを適切に設定すれば良い問題でもありますが、そうもいかないのが実情です。
#解決方法
SFTPでchrootしつつ、他のアカウントを見せないようにするために、ホームディレクトリを以下のように変更しました。
変更前
/home/hogehoge
/home/hugahuga
変更後
/home/chroot/hogehoge/hogehoge
/home/chroot/hugahuga/hugahuga
/home/chroot/dev
/chroot はあっても無くてもどちらでもいいです。ポイントはホームディレクトリの上の名前も同じアカウント名になっている点です。この理由は後ほど説明します。3つ目のdevはSFTPのログを取得するためのものなので、不要なら作らなくてもいいです。ホームディレクトリを移動したので、usermodコマンドでホームディレクトリの設定を変更しておきましょう。
# usermod -d /home/chroot/hogehoge/hogehoge hogehoge
# usermod -d /home/chroot/hugahuga/hugahuga hugahuga
#/etc/ssh/sshd_configの設定
/etc/ssh/sshd_config の設定は以下のように行いました。
# override default of no subsystems
#Subsystem sftp /usr/libexec/openssh/sftp-server
Subsystem sftp internal-sftp
Match Group ftponly
X11Forwarding no
AllowTcpForwarding no
ChrootDirectory /home/chroot/%u
ForceCommand internal-sftp -f authpriv -l info
この設定ではグループがftponlyの場合、SFTPのみ許可しchroot化します。ChrootDirectoryの %u はユーザー名に置き換わるので、たとえばユーザーhogehogeがログインした場合は /home/chroot/hogehoge/ がルートになります。ユーザーhugahugaなら /home/chroot/hugahuga がルートです。ルートには書き込めないので1つ下のディレクトリに移動する必要がありますが、他のアカウントを見えなくさせることは成功です。
vsftpdなんかはchrootしてもホームディレクトリがルートになるのに、なんでSFTPではこんな仕様になってるんでしょうね?
#SFTPのログを取る(CentOS 6)
sshd_configを設定しただけでは、誰がどのファイルを転送したのかといったログは取得できません。ログを記録するために /etc/rsyslog.conf に以下の行を加えます。
$AddUnixListenSocket /home/chroot/dev/log
sshd_config のForceCommandのオプション -f authpriv -l info がログを出力するための設定で、ログが不要ならこのオプションは付けなくてかまいません。そして rsyslog.conf の設定により /home/chroot/dev の下にログを取るためのソケットが作成されます。これでsshdとrsyslogdをrestartすれば、/var/log/secure にログが出力されると思います。
CentOS 7ではこの方法ではログがとれず、よくわかりません。