SSH 鍵にパスフレーズを設定したら、Windows が git push のたび、ssh のたびにそれを尋ねてくるようになりました。その解決策が SSH エージェントです。鍵を一度アンロックすれば、それ以降のすべての接続は黙って署名します。Windows ならではのひねりは、エージェントが 1 つ ではないことです。同時に動きうるものが 3 つあり、それぞれ別の場所に鍵を保持するため、一方に読み込んだ鍵は他方からは見えません。Windows で起きる「昨日は動いたのに」というエージェントの問題は、ほとんどが実は エージェントの取り違え の問題です。そこでこのガイドは、まず 3 つに名前を付け、次にそれぞれを起動させ、最後に実際に遭遇するエラーを読み解いていきます。
3 つのエージェントと、鍵を共有しない理由
| エージェント | 同梱元 | 待ち受け場所 | 認識する ssh |
|---|---|---|---|
| OpenSSH Authentication Agent(Windows サービス) | Windows 標準の OpenSSH | 名前付きパイプ \\.\pipe\openssh-ssh-agent | C:\Windows\System32\OpenSSH の ssh.exe |
MSYS2 のエージェント(ssh-agent) | Git for Windows / Git Bash | SSH_AUTH_SOCK が指す Unix 形式のソケット | Git Bash に同梱の ssh |
| Linux のエージェント | WSL ディストロの内側 | そのディストロ内の Unix ソケット | WSL 内で動く ssh |
この表から得られる教訓は、Git Bash での ssh-add は MSYS2 のエージェントに鍵を読み込むので、Windows 標準の ssh.exe からはその鍵が決して見えないということです。エンドポイントが違い、鍵の保管場所が違います。エージェントを 1 つ選び、そこに鍵を読み込み、それに対応する ssh を使ってください。これらを混ぜることが、以下で扱う混乱のほとんどの根本原因です。ssh-agent と ssh-add のガイド(英語)がクロスプラットフォームの仕組みを扱っています。このページはその Windows 固有の半分です。
標準搭載の OpenSSH Authentication Agent サービス
最近の Windows 10 と 11 は OpenSSH を同梱しており、エージェントを動かす Windows サービスもそれに付いてきます。ただし既定では無効です。管理者権限の PowerShell(管理者として実行)から、一度だけ有効にします。
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
Automatic にすると起動のたびにサービスが立ち上がるので、この設定は一度きりで済みます。結果を確認します。
Get-Service ssh-agent | Select-Object Status, StartType
Running と Automatic になっていれば OK です。以降は、通常の(Git Bash ではない)PowerShell や cmd で、ssh-add がこのサービスと通信します。
ssh-add # load default keys (id_ed25519, id_rsa, …)
ssh-add $env:USERPROFILE\.ssh\id_ed25519 # load a specific key
ssh-add -l # list loaded key fingerprints
どんなログイン失敗でも、最初の診断は ssh-add -l です。期待している鍵が一覧に出てこなければ、他がどれだけ正しく見えても、エージェントはその鍵で署名できません。
ssh-add を毎回打ち直さずに済ませるには、最初の接続に鍵を読み込ませましょう。%USERPROFILE%\.ssh\config(OpenSSH がどこでも読み込む、あの ssh_config ファイル(英語)と同じもの)に次を書きます。
Host *
AddKeysToAgent yes
これで、パスフレーズを必要とする最初の ssh が一度だけ尋ね、その副作用として鍵をサービスに読み込みます。Windows 標準の git と ssh はどちらもこのサービスを使うので、git push も黙って通るようになります。
エラー 1058:「unable to start the ssh-agent service」
Start-Service ssh-agent を実行すると、こう返ってきます。
Start-Service : Service 'OpenSSH Authentication Agent (ssh-agent)' cannot be started due to the following error:
Cannot start service ssh-agent on computer '.'.
... error 1058 ...
エラー 1058 は、サービスが 無効 になっていることを意味します。Windows は Startup type が Disabled のサービスを起動せず、Start-Service がそれを変えてくれることもありません。まず Startup type を直してから起動します(管理者権限の PowerShell)。
Set-Service ssh-agent -StartupType Manual
Start-Service ssh-agent
必要なときに起動するだけなら Manual で十分です。起動のたびに立ち上げたいなら Automatic を使ってください。管理対象やドメイン参加のマシンでは、グループポリシーが無効化していることがあります。その場合は、設定を効かせる前に管理者がサービスを許可する必要があります。
「error connecting to agent: No such file or directory」
これは Windows サービスではなく、Git Bash / MSYS2 の ssh から出るものです。ssh が(SSH_AUTH_SOCK を通じて)エージェントのソケットの場所を教えられたのに、そこに何もない、という意味です。よくある原因は 2 つです。
-
このシェルでエージェントが動いていない。 Git Bash は勝手にはエージェントを起動しません。いま使っているシェルで起動します。
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519evalが肝心です。ssh-agent -sは変数を 表示するだけ で、evalがそれらを設定することでsshがソケットを見つけられます。ssh-agentを単体で実行して、何も変わらないのを不思議がるのは典型的なつまずきです。 -
SSH_AUTH_SOCKが古い。 以前のセッション、ログインプロファイル、あるいは別のツールが設定した変数が、もう存在しないソケットを指しています。echo $SSH_AUTH_SOCKで確認し、変数を解除して新しいエージェントを起動するか、生きているソケットを指すよう直してください。
Git Bash の中から Windows サービスを使いたいなら、PATH 上の MSYS2 の ssh ではなく、標準のバイナリ /c/Windows/System32/OpenSSH/ssh.exe を直接呼んでください。そうすれば Git Bash はサービスに読み込んだのと同じ鍵に届き、SSH_AUTH_SOCK は関係なくなります。
WSL 内の鍵
WSL は独立した Linux システムなので、独自のエージェント、独自の ~/.ssh、独自の SSH_AUTH_SOCK を持ちます。Windows 側で読み込んだ鍵はディストロの中からは見えず、その逆も同じです。正直なところ、選択肢は 2 つです。
- WSL の中でエージェントを動かす。 ふつうの Linux のやり方で、
eval "$(ssh-agent -s)"とssh-add、あるいはディストロの~/.ssh/configにAddKeysToAgent yesを書きます。シンプルで完全に分離されており、ssh-add ガイド(英語)で扱っています。 - Windows のエージェントに橋渡しする。 両方の世界が 1 つの鍵の保管場所を共有するようにします。定番のやり方は、
npiperelay.exeとsocatを使って、Windows の名前付きパイプを WSL のSSH_AUTH_SOCKが指す Unix ソケットへ流し込むものです。設定さえ済めばうまく動きますが、可動部品が増えます。両側で本当に同じ鍵が必要なときだけ使ってください。
どちらを選ぶにせよ、WSL 内の ssh-add -l は PowerShell の ssh-add -l とは 別の問い だと覚えておいてください。デバッグのときは、正しい方を尋ねましょう。
エージェントは問題ないのに、ログインがまだ失敗するとき
ssh-add -l に鍵が出ているのにサーバーがなお Permission denied (publickey) と言うなら、エージェントは役目を果たしています。問題はその下流、つまりサーバーの authorized_keys、ユーザーの取り違え、あるいは誤った鍵が提示されること、へ移ったのです。それは別のチェックリストです。Permission denied (publickey) を順番に直す(英語)。そして ssh -A でエージェントをリモートのマシンへ転送する前に、エージェント転送が便利で危険な理由を読んでください。転送先であなたの鍵が実際に使われる状態をさらすことになります。
Termalin は Windows でこれをどう扱うか
サービス、ソケット、3 つの鍵の保管場所のやりくりが、考えたくもないほど面倒なら、それは Termalin が組み込みで引き受けるワークフローです。Termalin は Windows の名前付きパイプ \\.\pipe\termalin-ssh-agent の上で独自のキーエージェントを動かし、アプリ内ですでにアンロックした鍵を標準の ssh-agent プロトコルで提供します。そのプロトコルを話すツールは、有効化すべき OS サービスも、eval の一行も、手動の ssh-add もなしに、これを介して署名できます。秘密鍵は動作中のアプリの中に留まり、ディスクに書き出されることはありません。このエージェントの狙いは、Termalin 自身の MCP サーバーが、鍵そのものを一切保持することなく、あなたの鍵でサーバーへ認証できるようにすることです。エージェントが署名し、呼び出し側が秘密を見ることはありません。OpenSSH サービスと同じ「一度のアンロック」の発想で、Windows のセットアップだけあなたの手から取り除いたものです。
Termalin は無料のクロスプラットフォーム SSH クライアントで、内蔵のエージェントが鍵を一度アンロックして、あなたの代わりに署名します。ダウンロード、または鍵を安全に扱う仕組みをご覧ください。