インターネット公開 Linux サーバーの SSH 堅牢化チェックリスト
インターネットから SSH を受け付けなければならない Linux サーバー向けの、順序づけられたチェックリスト。何から手をつけるか、多くの一覧が外している点、そして後回しにしてよいもの。
この一覧の使い方
堅牢化チェックリストが失敗する理由はたいてい 1 つです。リスク順ではなく話題順に並んでいるため、上から潰していくとバナー設定のあたりで時間が尽き、認証にはついに辿り着かない。
こちらは順序づけてあります。第 1 節は、Linux サーバーが実際に乗っ取られる経路を取り除きます。1 時間しかないなら、第 1 節をやって止めてください——それ以下すべてを合わせたよりも価値があります。
この一覧は、任意のアドレスから SSH を受け付けなければならないサーバーを前提にしています。そうでないなら第 3 節はファイアウォール規則 1 本に縮み、それは良い知らせです。
1. 認証
侵害は、パッチの当たっていないデーモンよりも、有効な資格情報から始まる場合のほうがはるかに多いです。この節がすべてです。
- パスワード認証を完全に無効化する:PasswordAuthentication no。本書で最も価値の高い 1 行です——推測すべきパスワードがなければ、推測攻撃は成功しようがありません。
- あわせて KbdInteractiveAuthentication no も設定する。抜けると PAM が依然としてパスワード入力を提示し、パスワードは使えたままで、何も変わっていません。ファイルを読むのではなく sshd -T で検証してください。
- PermitRootLogin を prohibit-password に、root が直接接続しないなら no に設定する。root はあらゆる攻撃一覧の最初の名前です。
- 秘密鍵はパスフレーズで保護し、共有マシンには置かない。漏れた鍵は漏れたパスワードとまったく同じ悪さをし、漏れ方も同じです:盗まれたノート PC、誤ったコミット、CI ランナーの環境。
- 人が去ったら鍵を更新し、全アカウントの ~/.ssh/authorized_keys を棚卸しする。古い鍵は静かに溜まり、誰も取り除きません。
- AllowUsers または AllowGroups を明示的な一覧で設定する。鍵のみであっても、新しく作られたサービスアカウントが偶然リモートから到達可能になるのを防げます。
2. 到達できるものを減らす
「誰がログインできるか」の次の問いは「他に何が待ち受けているか」です。開いているポートはすべて、今この瞬間に誰かが試しているサービスです。
- 実際に何が待ち受けているかを棚卸しする:ホストで ss -tlnp を実行し、別のネットワークからどれが応答するか確認する。この 2 つの一覧が一致することはめったにありません。
- リモートである必要のないサービスは localhost にバインドする——特にデータベース。0.0.0.0 で待ち受ける PostgreSQL や Redis は、SSH がこれまでにもたらしたどの問題よりも大きな問題です。
- 既定拒否のファイアウォールを運用する:nftables かディストリビューションのフロントエンドで、名前を挙げたものだけを許可する。
- 可能なら SSH の送信元アドレスを制限する。正規の集合が小さく安定しているなら、これは最も安価な本物の対策です——そして誰かが出張した瞬間に機能しなくなります。
- ノイズ低減のためにポート 22 から移すことを検討する。ただしそれはノイズ低減であって防御ではないと理解したうえで。
3. ログイン失敗の自動遮断
鍵のみは推測が成功するリスクを取り除きます。トラフィックは取り除きません。この節はそのトラフィックの話です。
ボットはあなたの設定を知りません。接続を続け、パスワードを提示し、拒否され続けます——1 回ごとに TCP 接続、sshd のフォーク、ログ 1 行、CPU のひとかけらを消費して。放っておけば公開サーバーは 1 日に数千回を吸収し、ログは必要な出来事を失うほど速く回ります。
fail2ban が標準的な答えであり、妥当な出発点です。きちんと設定してください——bantime -1、自分のアドレスを ignoreip に、そしてサービスの状態ではなく遮断数の監視を。その故障の形は沈黙だからです。構造的な限界は、レンジを巡回するボットネットに対する単一アドレス遮断、作り直しに耐えない状態、そしてサーバー間で共有されない知識です。
SSH Protector は同じ仕事をマネージドエージェントとして行います:サブネット遮断、恒久かつ起動時に復元、sshd の設定から読む実際の SSH ポート、インストール時点でのアドレスのホワイトリスト登録、保護されたすべてのサーバー間での共有レピュテーション、そしてまだ動いているかに答えるコンソール。
4. sshd の設定詳細
設定する価値のある項目。個々は小さく、合わせると攻撃面が小さくなります。変更のたびに sshd -t を実行し、restart ではなく reload を。
- MaxAuthTries 3 —— 1 接続あたりの資格情報試行が減るので、同じ回数を試すのにより多くの接続が必要になります。
- MaxSessions と MaxStartups を下げる —— 同時に進行できる未認証接続の数を制限します。洪水が実際に消費するのはそこです。
- LoginGraceTime 30 —— 未認証の接続が 2 分も開いたままであるべきではありません。
- 本当に必要とするものがない限り X11Forwarding no と AllowAgentForwarding no。特にエージェント転送は、侵害された接続先にあなたの鍵を使わせてしまいます。
- 現代的なアルゴリズムのみ:レガシーな暗号、MAC、鍵交換方式を落とす。現行ディストリビューションの既定値は妥当なので、10 年前に書かれた堅牢化スニペットをコピーする前に確認してください——いくつかの有名なものは、いまや直すより壊すほうが多くなっています。
5. ログと検知
記録していないものは調査できませんし、既定の構成は期待より短くしか保持しません。
- sshd の LogLevel が最低でも INFO であることを確認する。QUIET では認証失敗を一切記録しません。
- journald の保持期間を延ばすか、ログをホストの外へ送る。侵害されたマシンのローカルジャーナルは攻撃者が編集できる証拠ですが、別の場所にある複製はそうではありません。
- 量ではなく意味のあることに警報を出す:見知らぬアドレスからの成功ログイン、鍵のみであるべきサーバーでの Accepted password 行、新しい sudoers エントリ、新しい authorized_keys エントリ。
- 成功ログインをときどき意識的に見直す。失敗はノイズであり、説明できない成功こそが本題です。
6. パッチと復旧
最後の 2 つ。両者の順序よりも、両方が存在することのほうが重要です。
sshd とカーネルを最新に保つ——変更手順が許すなら無人セキュリティ更新を有効に。OpenSSH には認証前の脆弱性があり、これからもあります。公開から大規模悪用までの窓は、いまや日単位です。
そしてバックアップ。他のどの性質よりも重要な性質が 1 つあります:サーバー自身が到達も削除もできない複製を少なくとも 1 つ持つこと。ランサムウェアの運用者は何かを暗号化する前にバックアップ先を探しますし、侵害されたホストが書き込めるマウントはバックアップではなく、破壊されるのを待っている 2 つ目の複製です。そして 1 つ復元してみること——一度も復元されていないバックアップは計画ではなく仮説です。
FAQ
- SSH 堅牢化で最も重要な 1 手は?
- パスワード認証を無効にすることです。PasswordAuthentication no と KbdInteractiveAuthentication no を設定すれば推測すべきパスワードが存在しなくなり、資格情報の推測攻撃という分類全体が「より難しい」ではなく「不可能」になります。労力に対する見返りで、これに並ぶ項目は堅牢化リストにありません。
- 堅牢化の一環として SSH ポートを変えるべきですか?
- ノイズ低減のためには価値がありますが、防御のためではありません。22 から移すとログイン失敗の量はたいてい 90% 以上減り、ログが再び読めるようになりますが、SSH はバージョンバナーで名乗るため、全範囲スキャナーはすぐに見つけます。ログの衛生管理として扱い、決して制御手段としては扱わないでください。
- fail2ban はまともな SSH 堅牢化の一部ですか?
- 妥当な土台であり、何もないよりはるかに良いです。bantime を -1 にし、自分のアドレスを ignoreip に入れ、サービスの状態ではなく遮断数を監視してください——ディストリビューションのアップグレードでフィルタが一致しなくなった jail は、平穏な一週間と見分けがつきません。
- MaxAuthTries はブルートフォースを防ぎますか?
- ごくわずかにしか防ぎません。1 接続内の資格情報試行を制限するだけなので、攻撃者は接続を増やすだけです。相手のコストをわずかに上げますが、結果は変わりません。3 に設定する価値はありますが防御ではありません——トラフィックを実際に減らすのは、ファイアウォールで送信元を遮断することです。
