通配符证书仅匹配一级子域名(如*.example.com支持www.example.com但不支持example.com或dev.api.example.com),需将根域等显式加入san;各域名须配置独立server块并共用同一完整证书链文件,路径以conf/为基准且必须通过nginx -t验证后重载。

通配符证书和多域名(SAN)证书都能让 Nginx 用一份证书支撑多个 HTTPS 域名,但配置稍有偏差,就容易出现“证书不匹配”“小锁变红叉”“访问跳转到错误站点”等问题。核心不在证书本身,而在 Nginx 怎么读、怎么分、怎么交出去。
通配符证书的覆盖边界必须清晰
*.example.com 不是“万能钥匙”,它只匹配一级子域名:
- ✅ 可用:www.example.com、api.example.com、shop.example.com
- ❌ 不可用:example.com(根域)、dev.api.example.com(二级子域)
若需支持根域,申请时必须将 example.com 显式加入证书的 Subject Alternative Names(SAN)列表;若需覆盖 dev.api.example.com,要么单独申请 *.api.example.com,要么改用 SAN 证书把所有目标域名列全——不能指望一个 * 跨两层。
每个域名必须有独立的 server 块,不能“挤在一起”
Nginx 不会自动按 Host 头智能选证书。如果把多个域名写进同一个 server 块的 server_name,比如:
server { listen 443 ssl; server_name a.com b.com; ssl_certificate ... }
这看似省事,实则埋雷:SNI 握手阶段无法精准绑定证书,浏览器可能拿到错误证书,或 fallback 到第一个定义的 server 块。
正确做法是为每个域名(或每组同证书域名)单独建一个 server 块:
- www.example.com → 指向 wildcard.pem + wildcard.key
- api.example.com → 同样指向 wildcard.pem + wildcard.key
- blog.example.com → 同样指向同一组文件
只要这些域名都在证书 SAN 中,Nginx 就能靠 SNI 正确分发,无需重复监听或额外开关。
证书链必须完整,fullchain.pem 是标配
只配 cert.pem 是常见失误。现代浏览器要求完整信任链——即服务器证书 + 中间证书。Let’s Encrypt 的 fullchain.pem 已合并二者,而 cert.pem 仅含自身证书。
务必检查你的配置是否用了这个:
- ✅ ssl_certificate conf/ssl/example.com.fullchain.pem;
- ❌ ssl_certificate conf/ssl/example.com.cert.pem;
同时确保私钥路径对应正确,且文件权限允许 Nginx 进程读取(Windows 下重点防杀软拦截,Linux 下注意 owner 和 chmod 600)。
路径别玩相对与绝对的“猜谜游戏”
Nginx 解析 ssl_certificate 路径时,是以其 配置文件所在目录(通常是 conf/)为基准的,不是当前工作目录,也不是安装根目录。
推荐统一存放并使用相对路径:
- 把证书放 conf/ssl/example.com.fullchain.pem 和 conf/ssl/example.com.key
- 配置中写 ssl_certificate ssl/example.com.fullchain.pem;(开头不加 conf/)
- 避免用 /etc/nginx/conf.d/xxx 这类绝对路径,跨环境易失效
配置完务必运行 nginx -t 验证语法,再 nginx -s reload 生效,不要跳过测试直接重启。











