mattintosh note

どこかのエンジニアモドキの備忘録

SFTP サーバの設定でファイルのパーミッションが 600 になってしまう挙動のメモ

「あるユーザだけファイルをアップロードするとパーミッションが 600 になる」と言われた。

ソフト側の設定でどうにでもなるのではないかと思ったが FileZilla はホスト毎にデフォルトのパーミッションを設定する機能が無いようなのでファイルが大量にあると大変なようだ(WinSCP にはあった気がする)。

現象を確認すると下記のような場合にファイルアップロード時にパーミッションが 600 になる。

  • ユーザのホームディレクトリがそのユーザの所有物ではない(useradd するときに $HOME を変更していたりする場合)

FileZilla に限らず sftp コマンドでも同様の結果になった。(FileZilla に関しては再接続だと反映されず、アプリケーションを再起動したら反映されたりするので検証としてはちょっと微妙)

OpenSSH の SFTP サーバの設定では sftp-server/usr/libexec/openssh/sftp-server 等)か、internal-sftp を選択出来るのだが、internal-sftp を使用すると $HOME の所有権に関わらず 600 になるっぽい。そんな仕様なのだろうか?

「なら適切な $HOMEsftp-server を使用しておけばいいじゃないか」ということになるんだけど、そうもいかないことがある。ChrootDirectoryinternal-sftp でしか使えないので隔離された SFTP ユーザを作成するときは internal-sftp を使わざるを得ない。

internal-sftpsftp-server にはファイルやディレクトリのパーミッションを設定する二つのオプションがある。

-u umask Sets an explicit umask(2) to be applied to newly-created files and directories, instead of the user's default mask. -m force_file_perms Sets explicit file permissions to be applied to newly-created files instead of the default or client requested mode. Numeric values include: 777, 755, 750, 666, 644, 640, etc. Option -u is ineffective if -m is set.

-u オプションは umask によってパーミッションを決め、-mパーミッションを指定出来る。-m が設定されている場合、-u は動作しない。

どちらも結果的に同じことになることもあるが、転送元が Unix/Linux の場合はローカルのパーミッションによってアップロードされたファイルのパーミッションが異なる可能性が考えられる。

-u 002 の場合

-m 664 の場合

まとめるとこう。

Local -u 002 -m 664
644 rw-r--r-- 644 rw-r--r-- 664 rw-rw-r--
664 rw-rw-r-- 664 rw-rw-r-- 664 rw-rw-r--
666 rw-rw-rw 664 rw-rw-r-- 664 rw-rw-r--

運用上困ることがあるのは 644 になってしまう場合で、複数ユーザで管理している Web サーバ上のファイルがオーナー以外編集出来なくなってしまう可能性がある。これ、Linux ユーザなら umask 0002 が定番なんだけど macOS は umask 0022 になっているのでよくある。

パーミッションの問題に関して internal-sftp -u 002sftp-server -u 002 のように umask を指定するものは Stackoverflow などにたくさん記述があったが、internal-sftp -m 664sftp-server -m 664 のようにデフォルトパーミッションを指定しているものはあまり無かった気がする。また、internal-sftpsftp-server の違いによるパーミッションの変化や $HOME の所有者が異なる場合の挙動については情報がなかった。

「アップロードした人間が責任持ってパーミッションの設定まですればええやん」とも思うが、実際の運用ではこのあたりの知識が無いユーザが操作するので難しかったりする。umask を指定するよりデフォルトパーミッションを指定した方が楽だとも思うが、本当に参照・編集されたくないファイルに自動で読み取りや書き込み権限が付いてしまうのは恐ろしい。

既存の Subsystem の設定が sftp-server になっているけど chroot で SFTP 専用ユーザを作りたい。更に初期ディレクトリも指定したい、となるとこんな設定になるだろうか。-d start_directoryChrootDirectory を使う場合はそこからの相対で指定する模様。なので下記の場合の初期パスは /var/www/html となる。

/etc/ssh/sshd_config

Subsystem sftp /usr/libexec/openssh/sftp-server

Match User sftp-user
    ChrootDirectory /var/www
    ForceCommand internal-sftp -u 2 -d html
    DisableForwarding yes

FileZillaディレクトリを試してみたけどローカルで 755 なのにアップロードすると 775 になるので umask が反映されていない気がする…。FileZilla の umask 設定どうなってるかよくわからん。

どっかにこの辺の検証結果まとまってないかな。