ワイルドカード証明書(Wildcard Certificate)
概要
ワイルドカード証明書(Wildcard Certificate) は、コモンネームまたは SAN(Subject Alternative Name)に *.example.com のようにアスタリスクを使い、1 枚の証明書でドメインの全サブドメインを保護できる SSL/TLS 証明書です。
*.example.com の証明書は www.example.com、mail.example.com、api.example.com など、直下の 1 レベルのサブドメインすべてに有効です。証明書の仕様は RFC 2818(2000年)および CA/Browser Forum の Baseline Requirements で規定されています。
サブドメインを複数運用する場合に個別の証明書をそれぞれ管理する手間を省けます。ただし *.example.com は sub.mail.example.com のような 2 レベル以上のネストには適用されません。sub.mail.example.com を保護するには別途 *.mail.example.com の証明書が必要です。
仕組み
ワイルドカードの * は 1 レベルのサブドメインにのみマッチし、SAN 証明書とは対象の指定方法が異なります。
アスタリストの有効範囲
ワイルドカードの * は単一のラベル(. で区切られた 1 要素)にマッチします。
*.example.com → www.example.com # 有効
*.example.com → api.example.com # 有効
*.example.com → example.com # 無効(サブドメインではない)
*.example.com → sub.api.example.com # 無効(2 レベルのネスト)
example.com 自体は *.example.com の証明書でカバーされないため、ルートドメインも保護したい場合は SAN に example.com を明示的に追加するか、個別の証明書を発行します。Let’s Encrypt のワイルドカード証明書は SAN に *.example.com と example.com の両方を含めることができます。
SAN との違い
SAN(Subject Alternative Name)証明書は、複数の特定ホスト名を 1 枚の証明書に列挙します。
SAN 証明書の例:
Subject Alternative Names:
DNS: example.com
DNS: www.example.com
DNS: api.example.com
DNS: mail.example.com
ワイルドカード証明書はパターンマッチングで対応するため、新しいサブドメインを追加しても証明書の再発行が不要です。一方 SAN は対象ホストが明確で、証明書が露出した場合の影響範囲を限定できます。
実際には両者を組み合わせることが多く、Let’s Encrypt でも *.example.com と example.com を 1 枚の証明書にまとめた形での発行が一般的です。
発行に必要な検証(DV)
ワイルドカード証明書は DV(Domain Validation)で発行できます。Let’s Encrypt の場合、DNS チャレンジ(dns-01)でドメイン所有権を検証します。
# Let's Encrypt が検証に使う TXT レコード
_acme-challenge.example.com. IN TXT "ランダムな検証トークン"
HTTP チャレンジ(http-01)はワイルドカード証明書の発行には使えません(Let’s Encrypt の制約)。Certbot などのクライアントでは --preferred-challenges dns を指定します。
OV(Organization Validation)や EV(Extended Validation)のワイルドカード証明書は、商用 CA(DigiCert、Comodo など)で取得できます。
設定例
Let’s Encrypt の Certbot を使った DNS チャレンジでの取得と、Nginx への設定方法を示します。
Certbot での証明書取得
Certbot で Let’s Encrypt のワイルドカード証明書を取得する例です。
certbot certonly \
--manual \
--preferred-challenges dns \
-d "*.example.com" \
-d "example.com"
certbot が表示する TXT レコードを DNS に設定してから検証を進めます。
_acme-challenge.example.com. IN TXT "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Nginx での設定
nginx でワイルドカード証明書を設定する例です。
server {
listen 443 ssl;
server_name *.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
}
確認方法
証明書の SAN を openssl で確認します。
openssl s_client -connect www.example.com:443 -servername www.example.com < /dev/null 2>/dev/null \
| openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
X509v3 Subject Alternative Name:
DNS:*.example.com, DNS:example.com
DNS:*.example.com が含まれていればワイルドカード証明書です。証明書の有効期限も合わせて確認できます。
openssl s_client -connect www.example.com:443 -servername www.example.com < /dev/null 2>/dev/null \
| openssl x509 -noout -dates
notBefore=Jan 13 00:00:00 2026 GMT
notAfter=Apr 13 23:59:59 2026 GMT
外部の視点からも確認したい場合は、Labee Dev Toolbox の SSL Cert API を使うと、外部の視点から見た結果を取得できます。
curl "https://labee.dev/api/ssl-cert?hostname=www.example.com"
{
"success": true,
"data": {
"hostname": "www.example.com",
"port": 443,
"reachable": true,
"status": 200
},
"error": null,
"meta": { "responseTime": 123 }
}
data.reachable が true であれば HTTPS で到達可能な状態です。data.status に HTTP ステータスコードが返ります。
よくある問題
ワイルドカード証明書の運用では、ネスト深度の制約やルートドメインのカバー漏れが典型的な落とし穴です。
ネストしたサブドメインに証明書が適用されない
*.example.com は api.example.com はカバーしますが、v2.api.example.com はカバーしません。サービスを v2.api.example.com のような 2 段ネストで運用している場合は、*.api.example.com の証明書を別途発行するか、SAN にホスト名を明示的に追加します。
ルートドメインが HTTPS で表示されない
*.example.com の証明書は example.com 自体をカバーしません。Let’s Encrypt でワイルドカード証明書を取得する際は -d "example.com" も同時に指定して、SAN に両方を含めます。
証明書の更新自動化が DNS チャレンジのため手間がかかる
ワイルドカード証明書は DNS チャレンジが必須です。certbot の --manual モードでは更新のたびに手動で TXT レコードを設定する手間が発生します。DNS プロバイダーが API を提供している場合は certbot のプラグイン(certbot-dns-cloudflare など)を使って自動化できます。Cloudflare、Route 53、Google Cloud DNS などは対応プラグインが公式に提供されています。
証明書漏洩時の影響範囲が広い
1 枚のワイルドカード証明書と秘密鍵が漏洩した場合、そのドメインの全サブドメインがなりすまし可能な状態になります。Certificate Transparency(CT)ログを監視して、不正な証明書発行を検知します。サービスによっては CAA レコードで発行可能な CA を制限します。
example.com. IN CAA 0 issue "letsencrypt.org"
example.com. IN CAA 0 issuewild "letsencrypt.org"