Claude DesktopのSSHでhost key verification failedが出る原因と対処
Claude DesktopのSSHで「Host key changed or not trusted」が出たときの切り分けを、Windowsのクライアント有無、鍵の照合、known_hostsの掃除の順にまとめます。
Claude DesktopのCodeタブでSSHセッションを開くと、SSH host key verification failedやConnection failed: Host key changed or not trustedで接続を断られることがあります。これは壊れたのではなく、Desktopがホスト鍵を信用しないと判断した状態です。原因は、保存済みの鍵と違う、そもそも保存されていない、Windowsにsshが無い、のどれかに絞れます。
この記事は、画面に出た文言から入って、どの順で何を確かめるかを並べます。
同じ原因で出る3種類のメッセージ
次の表示は、いずれもDesktopがホスト鍵を拒否したことを指します。
| 出る場所 | 文言 |
|---|---|
Couldn't connect to <host>カードのView details | 文言SSH host key verification failed、またはHost denied (verification failed) |
| プロンプトボックスの横、またはTest connectionの後 | 文言Connection failed: Host key changed or not trusted |
| 切断されたセッション | 文言<host>'s host key is not trusted、または<host>'s host key has changed |
拒否の理由は多くの場合、あなたのPCに保存された鍵と違うか、そのマシンの鍵がまだ保存されていないかです。再構築や再インストールをしたマシンは新しい鍵を出します。通信を横取りする何かがあるときも、鍵は変わって見えます。
だから、鍵が変わったと分かった時点で「信用して進める」のは最後です。先に、そのマシン自身が持つ鍵と見比べます。
Windowsではまずsshコマンドの有無を見る
WindowsでConnection failed: Host key changed or not trustedが出たら、鍵より先にOpenSSHクライアントの有無を疑います。クライアントが無いと、Desktopは保存済みの鍵を引けず、正しい鍵まで拒否します。
PowerShellでsshと打ち、認識されなければクライアントを入れます。
ssh -Vsshが見つからないときは、Windowsのオプション機能でOpenSSH Clientを追加して未適用のWindows Updateも済ませるか、Microsoftの新しいビルドを入れます。そのあとDesktopを終了して開き直します。入れ直したあとにもう一度接続すると、初回接続の確認が出ることがあります。その場合は次の節の手順で鍵を照合してから信用します。
Desktopがクライアントを見つけたかどうかは、あとで触れるssh.logのWindows OpenSSH client:の行(バージョンが続きます)か、no usable Windows OpenSSH clientの行で分かります。
sshはGit BashやWSLのものではなくPowerShell側のものを使います。Desktopはその2つのsshでは接続しません。Failed to spawnのような別の症状は、「Failed to spawn /usr/bin/ssh」の原因と対処で扱っています。
Desktopの表示から次の一手を決める
Desktopが出しているボタンや指示で、進む先が分かれます。
UserKnownHostsFileを設定するよう促される:~/.ssh/configでUserKnownHostsFileを~/.ssh/known_hostsに設定し、次の節のとおり端末から確かめます- Review new keyボタンがある: 押して、表示されたフィンガープリントをマシン自身のものと照合します。一致したらTrust new keyで保存済みの鍵を置き換え、違えばCancelです
- ボタンが無い、
Couldn't show the new keyと出る、Trust new keyの後も拒否される: 端末から確かめます
ボタンで済むケースは、照合さえ済ませれば端末を開かずに済みます。端末の手順は、ボタンで進めないときの保険です。
端末でsshを通したのにDesktopが再び拒否するなら、鍵ではなくDesktop側の状態を疑います。その場合は最後の節のとおりログを集めます。
信用する前に、マシン自身の鍵を取る
フィンガープリント(鍵を短くした識別値)は、接続している経路の外で取ります。接続を疑っているのに、その接続越しに鍵を見ても照合になりません。
まず、どのマシンの鍵かを決めます。
Connect to <host> for the first time?と出たら、名前の出ている<host>ですConnect through <jump host> for the first time?と出たら、経由先のジャンプホストです。目的のマシンではありません- 端末の
sshが尋ねてきたら、sshのメッセージに出ているマシンです。自分が打った名前と違うことがあります
次に、そのマシンの鍵を手に入れます。他の人が管理するマシンなら、フィンガープリントを教えてもらいます。自分で管理するLinuxかmacOSなら、そのマシンのコンソール、または信用できる別経路で次を実行します。
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubこのコマンドは、鍵ファイルの中身ではなくフィンガープリントを表示します。Desktopやsshが示した値と、文字列がそのまま一致するかを見ます。
ed25519の部分は、Desktopやsshが表示した鍵の種類を小文字にして合わせます。ED25519やssh-ed25519ならed25519です。
一致すれば、Trust and connectかTrust new key、端末ならyesで信用します。違うか、確かめられないなら進めません。DesktopではCancel、端末ではnoです。管理者がいるなら、表示されたフィンガープリントを伝えます。
端末からsshを打って切り分ける
Desktopで進めないときは、PCの端末で、Desktopの接続に入れたSSH hostと同じ値でsshを実行します。ポートを指定している接続なら-pも付けます。
ssh -p 2222 dev@build.example.comsshの反応で、次の4通りに分かれます。
sshの反応 | やること |
|---|---|
| 続行してよいか尋ねてくる | やること出たフィンガープリントを、そのマシン自身のものと比べる。一致したときだけyes |
| 鍵が変わったと警告する | やること警告のフィンガープリントを照合する。一致したら、Offending <type> key in <file>:<line>が指す行を消して再実行。別の行で再び警告されたら同じ手順を繰り返す |
| 尋ねずに、知らない鍵を拒否する | やること管理者からknown_hostsの行をもらう。ネットワーク越しに取らない。sshのメッセージにある名前をホスト名にして、自分のknown_hostsに足す |
| 鍵について何も聞かずにサインインへ進む | やることパスワードを打たない。次の節で、すでに信用されている鍵を調べる |
sshが鍵を受け入れたら、Desktopで再接続します。
黙ってサインインへ進むときは-v -S noneで調べる
鍵を聞かれないのは、どこかの設定ファイルがその鍵をすでに信用しているからです。同じコマンドに-v -S noneを足して再実行します。
ssh -v -S none -p 2222 dev@build.example.com出力のServer host key:行にフィンガープリントがあり、次のHost '<name>' is known行が、それがどのマシンのものかを示します。それぞれをマシン自身のものと比べます。ジャンプホストを挟む接続では、ジャンプホストのServer host key:行が出ないことがあります。その場合はssh -v -S none <ジャンプホスト>も実行して、同じように照合します。
照合の結果で分かれます。
- 合わない、または確かめられない: もう接続しません。
Found key in <file>:<line>が指すファイルに鍵が入っているので、ssh-keygen -R "<name>" -f <file>で消します。鍵を複数のファイルに分けているなら、それぞれから消します。PCの管理者がファイルを握っているなら、管理者に伝えます - すべて合う: Desktopでもう一度試します。それでも拒否されるなら、ログを見ます
鍵が変わる側の原因を潰す
画面の症状は同じでも、鍵が変わる理由は運用側にあります。
- マシンを作り直した: コンテナやイメージを作り直すたびに、SSHサーバーが新しい鍵を生成します。コンテナ経由で接続する構成では、イメージを作り直したりコンテナを再作成したりしても同じホスト鍵が残るように、OpenSSHサーバーを入れておきます
- ホスト名を使い回す: 作成ツールが同じ名前の別マシンを作るなら、古い鍵の行を消してから新しい鍵を入れます
known_hostsが空:StrictHostKeyCheckingがnoかaccept-newで、さらにUserKnownHostsFileが/dev/nullかnoneだと、鍵はどこにも記録されません。ホスト名が別のマシンに使い回されても、警告が出ません
最後の項目は、警告を黙らせたくて入れた設定が、本当の中間者を見逃す穴になるという話です。警告が面倒でも、対象のホストでは鍵の確認とknown_hostsの保管を続けます。
ジャンプホストを挟む接続では、確かめる相手が増えます。Connect through <jump host> for the first time?で尋ねられている鍵はジャンプホストのものなので、目的のマシンの鍵と取り違えないようにします。ジャンプホストを信用しても、目的のマシンの鍵はまだ未確認のままです。そのため、次にDesktopが別の鍵を尋ねてきたら、尋ねられたマシンの名前を見直してから、もう一度同じ手順で照合します。
最初の接続の質問を省きたいなら、そのマシンを作ったツールが知っている鍵を、ホスト名が表示される前に~/.ssh/known_hostsへ書かせます。ポートが22以外のときは、行の先頭を[host]:portの形にします。
それでも解決しないときはログを集める
ssh.logはDesktopのSSH接続の記録です。Desktopのログをzipファイルにまとめて保存すると、その中に入ります。保存するにはHelp > Troubleshootingを開き、お使いのOSの項目を選びます。macOSはShow Logs in Finder、WindowsはShow Logs in File Explorer、LinuxはShow Logs in File Managerです。
Windowsで拒否が続くなら、ssh.logのWindows OpenSSH client:の行とno usable Windows OpenSSH clientの行を先に探します。クライアントを見つけられていないなら、鍵の照合より前にクライアントの導入からやり直しになります。
zipには、接続先のマシンに入るヘルパープログラムのログは含まれません。必要なら、接続したユーザーのホームにある~/.claude/remote/run/の下のヘルパーのフォルダからremote-server.logをコピーします。
他の人に渡す前に、どちらも中身を確認します。ログの<host>と<user>はDesktopが置き換えた名前ですが、すべての名前を置き換えるわけではありません。SSHのホスト名やユーザー名が、書いたとおりに残ることがあります。zipを渡すときは、どのホストでいつ失敗したかも添えます。ログにホスト名が出ていないことがあるためです。
SSHのタイムアウトなど、別の理由で切れる場合はConnectTimeoutを延ばす手順が切り分けの参考になります。組織でSSH先を絞っているなら、sshHostAllowlistの設定も接続先の拒否に関わります。
まとめ
メッセージの文言は3種類ありますが、やることは共通です。Windowsならsshの有無を見て、次にマシン自身の鍵と画面の鍵を照合し、合ったときだけ信用します。信用してよいかを決めるのは、Desktopのボタンではなく、そのフィンガープリントの照合です。