「あるユーザだけファイルをアップロードするとパーミッションが 600 になる」と言われた。
ソフト側の設定でどうにでもなるのではないかと思ったが FileZilla はホスト毎にデフォルトのパーミッションを設定する機能が無いようなのでファイルが大量にあると大変なようだ(WinSCP にはあった気がする)。
現象を確認すると下記のような場合にファイルアップロード時にパーミッションが 600 になる。
- ユーザのホームディレクトリがそのユーザの所有物ではない(
useradd
するときに$HOME
を変更していたりする場合)
FileZilla に限らず sftp
コマンドでも同様の結果になった。(FileZilla に関しては再接続だと反映されず、アプリケーションを再起動したら反映されたりするので検証としてはちょっと微妙)
OpenSSH の SFTP サーバの設定では sftp-server
(/usr/libexec/openssh/sftp-server
等)か、internal-sftp
を選択出来るのだが、internal-sftp
を使用すると $HOME
の所有権に関わらず 600 になるっぽい。そんな仕様なのだろうか?
「なら適切な $HOME
で sftp-server
を使用しておけばいいじゃないか」ということになるんだけど、そうもいかないことがある。ChrootDirectory
は internal-sftp
でしか使えないので隔離された SFTP ユーザを作成するときは internal-sftp
を使わざるを得ない。
internal-sftp
と sftp-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
の場合
- ローカルのパーミッションが 666 の場合はアップロード先は 664 になる
- ローカルのパーミッションが 664 の場合はアップロード先は 664 になる
- ローカルのパーミッションが 644 の場合はアップロード先は 644 になる
-m 664
の場合
- ローカルのパーミッションに関わらずアップロード先は 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 002
や sftp-server -u 002
のように umask を指定するものは Stackoverflow などにたくさん記述があったが、internal-sftp -m 664
や sftp-server -m 664
のようにデフォルトパーミッションを指定しているものはあまり無かった気がする。また、internal-sftp
と sftp-server
の違いによるパーミッションの変化や $HOME
の所有者が異なる場合の挙動については情報がなかった。
「アップロードした人間が責任持ってパーミッションの設定まですればええやん」とも思うが、実際の運用ではこのあたりの知識が無いユーザが操作するので難しかったりする。umask を指定するよりデフォルトパーミッションを指定した方が楽だとも思うが、本当に参照・編集されたくないファイルに自動で読み取りや書き込み権限が付いてしまうのは恐ろしい。
既存の Subsystem
の設定が sftp-server
になっているけど chroot で SFTP 専用ユーザを作りたい。更に初期ディレクトリも指定したい、となるとこんな設定になるだろうか。-d start_directory
は ChrootDirectory
を使う場合はそこからの相対で指定する模様。なので下記の場合の初期パスは /var/www/html
となる。
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 設定どうなってるかよくわからん。
どっかにこの辺の検証結果まとまってないかな。