curl – cURL error 60: SSL certificate problem 対処方法に関して

概要

先日 perl の LWP でも SSL がらみのエラー対処をしていたのですが、curl で Google Alert の RSS フィードを RSS リーダーに登録して気付きました。

事象

cURL error 60: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
とか
curl: (51) SSL: certificate subject name ‘anja.haxx.se’ does not match target host name ‘curl.haxx.se’
とか
エラー: 証明書に記載されている名前 `anja.haxx.se’ とホスト名 `curl.haxx.se’ が一致しません
curl.haxx.se に安全の確認をしないで接続するには、`–no-check-certificate’ を使ってください。
SSL による接続が確立できません。
などなど

cacert_error

原因

CA が古いため

対応

Mozilla から提供されている最新の CA 証明書をダウンロードして置き換えれば良い。ただし、RHEL や CentOS では yum provides */ca-bundle.crt を実行してみると確認できるのですが、openssl パッケージに同梱されているため、本来は yum update openssl -y で更新できることが望ましいのです。しかし、手元の CentOS 5.11 だと 7月4日現在(openssl-0.9.8e-36.el5_11.x86_64)ではまだ改善されていないようです。

curl performs SSL certificate verification by default, using a “bundle”
of Certificate Authority (CA) public keys (CA certs). The default
bundle is named curl-ca-bundle.crt; you can specify an alternate file
using the –cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you’d like to turn off curl’s verification of the certificate, use
the -k (or –insecure) option.

ということなので、暫定では curl なら -k–insecure オプションを、wget なら –no-check-certificate を利用して凌いでおき、openssl パッケージの新しいパッケージが利用できるようになったらインストールしておくのが良さそうですね。

例)
# curl https://curl.haxx.se/ca/cacert.pem -k
# curl https://curl.haxx.se/ca/cacert.pem –insecure
# wget https://curl.haxx.se/ca/cacert.pem –no-check-certificate

補足
否、それでは HTTPS を利用している意味がないのだという諸兄は以下のように置き換えてしまっても然程困ることもないと思われる。
# curl https://curl.haxx.se/ca/cacert.pem -k -o /etc/pki/tls/certs/ca-bundle.crt

ただ、私の環境では、回避方法は何れもうまく動作したが、実際に cacert.pem を新しいものに置き換えた場合でも、結局ネイキッドドメインだったりホスト名部分が証明書の異なる場合は curl: (51) や curl: (60) や wget のエラーは解消されなかった。暫定回避するか FQDN が証明書の subject と一致するようにするほかないと思われる。

例えば GoogleAlert (日本語) の場合、www.google.co.jp が HTTPS でアクセスする際の FQDN になっているが、wget すると検証に失敗する。
# wget https://www.google.co.jp/alerts/feeds/10023952253983940424/8750379385282834927
–2016-07-04 23:32:45– https://www.google.co.jp/alerts/feeds/10023952253983940424/8750379385282834927
www.google.co.jp をDNSに問いあわせています… 172.217.25.99, 2404:6800:4004:819::2003
www.google.co.jp|172.217.25.99|:443 に接続しています… 接続しました。
エラー: www.google.co.jp の証明書(発行者: /C=US/O=Google Inc/CN=Google Internet Authority G2)の検証に失敗しました:
発行者の権限を検証できませんでした。
エラー: 証明書に記載されている名前 `google.com’ とホスト名 `www.google.co.jp’ が一致しません
www.google.co.jp に安全の確認をしないで接続するには、`–no-check-certificate’ を使ってください。
SSL による接続が確立できません。

同様に curl の場合なら curl: (60) が返される。
# curl https://www.google.co.jp/alerts/feeds/10023952253983940424/8750379385282834927
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

コマンドラインなら気付けるし分かりやすいのだけれど Web アプリケーションなどで Web API や HTTPS を叩くような場合は値が空になったりして気付きにくいように思う。

スポンサーリンク

シェアする

フォローする

スポンサーリンク