エラーメッセージ
Host key verification failed.
別の表記
- No ED25519 host key is known for 127.0.0.1 and you have requested strict checking.
- fatal: Could not read from remote repository.
Git では、このメッセージに続いて「fatal: Could not read from remote repository.」が出力されます。直前の行にある鍵の種類(`ED25519`、`ECDSA`、`RSA`)は、サーバーが提示した種類です。
このエラーの意味
ssh は、サーバーが名乗っているとおりのサーバーであることを確認できなかったため、認証の前に処理を中止しました。ホストが `known_hosts` になく、ssh が確認を求められなかった(バッチモード、CI、ターミナルのない Git コマンド)か、ホストが別の鍵で登録されているかのどちらかです。どちらであるかは直前の行でわかります。未知のホストでは「No … host key is known for …」、鍵が変わったホストでは「REMOTE HOST IDENTIFICATION HAS CHANGED」という大きな警告が表示されます。
発生する理由
ターミナルなしでの初回接続
よくあるCI ランナー、cron ジョブ、Docker のビルド、スクリプト内の `git` は、空の `known_hosts` から始まります。`BatchMode yes` の場合や TTY がない場合、ssh は確認のプロンプトを表示できずに失敗します。
ホストの鍵が記録されたものと異なる
よくあるサーバーの再インストール、別のマシンによる IP アドレスの再利用、鍵の異なる複数のホストの前段にあるロードバランサー、あるいは通信の傍受が考えられます。「REMOTE HOST IDENTIFICATION HAS CHANGED」の項目を参照してください。
known_hosts ファイルが想定しているものと違う
ときどきCI や sudo で `HOME` が異なる、`UserKnownHostsFile` が別の場所を指している、またはファイルが別のユーザーの所有で ssh が読み書きできない、といったケースです。
修正方法
- 1.
ホスト鍵を検証してから記録する
`ssh-keyscan` が示すのは、ネットワークから返された鍵にすぎません。信頼する前に、そのフィンガープリントを信頼できる情報源のものと比較してください。
bash # Store the server's host key once, after checking its fingerprint out of band. ssh-keyscan -t ed25519 server.example.com > /tmp/hostkey ssh-keygen -lf /tmp/hostkey # compare with the fingerprint from your provider/console cat /tmp/hostkey >> ~/.ssh/known_hosts - 2.
検証済みの known_hosts を CI に配布する
検証済みの行を、シークレットとして、またはリポジトリに保存してください。`StrictHostKeyChecking no` や実行時の `ssh-keyscan` を使うと、ジョブは応答したものを何でも受け入れてしまいます。
yaml # GitHub Actions: put the verified known_hosts line into a secret, not ssh-keyscan at run time - name: Configure SSH run: | install -d -m 700 ~/.ssh echo "${{ secrets.DEPLOY_KNOWN_HOSTS }}" > ~/.ssh/known_hosts chmod 600 ~/.ssh/known_hosts - 3.
Git ホスティングサービスが公開している鍵を使う
GitHub、GitLab、Bitbucket はホスト鍵のフィンガープリントを公開しています。GitHub は meta API でも提供しています。
bash # GitHub publishes its SSH host keys (also at https://api.github.com/meta, "ssh_keys") curl -s https://api.github.com/meta | jq -r '.ssh_keys[] | "github.com " + .' >> ~/.ssh/known_hosts