できない.dev

SSH の鍵を ssh-add しても毎回パスフレーズを聞かれる

ssh-agent はシェルのプロセスに紐づくため、端末を開き直すと登録済みの鍵が失われる。AddKeysToAgent yes~/.ssh/config に書くか、OS のエージェント常駐サービスへ接続するのが確実である。

公開:

要約

ssh-add で鍵を登録したのに、端末を開き直すとまたパスフレーズを聞かれる。
原因は ssh-agent が「常駐サービス」ではなく「起動したプロセス」でしかないことである。
エージェントのプロセスが消えれば、そこに預けた鍵も一緒に消える。

ssh-add -l
Could not open a connection to your authentication agent.

このメッセージは「登録した鍵が消えた」のではなく「そもそも接続先のエージェントが居ない」状態を指す。ssh-agent(1)(新しいタブで開く) が書いているとおり、ssh は環境変数 SSH_AUTH_SOCK が指すソケット経由でエージェントを探すので、この変数が引き継がれない端末では毎回ゼロからやり直しになる。

恒久的に直すなら、鍵を登録し直す運用をやめて、AddKeysToAgent で自動登録させるか、OS が管理する常駐エージェントに接続する。

よくある原因

  1. 端末ごとに ssh-agent を起動している: eval "$(ssh-agent -s)".bashrc.zshrc に書くと、端末を開くたびに新しいエージェントが起動する。
    前の端末で ssh-add した鍵は別プロセスの中なので見えない。ps aux | grep ssh-agent が何行も並ぶなら、この状態である。
  2. SSH_AUTH_SOCK が引き継がれていない: エージェントは生きているのに、tmux のセッションや sudo 後のシェル、デスクトップから起動した GUI アプリに変数が渡っていないことがある。
    エージェントの有無ではなく、変数の有無を先に疑う。
  3. 鍵が既定のファイル名ではない: ~/.ssh/id_ed25519 などの既定名なら ssh が自動で読むが、~/.ssh/work_key のような名前は IdentityFile を書かないと拾われない。
    エージェントに入っていない鍵はその都度ファイルから読まれ、そのたびにパスフレーズを求められる。
  4. 寿命付きで登録している: ssh-add -t 3600 のように登録すると、指定した秒数でエージェントから自動的に削除される。
    「しばらくすると聞かれるようになる」場合はこれを疑う。
  5. 登録自体は成功しているが接続で別の鍵が使われている: エージェントに複数の鍵が入っていると、ssh は順に試す。
    目的の鍵に到達する前にサーバー側の試行回数上限に達すると、結局パスフレーズ入力に落ちる。

解決策

1. AddKeysToAgent で自動登録させる

もっとも手数が少ないのはこれである。~/.ssh/config に書いておくと、その鍵を初めて使うときに一度だけパスフレーズを聞き、以後はエージェントに載ったものが使われる。

Host *
  AddKeysToAgent yes
  IdentityFile ~/.ssh/id_ed25519

ssh_config(5)(新しいタブで開く)AddKeysToAgentyes のほか confirmask1h のような寿命指定も受け付ける。
共用マシンなら confirm にして、鍵を使うたびに確認を出す運用にできる。

2. OS の常駐エージェントに接続する

シェル起動ファイルで ssh-agent を起動するのをやめ、OS が管理しているエージェントを使う。
プロセスの寿命がログインセッションに揃うため、端末を開き直しても鍵が残る。

macOS は標準で launchd がエージェントを起動しており、SSH_AUTH_SOCK も自動で入る。
Linux では systemd の user unit を有効にする。

systemctl --user enable --now ssh-agent.service

Windows は OpenSSH Authentication Agent サービスを自動起動にする。

Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent

3. macOS は Keychain にパスフレーズを預ける

macOS 限定だが、UseKeychain yes を併用するとパスフレーズ自体を Keychain が保持する。
再起動後の初回接続でも聞かれなくなる。

Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

登録済みのパスフレーズを Keychain に入れ直したい場合は ssh-add --apple-use-keychain ~/.ssh/id_ed25519 を一度実行する。

4. 切り分けは ssh-add -l から始める

原因が「エージェントが居ない」のか「鍵が入っていない」のかで対処が変わる。
まず状態を見る。

echo "$SSH_AUTH_SOCK"
ssh-add -l

SSH_AUTH_SOCK が空ならエージェントに繋がっていない(原因 1 か 2)。
変数はあるのに The agent has no identities. が返るならエージェントは生きていて鍵だけが無い(原因 4 か、単に未登録)。
鍵が並んでいるのに聞かれるなら、使われている鍵が違う(原因 3 か 5)ので ssh -v で実際に提示された鍵を確認する。

この記事は役立ちましたか?