TT Lab
はじめる
学ぶ 学習パス コース

SSHとファイル転送

sshdハードニングの順序と検証

TT Labで続きを見る

一言でいうと

sshdの設定を変えるときに最も重要なのは、どの値を入れるかではなく、どの順序で確認するかです。間違えると、自分自身を締め出してしまいます。

なぜ必要なのか

リモートサーバーのsshd設定を変更することは、乗っている木の枝を切ることと同じです。設定が間違っているとsshdが起動せず、起動しなければ入る方法がありません。コンソールにアクセスできないクラウドインスタンスなら、インスタンスを丸ごと作り直す必要が出るかもしれません。

そのため、手順があります。

  1. 現在のセッションを維持したまま、新しいターミナルをもう1つ開いておきます
  2. 設定ファイルを修正します
  3. sshd -tで構文を検査します
  4. サービスをリロードします
  5. 既存のセッションを閉じずに、新しいターミナルで接続を確認します
  6. 確認が終わったあとにだけ、既存のセッションを閉じます

3つ目と5つ目を飛ばす人が、本当に多いです。そして、そのうちの一部が明け方にデータセンターへ向かいます。

どう動くのか

検査コマンドは2つあります。

sshd -t                      # 문법만 검사
sshd -T | sort | head -40    # 실제 적용될 유효 설정 전체 출력
sshd -T -C user=deploy,host=10.0.3.14,addr=10.0.3.14 | grep -i 'passwordauth\|pubkey'

-tは構文だけを見ます。-Tは最終的に適用される値をすべて表示します。この違いが重要なのは、最近のディストリビューションが設定を分割するからです。

Include /etc/ssh/sshd_config.d/*.conf

同じキーが複数回現れると、sshdは最初の値を使います。そのため、Includeがファイルの前のほうにあれば断片ファイルが勝ち、後ろのほうにあれば本体が勝ちます。「確かに変更したのに効かない」の半分は、ここから来ます。-Tで確認する習慣が、この問題を根本から断ちます。

推奨設定と、各値の意味です。

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
AllowGroups sshusers
X11Forwarding no
PermitEmptyPasswords no
LogLevel VERBOSE

Matchブロックで例外を作ります。

Match Group sftponly
  ChrootDirectory /srv/sftp/%u
  ForceCommand internal-sftp
  AllowTcpForwarding no

Matchは、条件が合うと、次のMatchまたはファイルの末尾までの設定を上書きします。同じキーワードが複数のMatchで満たされると、最初のものだけが適用されます。順序が結果を変えるので、sshd -T -C ...で必ず検証します。

現場での姿

接続できないときの層別の診断。3つのメッセージの区別が、診断の半分です。

そしてssh -vvvを読むコツです。debug1: Connecting toまで進めなければ、ネットワークの問題で、Offering public keyのあとにAuthentications that can continueが繰り返されるなら、サーバーがその鍵を拒否したのです。

締め付けて、自分自身を締め出さない方法

sshdの設定を締める作業は、自分自身を外へ追い出してしまいかねない、数少ない作業の1つです。順序を守れば、その危険はなくなります。

今のセッションを絶対に切りません。sshdを再起動しても、すでに確立された接続は維持されます。ですから、そのセッションを生かしたまま、新しいウィンドウで接続を試します。通ればそのときに元のセッションを閉じ、通らなければ元のセッションで元に戻します。

sshd -t                       # 문법 검사. 통과해야 재시작한다
systemctl reload sshd
ssh -o BatchMode=yes user@host true   # 다른 창에서

設定ファイルを2か所とも見ます。最近のディストリビューションは/etc/ssh/sshd_config.d/*.confを読み込み、先に出た値が勝ちます。本体のファイルを変更したのに効かないなら、ドロップインが先に決めているのです。

sshd -T | grep -iE 'permitrootlogin|passwordauth|pubkeyauth|port'

sshd -Tは実際に適用される値を表示します。ファイルを読むより、こちらのほうが正確です。

一度にすべてを締めません。パスワード認証をオフにする前に、全員が鍵で入れるかを先に確認します。確認せずにオフにすると、その瞬間から入れない人が出て、その事実を、その人が必要なときに知ることになります。

ポートを変えるのは、セキュリティではなくノイズの削減です。自動スキャンのログは減りますが、実際の攻撃は防げません。代わりに、ファイアウォールで接続できる接続元を制限したり、fail2banで繰り返しの失敗を遮断したりするほうが、実効があります。

本当に価値が大きい3つは、これです。

設定 効果
PasswordAuthentication no ブルートフォース攻撃が通用しない
PermitRootLogin no アカウント名をもう1つ突き止める必要がある
AllowGroups ssh-users 新しいアカウントが自動でログイン権限を得ない

コンソールへのアクセスを確保しておきます。クラウドのシリアルコンソールやIPMIで入れるかどうかを、事前に確認します。sshでしか届かないサーバーでsshdの設定を締めるのは、元に戻す道がない作業になります。

次のラボですること

drop-in設定ファイルでsshdをハードニングし、sshd -tとsshd -Tで検証します。Matchブロックを作って条件付きの適用まで確認し、最後に、鍵での接続は引き続き通り、パスワード認証は拒否されるかを、実際に試します。