証明書のトラブルは「証明書が壊れた」というより、設定・期限・信頼・チェーン・SNI のどれかが噛み合っていないだけ、というケースがほとんどになる。
とはいえ現象は「突然つながらない」「警告が出る」「端末によって出たり出なかったり」と派手なので、落ち着いて 確認順 を固定しておくと解決が早い。
このページでは、よくある証明書エラーを「症状→原因→確認コマンド」で整理し、最後に最短の切り分け手順をまとめる。
(IIS系の観点、公開CAのブラウザエラー、Linux側の検証コマンドなども含める)
証明書トラブルは、基本的にこの順番で潰すのが一番早い。
- いま何の証明書が返ってきているか(SNI付きで確認)
- その証明書は正しいか(名前・期限・発行者)
- チェーンは揃っているか(中間証明書が返っているか)
- 信頼できるか(公開CA / 内部CAのルートが端末にあるか)
- 端末の時刻は正しいか(証明書の期限判定に直撃)
- プロトコルと暗号が合うか(TLS1.2/1.3、古い端末など)
ここは「見た目の警告」から入ってもよい。原因はだいたい有限。
(ブラウザによって表示名が違うが、意味はほぼ共通)
- 典型原因:信頼されないCA(自己署名、内部CAでルート未配布)
- 典型原因:中間証明書不足(チェーン不完全)
- 典型原因:端末の時刻ずれ
- 典型原因:証明書の期限切れ(更新漏れ)
- 典型原因:端末の時刻が未来/過去(期限判定が狂う)
- 典型原因:アクセスしたホスト名がSAN/CNに入っていない
- 典型原因:SNI不一致で別サイトの証明書が返っている
- 典型原因:中間証明書不足(PCは補完できるが一部環境はできない)
- 典型原因:古い端末がTLS1.2/1.3や暗号に対応していない
- PCでは通るがスマホで警告:窓口の情報(中間証明書)が足りず、受け取り側の能力差で結果が変わる
(中間証明書不足で端末差が出る話は、公開CAのサポートでもよく触れられる)
ここを確認すると「そもそも違う証明書が返ってる」系が一発で分かる。
- Subject:どの名前の証明書か(対象ドメイン)
- Issuer:誰が発行したか(公開CAか、内部CAか)
- Not After:いつまで有効か(期限)
- PC(特定ブラウザ)では警告が出ない
- 端末やブラウザによっては警告が出る
- SSLチェッカーで「Chain incomplete」的な指摘
- サーバーが サーバー証明書だけ を返している
- 中間証明書(Intermediate)を返していない
- fullchain相当を使っていない(設定漏れ)
example.com にアクセスしているのに、別ドメインの証明書が返る
- ある端末では正しいが、別の方法(監視や検証ツール)だと違う証明書になる
- 複数VirtualHost環境で起きやすい
- SNIが付かない接続(または設定不備)で デフォルトの証明書 が返る
- Apache側で意図しない VirtualHost が default 扱いになっている
- 社内ではOKだが、社外端末では必ず警告
- 端末を変えると信頼されない
- 「発行元が不明」「信頼されていない」系
- ADCSなど 内部CAのルート証明書が端末に入っていない
- 自己署名証明書を利用している(意図的ならOKだが外部向けには不向き)
- 期限切れ警告が出る
- 本当は期限が残っているのに期限切れ扱いになる
- Let’s Encryptの更新が失敗して期限切れ(自動更新が前提のため)
- クライアントの時計がズレている(未来/過去)
(端末の時刻がズレると証明書検証に影響する、という注意は公開CAの解説でも頻出)
- 「安全な接続を確立できません」系
- 古い端末だけ接続できない
- ツールで handshake failure
- サーバが古いSSL/TLSを無効化している(安全側の設定)
- クライアントがTLS1.2/1.3や暗号スイートに対応していない
- 中間装置(プロキシ、フィルタ)がTLSの挙動に追従できない
この章は「いま起きている事実」を掴むためのもの。
openssl s_client -connect example.com:443 -servername example.com |
openssl x509 -noout -subject -issuer -dates
openssl s_client -connect example.com:443 -servername example.com -showcerts
curl -I http://example.com/
curl -I https://example.com/
openssl verify -untrusted intermediate.crt -CAfile root.crt server.crt
Get-ChildItem Cert:\LocalMachine\Root | Select-Object Subject, NotAfter
Get-ChildItem Cert:\LocalMachine\My | Select-Object Subject, NotAfter
- 返ってきた証明書は想定どおりか(SNI付きで確認)
- Subject(SAN/CN)はアクセスした名前と一致しているか
- Issuerは想定どおりか(公開CA / 内部CA)
- 期限(Not After)は切れていないか
- 中間証明書が返っているか(チェーンが切れていないか)
- 内部CAなら、端末にルート証明書が配布されているか
- 端末の時計は正しいか
- 端末がTLSバージョンと暗号に対応しているか
- 更新したなら、サーバ側の再読み込みは済んでいるか