一週間ほど前に gisty (gist をより便利に使う Ruby スクリプト)を使おうとしたら何かエラーが出ていたので、それ関連の雑多なメモです。
2011-10-23 追記: 長々と書いてますけど
gisty で
Error: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
みたいなエラーになるのをなんとかしたいって方は、環境変数の GISTY_SSL_CA に msysGit(新しいバージョンのほうがよいです)に付属してくる CA ファイルを指定すればよいです。
set GISTY_SSL_CA=C:\Program Files\Git\bin\curl-ca-bundle.crt
みたいな感じ。私はよくやってしまうんですが、set で環境変数を設定するときにダブルクォートをつけてしまうとうまくいかないのでお気をつけください。
gisty とっかかり
使い方の基本的な解説は
を見るといいかと。最新バージョンを入れたい場合はこの手順に従わず、次項に書いた方法でインストールしましょう。
Windows で使うときの注意点ですが、GISTY_DIR に指定するパスは「\」区切りではなく「/」で指定しましょう。そうしないと gisty list 等がうまく動作しません。
久々に使うとエラーが
これで以前入れてたんですが、久々に実行すると「redirection forbidden」というエラーになっていました。たぶん昨年 github が HTTPS に対応したのでその影響だと思うんですが。
最新版が gemcutter にあるので、github のを入れてる場合は一度
gem uninstall swdyh-gisty
したうえで、
に書いてある、
# (2011-01-25)gem sources は要らないみたいなので削除 # gem sources -a http://gemcutter.org gem install gisty
を実行すればよいです。
「certificate verify failed」エラー
ということで無事 gisty を入れなおしたんですが、今度は別のエラーが。
>gisty sync C:/Program Files/ruby-1.8/lib/ruby/1.8/net/http.rb:586:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError) from C:/Program Files/ruby-1.8/lib/ruby/1.8/net/http.rb:586:in `connect' from C:/Program Files/ruby-1.8/lib/ruby/1.8/net/http.rb:553:in `do_start' from C:/Program Files/ruby-1.8/lib/ruby/1.8/net/http.rb:542:in `start' :
エラーで検索すると、最初に見つかったのはこちら。
うーん。ちょっとソースにパスをべた書きするのは嫌かなぁ。あと crt ファイルってなんだろ?
ということでさらに調べると、
ca_file 作ればいいとかなんとか。あとコメント欄で
swdyh 2010/12/13 20:17
GISTY_SSL_CAという環境変数で、CAファイルを指定できるようにしました。
という情報が。じゃあ CA ファイルを・・・ってこれどうすればいいんだろ?
とりあえず回避策(定数の上書き)
ちょっとその時は時間がなかったので、見つけた別の回避策を実施しました。
で紹介されていたんですが、
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
のようにして、定数を書き換えてしまう方法です。
今回であれば、lib\ruby\gems\1.8\gems\gisty-0.0.17\lib\gisty.rb の require の最後あたりに
require 'openssl' OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
を追加すると、いちおう動作するようになりました。
Go Daddy の pem ファイルを指定してみる→エラー解決せず
いちおう回避はできたんですが、定数を上書きする方法だと、実行するたびに
warning: already initialized constant VERIFY_PEER
のような警告が出て気持ち悪いので、まともな解決策を調べてみることにしました。
github の証明書をブラウザで確認すると、
こんな感じになっているようで。
ca_file は接続先の証明書を証明した CA(認証局)が正統であることを示すためのものだろうから、
- Go Daddy Secure Certification Authority
- Go Daddy Class 2 Certification Authority
のどちらかを指定すればいいんだろうということで、
を参考にしつつ、証明書をエクスポートして(※Chrome でも IE と同じ証明書ダイアログが出るので Chrome でやりました)、この .cer ファイルを指定してみました。
テストスクリプトは、
require 'net/https' https = Net::HTTP.new('github.com',443) https.use_ssl = true https.verify_mode = OpenSSL::SSL::VERIFY_PEER https.ca_file = 'c:/github.cer' https.start{|w| response = w.get('/') puts response.body.length }
こんな感じなんですが・・・どの証明書を使っても「certificate verify failed」エラーになってしまうようで。
デバッグ方法について調べてみる
https.set_debug_output(STDERR)
とかやると Net::HTTP レベルのデバッグはできるみたいですが、ここには openssl まわりの情報はなく。
にも情報がないので、ruby のソースを読むと、
OpenSSL::debug = true
とすればより詳細な情報が拾えることがわかりました。
これを先頭につけてみると・・・。
OSSL_DEBUG: IS NOW ON! C:/Program Files/ruby-1.8/lib/ruby/1.8/net/http.rb:586: warning: error on stack: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
とより詳細な情報が拾えました。
ちなみに今回ソースを読みましたが、
のほうはソースから生成されたドキュメントみたいですね。今度からこっちを見るようにしよう・・・。
使えそうな CA ファイル
このエラーメッセージを元に検索すると、ずいぶん情報が増えてきて。
まず、
で、 http://curl.haxx.se/ca/cacert.pem という CA ファイルが紹介されていて。これを ca_file に指定するとちゃんと動作することが確認できました。
たくさん証明書が入っているようですが、どの証明書が効いているのかちまちま調べると「ValiCert Class 2 VA」があればエラーにならないようで。これどこから出てきたの?
より詳細な情報
に github の証明書をうまく通すための具体的な方法が載っていました。
openssl s_client -connect github.com:443 -showcerts
として証明書チェーンを内容込みで表示して、ハッシュ値を元にシンボリックリンクを作ればいいとかなんとか。
とりあえず
openssl s_client -connect github.com:443
として内容を確認すると、確かに
CONNECTED(00000003) depth=3 /L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority /CN=http://www.valicert.com//emailAddress=info@valicert.com verify error:num=19:self signed certificate in certificate chain verify return:0 --- Certificate chain 0 s:/O=*.github.com/OU=Domain Control Validated/CN=*.github.com i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository /CN=Go Daddy Secure Certification Authority/serialNumber=07969287 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository /CN=Go Daddy Secure Certification Authority/serialNumber=07969287 i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority 2 s:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority i:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority /CN=http://www.valicert.com//emailAddress=info@valicert.com 3 s:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority /CN=http://www.valicert.com//emailAddress=info@valicert.com i:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority /CN=http://www.valicert.com//emailAddress=info@valicert.com
みたいに ValiCert が最上位にきてるみたいですね。なんでブラウザだと表示されないんだろう・・・?
なにはともあれ
上のほうにあった使えそうな CA ファイルを %APPDATA%\ssl\certs\cacert.pem として置いて、
環境変数 GISTY_SSL_CA に
C:\Documents and Settings\****\Application Data\ssl\certs\cacert.pem
みたいに設定して。今度こそうまくいくかと思ったら・・・エラーが変わってない??
と、GISTY_SSL_CA が説明されてるページをよくみると、
- 通常のコマンドは OpenSSL::X509::DEFAULT_CERT_FILE の場所に ca_file を置くことで解決
- gisty post については net/https を使っているので ca_file を書き換えて対応
- GISTY_SSL_CA の変更はこの部分にだけ適用されている
ということのようで。
OpenSSL::X509::DEFAULT_CERT_FILE の場所がどこか調べてみると・・・
>ruby -ropenssl -e "p OpenSSL::X509::DEFAULT_CERT_FILE" "c:/users/arton/documents/ssl/cert.pem"
ActiveRuby 使ってるから arton 氏の名前が・・・。確かにこの名称でファイルを置いたらうまくいくけど、こういう謎なパスを作るのは嫌だなぁ。ちなみにこのパスは C:\Program Files\ruby-1.8\bin\libeay32.dll に埋め込まれてるから、気軽には変更できない模様。
ということで、結局一週間前にやった定数の置き換えで回避してます。GISTY_SSL_CA が指定されてたら OpenSSL::X509::DEFAULT_CERT_FILE も書き換えてもらえるとうれしいなぁ・・・。
2011-01-25 追記: 0.0.18 で対応していただきました。
その他
今回色々探してて見かけたのでついでに。
確かに「あの処理どこで使ったっけ?」ってことはあるから、これ便利そう。lib\ruby\gems\1.8\gems\gisty-0.0.17\bin\gisty に何行か足すだけだから、追加しておくといいかも。