ssh-agent転送(Agent Forwarding)がうまく動かない、というトラブルにたまに遭遇しては毎回悩んでいる気がしたのでまとめてみます。
ssh-agent転送の概要
ssh-agent転送というのは、ローカルサーバのssh-agentがリモートサーバでも使えるようになる仕組みです。いちいちパスフレーズを打たなくていい環境がリモートでも使えて便利、という奴ですね。
$ ssh -A [リモートホスト名]
上記のようにリモートサーバにログインすると、リモートサーバからSSHアクセスする場合にローカルのssh-agentを使って認証してくれます($HOME/.ssh/config
で設定することもできます)。
上のざっくり説明で通じない人はこの記事に辿り着かないと思うんですが、それでもわからんという場合は「ssh agent forwarding」でググってください。
ssh-agent転送の状態はssh-add -L
で確認できる
さて、ssh-agent転送の設定をしているのになぜかSSH認証が失敗する、という状況になったとしましょう。
この場合、リモートサーバ上でssh-add -L
と打つとssh-agent転送がうまくいっているか確認できます。
ssh-agent転送自体がうまくできていないとき
ssh-agent転送がうまくできておらず、ssh-agentにアクセスできないときは次のように表示されます。
$ ssh-add -L
Could not open a connection to your authentication agent.
この場合は一度ログオフして、.ssh/config
にForwardAgent Yes
を追加するなり、ssh -A [リモートホスト名]
でログインし直すなりしてみてください。
鍵が登録されていないとき
リモートサーバ上でssh-agentが見つかったものの、鍵が登録されていないときは次のように表示されます。
$ ssh-add -L
The agent has no identities.
この場合、ローカルサーバでssh-add
して鍵を登録しましょう。
ただし、ローカルサーバがmacOSの場合は注意が必要です。macOSでは手元のssh-agentは何も仕事をしていません。普段同等の仕事をしているのはkeychainという別のプロセスなのです。ssh-add -K
とすることで、keychainの持っている情報をssh-agentに連携できます。
鍵が登録されているとき
ssh-agentに鍵が登録されている場合は次のように表示されます。
$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDi(中略)K6CmI7kEsQxkBmZ1/nSAOiOgu3eTNkDF hnw@example.com
登録されている鍵ペアの公開鍵が表示されます。この鍵が期待通りかどうか、手元の公開鍵と見比べてみてください。
補足: ssh-agent転送を共用サーバで使ってはいけない
指摘している人はあまり多くないのですが、ssh-agent転送は状況によってはセキュアではありません。
以上のように、ForwardAgent は大変便利な機能であるが、 ログインした先のマシンの root 権限を持っている人が自分以外にもいる場合は、 注意が必要である。
(略)
つまり、その人は senri 上で動いている私の ssh-agent すなわち私の ssh 秘密鍵を (passphrase 無しで) 利用することができてしまう。
上記の記事でも指摘されているように、攻撃者がssh-agentの利用するUNIXドメインソケットにアクセスできた場合、パスフレーズ無しで自分の鍵ペアを使われてしまうのです。
とはいえ、ssh-agent転送より良い選択肢はあるのでしょうか。
実は多段でSSHするのが目的であればssh-agent転送は必須ではありません。ProxyCommand
/ ProxyJump
を使えば同等の状況が実現できる上にセキュアなのでオススメです1。
また、デプロイ時などリモートサーバ上でSSH経由でgit pull
したいような用途であればデプロイキーの利用も検討すべきでしょう。
もちろん、ssh-agent転送が一番良いという場合もあります。ssh-agent転送は用法・用量を守って正しくお使いください。
-
「多段SSH ProxyCommand」でググってください ↩