SSHサーバーを堅牢化するための10の必須ベストプラクティス
より安全な認証、最小権限アクセス、ファイアウォールルール、レート制限、アップデート、ログチェックでSSHサーバーを堅牢化します。
SSHサーバーを堅牢化するための10の必須ベストプラクティス
Secure Shell(SSH)は通常、サーバーへの玄関口です。この玄関が弱いパスワードを受け入れたり、直接のrootログインを許可したり、インターネット全体からのトラフィックを許可したりすると、攻撃者はすぐにそれを見つけます。
このガイドでは、一般的なLinuxディストリビューション上のOpenSSHに適用できる、10の実践的なSSHサーバー堅牢化手順を紹介します。各変更をテストする間、1つの作業セッションを開いたままにして、ファイアウォールルールや設定の編集で新しいログインがブロックされた場合に復旧できるようにしてください。
1. デフォルトのSSHポートを変更する
デフォルトのSSHポートは22です。これは広く知られており、脆弱なサーバーを探す自動化されたボットによって常にスキャンされています。デフォルトポートを変更することで、シンプルでありながら効果的な難読化の層を提供します。それ自体はセキュリティ対策ではありませんが、自動スキャンからのノイズを大幅に減らし、日和見的な攻撃の多くを回避するのに役立ちます。
ポートを変更するには、通常/etc/ssh/sshd_configにあるsshd_configファイルを編集します。
sudo nano /etc/ssh/sshd_config
Port 22という行を見つけ(存在しない場合は追加し)、22を非標準で未割り当てのポート番号(例:2222、49152-65535はユーザー/動的ポート)に変更します。
#Port 22
Port 2222
SSHを再起動する前に、ファイアウォールで新しいポートを許可します。次に、ポート22へのアクセスを削除する前に、新しいポートで新しいログインをテストします。
# UFW(Uncomplicated Firewall)の場合:
sudo ufw allow 2222/tcp
sudo ufw reload
# Firewalldの場合:
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo sshd -t
sudo systemctl restart sshd
ヒント: 設定変更をテストする間は、常に少なくとも1つのSSHセッションを開いたままにしてください。ロックアウトされた場合、アクティブなセッションで変更を元に戻すことができます。
2. rootログインを無効にする
SSHを介した直接のrootログインは強く推奨されません。rootユーザーは無制限の権限を持っているため、攻撃者の主要な標的になります。攻撃者がrootアクセスを獲得すると、システムを完全に制御できます。代わりに、通常の非特権ユーザーとしてログインし、sudoを使用して管理タスクを実行します。
sshd_configで、PermitRootLoginディレクティブを見つけ、noに設定します。
PermitRootLogin no
保存してSSHサービスを再起動します:
sudo systemctl restart sshd
3. キーベースの認証を使用する
パスワードベースの認証は、特にユーザーが弱いパスワードを選択した場合、ブルートフォース攻撃や辞書攻撃に対して脆弱です。SSHキーベースの認証は、はるかに安全な代替手段です。これは、サーバーに保存される公開鍵とローカルマシンに保持される秘密鍵のペアを使用します。一致する秘密鍵を持つクライアントのみが認証できます。
キーベースの認証を実装する手順(簡略):
ローカルマシンでキーペアを生成します:
ssh-keygen -t ed25519 -C "[email protected]"ed25519は、固定キーサイズの最新の安全なアルゴリズムです。rsaも一般的です。RSAを使用する場合は、ssh-keygen -t rsa -b 4096のように大きなキーを生成します。
公開鍵をサーバーにコピーします:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your_server_ipまたは、ログインするユーザーのサーバー上の
~/.ssh/authorized_keysに~/.ssh/id_ed25519.pubの内容を手動で追加します。サーバー上の正しい権限を確認します:
~/.sshディレクトリ:700(所有者のみrwx)~/.ssh/authorized_keysファイル:600(所有者のみrw)
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys
4. パスワード認証を無効にする
必要なすべてのユーザーに対してキーベースの認証を正常に設定してテストしたら、パスワード認証を完全に無効にする必要があります。これにより、ブルートフォースパスワード攻撃を不可能にすることで、SSHセキュリティの最も弱い部分が取り除かれます。
sshd_configで、PasswordAuthenticationをnoに設定します。
PasswordAuthentication no
KbdInteractiveAuthentication no
一部のディストリビューションでは、PAMやキーボードインタラクティブ認証が、無効にしない限りパスワードを要求し続けることがあります。既存のセッションを閉じる前に、新しいターミナルでテストしてください。
保存してSSHサービスを再起動します:
sudo systemctl restart sshd
警告: アクセスが必要なすべてのユーザーに対してキーベースの認証が正しく機能することを確認する前に、パスワード認証を無効にしないでください。そうしないと、サーバーからロックアウトされるリスクがあります。
5. ユーザーアクセスを制限する
デフォルトでは、サーバー上のすべてのユーザーアカウントがSSH経由でログインを試みることができます。特定のユーザーまたはグループのみにSSHアクセスを制限することで、攻撃対象領域を最小限に抑えることができます。
sshd_configでAllowUsersまたはAllowGroupsディレクティブを使用します。
特定のユーザーのみを許可する場合(例:adminuser、devuser):
AllowUsers adminuser devuser
特定のグループのメンバーのみを許可する場合(例:sshusers):
AllowGroups sshusers
ヒント: 複数のユーザーがいる場合は、AllowGroupsを使用する方が一般的に優れています。SSHアクセス用の専用グループを作成し、承認されたユーザーを追加します。
sudo groupadd sshusers
sudo usermod -aG sshusers adminuser
sudo usermod -aG sshusers devuser
変更後、保存してSSHを再起動します。
6. SSHキーに強力なパスフレーズを使用する
キーベースの認証は堅牢ですが、秘密鍵は依然として重要な資産です。攻撃者がローカルマシンにアクセスした場合、秘密鍵を盗まれる可能性があります。強力なパスフレーズは秘密鍵を暗号化し、使用前にパスフレーズの入力を要求します。これにより、たとえ鍵が悪意のある者の手に渡っても、鍵を保護する追加のセキュリティ層が追加されます。
SSHキーを生成するとき(手順3のように)、パスフレーズの入力を求められます。他のどのパスワードとも異なる、長く、複雑で、覚えやすいパスフレーズを選択してください。
7. 接続レート制限を実装する(Fail2Ban)
キーベースの認証を使用していても、SSHサーバーは依然として接続試行の対象となります。Fail2Banのようなツールは、SSHログを積極的に監視し、同じIPアドレスからの繰り返しの失敗したログイン試行を検出し、ファイアウォールルールを使用してそのIPアドレスを一定期間自動的にブロックできます。
インストール(Debian/Ubuntuの例):
sudo apt update
sudo apt install fail2ban
Fail2BanはデフォルトのSSHルールでそのまま動作しますが、jail.confをjail.localにコピーして編集することで設定をカスタマイズできます。
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
jail.local内で、[sshd]セクションのbantime、findtime、maxretryを調整できます。
[sshd]
enabled = true
port = 2222 # 新しいSSHポート
logpath = %(sshd_log)s
maxretry = 3
bantime = 1h
findtime = 10m
設定変更後にFail2Banを再起動します:
sudo systemctl restart fail2ban
8. SSHサーバーソフトウェアを最新の状態に保つ
ソフトウェアの脆弱性は常に発見され、修正されています。古いSSHデーモンソフトウェア(OpenSSH)を実行していると、既知のエクスプロイトにさらされる可能性があります。OpenSSHサーバーパッケージを含むサーバーのソフトウェアを定期的に更新することは、セキュリティの脆弱性にパッチを当てるために重要です。
# Debian/Ubuntuの場合:
sudo apt update && sudo apt upgrade
# CentOS/RHELの場合:
sudo yum update
# または
sudo dnf update
適切な場合にセキュリティ更新を自動的に適用するようにシステムを設定するか、手動更新のルーチンを確立します。
9. SSHログを監視して不審なアクティビティを検出する
強力な予防策があっても、警戒が重要です。SSH認証ログを定期的に確認して、異常なパターン、失敗したログイン試行、または不正なアクセス試行を検出します。これにより、潜在的な侵害や進行中の攻撃を特定できます。
SSHログは通常、次の場所にあります:
/var/log/auth.log(Debian/Ubuntu)/var/log/secure(CentOS/RHEL)journalctlを使用(systemdシステム):sudo journalctl -u sshd -f
繰り返しの認証失敗、異常なIPアドレスからのログイン、または見慣れないユーザーによる成功したログインを探します。大規模な環境では、LogwatchやElastic Stack(ELK)などのツールがログ分析とアラートを自動化できます。
10. ファイアウォールルールを設定してアクセスを制限する
ファイアウォールは防御の最前線です。デフォルトでは、明示的に公開する必要があるサービスを除き、すべての着信トラフィックをブロックする必要があります。SSHの場合、選択したポート(例:2222)での接続のみを許可し、理想的には特定の信頼できるIPアドレスまたはネットワークからのみ許可することを意味します。
UFW(Uncomplicated Firewall)を使用した例:
特定のIPアドレス192.168.1.100からのSSHをポート2222で許可:
sudo ufw allow from 192.168.1.100 to any port 2222
特定のサブネット192.168.1.0/24からのSSHを許可:
sudo ufw allow from 192.168.1.0/24 to any port 2222
Firewalld(CentOS/RHEL)を使用した例:
特定のIPアドレス192.168.1.100からのSSHをポート2222で許可:
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port=2222 protocol="tcp" accept'
sudo firewall-cmd --reload
警告: 動的IPアドレスからサーバーを管理している場合は、厳格なファイアウォールルールに注意してください。より広い範囲からのアクセスを許可するか、VPNを使用する必要があるかもしれません。
追加の堅牢化のヒント
必須の10に加えて、さらにセキュリティを高めるために次のディレクティブを検討してください:
MaxAuthTries:接続ごとの認証試行回数を制限します。デフォルトは6です。減らす(例:3)とブルートフォースの可能性が減ります。sshd_configで設定します。MaxAuthTries 3LoginGraceTime:ユーザーが認証を完了できる時間を制限します。デフォルトは2分です。減らす(例:30s)と、低速攻撃の時間枠が減ります。LoginGraceTime 30sClientAliveIntervalとClientAliveCountMax:アイドル状態のSSHセッションが無期限に開いたままになるのを防ぎます。ClientAliveIntervalは、X秒ごとにキープアライブメッセージを送信します。ClientAliveCountMaxの応答が欠落すると、接続が終了します。ClientAliveInterval 300 ClientAliveCountMax 2Banner:認証前に警告メッセージを表示します。これは、潜在的な不正ユーザーへの法的通知として機能します。
希望する警告メッセージを含むBanner /etc/issue.net/etc/issue.netファイルを作成します。
実践的なポイント
最大のリスクを取り除く変更から始めましょう:rootログインを無効にし、SSHキーを要求し、接続できるユーザーを制限し、可能な場合は送信元ネットワークを制限します。現在のセッションを閉じる前に、sshd -tと新しいログインセッションですべての変更をテストしてください。