openssh chrootかつsftpだけ利用できる環境を構築する

参考

設定があまり複雑でなくて、色々な落としどころ求めたらこうなった。

利用するのはopenssh。
opensshのMatch User(Group)とChrootDirectoryを使えばいいけど、
opensshの仕様により、ChrootDirectoryはroot権限でなければいけない。

方法1 他のuser directory名が見れてもいい

今わかっている限りではこれが良さげ。

Match Group sftpuser
  ChrootDirectory /home
  ForceCommand internal-sftp -d %u

internal-sftp -d はCentOS 6.6 のopenssh 5.3pでは利用不可で、最新のopenssh 6.8pでは利用可能だった。
ちなみにこれはsftpログイン時のディレクトリを/homeではなく、ユーザの/home/user に移動させるための設定なので必須ではない。

あとはchrootユーザでログが取れるように/devをmountしておく。
(/dev/log が見えれば良いだけなので本当は/devごとは不要だけど簡単なので)

mkdir /home/dev
mount -o bind /dev /home/dev
useradd hoge -g sftpuser
chmod 705 /home/hoge

概要

  • chroot sftp userでもログが取れるように/devをbindでmount
  • /homeでchrootしているので、他のuser名(directory)は見えてしまう
  • chmod 705でgroupの権限を除外してsftpで他のuserのファイルは取れないようにしてる

apache自体がchrootされていない場合、cgi経由で/etc/passwd 等が見れるので、
user名が見えてしまうことはあまり気にしないことに。
なおapacheがsuexec化していない場合は、apache経由で他userのファイルも読める。

方法2 他のuser directory名も見せたくない場合

ChrootDirectoryをuserのホームディレクトリ自身にする。

Match Group sftpuser
  ChrootDirectory %h
  ForceCommand internal-sftp

ただし、opensshの仕様でChrootDirectoryはroot権限にする必要がある。しとかないと

fatal: bad ownership or modes for chroot directory "/home/hoge"

といって怒られる。なので諦めてホームディレクトリのownerはrootにしてしまって、
サブディレクトリを1個用意して、そこから下を触ってねという仕様にしてしまう。
あとは鍵も設定できるように.sshもuser権限にしておく。

useradd hoge
chown root:root /home/hoge
chmod 755 /home/hoge
mkdir -p /home/hoge/work
mkdir -p /home/hoge/.ssh
chown -R hoge:sftpuser /home/hoge/work
chown -R hoge:sftpuser /home/hoge/.ssh

workの下はpublic_htmlやtmpなどお好きにどうぞっていう。
ホームディレクトリ直下を好きに触れないというのはかなり違和感あるけど、
chrootかつsftp に縛るっていう時点で何かしらの制限ユーザということなので
そこだけ諦めてもらえば良いかなと。

この方法の欠点

  • 上に書いた通り、ホームディレクトリがユーザ権限じゃないので他のサーバと使い勝手が変わる
  • sftpログを取る場合ユーザごとのホームディレクトリの下に/dev/log を置く必要がある
補足: ユーザのホームディレクトリのownerはユーザのままにしたい

ChrootDirectoryはroot権限じゃないとダメなのでまずchroot用のディレクトリを作る。

Match Group sftpuser
  ChrootDirectory /chroot
  ForceCommand internal-sftp

/etc/passwd のユーザのホームディレクトリはいつもの/home/hoge で設定

hoge:x:1001:1001::/home/hoge:/sbin/noglogin

ただし、実際のユーザがsftpした場合のディレクトリはChrootDirectoryとホームディレクトリをくっつけた
/chroot/home/hoge になるので、ここにディレクトリを作ってあげる必要がある。

mkdir /chroot
useradd hoge -d /chroot/home/hoge -s /sbin/nologin

(ln -s /chroot/home/hoge /home/hoge とsymlink張れば解決できるけど)
この構成の何が欠点かというと、chrootユーザと通常ユーザが混在した場合でも
/etc/passwdのホームディレクトリは全員 /home/username となるのに、
実際のデータディレクトリは
通常ユーザ /home/username
chrootユーザ /chroot/home/username
となって管理がやや複雑になること?