ssh-agent(1)
の機構はあまりに素朴過ぎて使いづらいので、実用と現実逃避を兼ねてssh-agent-proxy(1)
なるものを作った。例によってRubyで書いたプロトタイプだけど、一応動くので公開。
こいつは何かというと文字通りssh-agent(1)
のプロクシだが、ポイントは二点。
- それ自身がSSH認証エージェントとして動き、固定パスにソケットを開く。
- クライアントからの接続があると、その場で利用可能な本物のエージェントソケットを探し、通信を中継する。
1により、SSH_AUTH_SOCK
には常に固定値を設定すればよくなる。(これはssh-agent(1)
でも-a
オプションで指定すれば可能) そして2によって、いつでも動的にその時点で利用可能なエージェントソケットを探してつないでくれる。
これがどのように役に立つのかと言えば、たとえばこういうときだ。いつものように、リモートホストにエージェント転送をオンにしてSSH接続したとしよう。そこでscreen(1)
を起動し、作業をする。この段階では、問題なくエージェント転送が効いている。ところが、ここで不慮の、あるいは意図的な切断によって、SSH接続が切れてしまったらどうなるか。screeen
およびその子プロセスが持つSSH_AUTH_SOCK
は、もはや無効なソケットを指した状態で取り残されてしまう。後で再び同ホストにSSH接続し、保存されたscreenセッションに接続(attach)しても、新しい(転送)エージェントのソケットは使われず、古いSSH_AUTH_SOCK
が指すソケットにつなごうとして失敗するだけだ。手で同環境変数の値を更新するしかないが、これはシェル関数(やEmacs用のelisp関数)を用意したとしても非常に面倒な作業だ。
そんな憂鬱も、ssh-agent-proxy(1)
を使えば一発で解決する。リモートホストのログインスクリプト内に、次のように書いておく:
1 |
eval $(ssh-agent-proxy 2>/dev/null) |
これだけ。*1あとは、勝手にそのときそのとき使えるソケットに中継してくれる。multi-tty版Emacsだけを飼うscreenセッションを裏に置いておけば、いつでもemacsclient
で瞬時にエディタが起動し、tramp
やvc
やpcl
でのSSH接続も無問題。
もちろん、転送元ホストでもssh-agent-proxy
を使うメリットはある。もし何らかの理由によって、ssh-agent
のインスタンスが死んでしまったりソケットが消えてしまったりしても、慌てずに新しくssh-agent
を起動するだけでいい。(もちろん続いてssh-add
も必要) 仮にssh-agent-proxy
自身が死んでしまったとしても、やはり起動し直せば問題ない。
まだβ版ですが、0.0.1のタグを打っておいたので興味のある人は試してみてください。
こういう行動力はあるじゃないですか。
アタシはこっちのほうが羨ましい。
んー。すわったままできることだからなあ。
仕事中すわったままねるの巻
ssh-agent-proxy(1) 0.0.2リリース
ssh-agent-proxy(1)の0.0.2をリリースします。0.0.1からの主な変更点は以下の通り。 作ろうとしたソケットがすでに存在する場合、実際に接続可能かをチェックし、もし接続できなければ削除してソケットを開くようにした。 すでにdaemonが上がっている場合も環境変数定義..
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.