はじめに
とある作業で動作確認を実施中、Nginx のアクセスログを確認していたら次のようなエラーログがたくさん出力されていました。
YYYY/MM/DD hh:mm:ss [error] 9662#9662: ocsp.digicert.com could not be resolved (110: Operation timed out) while requesting certificate status, responder: ocsp.digicert.com, certificate: "/etc/pki/tls/certs/cert_combine.pem"
・・・
ocsp.digicert.com
にアクセスできずにタイムアウト起こしているようです。
そもそも何をしようとしていたのか?
そもそも ocsp.digicert.com
にアクセスしようとしていたのは、 OCSP(Online Certificate Status Protocol) ステープリングという機能を使って、サーバーにインストールされている証明書が有効であるということを認証局のOCSPレスポンダーに問い合わせていたためです。OCSP ステープリングの詳細はここでは割愛します。Qiita の記事 OCSP Stapingの調査 あたりを確認いただくとよいと思います。
なぜタイムアウト?
エラーログの内容、事象は理解できました。
OCSP レスポンダーへの問い合わせは、 HTTP プロトコルを使ってやりとりが行われるため、サーバーからocsp.digicert.com
への HTTP の通信が通っていない可能性を考えました。
この旨ネットワーク担当者に確認したところ、サーバーからインターネット外部への方向のすべてのHTTP通信は全開放しているとのことで、ちょっと理解できませんでした。
サーバー側の設定とかを確認しても特に問題は見当たりません。
念のため、OCSP レスポンダーへ手動で通信が通るか確認してみました。
$ curl -V ocsp.digicert.com/ping.html
* About to connect() to ocsp.digicert.com port 80 (#0)
* Trying xxx.xxx.xxx.xxx...
* Connected to ocsp.digicert.com (xxx.xxx.xxx.xxx) port 80 (#0)
> GET /ping.html HTTP/1.1
> User-Agent: curl/7.29.0
> Host: ocsp.digicert.com
> Accept: */*
>
* Recv failure: 接続が相手からリセットされました
* Closing connection 0
curl: (56) Recv failure: 接続が相手からリセットされました
タイムアウトというより接続が切れてしまっています。
tcpdump でパケットキャプチャしてみたところ、エラーになるパケットの TTL が 1 しか減っていなかったので、そもそも最後までパケットが到達せず、デフォルトゲートウェイ先となっている機器で通信をはじいている事象が確認できました。この機器はファイアウォールであることが分かったため、改めてネットワーク担当者にファイアウォールの設定確認をお願いしました。
解決!
少し時間がかかりましたが、解決しました。
原因としては「ファイアウォールで、サーバーからインターネット外部へのOCSPプロトコルの通信が遮断されていた」というものでした。
OCSP 自体は HTTP プロトコルで通信するのですが、この中で OCSP プロトコルのメッセージがやりとりされており、このメッセージの内容をファイアウォールで解析して接続をリセットしていたようです。
ファイアウォールにてこのプロトコルが通過できるようにホワイトリストを追加してもらい、無事このエラーは解消しました。
あとがき
Web サービスを構築する際には、HTTP/HTTPS の疎通はもちろん、OCSP の観点でも疎通が大丈夫か確認をしておくとよいことがわかりました。
ネットワークの疎通がうまくいっていないときは、レイヤ 3 の通信だけではなく、さらに上のレイヤの通信の観点でも確認してみると解決できることがあるかもしれません。
改めて OSI 参照モデルへの理解が深まりました。