Windows + 公開鍵認証でCapistrano

できた。ハマるポイントがいくつかあったのでメモを残しておく。

確認したのは

  • Windows Vista/7
  • Ruby 1.9.3-p429
  • Capistrano というか net-ssh 2.6.7
  • Putty 0.6.2

password認証ならたぶん何も考えなくていい

でもねぇ。

経路にもよるけど公開している ssh サーバにパスワード認証で繋がないでしょ?

proxyは試してないのであしからず

ということです。

cygwinでやれるならそれでいいかも

Windows 環境とは別個の閉じた環境で Ruby も ssh(正確にはopenssl) も利用できれば openssh の公開鍵認証が普通に利用できるはず。

少なくとも mingw Ruby + cygwin + openssh 鍵の組み合わせならパスフレーズを聞かれて普通に認証できた。ただ、なぜこのような動作になったのかはイマイチ合点がいっていないことと、deploy のためだけに cygwin を入れるのはまったく目的に合ってないのでこれは深追いしていない。

cygwinなしの場合はpageant頼み

これはそもそもそういう設計になってる。

  • Net::SSH::KeyFactory の理解できる鍵は OpenSSL で理解できる鍵
  • PLATFORM を判別して :win32 の場合は pageant で処理するコードが読み込まれる
    • pageant とは Windows の API を通じてやりとりしているので要は起動してりゃオッケー。PATH が通っている必要なし。試したところ 32bit/64bit どちらでも同じように処理できるみたい。

というツクリになっている。まとめると

Windows では pageant に丸投げ

である。

Rubyは1.9以降で

Ruby 1.8 では OpenSSL 周りのエラーが出てまともに動かなかった。Windows では 1.9 の方が明らかに速いはずなので、素直に 1.9 以降を入れればいいと思う。

自分が試したのは RubyInstaller for Windows の 1.9.3-p429

:keysの設定が必須でしかもなんか変

config/deploy.rb で

ssh_options[:keys] = ["'~/.ssh/id_rsa'"]

あるいは

ssh_options[:keys] = %w('~/.ssh/id_rsa')

のように設定が必須だった。注意すべきは以下の3点。

  1. OpenSSH の鍵認証の場合は正しくデフォルトの鍵を認識してくれる
  2. OpenSSH の ssh-agent を使っている場合はそもそも鍵のパスを与える必要がない(サーバ側の公開鍵とのペアを agent が覚えている中から自動で探してくれる)
  3. :keys には「文字列の文字列の配列」を与える必要がある。

1, 2 は OpenSSH で十分な経験がある人がハマる罠。

3 は Ruby に慣れてる人がハマる罠。

コードを読んでみたが、なぜこのような挙動になるのかは理解できなかった。無念。

公開鍵がないことが原因ではない

上の設定をミスっていると

ArgumentError: Could not parse PKey: no start line

というエラーが出る。これの回答として対応する公開鍵がないからだというものが github などに上がっているんだけど、すでに見たように

公開鍵がないからとは限らない

ので注意が必要。

More