git clone https:// 時の証明書エラー
HTTPS で GitHub から clone しようとしたら証明書のエラーになる。
git clone --depth=1 https://github.com.example.com/repo.git Cloning into 'repo'... fatal: unable to access 'https://github.com.example.com/repo.git/': SSL certificate problem, verify that the CA cert is OK. Details:
メンテが微妙な共有サーバで cacert.pem が10年物で使い物にならない。それで仕方なくローカルに置いていたが、また古くなっているのかもしれない。
検索すると検証をオフにする話がよくヒットする。確かに GitHub に限っては ブラウザで commit ID を読めるので証明書の検証をオフにしても改竄は見つけられるが、それならば git プロトコルで clone したほうが楽そうだ。
そんなわけで今回検証を無効にせずに手探りで HTTPS のまま解決してみた。
解決法
http://curl.haxx.se/ca/cacert.pem
をダウンロードして git config の http.sslCAInfo に設定すればよい
git config --global http.sslCAInfo /path/to/cacert.pem
解決までの詳細
とりあえず認証局証明書を更新してみる。
wget http://curl.haxx.se/ca/cacert.pem -O $SSL_CERT_FILE.new diff -U0 $SSL_CERT_FILE $SSL_CERT_FILE.new | less mv $SSL_CERT_FILE.new $SSL_CERT_FILE
更新したのだが出力は変わらず。SSL_CERT_FILE
を参照していないのか。git のドキュメントによると GIT_CURL_VERBOSE
で詳しいエラーが出るらしい。
GIT_CURL_VERBOSE=1 git clone --depth=1 https://github.com.example.com/repo.git Cloning into 'repo'... * Couldn't find host github.com in the .netrc file, using defaults * About to connect() to github.com port 443 (#0) * Trying 192.30.252.128... * Connected to github.com (192.30.252.128) port 443 (#0) * successfully set certificate verify locations: * CAfile: /usr/local/share/curl/curl-ca-bundle.crt CApath: none * SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed * Expire cleared * Connection #0 to host github.com left intact fatal: unable to access 'https://github.com.example.com/repo.git/': SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
curl は SSL_CERT_FILE
を参照しないようだ。curl は CURL_CA_BUNDLE
を見るが、ヘルプによると git ではそれとは別に http.sslCAInfo
か GIT_SSL_CERT
で設定するようだ。
git config --global http.sslCAInfo $SSL_CERT_FILE GIT_CURL_VERBOSE=1 git clone --depth=1 https://github.com.example.com/repo.git Cloning into 'repo'... * Couldn't find host github.com in the .netrc file, using defaults * About to connect() to github.com port 443 (#0) * Trying 192.30.252.130... * Connected to github.com (192.30.252.130) port 443 (#0) * successfully set certificate verify locations: * CAfile: $SSL_CERT_FILE CApath: none * error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm * Expire cleared * Connection #0 to host github.com left intact fatal: unable to access 'https://github.com.example.com/repo.git/': error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
証明書は通ったがハッシュアルゴリズムが未知と出る。
openssl s_client -trace -connect github.com:443 -verbose ... SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES128-GCM-SHA256 ... ^C
openssl コマンドではネゴシエートでき繋がる。
なので cURL をなんとかすればよさそうな雰囲気だ。関係しそうなのは http.sslCipherList
(GIT_SSL_CIPHER_LIST
) だが、CURLOPT_SSL_CIPHER_LIST
の説明を見て適当に指定してみてもメッセージが変わらない。
仕方がないのでこの8年前の cURL を使うのは諦めてビルドし直すことにした。root 権がないので --prefix
を指定する。
./configure -C --prefix=$myBase --with-libidn --with-ca-bundle=$SSL_CERT_FILE make install
これで curl コマンドは使えるが git 側が古い libiconv を使っていて、libcurl ではローカルの最新版を使ってしまい libiconv のミスマッチが起きた (Undefined symbol "locale_charset"
と出る) ので git もビルドしなおす。
./configure -C --prefix=$myBase --with-libpcre
そのままでは make
できず、Makefile の CURL_LIBCURL
に -lcharset
を追加して CURLDIR=$myBase make all
した。(親切にも Makefile にヒントが書いてある。)
GIT_CURL_VERBOSE=1 git clone --depth=1 https://github.com.example.com/repo.git Cloning into 'repo'... Cloning into 'repo'... * Couldn't find host github.com in the .netrc file; using defaults * Trying 192.30.252.129... * Connected to github.com (192.30.252.129) port 443 (#0) * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH * successfully set certificate verify locations: * CAfile: $SSL_CERT_FILE CApath: none * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 ...
うっかり GIT_CURL_VERBOSE=1
のまま実行してしまって出力が大量になった。しかしようやく clone に成功した。
この共有サーバは PHP や Apache を近年バージョンアップするようになってまだ使えるかと思っていたのだが、基盤となるライブラリが古いままなので最近それらをリビルドするケースが増えてきた。
あまり手間が増えるようなら移ったほうがいいかもしれない。