sshdの公開鍵・パスワード認証をユーザー毎に変える方法(chroot・umaskも設定)
sshd の認証方式を「公開鍵認証のみ」に制限すると、sftp でも公開鍵認証が必須となりますが、実務上、パスワード認証しか使えないアプリからのアップロードも例外的に許可したい場合があります。
今回は、そういう場合の実用解というか、落とし所を自分なりにまとめてみました。
ちなみに、パスワード認証の sftp 経由でアップロードしたいファイルは、WEB の静的コンテンツを想定しています。
細かいコマンドなどの説明は避け、概要と方針、また重要な設定のみ書かせていただきます。
あくまでも「やり方のひとつ」ですので、参考程度にお願います。
※この記事は追記、更新する可能性があります。
パスワード認証を許可したユーザだけをchroot監獄に送り込む
今回の「実用解」の全体像は以下のとおりです。
「sftp でのパスワード認証を一部ユーザーのみ許可。ただし、chroot の上、sftp のみを利用可とする。また、chroot したディレクトリ内にアップロード用ディレクトリを作成。WEB サーバからはそこを Alias などで参照する。」
それを受けた具体的な設定方針はこんな感じに。
- sftp でパスワード認証を許可するユーザー:グループは、例として「sftpuploder1:chrootupload」とする
(この用途専用のユーザーとグループを用意) - 「1」のユーザー向けに、chroot 用ディレクトリを用意
例として「/var/www/chrootupload/sftpuploder1」とする
(※祖先と自分が全て owner = root:root / mode = 755 であること。この方針で設置できない場合、場所を変える) - 「1」のユーザーがアップロードできるディレクトリを「2」内に作成(※「2」には root 以外書き込めないため)
- WEB サーバからは「3」のディレクトリを Alias で参照するなり何なりして活用。(Virtualhost のホーム、シンボリックリンクで DocumentRoot 以下に練り込む…など)
※ WEB サーバからの書き込みがある場合は、WEBサーバ実行ユーザーの所属サブグループに chrootupload の追加が必要かも
また、sshd 側では以下の設定を行います。
- sshd / sftp の公開鍵認証・パスワード認証をユーザー毎に変更
- パスワード認証ユーザーのみ、shell ログインなどを禁止し sftp のみ許可する
- パスワード認証ユーザーのみ、chroot する
- パスワード認証ユーザーのみ、sftp 時の umask を設定する
これは、具体的には /etc/ssh/sshd_config の最後に以下を追加することで設定できます。
Match Group chrootupload ChrootDirectory /var/www/chroot/%u PasswordAuthentication yes X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp -u 002
Match は条件分岐で、先の「1」を実現する部分です。この例では chrootupdload グループだけに設定を適用しています。
chrootDirectory は、chroot するディレクトリを指定しています。%u は認証ユーザー名。(%h でホームディレクトリを表すことも可)
PasswordAuthentication yes は、パスワード認証を有効にしています。
最後の、ForceCommand は、chroot とセットで使うおまじない的な部分です。お尻の「-u 002」は umask が不要なら外してください。(internal-sftp でも –u オプションは使えます。)
なお、今回のように chroot する場合は、/etc/ssh/sshd_config の Subsystem も書き換える必要があります。
# override default of no subsystems #Subsystem sftp /usr/libexec/openssh/sftp-server Subsystem sftp internal-sftp -u 002
この設定をしないと、/var/log/secure に「error: subsystem: cannot stat /usr/libexec/openssh/sftp-server: No such file or directory」エラーが出てしまいます。
アップロード用ディレクトリのパーミッションに注意
Filezilla からの sftp 接続時に「Network error: Software caused connection abort」と出る場合など、うまく接続できない場合は、chroot 用のディレクトリの権限を疑うとよいかもしれません。
sshd_config の ChrootDirectory で指定したディレクトリと、その全ての祖先ディレクトリは、owner = root:root / mode = 755 である必要があります。
この制限は、chroot するディレクトリ、つまりは今回で言うところのアップロードディレクトリを置く場所の制約にもつながるため、若干面倒な部分ではあります。
余談
この手の設定は、ユーザー・グループやディレクトリの権限など、セキュリティ絡みで考える要素が多い部分で、なかなか面白い所ではあります。
今回の例で言えば、パスワード認証ユーザーを一般ユーザと別グループにするかどうか、とか、アップロードディレクトリで setgid / setuid する運用など、いろんな選択肢がある部分です。
そんなこんなもあって、今回は多くのケースで不要そうな umask の話もあえて出してみました。
なお、この記事には、古い OpenSSH では動かない設定内容が含まれています。(sftp の chroot と setuid)
一部を除いては日本語情報が溢れていそうな領域ですが、実運用である程度セキュリティを考慮すると、ごっそりセットで必要になりそうな気がするので、まとめておきました。
関連サイト: