CDN、WAF配下のオリジンサーバーのSSLサーバー証明書の確認方法
はじめに
WebサーバーにSSLサーバー証明書を設定したときは、Webブラウザで証明書の情報を確認しますね。
また、僕は「SSL Server Test (Powered by Qualys SSL Labs)」でも、SSL設定や証明書の情報を確認します。
SSL Server Testでは、Webブラウザからのアクセスではわからない、たとえば次のような内容を確認できるので、とても便利です。
- 中間証明書チェーンに不具合がないか。
- Apache/Nginx等のWebサーバーソフトウェアのHTTPSセキュリティ設定、暗号化通信設定が適切か。
- デバイス、ブラウザごとの対応状況。
ここで、以下のようにWebサーバーがCDNやWAF配下のオリジンとなる構成の場合を考えてみます。
このような構成の場合、Webブラウザで確認できる証明書情報や、SSL Server Testで表示される証明書の情報は、CDNやWAFに設定された証明書情報であって、Webサーバーに設定した証明書情報ではありません。
ここでは、Webサーバーの前段にCDNやWAFがある場合に、オリジンWebサーバーに設定した証明書の情報を確認する方法について記載します。
確認方法
SSLサーバー証明書を設置したオリジンWebサーバー上で openssl s_client コマンドでクライアントからのWebアクセスを実行することで、証明書の情報を確認します。
openssl s_client コマンドを利用したSSLサーバー証明書の検証方法については、以下の記事がとてもわかりやすいです。
(参考)
・WebサーバーなどのSSL証明書 検証方法 – Info Circus, Inc. 技術情報
https://www.infocircus.jp/2019/10/23/openssl_cert_verify/
以下、証明書を確認したいWebサイトのドメインは inaba-serverdesign.jp とします。
証明書の検証
証明書の有効期限が切れていないことや、中間証明書のチェーンが正しいことを確認します。
-conect オプションで、ローカルホストのHTTPSポート 127.0.0.1:443 を指定するのがポイントです。
-servername で、確認したいWebサイトのドメインを指定します。
※ここで、-connect inaba-serverdesign.jp:443 とすると、DNSを参照して、前段のWAFもしくはCDNにアクセスします。そのため、出力される情報は、WAFまたはCDNに設定した証明書の情報となり、オリジンWebサーバーの証明書情報を確認できません。
$ openssl s_client -connect 127.0.0.1:443 \ -servername inaba-serverdesign.jp < /dev/null CONNECTED(00000003) depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3 verify return:1 depth=1 C = US, O = Let's Encrypt, CN = R3 verify return:1 depth=0 CN = inaba-serverdesign.jp verify return:1 --- Certificate chain 0 s:/CN=inaba-serverdesign.jp i:/C=US/O=Let's Encrypt/CN=R3 1 s:/C=US/O=Let's Encrypt/CN=R3 i:/O=Digital Signature Trust Co./CN=DST Root CA X3 --- Server certificate -----BEGIN CERTIFICATE----- (証明書の内容、省略) -----END CERTIFICATE----- subject=/CN=inaba-serverdesign.jp issuer=/C=US/O=Let's Encrypt/CN=R3 --- No client certificate CA names sent Peer signing digest: SHA512 Server Temp Key: ECDH, P-256, 256 bits --- SSL handshake has read 3174 bytes and written 445 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES256-GCM-SHA384 Session-ID: 032E9F21804B382BA5B56F8F9FEBD698545637ADCA5C9DE58A1584E6B5FF1F8B Session-ID-ctx: Master-Key: CB6AB037311B98F9A960339D902435E54239AA42ED7194D4297EFA6255F64DDEB6C7D998B8BF3A1FC352B1CD7EE37821 Key-Arg : None Krb5 Principal: None PSK identity: None PSK identity hint: None TLS session ticket lifetime hint: 600 (seconds) TLS session ticket: (TLSセッションチケットの内容、省略) Start Time: 1608705697 Timeout : 300 (sec) Verify return code: 0 (ok) --- DONE
証明書のチェーンやSSL接続情報などが出力されます。
検証としては、末尾のほうの「Verify return code: 0 (ok)」がポイントです。
Start Time: 1608705697 Timeout : 300 (sec) Verify return code: 0 (ok)
この値が「0」以外であれば、中間証明書のチェーンがおかしい、証明書の有効期限が切れている、などの問題があります。
エラーの内容がエラーコードのうしろのカッコ内に記載されているので、それをもとに調査、対処することになります。
証明書の情報を確認
先ほどの検証コマンドの出力結果に対して、openssl x509 コマンドを実行することで、有効期間の日時や、、コモンネーム以外に証明書に追加したドメインを確認できます。
$ openssl s_client -connect 127.0.0.1:443 \ -servername inaba-serverdesign.jp < /dev/null \ 2> /dev/null | openssl x509 -text Certificate: Data: Version: 3 (0x2) Serial Number: 03:ad:71:c4:f1:42:5b:56:4d:d5:07:63:2e:58:cd:77:a0:2c Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, O=Let's Encrypt, CN=R3 Validity Not Before: Dec 3 04:50:43 2020 GMT Not After : Mar 3 04:50:43 2021 GMT Subject: CN=inaba-serverdesign.jp Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: (省略) Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication X509v3 Basic Constraints: critical CA:FALSE X509v3 Subject Key Identifier: B4:6A:05:34:E4:66:F1:BD:01:DD:B4:93:95:3A:69:75:1C:54:07:D5 X509v3 Authority Key Identifier: keyid:14:2E:B3:17:B7:58:56:CB:AE:50:09:40:E6:1F:AF:9D:8B:14:C2:C6 Authority Information Access: OCSP - URI:http://r3.o.lencr.org CA Issuers - URI:http://r3.i.lencr.org/ X509v3 Subject Alternative Name: DNS:inaba-serverdesign.jp X509v3 Certificate Policies: Policy: 2.23.140.1.2.1 Policy: 1.3.6.1.4.1.44947.1.1.1 CPS: http://cps.letsencrypt.org CT Precertificate SCTs: Signed Certificate Timestamp: Version : v1(0) Log ID : 5C:DC:43:92:FE:E6:AB:45:44:B1:5E:9A:D4:56:E6:10: 37:FB:D5:FA:47:DC:A1:73:94:B2:5E:E6:F6:C7:0E:CA Timestamp : Dec 3 05:50:43.663 2020 GMT Extensions: none Signature : ecdsa-with-SHA256 (省略) Signed Certificate Timestamp: Version : v1(0) Log ID : 7D:3E:F2:F8:8F:FF:88:55:68:24:C2:C0:CA:9E:52:89: 79:2B:C5:0E:78:09:7F:2E:6A:97:68:99:7E:22:F0:D7 Timestamp : Dec 3 05:50:43.767 2020 GMT Extensions: none Signature : ecdsa-with-SHA256 (省略) Signature Algorithm: sha256WithRSAEncryption (省略) -----BEGIN CERTIFICATE----- (証明書の内容、省略) -----END CERTIFICATE-----
証明書の有効期間は「Validity Not Before, Not After」で、コモンネームは、「Subject: CN」で確認できます。
Validity Not Before: Dec 3 04:50:43 2020 GMT Not After : Mar 3 04:50:43 2021 GMT Subject: CN=inaba-serverdesign.jp
また、コモンネーム以外に証明書に追加したドメインは、「Subject Alternative Name DNS:」で確認できます。
X509v3 Subject Alternative Name: DNS:inaba-serverdesign.jp
有効期間の日時のみピックアップしたい場合は、実行結果の標準出力に対して「Not」で grep すればよいです。
あるいは、openssl x509 のオプションで -noout -dates としても同様の結果となります。
$ openssl s_client -connect 127.0.0.1:443 \ -servername inaba-serverdesign.jp < /dev/null \ 2> /dev/null | openssl x509 -text | grep "Not" Not Before: Dec 3 04:50:43 2020 GMT Not After : Mar 3 04:50:43 2021 GMT $ openssl s_client -connect 127.0.0.1:443 \ -servername inaba-serverdesign.jp < /dev/null \ 2> /dev/null | openssl x509 -noout -dates notBefore=Dec 3 04:50:43 2020 GMT notAfter=Mar 3 04:50:43 2021 GMT
証明書の更新作業の際は、有効期間を確認することで、古い証明書ではなく、新しく設定した証明書が参照されていることを確認できますね。
まとめ
CDNやWAF配下のオリジンWebサーバーに設置した証明書の確認方法を記載しました。
なぜ今回、この確認方法をブログ記事にしたかというと。。
僕は一度、外部WAFサービス配下のオリジンWebサーバーの証明書更新作業の際に確認を怠って、証明書の設定ミスに気付かなかったことがあるからです。
新しい証明書ファイルをサーバーに保存し、証明書ファイルそのものの内容は確認したのですが、シンボリックリンクの設定ミスでApacheに反映されず、古い証明書ファイルが参照されたままとなっていました。
そのときは幸い、オリジンWebサーバーの証明書の有効期限が切れたあとも、Webサイトはエラーもなく正しく表示されていたので、実質的な悪影響はありませんでした。
(外部WAFサービスからオリジンWebサーバーへのHTTPS通信時に、証明書の有効期限切れをスルーしていたようだ。)
ですが、エンジニアとしては、設定ミスそのものよりも、未テストで済ませてしまったことが恥ずかしいミスでした。
SSLサーバー証明書を新規、もしくは更新設定したときは、必ず何らかのクライアントからのアクセスで、証明書の情報を確認しましょう!