問題の本質:あなたのSSHサーバーは今この瞬間も狙われている
サーバーのポート22がインターネットに開放されているなら、すでにスキャンされています。「かもしれない」ではなく、今まさに起きていることです。公開されているLinuxサーバーで次のコマンドを実行してみてください:
sudo journalctl -u ssh --since "1 hour ago" | grep "Failed password" | wc -l
おそらく数十件、場合によっては数百件のログイン失敗が確認できるはずです。ボットは常にインターネット上のSSHポートをスキャンし、認証情報を総当たりで試し続けています。こうした攻撃を助長する最大の脆弱性は2つ——SSH経由でのrootログインを許可していること、そして暗号鍵の代わりにパスワード認証に頼っていることです。
パスワードはブルートフォースで破られる可能性があります。rootアカウントが乗っ取られれば、攻撃者は追加の手順なしにマシンを完全に掌握できます。この2つが重なると、簡単に侵害できるサーバーの出来上がりです。
根本原因:デフォルトのSSH設定がなぜ危険なのか
rootログインは最高権限アカウントを危険にさらす
ほとんどのLinuxディストリビューションは、デフォルトでrootのSSHログインを許可しています(少なくとも明示的にはブロックしていません)。rootログインが許可されている場合、攻撃者に必要なのはパスワード一つだけです。権限昇格のステップは不要——一度の成功で全てを掌握されてしまいます。
代わりにsudo権限を持つ一般ユーザーに切り替えましょう。これにより第二の防衛層が加わります。攻撃者がユーザーの認証情報を入手しても、実際の被害を与えるにはさらにsudoパスワードが必要になります。
パスワード認証は推測される可能性がある
強固なパスワードでも、十分な時間と計算リソースがあれば解読できます。SSHの公開鍵認証は非対称暗号を使用します——秘密鍵はあなたのマシンに、公開鍵はサーバーに置きます。秘密鍵ファイルがなければ、どれだけ計算能力があってもログインは数学的に不可能です。
私の本番Ubuntu 22.04サーバーでは、その差は明確に計測できました。公開鍵認証に切り替える前、サーバーは毎時200〜400件のパスワード認証失敗を処理していました。各試行はSSHハンドシェイクと鍵導出処理を発生させ、実際のCPU負荷となっていました。パスワード認証を完全に無効化した後、そのバックグラウンドノイズは消えました。
実践:SSHサーバーを段階的に強化する
ステップ1:sudo権限を持つ非rootユーザーを作成する
rootログインを無効化する前に、別のアクセス手段を確保してください。一般ユーザーがいない場合は作成します:
# サーバー上で実行
sudo adduser deployuser
sudo usermod -aG sudo deployuser
次のステップに進む前に、そのユーザーがsudoを使えることを確認してください:
su - deployuser
sudo whoami
# 出力されるはず: root
ステップ2:ローカルマシンでSSH鍵ペアを生成する
この操作はサーバーではなく、ローカルのワークステーションで行います:
ssh-keygen -t ed25519 -C "deployuser@myserver" -f ~/.ssh/myserver_ed25519
RSAよりもed25519を使用してください——高速で、鍵が短く(RSA-4096の700文字以上に対して68文字)、かつ同等のセキュリティを持ちます。-Cフラグは鍵を識別するコメントを追加します。パスフレーズを求められたら設定しましょう。これにより秘密鍵ファイルがローカルで暗号化されるため、たとえラップトップを盗まれても、パスフレーズなしでは鍵は使えません。
この操作で2つのファイルが生成されます:
~/.ssh/myserver_ed25519— 秘密鍵(絶対に共有しないこと)~/.ssh/myserver_ed25519.pub— 公開鍵(これをサーバーに置く)
ステップ3:公開鍵をサーバーにコピーする
最も簡単な方法:
ssh-copy-id -i ~/.ssh/myserver_ed25519.pub deployuser@your-server-ip
ssh-copy-idが使えない場合(macOSやWindowsでは一般的)、手動で行います:
# サーバー上でdeployuserとしてログインした状態で実行
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# このファイルに公開鍵の内容を貼り付ける
nano ~/.ssh/authorized_keys
パスワード認証を無効化する前に、公開鍵でのログインが機能することを確認してください:
ssh -i ~/.ssh/myserver_ed25519 deployuser@your-server-ip
パスワードを求められずに(鍵のパスフレーズは除く)ログインできれば、次のステップに進んでも大丈夫です。
ステップ4:SSHの設定でrootログインとパスワード認証を無効化する
SSHデーモンの設定ファイルを編集します:
sudo nano /etc/ssh/sshd_config
以下のディレクティブを見つけて更新します(存在しない場合は追加):
# rootログインを完全に無効化
PermitRootLogin no
# パスワード認証を無効化
PasswordAuthentication no
# 空のパスワードを無効化
PermitEmptyPasswords no
# 特定のユーザーのみ許可(任意だが推奨)
AllowUsers deployuser
# チャレンジレスポンス認証を無効化(PAMのキーボードインタラクティブを含む)
# OpenSSH 8.7以降はKbdInteractiveAuthenticationに名称変更 — 安全のため両方設定
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
# 切断された接続を検出するためのキープアライブ設定
ClientAliveInterval 300
ClientAliveCountMax 2
Ubuntu 22.04以降では注意が必要です。sshd_config.d/ディレクトリにオーバーライドファイルがないか確認してください:
ls /etc/ssh/sshd_config.d/
cat /etc/ssh/sshd_config.d/*.conf 2>/dev/null
Ubuntu 22.04には/etc/ssh/sshd_config.d/50-cloud-init.confが同梱されており、PasswordAuthentication yesを再有効化します。上書きするか削除してください:
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config.d/50-cloud-init.conf
# その行だけが含まれているなら削除してもよい
# sudo rm /etc/ssh/sshd_config.d/50-cloud-init.conf
ステップ5:設定を検証してSSHをリロードする
リロード前に必ず設定をテストしてください——構文エラーがあるとロックアウトされる可能性があります:
sudo sshd -t
# 出力なし = エラーなし
sudo systemctl reload ssh
# ディストリビューションによっては: sudo systemctl reload sshd
現在のSSHセッションは開いたままにしてください。新しいターミナルウィンドウを開いてログインをテストします:
ssh -i ~/.ssh/myserver_ed25519 deployuser@your-server-ip
パスワードログインが拒否されることも確認してください:
ssh deployuser@your-server-ip
# すぐに表示されるはず: Permission denied (publickey)
ステップ6:任意——デフォルトのSSHポートを変更する
ポート22を変更しても実質的なセキュリティ向上にはなりませんが、ログのノイズを劇的に減らす効果があります。ボットは主にポート22をスキャンするため、非標準ポートに移すと自動化された攻撃を私の経験では90%以上削減できます:
# /etc/ssh/sshd_config に記述
Port 2222
UFWを使用している場合:
sudo ufw allow 2222/tcp
sudo ufw delete allow ssh # ポート22のルールを削除
sudo ufw status
カスタムポートで接続する:
ssh -p 2222 -i ~/.ssh/myserver_ed25519 deployuser@your-server-ip
毎回ポートを入力しなくて済むよう、ローカルの~/.ssh/configにエントリを追加します:
Host myserver
HostName your-server-ip
User deployuser
Port 2222
IdentityFile ~/.ssh/myserver_ed25519
これでssh myserverだけで接続できるようになります。
ステップ7:変更が反映されたことを確認する
実行中のSSH設定を確認します:
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|port'
期待される出力:
port 2222
permitRootLogin no
passwordauthentication no
認証ログを確認して、ブルートフォース試行がパスワード段階ではなく鍵の段階で拒否されていることを確認します:
sudo tail -f /var/log/auth.log | grep sshd
ボーナス:複数のSSH鍵をすっきり管理する
複数のサーバーを管理する場合、鍵を整理しておくと混乱を防げます:
# ~/.ssh/config
Host production
HostName 203.0.113.10
User deployuser
Port 2222
IdentityFile ~/.ssh/prod_ed25519
Host staging
HostName 203.0.113.20
User deployuser
Port 22
IdentityFile ~/.ssh/staging_ed25519
設定ファイルのパーミッションを正しく設定します:
chmod 600 ~/.ssh/config
達成できたこと
完了です。SSHサーバーへのアクセスには暗号鍵が必要になりました。パスワードへのブルートフォース攻撃はもう通用しません。rootログインはブロックされ、万が一ユーザーアカウントが侵害されても被害を最小限に抑えられます。ポートも変更すれば、自動スキャンのノイズを90%以上削減できます。
この3つのステップ——専用の非rootユーザー、公開鍵認証、パスワードログインの禁止——でSSHの主要な攻撃面をカバーできます。可能であれば既知のIPアドレス範囲にSSHアクセスを制限するファイアウォールルールも追加すると、デフォルト設定と比べてサーバーのセキュリティは格段に向上します。
最後に一点:秘密鍵のバックアップを安全な場所に保管してください。バックアップなしで鍵を紛失すると、ロックアウトされてしまいます。パスワードマネージャーのセキュアノートや暗号化されたUSBドライブが有効な選択肢です。

