核心是“一域名一server块一证书”,即每个域名必须配置独立server块,显式声明listen 443 ssl、匹配的server_name、绝对路径的ssl_certificate与ssl_certificate_key,私钥权限600,且不可用if或全局http块复用证书。

在 Nginx 中为多个虚拟主机配置各自独立的 SSL 证书,核心原则是:**每个域名(或子域名)必须对应一个独立的 server 块,且该块内显式声明专属的 ssl_certificate 和 ssl_certificate_key 路径**。不能靠 if 判断切换证书,也不能把证书指令提到 http 全局块里复用。
每个域名配一个完整的 HTTPS server 块
不同域名(如 site-a.com、blog.site-b.net)必须各自拥有独立的 server 块,都监听 443 ssl,并精确匹配 server_name:
-
server_name必须与证书的 CN 或 SAN 字段完全一致(例如写example.com www.example.com,证书就必须同时包含这两个域名) - 通配符证书(如
*.example.com)可覆盖所有子域,但仍需单独配置块,不能和other-site.org合并在同一块中 - 跨主域(如
a.com和b.net)必须使用各自专属证书,不可混用
证书路径与权限必须严格准确
证书和私钥路径必须是绝对路径,Nginx 不会自动补全;权限错误会导致启动失败:
- 私钥文件权限必须设为
600:chmod 600 /etc/nginx/ssl/site-a.com.key - 证书文件(
.crt或.pem)一般设为644即可,确保 Nginx 主进程能读取 - 推荐统一存放,例如:
/etc/nginx/ssl/site-a.com.crt和/etc/nginx/ssl/site-a.com.key - 用
openssl x509 -in cert.pem -text -noout | grep "Subject Alternative Name"验证证书是否覆盖你声明的所有server_name
配套 HTTP 跳转与兜底处理不能少
仅配 HTTPS 不够,还需保障访问体验和安全性:
- 每个域名都应配一个对应的
80端口server块,用return 301 https://$host$request_uri;强制跳转 - 加一个
default_server拦截非法 SNI 请求,例如:server { listen 443 ssl default_server; server_name _; return 444; } - SSL 公共参数(如
ssl_protocols、ssl_ciphers)可统一写在http块中复用,但ssl_certificate和ssl_certificate_key必须保留在各自的server块内
修改后务必验证再重载
Nginx 对 SSL 配置语法极其敏感,错误会导致整个 HTTPS 服务中断:
- 每次改完配置,先运行
sudo nginx -t—— 必须看到syntax is ok且test is successful - 确认无误后再执行
sudo nginx -s reload(不要用restart,避免连接中断) - 浏览器访问各域名,点击地址栏锁图标查看证书详情;也可用命令行验证:
curl -I --resolve site-a.com:443:你的IP https://site-a.com











