Host key verification failedの直し方|GitHubのknown_hostsを安全に更新する手順

Host key verification failedREMOTE HOST IDENTIFICATION HAS CHANGED! が表示されても、known_hostsファイル全体を削除してはいけません。いったん接続を止め、GitHub公式のSSHホスト鍵フィンガープリントと鍵変更の告知を確認し、正当な変更だと判断できたホストのエントリーだけを更新します。

この警告は、以前接続したサーバーの鍵と、今回提示された鍵が一致しないことを知らせるセキュリティ機能です。GitHubは、公式なホスト鍵変更があった場合はGitHub Blogで告知し、現在の公開鍵フィンガープリントを公式ドキュメントに掲載すると案内しています。公式な裏付けが見つからない場合は、接続しないのが安全です。([GitHub Docs][1])

目次

GitHubのSSHホスト鍵警告を安全に確認する方法

最初に、表示されたメッセージの種類を確認します。似たメッセージでも、初回接続と既存鍵の不一致では対応が異なります。

表示されるメッセージ主な意味対応
The authenticity of host ... can't be establishedそのホストの鍵がまだ登録されていない公式フィンガープリントと一致した場合だけ接続を承認する
REMOTE HOST IDENTIFICATION HAS CHANGED!保存済みの鍵と今回の鍵が異なる接続を中止し、鍵変更の理由を確認する
Host key verification failedホスト鍵の検証に失敗して接続が中断された直前に表示されたホスト名、鍵種別、ファイル、行番号を確認する
fatal: Could not read from remote repository.SSH接続の失敗によりGit操作も失敗した先にホスト鍵エラーを解決する

初回接続時であっても、表示された鍵を無条件で承認してよいわけではありません。GitHub公式の接続テスト手順でも、表示されたフィンガープリントが公式情報と一致することを確認してから、接続を承認するよう案内されています。([GitHub Docs][2])

known_hosts全体を削除してはいけない理由

known_hostsには、過去に接続して信頼したSSHサーバーのホスト鍵が保存されています。通常の保存先は次のとおりです。

利用環境一般的な保存先
Windows OpenSSH/PowerShell$HOME\.ssh\known_hosts
Git Bash~/.ssh/known_hosts
WSL~/.ssh/known_hosts
macOS/Linux~/.ssh/known_hosts

実際の保存先はSSH設定によって変更できます。エラーメッセージにファイルパスが表示されている場合は、そのパスを優先してください。OpenSSHでは、ユーザー用のホスト鍵データベースとして、標準では~/.ssh/known_hostsなどが参照されます。([OpenBSD Manual Pages][3])

known_hosts全体を削除すると、GitHubだけでなく、社内サーバー、VPS、NAS、クラウドサーバーなど、登録されていたすべてのホストが初回接続状態に戻ります。その結果、以前と鍵が変わったことを検出するための履歴まで失われます。

ただし、known_hostsを削除しても、次のものは削除されません。

  • 自分のSSH秘密鍵
  • GitHubに登録した公開鍵
  • GitHubのリポジトリ
  • Gitのコミット履歴

ホスト鍵は「接続先サーバーが本物か」を確認するものです。一方、自分のSSH鍵は「接続している利用者が誰か」をGitHubへ証明するものです。

したがって、Host key verification failedに対して、自分のid_ed25519id_rsaを作り直すのは、通常は適切な解決策ではありません。

警告が出る主な原因

ホスト鍵が変わる理由は、攻撃だけとは限りません。しかし、正当な変更と危険な変更をメッセージだけで区別することはできません。

考えられる原因判断の手がかり
GitHubによる正式なホスト鍵変更GitHub公式の告知と現行フィンガープリントが確認できる
古いホスト鍵が端末に残っている長期間使っていなかった端末だけで発生する
SSHの接続先やポートを変更したgithub.comからssh.github.com:443などへ変更している
~/.ssh/configの設定が変わったHostnamePortProxyJumpなどが追加されている
GitHub Enterpriseへ接続している接続先がgithub.comではなく組織独自のドメインになっている
VPN、プロキシ、踏み台サーバーを経由している特定のネットワーク環境だけで警告が出る
DNS偽装や中間者攻撃公式告知がなく、提示されたフィンガープリントも一致しない

GitHub.comのホスト鍵が予期せず変わり、公式な変更情報も確認できない場合は、警告を解除するよりも接続を中止することが優先です。([GitHub Docs][1])

安全にknown_hostsを更新する手順

接続を中止し、警告内容を記録する

警告が出た時点では、yesを入力したり、検証を無効化したりしないでください。

次の情報を記録します。

  • 接続先のホスト名
  • ポート番号
  • 鍵の種類
  • 表示されたSHA256:形式のフィンガープリント
  • known_hostsのファイルパス
  • Offending ... keyに続く行番号

典型的な警告では、次のような情報が表示されます。

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
Offending ED25519 key in .../.ssh/known_hosts:5
Host key verification failed.

この例では、問題の候補がknown_hostsの5行目にあることが分かります。ただし、行番号だけを見てすぐ削除するのではなく、先に接続先と新しい鍵を確認します。

実際の接続先を確認する

リポジトリのディレクトリで、Gitの接続先を確認します。

git remote get-url origin

一般的なGitHub.comのSSH URLは次の形式です。

[email protected]:OWNER/REPOSITORY.git

次のような独自名が表示された場合は、SSH設定のエイリアスを使用している可能性があります。

git@github-work:OWNER/REPOSITORY.git

OpenSSHでは、次のコマンドで接続せずに有効な設定を確認できます。

ssh -G github.com

エイリアスを使用している場合は、エイリアス名を指定します。

ssh -G github-work

出力された次の項目を確認してください。

hostname
port
userknownhostsfile

ssh -Gは、HostMatchの設定を評価した結果を表示して終了するため、実際の接続先や利用する設定ファイルの確認に役立ちます。([OpenBSD Manual Pages][4])

known_hostsをバックアップする

対象エントリーを削除する前に、known_hostsをバックアップします。

macOS、Linux、Git Bashでは次のように実行します。

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

Windows PowerShellでは次のように実行します。

Copy-Item "$HOME\.ssh\known_hosts" "$HOME\.ssh\known_hosts.bak"

エラーに別のファイルパスが表示されている場合は、そのファイルをバックアップしてください。

現在登録されているGitHubのエントリーを確認する

次のコマンドで、github.comに対応する登録済みエントリーを検索できます。

ssh-keygen -F github.com

ホスト名がハッシュ化されていて、テキストエディターでgithub.comを検索しても見つからない場合にも利用できます。

ポート番号を含む接続先は、[ホスト名]:ポート番号の形式で指定します。

ssh-keygen -F "[ssh.github.com]:443"

ssh-keygen -Fは、通常のホスト名だけでなく、ハッシュ化されたホスト名やポート番号付きのエントリーも検索できます。([OpenBSD Manual Pages][5])

GitHub公式のフィンガープリントと告知を確認する

ここが最も重要な手順です。

ブラウザでGitHub公式のSSHホスト鍵フィンガープリント一覧を開き、警告画面に表示された次の情報を照合します。

  • 鍵の種類が一致しているか
  • SHA256:から始まる文字列全体が一致しているか
  • GitHub.comではなく別ドメインへ接続していないか
  • 鍵変更の公式告知があるか

フィンガープリントは一部だけでなく、文字列全体を比較してください。検索結果の抜粋、古いブログ記事、掲示板に転載された値ではなく、その時点のGitHub公式情報を使用します。GitHubが公開している現行フィンガープリントは公式ドキュメントで確認できます。([GitHub Docs][6])

鍵変更警告が出ているにもかかわらず、次のいずれかに該当する場合は接続しません。

  • 提示されたフィンガープリントが公式情報と一致しない
  • GitHubの公式な鍵変更情報が見つからない
  • 意図しないホスト名やポートへ接続している
  • 社内プロキシやVPNの仕様を確認できない
  • GitHub Enterpriseの正式なフィンガープリントを確認できない

企業や自治体などの管理端末では、独自のSSH中継環境やセキュリティ製品が使われている場合があります。その場合は、自己判断で削除せず、システム管理者が示すフィンガープリントを別経路で確認してください。

正当な変更と確認できた対象エントリーだけを削除する

GitHub.comの変更が正当だと確認できた場合は、次のコマンドでgithub.comに対応するエントリーだけを削除します。

ssh-keygen -R github.com

SSH over HTTPSポートを利用し、警告の対象が[ssh.github.com]:443の場合は次のように指定します。

ssh-keygen -R "[ssh.github.com]:443"

特定のknown_hostsファイルを明示する場合は、-fを追加します。

macOS、Linux、Git Bashの例です。

ssh-keygen -R github.com -f ~/.ssh/known_hosts

Windows PowerShellの例です。

ssh-keygen -R github.com -f "$HOME\.ssh\known_hosts"

ssh-keygen -Rは、指定したホストに属する鍵をknown_hostsから削除します。ハッシュ化されたホスト名にも対応するため、手作業で行番号を削除するより安全です。([OpenBSD Manual Pages][5])

ここで重要なのは、警告に表示された正確なホスト名を使うことです。github.comを削除しても警告が続く場合、実際の対象が次のようになっている可能性があります。

[ssh.github.com]:443
github-work
GitHub Enterpriseの独自ドメイン
IPアドレス

再接続時に新しい鍵を照合する

GitHub.comへの接続をテストします。

ssh -T [email protected]

SSH over HTTPSポートを直接テストする場合は、次のコマンドを使います。

ssh -T -p 443 [email protected]

GitHubでは、ポート443を使う場合のホスト名はgithub.comではなくssh.github.comです。初回接続時には[ssh.github.com]:443の鍵を登録する確認が表示されることがあります。([GitHub Docs][7])

次のような確認が表示されたら、フィンガープリントをもう一度GitHub公式情報と照合します。

Are you sure you want to continue connecting (yes/no/[fingerprint])?

完全に一致した場合だけ、yesを入力します。

接続に成功すると、GitHubのユーザー名とともに、認証には成功したがシェルアクセスは提供していないという内容が表示されます。GitHubの接続テストでは、正常に認証できた場合でもコマンドの終了コードが1になる仕様です。([GitHub Docs][2])

最後に、Git操作を再確認します。

git fetch

ここでHost key verification failedが消え、別途Permission denied (publickey)が表示された場合は、ホスト鍵の問題は解決しています。次は、自分の秘密鍵、ssh-agent、GitHubアカウントに登録した公開鍵を確認します。

known_hostsを更新しても警告が消えない場合

別のSSH環境を使用している

Windowsでは、次の環境がそれぞれ異なるSSH設定やホームディレクトリを使用していることがあります。

  • PowerShellのWindows OpenSSH
  • Git Bashに含まれるSSH
  • WSL内のOpenSSH
  • Visual Studio Codeなどの開発ツール
  • Dockerコンテナや仮想環境

PowerShellで修正したのにGit Bashでは警告が続く場合、異なるknown_hostsを参照している可能性があります。

エラーに表示されたファイルパスを確認するほか、次のコマンドで実際に使われる設定を調べます。

ssh -G github.com

ポート443用のエントリーが残っている

次の2つは、known_hosts上では別の接続先として扱われます。

github.com
[ssh.github.com]:443

ssh-keygen -R github.comだけでは、[ssh.github.com]:443のエントリーは削除されません。警告に表示されたホスト名とポートをそのまま指定してください。

SSH設定でHostKeyAliasを使用している

~/.ssh/configHostKeyAliasが指定されている場合、実際の接続先とは異なる名前でホスト鍵が保存されることがあります。

設定例は次のとおりです。

Host github-work
    HostName github.com
    User git
    HostKeyAlias github-company

この場合、削除対象がgithub.comではなくgithub-companyになることがあります。エラーメッセージとssh -Gの出力を確認してください。

ユーザー用とは別のknown_hostsを参照している

OpenSSHでは、UserKnownHostsFileによって別のファイルを指定できます。また、組織の管理環境ではシステム共通のホスト鍵ファイルが使われることもあります。

ユーザー用ファイルに該当エントリーが見つからない場合は、独自設定や管理者配布の設定を確認します。管理対象のファイルは、権限を変更したり無断で編集したりせず、管理者へ問い合わせてください。

やってはいけない対処法

known_hostsファイルを丸ごと削除する

GitHub以外の信頼情報まで失われます。削除するのは、正当な変更と確認できた対象ホストのエントリーだけにします。

StrictHostKeyCheckingを無効化する

次のような設定を、一般的な解決策として使うべきではありません。

ssh -o StrictHostKeyChecking=no [email protected]

StrictHostKeyChecking=noまたはoffは、変更されたホスト鍵でも接続を進める場合があります。一方、accept-newは未知のホスト鍵を追加しますが、既存ホストの鍵変更は拒否します。鍵変更警告を解決するために検証そのものを弱めるのではなく、鍵の正当性を確認してエントリーを更新してください。([OpenBSD Manual Pages][3])

UserKnownHostsFileを無効化する

次のようにホスト鍵の記録を捨てる設定も、通常の運用では避けます。

UserKnownHostsFile=/dev/null

毎回の接続で過去のホスト鍵を参照できなくなり、鍵変更の検出というknown_hosts本来の役割を失います。

ssh-keyscanの結果を無条件で追記する

次のようなコマンドは、単独では安全な本人確認になりません。

ssh-keyscan github.com >> ~/.ssh/known_hosts

ssh-keyscanで取得した鍵が、本物のGitHubから返されたものだとは限らないためです。OpenSSHのマニュアルも、検証せずにssh-keyscanの結果からknown_hostsを作成すると、中間者攻撃に対して脆弱になると警告しています。取得した鍵を使用する場合でも、必ずGitHub公式のフィンガープリントと別経路で照合します。([OpenBSD Manual Pages][8])

警告に書かれた行を確認せず削除する

行番号が表示されても、その行に複数のホスト名が記録されていることがあります。また、対象ファイルが普段想定しているknown_hostsとは限りません。

手作業で編集する前に、次のコマンドを優先します。

ssh-keygen -F github.com
ssh-keygen -R github.com

安全な判断基準

GitHubのSSHホスト鍵警告が出たときは、次の条件がすべてそろってから更新します。

  • 実際の接続先ホスト名とポートを確認した
  • 提示された鍵種別を確認した
  • フィンガープリント全体がGitHub公式情報と一致した
  • 鍵変更警告の場合は、公式告知や環境変更によって理由を説明できた
  • known_hostsをバックアップした
  • ファイル全体ではなく、対象ホストのエントリーだけを削除した
  • 再接続時にもフィンガープリントを照合した

どれか一つでも確認できない場合は、接続を通すことより、いったん止めることを優先してください。known_hostsの警告は邪魔なエラーではなく、接続先のすり替わりを検出するための重要な防御機能です。
[1]: https://docs.github.com/en/authentication/troubleshooting-ssh/error-host-key-verification-failed “Error: Host key verification failed – GitHub Docs”
[2]: https://docs.github.com/en/authentication/connecting-to-github-with-ssh/testing-your-ssh-connection “Testing your SSH connection – GitHub Docs”
[3]: https://man.openbsd.org/ssh_config.5 “ssh_config(5) – OpenBSD manual pages”
[4]: https://man.openbsd.org/ssh.1 “ssh(1) – OpenBSD manual pages”
[5]: https://man.openbsd.org/ssh-keygen.1 “ssh-keygen(1) – OpenBSD manual pages”
[6]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints “GitHub’s SSH key fingerprints – GitHub Docs”
[7]: https://docs.github.com/en/authentication/troubleshooting-ssh/using-ssh-over-the-https-port “Using SSH over the HTTPS port – GitHub Docs”
[8]: https://man.openbsd.org/ssh-keyscan.1 “ssh-keyscan(1) – OpenBSD manual pages”

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次