SSH「Host key verification failed」エラーの原因と対処法|安全な解決方法

  • 作成日 2026.06.18
  • linux
SSH「Host key verification failed」エラーの原因と対処法|安全な解決方法

リモートサーバーに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:xxxxxxxxxxxxxxxxxxxxxxx.
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /home/user/.ssh/known_hosts:5
Host key verification failed.

「中間者攻撃の可能性があります」という赤い警告が出るため、ネット記事に書いてある通り ssh-keygen -R で削除して何も考えずに対処してしまう方が多いのではないでしょうか。

しかし、このエラーは本来SSHのセキュリティ機能の正常動作で、原因によっては実際にMITM攻撃を受けている可能性もあります。「警告が出たら言われた通り削除する」習慣は危険です。

  • 警告が出たがどう対処すべきか分からない
  • ssh-keygen -R で消すのは安全か不安
  • Docker/Vagrant再起動のたびに警告が出る
  • EC2で再起動したら接続できなくなった
  • Git pushで突然このエラーが出る
  • CI/CDパイプラインで自動接続が止まった

本記事では、「Host key verification failed」エラーのすべての原因と対処法を、セキュリティ視点と実用性の両面から整理します。仕組みの理解、安全な対処手順、Docker/Vagrant/クラウド環境別の対処、CI/CD対応、再発防止策まで完全網羅。この1本で「ホスト鍵検証エラー」と適切に付き合えるようになります。


目次

結論:今すぐ試すべき3ステップ

時間がない方向けに、安全な手順を示します。

ステップ1:状況を確認(重要)

警告メッセージから以下を読み取ります:

  • どのホストでエラーが出たか
  • known_hosts の何行目が問題か
  • 新しいホスト鍵のフィンガープリント
Offending ED25519 key in /home/user/.ssh/known_hosts:5

~/.ssh/known_hosts の5行目が問題。

ステップ2:心当たりの確認

このサーバー、最近自分または管理者が以下のいずれかをしましたか?

  • サーバー再構築・OS再インストール
  • クラウドインスタンス再作成
  • Dockerコンテナ削除→再起動
  • IPアドレス変更・再割り当て

心当たりがある場合 → ステップ3へ ⚠️ 心当たりが全くない場合 → MITM攻撃の可能性。サーバー管理者に連絡し、別経路でフィンガープリントを確認してから対処

ステップ3:古いホスト鍵を削除

# ホスト名指定で削除
ssh-keygen -R hostname.example.com

# IPアドレス指定で削除
ssh-keygen -R 192.168.1.100

# ポート指定の場合
ssh-keygen -R '[hostname.example.com]:2222'

これでknown_hostsから該当エントリが削除され、次回SSH接続時に新しいホスト鍵を登録できます。


まず押さえる:ホスト鍵検証の仕組み

このエラーを理解するには、SSHのホスト鍵検証の仕組みを知る必要があります。

SSH接続の流れ

  1. クライアントがサーバーに接続要求
  2. サーバーが自身のホスト公開鍵を送信
  3. クライアントが~/.ssh/known_hostsから該当ホストの鍵を検索
  4. 記録された鍵と一致 → 接続を継続
  5. 未登録ホスト → ユーザーに確認後、known_hostsに追加
  6. 登録された鍵と異なる「Host key verification failed」を出してブロック

なぜホスト鍵検証が必要か

中間者(MITM)攻撃を防ぐためです。

[クライアント] ←→ [攻撃者がなりすまし] ←→ [本物のサーバー]
                       ↑
            通信を盗聴・改ざんできる

攻撃者が「サーバー」を装ってクライアントと通信した場合、攻撃者のホスト鍵が送られてきます。これを「初回登録時の鍵」と照合することで、なりすましを検出できます。

つまり、「Host key verification failed」は SSHが正しく仕事をしている証でもあります。


エラーが出る原因カテゴリ

カテゴリ頻度危険度
サーバー再構築系OS再インストール、Docker再作成低(自分の操作なら安全)
IP/ホスト名再利用系同じIPに別サーバー、DHCPで他人のIP割当
開発環境特有系Vagrant、Docker、VirtualBox
クラウド特有系EC2インスタンス停止→起動でIP変動
アルゴリズム変更系サーバー設定変更、OpenSSHバージョンアップ
MITM攻撃系実際の攻撃極高

順番に切り分けます。


【原因①】サーバー再構築・再インストール

最も多いケースです。

発生パターン

  • 同じホスト名・IPでOS再インストール
  • VPSで OS 入れ替え
  • Dockerコンテナを docker rm してから docker run で再作成
  • Vagrantで vagrant destroy → vagrant up
  • AMI更新でEC2再構築

サーバー側のホスト鍵は再構築時に新しく生成されるため、古いknown_hostsの記録と一致しなくなります。

対処

自分が再構築したなら安全なので、古いエントリを削除します。

# ホスト名で削除
ssh-keygen -R hostname.example.com

# IPアドレスで削除
ssh-keygen -R 192.168.1.100

# 削除確認(known_hostsを表示)
cat ~/.ssh/known_hosts | grep hostname

削除後、再度SSH接続すると新しいホスト鍵の登録確認が出ます:

The authenticity of host 'hostname.example.com (192.168.1.100)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

yes を入力すると新しい鍵が登録されます。


【原因②】IPアドレスの再利用

前は別のサーバーに割り当てられていたIPが、別のサーバーに再割り当て」されたケースです。

発生パターン

  • DHCPで割り当てられたIPが、別マシンに割り当て直された
  • クラウドの動的IPプール
  • 社内ネットワークの端末入れ替え
  • 公衆Wi-Fiで他人と同じIPを使用

対処

新しいサーバーが信頼できるなら、原因①と同じく削除して再登録:

ssh-keygen -R 192.168.1.100
ssh-keygen -R hostname.example.com  # ホスト名も登録されていれば

⚠️ ただし、同じホスト名で予期せず別のマシンに繋がっている場合、業務上の重要データを誤って別マシンに送るリスクがあります。心当たりがない場合は、ホスト名・IP・到達先を確認してから対処してください。


【原因③】Docker・Vagrant・VM環境

開発環境で最頻発するパターンです。

Dockerでの典型ケース

# コンテナ初回起動
docker run -d -p 2222:22 --name myssh ssh-server-image

# SSH接続OK
ssh -p 2222 user@localhost

# コンテナ削除→再作成
docker rm -f myssh
docker run -d -p 2222:22 --name myssh ssh-server-image

# SSH接続するとエラー!
ssh -p 2222 user@localhost
# → Host key verification failed

新コンテナは別のホスト鍵を生成するため、警告が出ます。

対処:ポート番号込みで削除

ssh-keygen -R '[localhost]:2222'

⚠️ ポート指定の場合、ホスト名は [hostname]:port のように角括弧付き形式です。

Docker環境の根本対処

毎回エラーが出るのを避けるには、SSH設定で警告を抑制:

# ~/.ssh/config
Host docker-dev
    HostName localhost
    Port 2222
    User root
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    LogLevel ERROR

これでssh docker-dev接続時に警告が出ず、known_hostsにも記録されません。

⚠️ 本番サーバーには絶対に設定しないこと。開発環境(localhost、Docker、VM)限定で使ってください。

Vagrantでの対処

Vagrantはvagrant sshコマンドが内部でホスト鍵検証を回避する設定を生成するため、Vagrant経由なら問題ありません。直接sshで繋ぐ場合は上記のSSH config設定を行ってください。


【原因④】クラウドVMの再起動・IP変更

AWS EC2やGCEで頻発します。

EC2でのよくあるパターン

  • インスタンスを停止 → 起動でパブリックIPが変動
  • 同じパブリックIPが他インスタンスに再割り当て

対処

ssh-keygen -R ec2-xx-xx-xx-xx.compute.amazonaws.com
ssh-keygen -R xx.xx.xx.xx

根本対処:Elastic IP / 静的IP の利用

クラウドの固定IP機能を使うと、再起動でIPが変わらず、ホスト鍵問題も発生しにくくなります。

  • AWS: Elastic IP
  • GCP: Static external IP
  • Azure: Static Public IP

ただし固定IPでも、インスタンス再構築時にはホスト鍵が変わるので注意。

EC2のホスト鍵をコンソールから確認

EC2の場合、システムログにホスト鍵フィンガープリントが出力されます:

aws ec2 get-console-output --instance-id i-xxxxxxxxx | grep -A 5 "BEGIN SSH HOST KEY"

または管理コンソールから「アクション → モニタリングおよびトラブルシューティング → システムログを取得」。

ここで表示されるフィンガープリントと、SSH接続時に表示される値が一致すれば、なりすましではなく正しいサーバーに繋がっていることを確認できます。


【原因⑤】サーバー側のホスト鍵変更・アルゴリズム更新

たまにあるケースです。

発生例

  • 古いホスト鍵(RSA 1024bit等)がセキュリティ要件で更新された
  • 管理者がホスト鍵を手動で再生成
  • OpenSSH のバージョンアップで使用アルゴリズムが変更

対処

サーバー管理者から「ホスト鍵を更新した」連絡があれば、新しいフィンガープリントを確認した上で削除・再登録:

ssh-keygen -R hostname.example.com
ssh hostname.example.com
# 接続時、新しいフィンガープリントが管理者から伝えられた値と一致することを確認

【原因⑥】実際のMITM攻撃の可能性(要注意)

最後に、本当に攻撃を受けているケースもあり得ます。確率は低いですが、無視できない可能性です。

注意すべきシナリオ

  • 公衆Wi-Fi・カフェ・空港等の信頼できないネットワーク
  • 管理者から再構築の連絡が無いのにエラーが出る
  • 同じネットワークの別端末では問題なく接続できる
  • フィンガープリントが毎回違う値になる

安全に判別する方法

1. 別経路でフィンガープリントを確認

サーバー管理者にSSH以外の手段(電話、社内チャット、メール等)で:

「現在のホスト鍵フィンガープリントを教えてください」

と問い合わせ、それと一致することを確認。

2. サーバーに直接ログインして確認

別の経路(コンソール、別の信頼できるネットワーク)でログインし、ホスト鍵フィンガープリントを取得:

# サーバー上で全ホスト鍵のフィンガープリント表示
for key in /etc/ssh/ssh_host_*_key.pub; do
    ssh-keygen -lf "$key"
done

これで表示される値と、エラーで提示された値が一致するか確認。

3. クラウドのコンソールログから確認

AWS EC2、GCP等は、インスタンス起動時にホスト鍵をシステムログに出力します。別経由でログを取得して確認。

一致しない場合

実際の攻撃の可能性があります。対応:

  • 当該ネットワークでの作業を中止
  • セキュリティチーム・管理者にエスカレート
  • パスワード等の機密情報を入力していないか確認・変更

known_hostsファイルを直接編集する

ssh-keygen -R以外の方法として、~/.ssh/known_hostsを直接編集することもできます。

ファイルの場所

# Linux/Mac
~/.ssh/known_hosts

# Windows (OpenSSH)
%USERPROFILE%\.ssh\known_hosts

ファイル内容の例

hostname.example.com,192.168.1.100 ssh-rsa AAAAB3NzaC1yc2EAAAAB...
[localhost]:2222 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlz...
|1|xxxxx|yyyyy ssh-ed25519 AAAAC3NzaC1lZDI1NTE5...

最後の|1|xxxxx|yyyyyはホスト名がハッシュ化されたエントリです(後述のHashKnownHosts機能)。

特定行を削除する例

# 5行目を削除(警告メッセージの:5 から特定)
sed -i.bak '5d' ~/.ssh/known_hosts

# Macの場合
sed -i '' '5d' ~/.ssh/known_hosts

全エントリ確認

# 平文ホスト名のエントリを確認
cat ~/.ssh/known_hosts | awk '{print $1}'

# ハッシュ化エントリが含まれる場合
ssh-keygen -H -f ~/.ssh/known_hosts  # 既存をハッシュ化
ssh-keygen -F hostname  # 検索(ハッシュ化エントリも見つかる)

バックアップを忘れずに

cp ~/.ssh/known_hosts ~/.ssh/known_hosts.bak

編集ミスでファイルが壊れると、全SSH接続で再登録が必要になります。


StrictHostKeyChecking 設定の使い分け

SSH の動作を細かく制御できる設定です。

設定値と挙動

動作
yes既知ホストのみ接続。未知ホストは拒否
accept-new未知ホストは自動登録、既知ホストの変更は拒否(推奨)
no または false警告を表示するが接続は続行(既知ホストの変更も)
off または ask(デフォルト)未知ホストは確認、変更は拒否

コマンドラインでの一時指定

# 一時的に警告を無視(信頼できる開発環境のみ)
ssh -o StrictHostKeyChecking=no user@host

# known_hostsを書き換えない
ssh -o UserKnownHostsFile=/dev/null user@host

# 両方を組み合わせて完全に無視
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@host

~/.ssh/config での恒久設定

# 全体的なデフォルト
Host *
    StrictHostKeyChecking accept-new

# 開発環境のみ無効化
Host dev-* docker-* vagrant-*
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    LogLevel ERROR

# 本番サーバーは厳格に
Host *.production.example.com
    StrictHostKeyChecking yes

accept-new が推奨される理由

OpenSSH 7.6(2017年)で導入された値です:

  • 初回接続時: 自動的に登録(プロンプト不要)
  • 2回目以降: 鍵が変わっていれば拒否

「初回登録の手間を減らしつつ、変更検知は確実に行う」というバランスの良い設定です。


Windows環境での対処

Windows標準のOpenSSH(Win10 1809以降)

Windows 10/11には標準でOpenSSHクライアントが入っています。

ssh user@host

対処は基本的にLinux/Macと同じ:

ssh-keygen -R hostname

known_hostsの場所: C:\Users\<username>\.ssh\known_hosts

PowerShellでの操作

# known_hosts内容確認
Get-Content ~/.ssh/known_hosts

# 特定ホストの削除
ssh-keygen -R hostname

# known_hosts丸ごとリセット
Remove-Item ~/.ssh/known_hosts

WSL/WSL2のSSH

WSLはLinux環境なのでLinuxと同じ手順:

ssh-keygen -R hostname

注意点として、WindowsホストのknownとWSL内のknownは別ファイルです。両方で問題が起きていないか確認してください。

PuTTY

PuTTYはOpenSSHと別のキャッシュを使います:

  1. レジストリエディタで以下を開く: HKEY_CURRENT_USER\SOFTWARE\SimonTatham\PuTTY\SshHostKeys
  2. 該当エントリを削除
  3. または、PuTTYで接続を試みた時に表示される「鍵の更新」確認に応答

Git for Windows

Git付属のbashも独自のknown_hostsを持つことがあります:

# Git Bash内で
ls ~/.ssh/
# 標準OpenSSHと同じ場所

Git経由のSSH接続でのエラー

GitHubやGitLabへのGit操作時に発生するケースです。

典型的なエラー

$ git push
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
...
Host key verification failed.
fatal: Could not read from remote repository.

GitHubの場合

GitHubは2023年3月にRSAホスト鍵をローテーションしました。古いknown_hostsのまま新規接続するとこのエラーが出る場合があります。

# 古い鍵を削除
ssh-keygen -R github.com

# 公式の新ホスト鍵を確認・追加
# 公式ドキュメント: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
ssh-keyscan github.com >> ~/.ssh/known_hosts

# 接続テスト
ssh -T git@github.com

ssh-keyscan の利用

ホスト鍵を自動取得する便利なコマンド:

# 単一ホスト
ssh-keyscan github.com >> ~/.ssh/known_hosts

# 複数ホスト
ssh-keyscan github.com gitlab.com bitbucket.org >> ~/.ssh/known_hosts

# 特定鍵タイプのみ
ssh-keyscan -t ed25519,rsa github.com >> ~/.ssh/known_hosts

⚠️ ssh-keyscanネットワーク経由で鍵を取得するため、MITM下で実行するとブロックされた鍵が記録されてしまいます。公式ドキュメントのフィンガープリントと照合してから使うのが安全です。

GitHubの公式フィンガープリント

GitHubは公式に以下のフィンガープリント値を公開しています:

  • ED25519: SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU
  • RSA: SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s
  • ECDSA: SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM

接続時に表示される値と一致するか確認してください。


CI/CD パイプラインでの対処

自動化された環境では対話的な確認ができないため、特別な工夫が必要です。

GitHub Actions

name: Deploy
on: push
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          
          # ホスト鍵を事前登録
          ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
      
      - name: Deploy
        run: ssh user@${{ secrets.SSH_HOST }} 'deploy-command.sh'

GitLab CI

deploy:
  before_script:
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - ssh-keyscan -H $SSH_HOST >> ~/.ssh/known_hosts
  script:
    - ssh user@$SSH_HOST 'deploy-command.sh'

Jenkins

pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                sshagent(credentials: ['ssh-key']) {
                    sh '''
                        mkdir -p ~/.ssh
                        ssh-keyscan -H ${SSH_HOST} >> ~/.ssh/known_hosts
                        ssh user@${SSH_HOST} 'deploy-command.sh'
                    '''
                }
            }
        }
    }
}

CI/CDでのセキュリティ考慮

  • ssh-keyscanは便利だが、MITM対策にはならない
  • 理想は信頼できるホスト鍵を事前登録し、StrictHostKeyChecking=yesで運用
  • Secretsに期待されるホスト鍵フィンガープリントを保存し、起動時に検証
# 期待される鍵と一致するか検証
EXPECTED_KEY="ssh-ed25519 AAAA..."
ACTUAL_KEY=$(ssh-keyscan -t ed25519 $SSH_HOST 2>/dev/null | awk '{$1=""; print $0}' | xargs)
if [ "$ACTUAL_KEY" != "$EXPECTED_KEY" ]; then
    echo "Host key mismatch!"
    exit 1
fi

プログラム言語からのSSH接続

ライブラリ経由でも同様の問題が発生します。

Python(paramiko)

import paramiko

# ❌ 危険:全ホスト鍵を無条件で受け入れる
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('hostname', username='user')

# ✅ 推奨:システムのknown_hostsを利用
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.RejectPolicy())  # 未知ホストは拒否
client.connect('hostname', username='user')

Python(fabric)

from fabric import Connection

# known_hostsを使う標準的な方法
conn = Connection('user@hostname')
conn.run('uname -a')

# 開発環境用:known_hosts無視
conn = Connection('user@hostname', connect_kwargs={
    'host_key_policy': 'AutoAddPolicy'  # 注意:本番非推奨
})

Node.js(ssh2)

const { Client } = require('ssh2');

const conn = new Client();
conn.connect({
    host: 'hostname',
    username: 'user',
    privateKey: require('fs').readFileSync('/path/to/key'),
    
    // ホスト鍵検証コールバック
    hostVerifier: (hashedKey, callback) => {
        const expectedKey = 'SHA256:xxxxxxx';  // 事前登録した値
        callback(hashedKey === expectedKey);
    }
});

Go(golang.org/x/crypto/ssh)

package main

import (
    "fmt"
    "io/ioutil"
    "net"
    "os"
    
    "golang.org/x/crypto/ssh"
    "golang.org/x/crypto/ssh/knownhosts"
)

func main() {
    // known_hostsを利用
    hostKeyCallback, err := knownhosts.New(os.ExpandEnv("$HOME/.ssh/known_hosts"))
    if err != nil { panic(err) }
    
    config := &ssh.ClientConfig{
        User: "user",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: hostKeyCallback,
    }
    
    client, err := ssh.Dial("tcp", "hostname:22", config)
    if err != nil { panic(err) }
    defer client.Close()
    
    fmt.Println("Connected!")
}

セキュリティベストプラクティス

ホスト鍵運用のお勧め設定を整理します。

1. StrictHostKeyChecking=accept-new を採用

Host *
    StrictHostKeyChecking accept-new

未知ホストは自動登録、既知ホストの変更は拒否。バランスの良い設定です。

2. HashKnownHosts で記録をハッシュ化

Host *
    HashKnownHosts yes

known_hosts内のホスト名がハッシュ化され、ファイル流出時のリスク軽減になります。

3. 警告を真剣に扱う

何度警告が出ても「とりあえず削除」する習慣を改めましょう。原因の心当たりを毎回確認するクセを付けると、本物のMITM検出につながります。

4. 重要サーバーのフィンガープリントを記録

業務で頻繁に接続するサーバーは、初回接続時にフィンガープリントを別途記録しておきます。Slack/Notion等のチームナレッジに残すと共有しやすいです。

5. SSHFP DNSレコードの活用(上級)

DNSにホスト鍵を登録する仕組みです。設定済みなら自動的にホスト鍵を検証できます:

ssh -o VerifyHostKeyDNS=yes user@host

DNSSEC との併用が前提となります。

6. Certificate Authority(CA)方式

大規模環境では、ホスト鍵にCA署名を使う方式が推奨されます。CAの公開鍵さえあれば、新規ホストの鍵を毎回登録する必要がなくなります。

# CA公開鍵を信頼する
echo '@cert-authority *.example.com ssh-ed25519 AAAA...' >> ~/.ssh/known_hosts

トラブルシューティング・チェックリスト

エラーが出た時の手順整理:

  1. エラー全文を読む: ホスト名・known_hostsの行番号を確認
  2. 心当たりを確認: 自分または管理者がサーバー変更したか
  3. 心当たりがある場合: ssh-keygen -Rで削除→再接続
  4. 心当たりがない場合: 別経路でフィンガープリント確認
  5. 公衆Wi-Fi等: 接続停止、信頼できるネットワークで再試行
  6. Docker/Vagrant: SSH config で StrictHostKeyChecking=no(開発のみ)
  7. CI/CD: ssh-keyscanで事前登録、もしくは固定値検証
  8. GitHub/GitLab: 公式フィンガープリントと照合
  9. 再発防止: accept-new 設定への移行
  10. 本物の攻撃の可能性: セキュリティチームへ報告

よくある質問(FAQ)

Q1. 警告を毎回 ssh-keygen -R で消すのは安全ですか?

サーバーの再構築や Docker/Vagrant 等、自分が変更した心当たりがあれば安全です。心当たりが全くない時は、MITM攻撃の可能性も考慮し、別経路で確認してから対処してください。

Q2. known_hosts ファイルを丸ごと削除しても大丈夫?

技術的には可能ですが、全SSH接続で初回登録ダイアログが出るため不便です。問題のあるエントリだけssh-keygen -Rで削除する方が現実的です。

# 不便を承知でリセット
mv ~/.ssh/known_hosts ~/.ssh/known_hosts.bak

Q3. StrictHostKeyChecking=no を常用するのは危険ですか?

本番接続では危険です。MITM攻撃を完全に無視することになります。開発環境(localhost、Docker、Vagrant等)に限定して使用してください。

Q4. accept-new と no の違いは?

設定既知ホストの鍵変更時未知ホスト
no警告のみ・接続続行確認なしで接続
accept-newエラーで拒否自動登録

accept-new は変更検知をきちんと行うため、セキュリティ的に大幅に優れています

Q5. Docker再起動のたびにエラーが出るのを止めたいです

~/.ssh/config で開発環境を分離:

Host docker-* localhost-*
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    LogLevel ERROR

ホスト名規約(docker-myapp等)を決めて運用します。

Q6. GitHubに突然繋がらなくなりました

2023年3月のGitHubホスト鍵ローテーションが原因の可能性。古いエントリを削除して再登録:

ssh-keygen -R github.com
ssh-keyscan github.com >> ~/.ssh/known_hosts
ssh -T git@github.com

接続時のフィンガープリントがGitHub公式値と一致するか必ず確認。

Q7. WindowsとWSLでknown_hostsを共有したいです

WSL内からシンボリックリンクを作成:

# WSL内で
rm -rf ~/.ssh
ln -s /mnt/c/Users/<username>/.ssh ~/.ssh

ただしパーミッション周りで問題が出ることがあるので慎重に。

Q8. ssh-keygen -R が動きません

考えられる原因:

  • known_hosts ファイルがない
  • 削除対象のホスト名が間違っている(ポート指定形式を含む)
  • ハッシュ化されたエントリで通常のホスト名指定では見つからない
# ハッシュ化エントリも検索
ssh-keygen -F hostname
ssh-keygen -R hostname  # ハッシュ化エントリも削除される

Q9. CI/CDで毎回 known_hosts を作る運用は安全?

ssh-keyscan単独ではMITM対策にならないため、理想的には:

  1. 期待される鍵フィンガープリントをCIシークレットに保存
  2. ssh-keyscan 取得結果と比較
  3. 一致しなければ即座にビルド失敗

これで自動化と安全性を両立できます。

Q10. 同じIPに何度も別サーバーが割り当てられて困ります

クラウドならElastic IP / Static IPを使うのが基本。動的IPプール環境では、ホスト名ベースで接続するように工夫:

# ホスト名を使う(known_hostsエントリも別になる)
ssh user@server-prod.example.com  # 別ホストと混同しにくい

Q11. PuTTY と OpenSSH で別々に管理されて面倒です

両ツールはホスト鍵ストアが別物です。完全統一は難しいですが、PuTTYからOpenSSH形式にエクスポートしてからインポートする方法があります。または PuTTY をやめて Windows標準のOpenSSHに統一するのもひとつの解。

Q12. fingerprint の表示形式が違って比較できません

OpenSSH では SHA256(Base64)が標準ですが、古い形式(MD5、16進)の場合もあります:

# SHA256形式で表示
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

# MD5形式で表示(古い形式)
ssh-keygen -E md5 -lf /etc/ssh/ssh_host_ed25519_key.pub

接続時の表示形式と合わせて確認してください。


参考リンク・関連資料

SSH公式・標準

Git ホスティング

Windows関連

クラウド関連

セキュリティ基礎

関連記事(本サイト)


まとめ

「Host key verification failed」はSSHのセキュリティ機能の正常動作ですが、原因によって対処の安全性が大きく変わります。要点を再整理します。

  • エラーの本質: ホスト鍵が known_hosts の記録と一致しない → MITM攻撃の可能性を警告
  • 3ステップ判断: 状況確認 → 心当たり確認 → 削除・再登録
  • 心当たりがある場合: ssh-keygen -R で削除して安全に対処
  • 心当たりがない場合: 別経路でフィンガープリント確認、攻撃の可能性も考慮
  • Docker/Vagrant: 開発環境専用にSSH config で警告抑制
  • クラウド: 静的IP・コンソールログでのフィンガープリント確認を活用
  • CI/CD: ssh-keyscan+フィンガープリント検証で安全に自動化
  • ベストプラクティス: StrictHostKeyChecking=accept-new への移行を推奨

これらの知識は、リモート開発・サーバー運用・CI/CD構築などのあらゆる場面で必須です。本記事をブックマークしておけば、SSH警告が出た時に安全かつ迅速に対応できるようになります。


本記事は2026年6月時点の情報をもとに、OpenSSH 9.x、Ubuntu 22.04/24.04、macOS Sonoma/Sequoia、Windows 11 での動作確認に基づき作成しています。OS・バージョンによって挙動が異なる場合があるため、ご利用の環境に応じてご確認ください。