关键在于每个域名或子域必须配置独立server块并显式绑定专属ssl证书,不可复用、不可条件判断、不可提至全局;需严格匹配sni、server_name与证书san,私钥权限设为600,http跳转与default_server兜底不可或缺。

关键在于每个虚拟主机(即每个域名或子域)必须拥有独立的 server 块,并在其中显式配置专属 SSL 证书,不能复用、不能条件判断、也不能提至全局作用域。
每个域名配一个完整 server 块
不同域名必须各自定义一个监听 443 端口并启用 SSL 的 server 块。Nginx 依靠 SNI(Server Name Indication)在 TLS 握手阶段识别请求的域名,再匹配对应证书。
-
server_name必须与证书的 CN 或 SAN 字段完全一致,例如证书覆盖example.com和www.example.com,则server_name example.com www.example.com; - 子域名如
blog.example.com或跨主域如site-a.net,都需另起server块,不可合并到同一块中用if ($host = ...)切换证书 - 通配符证书(如
*.example.com)可被多个子域共用,但前提是每个server_name都落在该通配符覆盖范围内
证书路径与权限要严格正确
SSL 证书和私钥路径必须写绝对路径,Nginx 不会自动补全或按工作目录查找;私钥权限过高会导致启动失败。
- 推荐统一存放,例如:
/etc/nginx/ssl/example.com.crt和/etc/nginx/ssl/example.com.key - 私钥文件权限必须为
600:chmod 600 /etc/nginx/ssl/example.com.key - 证书文件权限设为
644即可,确保 Nginx 主进程(通常以 root 身份运行)能读取 - 用 OpenSSL 验证证书是否匹配域名:
openssl x509 -in /etc/nginx/ssl/example.com.crt -text -noout | grep "Subject Alternative Name"
HTTP 跳转与兜底逻辑不能省
仅配 HTTPS 不够,还需处理 HTTP 请求和非法域名访问,避免用户遇到空白页或错误响应。
- 为每个域名单独配一个 80 端口
server块,强制 301 跳转:server { listen 80; server_name example.com; return 301 https://$host$request_uri; } - 加一个
default_server拦截未声明的 SNI 请求:server { listen 443 ssl default_server; server_name _; return 444; }(返回 444 表示直接关闭连接,更安全) - 避免把所有
server_name写在一个块里试图“统管”,这会导致证书错配或 SNI 不生效
配置结构建议与验证要点
保持配置清晰可维护,上线前务必检查语法和实际效果。
- 把每个站点的配置拆成单独文件,放在
/etc/nginx/conf.d/下(如example.com.conf),便于增删和重载 - 修改后执行
nginx -t检查语法,无误再nginx -s reload - 用浏览器或
curl -I https://example.com验证是否返回 200 及正确证书信息 - 用
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -subject确认证书主体匹配











