CentOSでsftpサーバを構築する
久々に備忘録。
経緯
- 知人にファイルの伝送をすることになったが用意されたのがftp
- 躊躇しつつアップロードするがchecksum失敗、リトライしても失敗
- よし、代わりの環境を用意しよう
どうするのか
手間とお金のかからないSFTPにしよう*1
環境
$ cat /etc/redhat-release; uname -r CentOS release 6.7 (Final) 2.6.32-573.7.1.el6.x86_64
手順
sftp用にsshdの導入
管理用のsshdとはPortを別にするため追加でコンパイルしています。既存のsshdに相乗りする場合は本項は飛ばして設定から。
cd /usr/local/src/ wget http://ftp.jaist.ac.jp/pub/OpenBSD/OpenSSH/portable/openssh-7.1p1.tar.gz tar -xzf ./openssh-7.1p1.tar.gz cd ./openssh-7.1p1
コンパイルオプションを確認
./configure --help
Makefileの生成。今回はインストール先だけ変更します。
./configure --prefix=/usr/local/openssh-7.1p1
ファイルが足りないと怒られたので必要なパッケージを導入してリトライ
yum install openssh-devel yum install libssh2-devel ./configure --prefix=/usr/local/openssh-7.1p1
インストール
make && make install
sshdの設定変更
cd /usr/local/openssh-7.1p1 vi etc/sshd_config
変更点は以下の通り
diff etc/sshd_config* 13c13 < Port 11121 --- > #Port 22 19c19 < Protocol 2 --- > #Protocol 2 44c44 < PermitRootLogin no --- > #PermitRootLogin prohibit-password 126,133c126 < #Subsystem sftp /usr/local/openssh-7.1p1/libexec/sftp-server < Subsystem sftp internal-sftp < < Match User sftp < ChrootDirectory /sftp < X11Forwarding no < AllowTcpForwarding no < ForceCommand internal-sftp --- > Subsystem sftp /usr/local/openssh-7.1p1/libexec/sftp-server
今回は特定ユーザのみなのでMatch User
としているが複数ユーザがいる場合はUserではなくGroupでMatchさせるとよい
sshdの起動
一時的なものなので手で起動させてます。initスクリプトを書く際は既存のものを参考にどうぞ。また、既存のsshdに相乗りした場合は当然ですがservice
もしくは systemctl
で。
/usr/local/openssh-7.1p1/sbin/sshd -f /usr/local/openssh-7.1p1/etc/sshd_config
sftp用ユーザの作成
useradd sftp -d / passwd sftp
chroot用にHOME_DIRは'/'としておく
chroot用のディレクトリ作成
mkdir /sftp ls -ld /sftp
所有権がroot.root、パーミッションが755であること
外部から接続確認*2
SSH
$ ssh sftpserver -l sftp sakura@sftpserver's password: This service allows sftp connections only. Connection to sftpserver closed.
sftp接続のみ許可しているので接続出来ない(正常)
SFTP
from OSX
sftp -P 11121 sftp@sftpserver
from Linux
sftp -oPort=11121 sftp@sftpserver Connecting to sftpserver... sftp@sftpserver's password: sftp> ls test.img test.md5
ファイルが見れればOK
ハマりどころ
作業時間は確認含めて小1時間程度だったけど意外なところでつまづきポイントががが
chrootに失敗するため接続できない
ディレクトリの所有者が一般ユーザだったり、root以外に書き込み権限が付与されてたりすると失敗する。
ここで注意しないといけないのは、ChrootDirectory で指定するディレクトリは root ユーザーだけが書き込みできる状態でなければなりません。所有者が一般ユーザーだったり、権限が 777 だと /var/log/secure に以下のようなエラーが吐かれます。
sshd[17779]: fatal: bad ownership or modes for chroot directory "/var/www"
CentOS の OpenSSH で chroot を設定する
そういえばchroot(1)ってroot onlyだった気がするなあ。
接続には成功するがファイルの一覧が取得できない
chroot先のディレクトリのパーミッションを705か755にすること。
700ではCouldn't get handle: Permission denied
とエラーが出るのに704(o+r)では何もエラーが出ない(そしてファイルの一覧も出ない)のでちょっと悩みました。
上記二項を鑑みての振り返り
共有ユーザが複数おり、同じディレクトリを共有する場合はグループで管理する(sftpusersなど)ことが必須。 この場合ディレクトリの所有者と権限は root.sftpusers 750( or 755 ) とする。
同じディレクトリを共有する要件がない場合は自由だが同じディレクトリを共有するケースに合わせておいた方があとあと運用が変更になっても設計を変更しなくて良い。これ大事。
sshdの設定もMatch Group
で括った上で個別に必要な要件があればMatch User
で設定する……という形が良いと思われる。が、その場合正しく設定が反映されるのかは確認してないので検証が必要かも。