核心是每个server块严格绑定专属fullchain.pem和privkey.pem;sni仅匹配域名并选择对应server块,之后nginx直接加载该块指定证书路径;证书链须完整且与server_name完全一致,不可混用或拼接。

在 Nginx 中为多域名配置独立证书链,核心是让每个 server 块严格绑定自己域名专属的完整证书文件(fullchain.pem)和私钥(privkey.pem),而不是共用或拼接。SNI 本身不参与证书链组装,它只负责在 TLS 握手初期把客户端声明的域名匹配到对应 server 块——之后 Nginx 就直接加载该块里指定的证书路径。
每个域名必须用独立的 fullchain.pem 路径
证书链必须完整且专属于该域名。Let’s Encrypt 默认生成的 fullchain.pem 已包含站点证书 + 中间证书,可直接使用:
ssl_certificate /etc/letsencrypt/live/site-a.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/site-a.com/privkey.pem;- 同理,
site-b.net必须指向/etc/letsencrypt/live/site-b.net/fullchain.pem,不能复用前者的路径
不要手动合并多个域名的证书到一个 PEM 文件
常见错误是把 site-a.com 和 site-b.net 的证书内容拼进同一个 combined.pem。Nginx 不会按域名从中“挑选”,而是整个加载——这会导致浏览器校验失败或显示证书不匹配。
- 证书链文件必须与
server_name完全对应:证书里 SAN 或 CN 包含site-a.com,server_name就只能写site-a.com或其子域名 - 若证书是通配符(如
*.example.com),server_name可写sub.example.com,但不能混用于other.net
验证证书链是否正确加载
用 OpenSSL 检查 SNI 是否生效、返回的是否为目标域名证书:
-
openssl s_client -connect your.ip:443 -servername site-a.com -showcerts 2>/dev/null | openssl x509 -noout -text | grep "Subject:"→ 应显示CN = site-a.com - 换
-servername site-b.net再执行一次,Subject 应变为site-b.net - 如果两次都返回同一个 CN,说明 SNI 未触发,大概率是 OpenSSL 版本不支持、或多个
server块误用了相同证书路径
路径权限和文件存在性必须检查
Nginx 启动时不校验证书内容,但运行时读取失败会导致 HTTPS 请求直接断连:
- 确保证书文件对
nginx进程用户(通常是www-data或nginx)可读 - 路径中不能有符号链接断裂,也不能遗漏
fullchain.pem中的中间证书(否则部分旧客户端会报“证书不可信”) - 用
nginx -t只能检查语法,需配合openssl s_client实际验证











