miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

gisty のエラー回避方法その他メモ

一週間ほど前に 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」というエラーになっていました。たぶん昨年 githubHTTPS に対応したのでその影響だと思うんですが。

最新版が 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 に何行か足すだけだから、追加しておくといいかも。