DevKitLab Logo DevKitLab
SSL / TLS / SAN / SNI / ドメイン / HTTPS

SSL 証明書とドメインが一致しない理由:SAN・ワイルドカード・SNI の確認

証明書の名前不一致は、申請ミスだけが原因ではありません。要求したホスト名、SAN、ワイルドカードの範囲、SNI、DNS、CDN、ロードバランサーのどれかで別の証明書を受け取ることがあります。公開経路をたどって誤った証明書を返す入口を見つけます。

ブラウザが証明書とドメインが一致しないと警告すると、証明書を間違って申請したと考えがちです。実際にそういう場合もありますが、証明書自体は正しいことも少なくありません。利用者が別のホスト名へアクセスしている、SNI がないためサーバーが既定の証明書を選んでいる、DNS が一部の通信を古い証明書を返す入口へ送っている、といった原因があります。

調査では二つを分けます。クライアントはどのホスト名を要求したか。公開 TLS 入口は実際にどの証明書を返したか。この二つが分かれると、NET::ERR_CERT_COMMON_NAME_INVALID のようなエラーも追いやすくなります。

まず SSL チェッカーで公開ホスト名に接続します。名前の一致、返されたチェーン、解決先アドレスを確認し、続いて 証明書デコーダーで Subject Alternative Name を読みます。

名前の対象はファイル名や Common Name ではなく SAN

現代のクライアントは Subject Alternative Name(SAN)拡張で、証明書がどの名前をカバーするかを判断します。Common Name が表示されることはあっても、名前の対象を確定する根拠にはなりません。ファイル名、注文名、管理画面のメモでも判断できません。

公開入口が返したリーフ証明書を開き、DNS SAN のすべてを、利用者がアドレスバーで要求した完全なホスト名と照合します。会社のドメインがどこかに見えるだけでは足りず、要求した名前そのものが対象である必要があります。

要求したアドレス必要な対象範囲よくある誤解
example.comexample.com の DNS SAN*.example.com はルートドメインも含む
www.example.comwww.example.com またはそれに一致するワイルドカードルートドメインだけの証明書で www も自動的に対象になる
api.example.comapi.example.com または *.example.comどのワイルドカードも任意の深さで使える
v2.api.example.com正確な SAN または *.api.example.com*.example.com は二階層をまたげる
https://203.0.113.10/一致する IP SANDNS SAN は IP アドレスへのアクセスもカバーする

ワイルドカードが置き換えるのは一つのラベルだけ

*.example.comapi.example.com をカバーできますが、example.comv2.api.example.com はカバーしません。アスタリスクはドットの間の一つのラベルを表すだけで、ドメイン下のすべての階層を許可するものではありません。

証明書を申請する前に、実際の入口から名前を洗い出します。ルート、www、API、管理画面、地域サブドメイン、監視用のホスト名を含めます。近く切り替える名前も更新や置き換えの計画に入れ、移行当日に SAN の不足が分かる事態を避けます。

SNI が最初に選ぶ証明書を決める

一つの IP では複数の HTTPS 名を扱えます。TLS は HTTP リクエストより先に始まるため、サーバーは証明書を選ぶ時点で URL のパスを見られません。クライアントは SNI で期待するホスト名を伝え、サーバーはその値から証明書を選びます。

IP だけへ接続した、監視が SNI を送らない、プロキシが SNI 名を書き換えた、といった場合、サーバーは既定サイトの証明書を返しがちです。その証明書は有効でも、利用者が到達したい名前には一致しません。

実際のホスト名でテストし、IP を試すときは期待する SNI を明示します。同じ IP で SNI の有無を比べてください。証明書が変わるなら、要求またはノードにより選択が変わっています。正しい SNI でも誤った証明書なら、対応する仮想ホスト、Ingress、ロードバランサーのルールを調べます。

DNS、CDN、負荷分散で古い入口へ行くことがある

SAN も SNI も正しくても、クライアントが意図したサーバーへ到達するとは限りません。移行や証明書更新後、IPv4 は新しくても IPv6 が古いサービスを向く、CNAME の先に CDN、プラットフォーム、複数の負荷分散層がある、といったことがあります。

DNS ルックアップで A、AAAA、CNAME、TTL を確認し、実際の公開入口が分かるところまで CNAME をたどります。TTL が低くても、すべての再帰キャッシュが古い答えをすぐに忘れるわけではありません。受け取った答えを保持できる時間が短くなるだけです。断続的なら、すべての解決結果とバックエンドノードを試します。

ディスク上で正しい証明書が、公開先で使われているとは限らない

「サーバー上の証明書には正しい SAN がある」で調査が終わることは多いですが、公開側の TLS 終端は CDN、クラウドのロードバランサー、Kubernetes Ingress、リバースプロキシ、あるいはまだ稼働中の旧サーバーかもしれません。バックエンドが正しいことは、バックエンドが正しいことしか示しません。

公開ハンドシェイクで得たシリアル番号または SHA-256 フィンガープリントを基準にします。その証明書を返す TLS 終端まで通信経路をたどってください。一つのエッジが古い証明書を返しているなら、アプリケーションサーバーを再び変えるのではなく、そのエッジを更新して再読み込みし、公開先から検証します。

ホスト名の形式も一致結果を変える

利用者が、あなたが想定した標準 URL を使うとは限りません。IP アドレス、旧名、内部別名、スペルの違うホスト名を入力することがあります。国際化ドメイン名は、証明書と DNS では Punycode で表されることが多いため、画面の表示だけではなくハンドシェイクで実際に使われたホスト名を比べます。

証明書の名前一致が答えるのは、要求名がカバーされているかだけです。証明書とチェーンが正しくても、特定ネットワークだけで見慣れない証明書が見えるなら、社内の HTTPS 検査、認証ポータル、セキュリティソフトによる置き換えも除外します。

エラーから修正までの実用的な順序

  1. ブラウザまたはクライアントの完全なホスト名とエラーを残し、「名前不一致」だけに縮めない。
  2. SSL チェッカーでその公開ホスト名を確認し、必要なら実際のポートと SNI を指定する。
  3. 証明書デコーダーで公開リーフの DNS SAN を開き、要求ホスト名と比べる。
  4. ルート、www、ワイルドカードの深さ、入れ子のサブドメイン、IP アクセスが意図した範囲に入るか確認する。
  5. 同じ IP で期待する SNI の有無を比べ、CDN、ロードバランサー、Ingress の名前ルーティングを確認する。
  6. DNS ルックアップで A、AAAA、CNAME と考えられるすべての公開入口を調べ、古いノードが誤った証明書を返していないか確認する。
  7. 実際の TLS 終端を直し、IPv4、IPv6、最初に失敗したクライアントから公開ハンドシェイクを繰り返す。

名前の対象が正しいのにクライアントが信頼できないなら、SAN を変え続けないでください。次に見るのはチェーンです。証明書チェーンが不完全な理由を確認し、全体の切り分けはSSL 証明書が無効になる理由を参照してください。