ssh-agentをscreenの中から使う方法(NFS,二重ログイン対応版)を使ってきたが、問題があったのでさらに改造。何とも言えないバッドノウハウ。
Steps to reproduce:
- 計算機 A1 で ssh-agent を仕込み、ForwardAgent を yes にして B にログイン。すると $HOME/.tmp/ssh-agent/`hostname` は A1 の ssh-agent のソケットへのシンボリックリンクになる。
- 計算機 A2 で ssh-agent を仕込み、ForwardAgent を yes にして B にログイン。すると既に $agent がソケットとして機能しているので、これが SSH_AUTH_SOCK に設定される。
- A1 から B への接続を切る。A1 の ssh-agent のソケットは消される。
- A2 側で ssh-agent が機能しなくなる。
そこで、既にあるソケットを流用する場合には、自分のソケットへのパスを SSH_AUTH_SOCK_OLD に控えておくことにする。接続が切れたときには screen 上で新しい端末を開いたり、update_ssh_agent を直接呼び出したりして SSH_AUTH_SOCK の値を更新すればよい。
しかし、正攻法は B に ssh-agent を常駐させておく方法のはず。そうすれば、A1、A2 からの forwarding に関わらず、B から先にログインできる。そこで、ローカルで ssh-agent が上がっている時にはそちらを優先することにする。さらに処理がぐちゃぐちゃになった。もっと簡単に解決できる予感。
安全性については自信がない。
# ssh-agent を立ち上げるときは init_ssh_agent を呼ぶ init_ssh_agent () { eval `ssh-agent` ssh-add if [ $? = "0" ]; then local agent="$HOME/.tmp/ssh-agent/`hostname`_local" ln -snf "$SSH_AUTH_SOCK" $agent && export SSH_AUTH_SOCK=$agent else echo "init failed" return 1 fi } update_ssh_agent () { update_ssh_agent_ "$HOME/.tmp/ssh-agent/`hostname`_local" \ || update_ssh_agent_ "$HOME/.tmp/ssh-agent/`hostname`" } update_ssh_agent_ () { local agent="$1" if [ -z "$agent" ]; then return 1 fi if [ -S "$agent" ]; then if [ ! "$SSH_AUTH_SOCK" -ef "$agent" ]; then export SSH_AUTH_SOCK_OLD=$SSH_AUTH_SOCK fi export SSH_AUTH_SOCK=$agent return 0 elif [ ! -S "$SSH_AUTH_SOCK" ]; then echo "no ssh-agent" if [ -L "$agent" ]; then rm -rf $agent fi if [ -n "$SSH_AUTH_SOCK_OLD" ]; then if [ -S "$SSH_AUTH_SOCK_OLD" ]; then SSH_AUTH_SOCK=$SSH_AUTH_SOCK_OLD fi unset SSH_AUTH_SOCK_OLD update_ssh_agent fi elif [ ! -L "$SSH_AUTH_SOCK" ]; then # ssh-agent が無効な場合には設定しない ssh-add -l >/dev/null \ && ln -snf "$SSH_AUTH_SOCK" $agent && export SSH_AUTH_SOCK=$agent fi }