GNU screen の バグ報告を行なう ついでに screen-devel ML に参加したら、 次のようなメールが ML に流れてきた:
There is a much simpler solution
http://www.2701.org/archive/200406150000.html
The key is that SSH_AGENT need not point to a socket, it can point to a symbolic link to a socket.
なるほど~
ssh-agent と通信するための UNIX ドメイン ソケット を指す (パス名固定の) シンボリック リンクを作るようにしておけば、 環境変数 SSH_AUTH_SOCK には、そのシンボリック リンクのパス名を 設定しておけば済むので screen の中で ssh を使うとき便利、 というわけである。 つまり、
senri:/home/sengoku % ssh asao Last login: Sun Sep 10 08:24:20 2006 from senri.flets.gcd.org Linux 2.6.16.28. asao:/home/sengoku % echo $SSH_AUTH_SOCK /tmp/ssh-chKJY25976/agent.25976 asao:/home/sengoku % screen -r
senri で ssh-agent を走らせておいて、 asao へ ssh でログインするさいに、 ForwardAgent を有効にしておくと、 上の実行例のように、SSH_AUTH_SOCK に UNIX ドメイン ソケットの パス名が設定され、このソケットを介して senri の ssh-agent と通信ができる。
ところが、前回のログイン時に使っていた screen を reattach すると、 screen の中では、SSH_AUTH_SOCK の値は、 前回のログイン時のパス名のままである:
asao:/home/sengoku % echo $SSH_AUTH_SOCK /tmp/ssh-ptnuvb3346/agent.3346
ForwardAgent はログアウトと共に終了するので、 screen の中の SSH_AUTH_SOCK の値は、 ログインするごとに設定し直す必要がある。 これはとてもメンドクサイ。
ログインし直すたびに SSH_AUTH_SOCK の値が変化するから、 このような問題が起きるわけで、 SSH_AUTH_SOCK の値が常に同じなら、 reattach した screen の中でも同じ SSH_AUTH_SOCK の値を使い続けることができる。
すなわち、 SSH_AUTH_SOCK が直接 UNIX ドメイン ソケットを指し示すのではなく、 UNIX ドメイン ソケットを指し示すシンボリック リンクを作成しておいて、 SSH_AUTH_SOCK にはこのシンボリック リンクのパス名を設定しておけばよい。
さっそく ~/.cshrc に次の行を追加した:
set agent = "$HOME/tmp/ssh-agent-$USER" if ($?SSH_AUTH_SOCK) then if (! -S $SSH_AUTH_SOCK) unsetenv SSH_AUTH_SOCK endif if ($?SSH_AUTH_SOCK) then if ($SSH_AUTH_SOCK =~ /tmp/*/agent.[0-9]*) then ln -snf "$SSH_AUTH_SOCK" $agent && setenv SSH_AUTH_SOCK $agent endif else if (-S $agent) then setenv SSH_AUTH_SOCK $agent else echo "no ssh-agent" endif unset agent
私は、かれこれ 20年近く csh をログイン シェルとして使い続けてきているので、 ~/.cshrc なのだが、今となっては (極めて?) 少数派だろう。 bash など、sh 系をログイン シェルとして使っている場合は、 ~/.profile などに
agent="$HOME/tmp/ssh-agent-$USER" if [ -S "$SSH_AUTH_SOCK" ]; then case $SSH_AUTH_SOCK in /tmp/*/agent.[0-9]*) ln -snf "$SSH_AUTH_SOCK" $agent && export SSH_AUTH_SOCK=$agent esac elif [ -S $agent ]; then export SSH_AUTH_SOCK=$agent else echo "no ssh-agent" fi
などと書いておけばよいだろう。
ssh-agentを複数の仮想端末から使う方法
「ssh-agent を screen の中から使う方法」にインスパイヤされた話。僕が家で使っているPCはWindowsで動いていまして、 Cygwin, CygTerm, PuTTY日本語版, zshを使っています。 SSHでサーバに接続したときは接続先でscreenを動かすんですけど、ローカルでは複数のPuTTYを動か…
Comment by blog.fuktommy.com — 2006年9月28日 @ 00:30
二重login shell対策の/tmp/*チェックだと思いますが、それだとシステム構成に影響されるので、私は
test ! -L “$SSH_AUTH_SOCK” -a -S “$SSH_AUTH_SOCK” && ln …
としています。
あと、二回ログインして後から入った方で抜けると壊れるため、netstat -lnx からソケットを拾いなおして再リンクするスクリプトを作っておくと重宝します(よくやってしまう)。
Comment by tai — 2006年9月28日 @ 15:02