TLS証明書インスペクター
ブラウザと同じようにサイトへTLS接続し、証明書を読み取ります。壊れた証明書でも読み取れます。問題があれば、よくある失敗のどれに当たるのかがわかります。
証明書は何のためにあるのか
ブラウザがhttps://example.comに接続すると、何かが応答します。その何かが本当にexample.comのものかどうかは、別の問題です。途中のネットワークにいる誰かが代わりに応答した可能性もあります。
そこでサーバーは身分証を見せる必要があります。証明書は小さなファイルで、公開鍵、その鍵が代表してよいホスト名の一覧、開始日、終了日、そしてそれらの名前を誰が管理しているか確認した認証局(CA)の署名が入っています。ブラウザは順番に確認します。アドレスバーの名前が証明書に載っていること。今日が2つの日付の間にあること。署名をたどると、端末がすでに信頼している認証局に行き着くこと。そしてサーバーが対応する秘密鍵を持っていると証明すること。どれか1つでも欠ければ、訪問者には全画面の警告が表示されます。
暗号化が始まるのは、そのすべてが確認できてからです。鍵マークは、サーバーが身元を証明したことを意味し、暗号化はその証明の上に成り立っています。
インスペクターがテストする項目
443番ポートに2回接続します。1回目はどんな証明書でも受け入れ、状態にかかわらず証明書を読み取ります。2回目は、厳格なクライアントと同じように、標準の信頼済みルート証明書の一覧に照らしてすべてを検証します。
| テスト | 結果 |
|---|---|
| 日付 | 期限切れか、まだ有効になっていなければ赤。残り7日未満なら黄、21日未満なら注記、それ以外は緑。 |
| 名前 | 入力したホスト名が対象外なら赤。対になる名前(wwwあり、またはなし)がDNSに存在するのに証明書に載っていなければ黄。 |
| 信頼 | 検証に失敗した場合、その原因を表示します。期限切れ、名前の不一致、自己署名、不完全なチェーン、または検証エラーそのもの。 |
| チェーンの順序 | 送られた証明書が順番に互いを署名していなければ黄。 |
| 鍵と署名 | 2048ビット未満のRSA鍵、またはSHA-1やMD5の署名なら赤。 |
| プロトコル | TLS 1.2より古いプロトコルで接続が確立されたら赤。 |
そのあと、アドレスの4つの形(httpとhttps、wwwありとなし)をリクエストし、それぞれの最終的な行き先と、サイトがHSTSヘッダーを送っているかを表示します。この部分を1ステップずつ見たい場合は、リダイレクト追跡を使ってください。
Chromeでは動くのに、ほかでは失敗する
認証局はルート鍵で直接あなたの証明書に署名するわけではありません。中間証明書で署名し、その中間証明書にルートが署名しています。端末が保存しているのはルートだけなので、サーバーは自分の証明書と一緒に中間証明書も送る必要があります。この2つを合わせたものがチェーンです。
サーバーが自分の証明書しか送らない場合でも、デスクトップ版のChromeとEdgeは寛容です。足りない中間証明書をダウンロードしたり、別のサイトで見たものを再利用したりすることがよくあります。新しいプロファイルのFirefox、古いAndroidスマートフォン、curl、決済のWebhook、メールサーバー、ほとんどのプログラミングライブラリは、そこまでしてくれません。こうして、持ち主には完璧に見えるのにAPIクライアントでは失敗するサイトができあがります。インスペクターはこれを不完全なチェーンと呼び、検証に失敗して証明書が1枚しか送られていない場合に報告します。
よくある失敗の直し方
- 期限切れ。自動発行の証明書は期限の約30日前に更新されます。期限が切れたなら、更新処理は何週間も失敗し続けていたということです。Certbotなら
certbot renew --dry-runを実行してエラーを読んでください。原因はたいてい、移動したDNSレコード、80番ポートを閉じているファイアウォール、/.well-known/acme-challenge/を飲み込んでしまうリダイレクトです。 - 名前が対象外。すべてのホスト名を並べて証明書を取り直します:
certbot -d example.com -d www.example.com。ワイルドカードの*.example.comがカバーするのはサブドメイン1階層だけです。example.com自体はカバーされず、多くの人がここでつまずきます。 - 不完全なチェーン。サーバーにフルチェーンのファイルを指定します。nginxなら
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;。Apache 2.4.8以降では、SSLCertificateFileに同じファイルを指定します。 - 自己署名。公的な認証局の証明書に置き換えます。Let’s Encrypt、ZeroSSL、Google Trust Servicesは無料で発行しています。
- 古いプロトコル。TLS 1.2と1.3を有効にします。nginxなら
ssl_protocols TLSv1.2 TLSv1.3;
ターミナルからもopenssl s_client -connect example.com:443 -servername example.comで同じ内容を確認できます。
インスペクターが接続するのは1つのIPアドレスの443番ポートだけで、報告するのは実際に確立されたプロトコルです。サーバーが受け入れるすべてのバージョンではありません。複数のサーバーに分散したサイトでは、別のアドレスで別の証明書が提示される場合があります。失効は確認しません。
よくある質問
SSLとTLSは同じものですか?
TLSはこのプロトコルの現在の名前です。SSLはその前身で、最後のバージョンは2015年に廃止されました。習慣で今も「SSL証明書」と呼ばれますが、現在使われている証明書はすべてTLSで動作します。
SSL証明書の有効期間はどのくらいですか?
Let’s Encryptの証明書は90日です。すべての公的な認証局で、許される最大期間は2026年3月に398日から200日に短縮され、2027年3月には100日、2029年3月には47日になります。このペースでは、手作業での更新は現実的ではなくなります。
証明書は有効なのに、ブラウザが「保護されていない通信」と表示するのはなぜですか?
原因はたいてい次の3つのどれかです。ページがhttp://で開かれ、HTTPSへのリダイレクトがない。証明書がアドレスバーのホスト名そのものをカバーしていない。ページがスクリプトや画像を暗号化されていないHTTPで読み込んでいる。1つ目については、結果のリダイレクト表でわかります。
ERR_CERT_COMMON_NAME_INVALIDとはどういう意味ですか?
訪れたホスト名が証明書の名前の一覧にありません。ドメイン名だけで証明書を取得したときのwwwや、デフォルトの証明書が提示されている新しいサブドメインでよく起こります。
無料の証明書は有料のものより安全性が低いですか?
いいえ。暗号化はまったく同じで、ブラウザも両者を同じように扱います。お金を払って得られるのはサポート、保証、証明書に組織の情報を載せることですが、ブラウザはもうそれを目立つ形では表示しません。
証明書はどのくらい前に更新すべきですか?
自動クライアントは有効期間の3分の1が残った時点で更新します。90日の証明書なら約30日前です。このチェックが警告を出し始める残り7日になっているなら、自動化はおそらく止まっています。