核心是“一业务线一域名一server块一证书路径”,每个业务线必须用独立server块绑定专属域名、证书路径及私钥(权限600),禁止混用;公共tls策略可置于http块,但ssl_certificate和ssl_certificate_key必须保留在各server块内,且须用openssl验证sni匹配。

核心是“一业务线一域名一 server 块一证书路径”,每个业务线的独立域名必须拥有专属的 server 块,且证书、私钥、域名三者严格绑定,不能复用或混放。
每个业务线域名单独写一个 server 块
比如业务线 A 用 app.team-a.com,业务线 B 用 api.team-b.net,就不能合并到同一个块里。必须分开定义:
- 每个块都写 listen 443 ssl http2; —— 缺少 ssl 参数会导致证书不加载
- server_name 要精确列出该业务线覆盖的所有主机名,例如:app.team-a.com www.app.team-a.com
- 不能写成
server_name app.team-a.com api.team-b.net;,否则后一个域名会覆盖前一个的证书配置
证书路径与业务线域名一一对应
证书不是“通用资源”,而是按业务线隔离的硬依赖:
-
ssl_certificate 和 ssl_certificate_key 必须用绝对路径,指向该业务线专属证书,例如:
/etc/nginx/ssl/app.team-a.com/fullchain.pem和/etc/nginx/ssl/app.team-a.com/privkey.pem - 私钥权限必须为 600(
chmod 600 privkey.pem),否则 Nginx 启动失败 - 泛域名证书(如
*.team-a.com)只对 team-a.com 下子域有效,不能用于 team-b.net
复用公共 TLS 安全策略,但绝不共享证书指令
避免重复写 TLS 配置,但证书本身不能上提:
- 在 http 块中统一设置:
ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:...;add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - 但 ssl_certificate 和 ssl_certificate_key 必须保留在各自的 server 块内,不可挪到 http 或 upstream 中
- 若某业务线需特殊策略(如禁用 TLSv1.2),可在其 server 块中覆盖全局设置
验证是否真正按业务线生效
别只靠浏览器访问,缓存和 CDN 可能掩盖问题:
- 用 OpenSSL 直接测 SNI 行为:
openssl s_client -connect your.ip:443 -servername app.team-a.com -showcerts 2>/dev/null | openssl x509 -noout -subject
应返回CN = app.team-a.com - 换域名再试:
openssl s_client -connect your.ip:443 -servername api.team-b.net -showcerts 2>/dev/null | openssl x509 -noout -subject
应返回另一张证书的 CN - 配置修改后务必执行
nginx -t校验语法,再nginx -s reload











