sshdの公開鍵・パスワード認証をユーザー毎に変える方法(chroot・umaskも設定)

 2024年8月9日

Binary code and lock shape on pixellated screen

sshd の認証方式を「公開鍵認証のみ」に制限すると、sftp でも公開鍵認証が必須となりますが、実務上、パスワード認証しか使えないアプリからのアップロードも例外的に許可したい場合があります。

今回は、そういう場合の実用解というか、落とし所を自分なりにまとめてみました。

ちなみに、パスワード認証の sftp 経由でアップロードしたいファイルは、WEB の静的コンテンツを想定しています。

細かいコマンドなどの説明は避け、概要と方針、また重要な設定のみ書かせていただきます。

あくまでも「やり方のひとつ」ですので、参考程度にお願います。

※この記事は追記、更新する可能性があります。

パスワード認証を許可したユーザだけをchroot監獄に送り込む

今回の「実用解」の全体像は以下のとおりです。

「sftp でのパスワード認証を一部ユーザーのみ許可。ただし、chroot の上、sftp のみを利用可とする。また、chroot したディレクトリ内にアップロード用ディレクトリを作成。WEB サーバからはそこを Alias などで参照する。」

それを受けた具体的な設定方針はこんな感じに。

  1. sftp でパスワード認証を許可するユーザー:グループは、例として「sftpuploder1:chrootupload」とする
    (この用途専用のユーザーとグループを用意)
  2. 「1」のユーザー向けに、chroot 用ディレクトリを用意
    例として「/var/www/chrootupload/sftpuploder1」とする
    (※祖先と自分が全て owner = root:root / mode = 755 であること。この方針で設置できない場合、場所を変える)
  3. 「1」のユーザーがアップロードできるディレクトリを「2」内に作成(※「2」には root 以外書き込めないため)
  4. WEB サーバからは「3」のディレクトリを Alias で参照するなり何なりして活用。(Virtualhost のホーム、シンボリックリンクで DocumentRoot 以下に練り込む…など)
    ※ WEB サーバからの書き込みがある場合は、WEBサーバ実行ユーザーの所属サブグループに chrootupload の追加が必要かも

また、sshd 側では以下の設定を行います。

  1. sshd / sftp の公開鍵認証・パスワード認証をユーザー毎に変更
  2. パスワード認証ユーザーのみ、shell ログインなどを禁止し sftp のみ許可する
  3. パスワード認証ユーザーのみ、chroot する
  4. パスワード認証ユーザーのみ、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)

一部を除いては日本語情報が溢れていそうな領域ですが、実運用である程度セキュリティを考慮すると、ごっそりセットで必要になりそうな気がするので、まとめておきました。

関連サイト:

Hatena Pocket Line

コメントを記入