問題点sub.api.example.com に新しいマイクロサービスをデプロイしたとしましょう。*.example.com 用のワイルドカードSSLは api.example.com や web.example.com で完璧に動作しているため、この新しいURLもカバーされると期待するでしょう。しかし、実際にはブラウザがプライバシー警告を表示し、接続をブロックしてしまいます。
Chromeユーザーには、次のような特定のエラーが表示されます。
NET::ERR_CERT_COMMON_NAME_INVALID: *.example.com does not cover sub.api.example.com
これはアーキテクチャを拡張する際によくある悩みです。既存の証明書がすべてのサブドメインをカバーする「万能な解決策」であると思い込み、dev.api.example.com のような専用のステージング環境を構築している際に、この壁に突き当たることがあります。
根本原因ワイルドカードは再帰的ではありません。SSL/TLSの仕様(RFC 6125)によると、ワイルドカード文字(*)はサブドメイン階層の単一レベルのみを保護します。ドットを越えて「見る」ことはできません。
*.example.comはone.example.comを検証します-*.example.comはtwo.example.comを検証します-*.example.comはsub.one.example.comには対応していませんこれを「ワンドット・ルール(One Dot Rule)」と考えてください。ブラウザがsub.api.example.comに遭遇すると、*.api.example.comや正確な FQDN など、その第4レベルを明示的にカバーする証明書を検索します。
デバッグプロセス設定を変更し始める前に、サーバーが具体的に何を送信しているかを確認しましょう。openssl を使用して、ターミナルから直接証明書の詳細を取得できます。
openssl s_client -connect sub.api.example.com:443 -servername sub.api.example.com | openssl x509 -text -noout | grep -A 1 "Subject Alternative Name"
出力を確認してください。DNS:*.example.com, DNS:example.com しか表示されない場合、技術的にその証明書はリクエストされたURLに対して無効です。ブラウザの警告は正当です。サブジェクト代替名(SAN)が単純に第4レベルドメインをカバーしていないからです。
解決策### オプション1:ネストされたワイルドカードの発行(スケーリングに最適)client1.api.example.com や client2.api.example.com のような複数のサブ・サブドメインをホストする予定がある場合は、その特定のレベルをカバーする証明書が必要です。実際、複数のワイルドカードレベルを1つの証明書にまとめることができます。
DNS-01チャレンジで Certbot を使用し、次のコマンドを実行してベースドメイン、第1レベル、および第2レベルをカバーします。
certbot certonly --manual --preferred-challenges dns \-d "example.com" \-d "*.example.com" \-d "*.api.example.com"
これにより、単一の .pem ファイルが生成されます。この検証プロセス中に、DNSプロバイダー側で2つの異なるTXTレコードを作成する必要があることに注意してください。
オプション2:マルチドメイン(SAN)証明書の使用billing.api.example.com のような例外が1つか2つしかない場合もあるでしょう。その場合、ネストされたワイルドカードは不要です。既存の証明書リクエストに特定の FQDN を追加するだけで済みます。
証明書署名要求(CSR)の SAN フィールドに以下のエントリが含まれていることを確認してください。
example.com-*.example.com-billing.api.example.com### オプション3:DNS構造のフラット化時には、最も賢明な修正はアーキテクチャの変更です。sub.api.example.comをsub-api.example.comに変更することはできますか?ドットをハイフンに置き換えることで、サブドメインを第3レベルに戻すことができます。そうすれば、元の*.example.com証明書が、追加のコストや設定なしで完全にカバーしてくれます。
Webサーバーの更新新しい証明書を取得したら、Webサーバーの設定を更新されたファイルに向け、サービスをリロードします。
Nginxの例```
server { listen 443 ssl; server_name sub.api.example.com;
ssl_certificate /etc/letsencrypt/live/api-combined/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api-combined/privkey.pem;
}
### Apacheの例```
<VirtualHost *:443>
ServerName sub.api.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/api-combined.crt
SSLCertificateKeyFile /etc/ssl/private/api-combined.key
</VirtualHost>
検証Webサーバーを再起動し(例:systemctl restart nginx)、curl で接続をテストします。-v フラグを使用すると、SSLハンドシェイクの詳細を確認できます。
curl -vI https://sub.api.example.com
出力の中から SSL certificate verify ok を探してください。エラーが解消されない場合は、サーバーが依然として古い証明書をキャッシュしているか、間違ったファイルパスを参照している可能性があります。
教訓ワイルドカードSSLはフラットな構造には適していますが、複雑なDNS階層においては誤った安心感を与えてしまうことがあります。次のプロジェクトでは、以下の3つのルールを覚えておいてください。
- ドット1つの制限: ワイルドカードは正確に1つのレベルのみをカバーします。それ以上でもそれ以下でもありません。- DNS-01が鍵: Let's EncryptのDNSチャレンジを使用して、マルチレベルのワイルドカード証明書を簡単に発行しましょう。- ハイフンの方が安上がり: ハイフンで繋いだ名前で同じ組織的な目的を達成できるのであれば、深いサブドメイン階層は避けましょう。

