win-ssh-agent.sh

このごろ Windows デスクトップを作業環境としていろいろいじっています。ただし身体に染み付いた Unix/GNU 環境の習慣は捨てようにも捨てられないので MSYS をメインに使っております (右のキモいイメージは msys.ico に入ってた 9 つのアイコンを並べたものです)。

もちろん MSYS はこういう生活環境向けに作られたものではなく、普通は Cygwin を使えということになるのでしょうが、 MSYS は Cygwin に比べてコンパクトで管理の面倒さがないので愛用してます。

それに最近は Git が流行しており Windows で Git を使う人の大半は Git for Windows パッケージで MSYS 環境をインストールすると思いますので、作業環境としての MSYS も増えてきているのではないでしょうか。

Windows における ssh-agent の運用

さて MSYS や Cygwin 環境で暮らしていると SSH については /bin/ssh を多用することになると思うのですが、そうなると必要になってくるのが ssh-agent です。

OpenSSH の ssh-agent の運用は結構悩ましい問題です。環境変数 SSH_AUTH_SOCK を使って UNIX ドメインソケットのパスを伝達する仕組みなので、ただ ssh-agent を起動しただけでは既存のシェルでの ssh コマンドには伝わらず使えません。起動したまま放置された野良 ssh-agent プロセスが多数発生しがちなのも悩みどころです。

最近の Linux や Mac のデスクトップ環境ではこの問題に対処するため ssh-agent のサポートがセッションマネージャに組み込まれており、ログイン後セッション初期化中に ssh-agent やそれに類するものを起動して、環境変数 SSH_AUTH_SOCK をあらかじめ設定するようになっています。

Windows で同じことをやるのは難しいのですが、似たような効果を得る方法として、 Windows のレジストリにはユーザおよびシステムの環境変数を登録するところ (コントロールパネルから設定できるあれです) があるので、これを利用することができます (環境変数をシステムに通知する方法 参照)。

ssh-agent 起動後、そいつが吐いた環境変数設定を当該レジストリに登録しておけば、その後エクスプローラが起動するプロセスについてはこの環境変数を設定するので ssh-agent が利用できるという寸法です。

これを自動的にやってくれるソフトウェアとして昔からあるのが GANA さん の作られた win-ssh-agent です。 C++ で書かれており GUI も備える完成度の高いソフトウェアです。ただし Cygwin 環境専用となっています。

win-ssh-agent のソース を見て、環境変数をレジストリに登録するだけなら、いまどきの Windows なら C++ を使わずとも標準搭載のスクリプティング環境だけで実現できるだろうと思い、最近覚えた PowerShell を使って書いてみたのが wih-ssh-agent.sh という /bin/sh スクリプトです。

win-ssh-agent.sh 使用法

win-ssh-agent.sh を使うには次のものが必要です。

win-ssh-agent.sh を bash などで実行すると次のことをしてくれます。

それ以降そのログインセッションでは、もう新たな ssh-agent を起動したりパスフレーズを入力したりする必要はありません。ただし win-ssh-agent.sh を実行したシェルには反映されませんのでこれは終了してください。

このスクリプトはログイン時に自動的に実行するのが便利でしょう。 Git for Windows を普通にインストールした状態なら .sh 拡張子のファイルは Git Bash に関連付けされているでしょうから、ショートカットなりスクリプトそのものなりをスタートメニューのスタートアップに放り込んでおけば動きます。

関連付けをしていなければ、次のように引数つきの bash.exe のショートカットを作ってください。

MSYS (Git for Windows) の場合:

"C:\Program Files\Git\bin\bash.exe" /path/to/win-ssh-agent.sh

Cygwin の場合:

C:\Cygwin\bin\bash.exe /path/to/win-ssh-agent.sh

重要: 残念ながら MSYS と Cygwin では ssh-agent の相互運用ができないようです (MSYS の ssh-agent は Cygwin の ssh から利用できないし、その逆もできない)。したがってこのスクリプトはどちらかの環境でしか使えません。

win-ssh-agent.sh 説明

レジストリに環境変数を登録するために内部で PowerShell を起動しています。ただし PowerShell が標準で使えるのは Windows 7 以降なので、可能なら WSH で VBScript でも使ったほうが Windows XP もサポートできてよかったかもしれません。

ssh-agent から渡される SSH_AUTH_SOCK には /tmp/ssh-BBgxwbJC52/agent.52 といった Cygwin/MSYS 環境内のパスが設定されています。これは当然ながらその環境の外では通用しないため、 Windows 環境変数に登録する前に Windows パスに変換する必要があります。

そのために Cygwin 環境では cygpath コマンド を使い、 MSYS 環境では Posix パスの自動変換 という謎めいた機能を使って変換したものを SSH_AUTH_SOCK に登録しています。

2013/02/12 追記

あとで調べたところ PowerShell や WSH なぞ使わなくても setx コマンドで同じことができるのを思い出しました…。

setx が標準で使えるのは Windows Vista 以降で、 Windows XP では別途インストールが必要なようです。

setx には setx 変数名 -f ファイル名 -a 縦位置,横位置 とかいうものすごい構文がありますね。なんだ縦位置横位置って。そこはふつう正規表現じゃないのか。ちょっとカルチャーショックでした。

まとめ

Windows のレジストリを使って MSYS/Cygwin 環境における ssh-agent 設定をログインセッションで永続化するスクリプトを書いたので紹介しました。

この問題についてはレジストリを使う手法以外にも Keychain とかいろいろなアプローチがありますので調べてみてください。

すでに書きましたが MSYS と Cygwin で ssh-agent の相互運用ができないので、これを何とかできないかと思っています。ついでにいうと PuTTY の Pageant プロトコルとも相互運用できるような ssh-agent があると理想的なのですが。

2013/02/12 追記

ssh-pageant の存在にいまごろ気づきました (pageant を pagent で検索していたらしい)。ただしこれは Cygwin 用のようですが MSYS でも使えるでしょうか。

また gniibe さんが Facebook で pageant-proxy-to-gpg.py というスクリプトを書かかれたことを教えてくれました。

やっぱり同じことを考えてる人はいるものですね。今後はもっとよく調べてから記事を書くようにしたいと思います…。

2013/02/10 08:31:00 JST