(2014/1/30追記)
Yahoo!のWebAPIやOpenIDでも同様の事象があったようです。
かなり影響の大きい問題だったのですね。
WebAPIやOpenIDでSSLエラーが起きる現象につきまして
http://techblog.yahoo.co.jp/maintenance/4/
問題
curlでとあるhttpsスキームのAPIを叩いたら、こんなエラーが。
SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
後付けで分かりましたが、原因は以下でした。
RHEL5/CentOS5でGlobalSignのルート証明書が有効期限切れで大騒ぎ
http://heartbeats.jp/hbblog/2014/01/rhel5centos5globalsign.html
記事内にもある通り、取り急ぎの対応は
接続側で証明書検証をしないようにする(curlコマンドなら -k をつける)
だったりするのですが、はじめは
証明書切れた癖に検証スルー出来るってどういうこと?そもそもそんな証明書意味ないんでは
とか思ってました・・
ということで、恥を忍んでもろもろ整理してみます。
何が起こっていたのか
結論はクライアント側にインストールされているルート証明書の有効期限切れなのですが、順を追ってみます。
そもそものSSLの仕組みをざっくりと
まずSSLの仕組みを把握しておく必要がありました。
ものすごいざっくりですが、大枠は以下の流れになります。
-
もともと、各クライアント(※)には、SSL通信に備えて(認証局/CAが発行した)ルート証明書がインストールされている。
-
そのルート証明書によって、(接続先のサーバから得られる)サーバ証明書を検証し、認証局によって正当性が担保されているかどうかチェックする。
-
サーバが正当と分かれば、クライアントは共通鍵を準備、サーバへ送信し、以降はその共通鍵を用いて通信を行う。
※ここで言うクライアントとは「あるサーバに対して接続を行う主体/接続元」のこと。
つまりそれは、ブラウザだったり、サーバだったり、何でも有り得ます。
※SSLについての詳細は、以下記事が分かりやすかったです。
イケメンとラブレターで学ぶSSLの仕組み
http://blog.jnito.com/entry/2013/05/26/064803
つまり、エラーが発生するのは
SSLの流れから考えて、基本的に遭遇するのは以下2パターンだと分かります。
- サーバ側の証明書が不正(有効期限切れorもともと認証局によって正当性が担保されていない、等)
- クライアント側にインストールされているルート証明書が不正(有効期限切れ等)
前者が特によくあるやつですね。
通常のwebユーザーとしてもちょくちょく遭遇するこれです。
ですが、今回の原因は後者でした。
RHEL5/CentOS5でGlobalSignのルート証明書が有効期限切れで大騒ぎ
http://heartbeats.jp/hbblog/2014/01/rhel5centos5globalsign.html
つまり、
(接続先サーバの正当性をチェックするための)クライアント側(となる接続元サーバ(CentOS/RedHat))のチェック用証明書
が期限切れで使えなくなってしまったということ。
こう考えると、
取り急ぎの対応として、接続先サーバの正当性チェックを止める(ことでエラーは回避できる)
というのも納得ですね(もちろん、その際は接続先が間違いなく信頼できる、という前提が必要ですが)。
はじめに問題に遭遇した時は
- クライアント(接続元)としてのサーバ(チェックする側)
- 接続先としてのサーバ(チェックされる側)
という二者を混同していたようです。
対策
概念としては、基本は以下の二つになります。
- (上記の通り)接続先のチェックを止めてしまう
- クライアント側にインストールされているルート証明書を最新にする
今回は問題の仕組みの理解/説明を残しておきたかったということで、
対策の詳細は以下記事へのポインタのみで失礼します!
[PHP][cURL] cURLでSSL(https)のCA証明書警告の回避や設定
http://mio-koduki.blogspot.jp/2012/08/php-curlsslhttpsca.html
サーバのSSL CA(認証局)証明書が古くてcurl がエラーになる件
http://d.hatena.ne.jp/hogem/20120705/1340284071