通配符证书*.example.com仅匹配一级子域,不支持根域或二级子域;需通过重签含对应san的证书、拆分server块配专属证书或使用多域名san证书解决。

通配符证书无法匹配多级域名,不是 Nginx 配置错了,而是证书本身能力边界被误用了。*.example.com 只能匹配一级子域(如 api.example.com、www.example.com),它不覆盖根域 example.com,也不覆盖二级子域(如 dev.api.example.com)。问题出在申请时没补全 SAN,而不是 reload 或语法问题。
确认证书实际覆盖哪些域名
运行命令检查证书的 Subject Alternative Name(SAN)字段:
openssl x509 -in conf/ssl/example.com.fullchain.pem -text -noout | grep -A1 "Subject Alternative Name"输出中必须显式包含:
- DNS:example.com(若需访问根域)
- DNS:*.example.com(支持一级子域)
- DNS:dev.api.example.com 或 DNS:*.api.example.com(若需支持二级子域)
缺哪一项,对应域名就会触发“证书与域名不匹配”警告——这不是 Nginx 能绕过的,必须重签证书。
按域名层级拆分证书或 server 块
一个 *.example.com 证书无法覆盖 dev.api.example.com,但有三种可行解法:
- 为 dev.api.example.com 单独申请一张证书(如 *.api.example.com)
- 改用 SAN 证书,把 example.com、www.example.com、api.example.com、dev.api.example.com 全部列进同一张证书
- 保持 *.example.com 不变,但为 dev.api.example.com 新建独立 server 块,并配专属证书(不共用)
不要尝试写 server_name dev.*.api.example.com —— Nginx 不支持中间通配符,会直接报 invalid server name 错误。
每个域名或域名组必须独占 server 块
Nginx 不靠 Host 头选证书,而是靠 SNI 和 server 块绑定。错误做法是:
server_name dev.api.example.com api.example.com;正确做法是分开定义:
- 一个 server 块只写 server_name api.example.com;,配 *.example.com 证书
- 另一个 server 块只写 server_name dev.api.example.com;,配 *.api.example.com 或含该域名的 SAN 证书
两个块都 listen 443 ssl,互不干扰。混在一个块里,SNI 分发会失效,浏览器可能拿到错证。
验证 fullchain.pem 是否完整且路径正确
即使证书 SAN 正确,若只配置了 cert.pem,浏览器仍会因证书链不全报错。必须确保:
- ssl_certificate 指向的是 fullchain.pem(域名证书 + 所有中间证书)
- ssl_certificate_key 指向对应的 privkey.pem
- 文件权限为 600(Linux),路径以 nginx 配置根目录为基准(如 conf/ssl/...)
用 openssl s_client 测试:openssl s_client -connect dev.api.example.com:443 -servername dev.api.example.com -showcerts,确认输出中至少有两段 BEGIN CERTIFICATE。











