エラーの全文
以前に接続したことのあるサーバーにSSH接続しようとすると、このエラーが表示されます:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:abc123xyz...
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/user/.ssh/known_hosts:42
ED25519 host key for 192.168.1.100 has changed and you have requested strict checking.
Host key verification failed.
接続がブロックされました。解決するまでサーバーにアクセスできません。
何が起きているのか
SSHは接続したことのあるサーバーのフィンガープリントを~/.ssh/known_hostsに保存しています。多忙なシステム管理者のマシンでは、このファイルに数百件のエントリが入っていることもあります。接続するたびに、SSHはサーバーの現在のキーと保存されているキーを比較します。不一致があればブロックされます。
これが起きる最も一般的な正当な理由:
- サーバーが再構築またはリイメージされた — OSをクリーンインストールすると新しいSSHホストキーが生成される
- サーバーのIPが別のマシンに割り当て直された
- 管理者がSSHホストキーを手動で再生成した
- ロードバランサーを経由して、前回とは異なるバックエンドノードに接続している
- サーバーが新しいクラウドインスタンスに移行した(AWS EC2の入れ替え、GCPの再構築など)
そして、まれではありますが、本物のman-in-the-middle攻撃の可能性もあります。サーバーで何が変わったか不明な場合は、作業を進める前にチームに確認してください。
修正1:問題のあるキーを削除する(手早い方法)
エラーメッセージには、known_hostsのどの行が問題を引き起こしているか正確に示されています。上の例では42行目です。ssh-keygen -Rで削除しましょう:
# ホスト名で削除
ssh-keygen -R hostname
# IPアドレスで削除
ssh-keygen -R 192.168.1.100
# hostname:port形式で削除(非標準ポートの場合)
ssh-keygen -R [hostname]:2222
古いエントリが削除されます。バックアップは~/.ssh/known_hosts.oldに保存されます。再接続すると、SSHが新しいフィンガープリントの承認を求めます:
ssh user@192.168.1.100
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ED25519 key fingerprint is SHA256:newfingerprint...
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.1.100' (ED25519) to the list of hosts.
修正2:known_hostsを手動で編集する
ssh-keygen -Rが使えない場合や、より細かく制御したい場合は、エラー出力に行番号(例:42行目)が示されているので、直接削除できます:
sed -i '42d' ~/.ssh/known_hosts
またはエディタでファイルを開いて、サーバーのホスト名またはIPから始まる行を削除するだけです。結果は同じです。
修正3:known_hostsを更新せずに一時的に接続する
known_hostsに触れずに今すぐ接続する必要がある場合は、2つのオプションで対応できます:
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@192.168.1.100
このセッションのみ、ホストキーの検証を完全にスキップします。**これを恒久的な設定にしないでください。**ホストキーチェックの意味がなくなってしまいます。接続先のマシンが確実に正しいと分かっていて、素早く作業する必要がある場合にのみ使用してください。
修正4:自動化スクリプトとAnsible
キーがローテーションされる複数のサーバーに対してAnsibleプレイブックやスクリプトを実行している場合は、~/.ssh/configでホストごとに厳密なホストチェックを無効化できます:
Host 192.168.1.*
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
より安全な設定で特定の環境にスコープを絞るのがベストです:
Host staging-*.example.com
StrictHostKeyChecking accept-new
UserKnownHostsFile ~/.ssh/known_hosts_staging
StrictHostKeyChecking accept-newは初めて接続するホストのキーを自動的に承認しますが、既知のキーが変更された場合はブロックします。ステージング環境に最適な設定です。
修正の確認
古いキーを削除して新しいキーを承認したら、簡単に動作確認をしましょう:
ssh user@192.168.1.100 'hostname && uptime'
新しいキーが正しく保存されていることを確認します:
ssh-keygen -F 192.168.1.100
# Host 192.168.1.100 found: line 42
192.168.1.100 ED25519 AAAAC3NzaC1lZDI1NTE5AAAA...
フィンガープリントを手動で確認したい場合は、サーバーにコンソールでログイン(SSH経由ではなく)して実行します:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
このフィンガープリントは、接続時にSSHが表示したものとバイト単位で完全に一致しているはずです。
繰り返し発生する場合
再接続するたびにこのエラーが出る場合は、一時的なキー変更ではなく、構造的な問題が原因です:
- 複数のバックエンドを持つロードバランサー — 各バックエンドは独自のホストキーを持っています。対策:すべてのバックエンドで同じホストキーを共有するか、1つのバックエンドに固定されたフローティングIPを使用する。
- Dockerコンテナの再起動 — 新しいコンテナが起動するたびに新しいSSHホストキーが生成されます。対策:
/etc/sshを永続ボリュームとしてマウントして、再起動後もキーが保持されるようにする。 - クラウドのオートスケーリング — AWS Auto Scaling、GCPのマネージドインスタンスグループなどは新しいキーを持つ新しいインスタンスを起動します。対策:SSHホストキーをAMIやマシンイメージに組み込むか、起動時にシークレットマネージャー(AWS Secrets Manager、HashiCorp Vault)から復元する。
予防策
自分で管理しているサーバーがある場合は、初期セットアップ直後にホストキーをバックアップしておきましょう:
sudo tar czf /root/ssh-host-keys-backup.tar.gz /etc/ssh/ssh_host_*
次回そのサーバーを再構築する際は、sshdを起動する前にキーを復元します。クライアントのknown_hostsエントリはそのまま有効です。誰も怖い警告を見ることはありません。

