核心是为每个子域名建立独立server块并严格一一对应专属证书路径,证书SAN须匹配server_name,私钥权限设为600,通用SSL参数可置于http块复用,但ssl_certificate和ssl_certificate_key必须保留在各server块内。

要让不同子域名(如 api.example.com、blog.example.com、shop.example.com)各自使用专属 SSL 证书并完全隔离配置,核心是为每个子域名建立独立的 server 块,并确保证书路径、域名匹配和权限细节准确无误。
每个子域名必须独占一个 server 块
Nginx 不支持在一个 server 块内动态切换证书。即使多个子域名指向同一 IP,也必须分开定义:
-
server_name api.example.com;对应一套证书路径 -
server_name blog.example.com;对应另一套证书路径 -
server_name shop.example.com;再对应第三套证书路径
不能写成 server_name api.example.com blog.example.com; 并试图配两套 ssl_certificate —— Nginx 只加载最后出现的一组,其余无效。
证书路径与域名必须严格一一对应
每个 server 块中的证书需满足两个条件:
- 证书的 Subject Alternative Name(SAN) 必须包含该块中声明的全部
server_name(例如同时含blog.example.com和www.blog.example.com) - 私钥文件权限设为
600(chmod 600 /path/to/privkey.pem),防止 Nginx 启动失败 - 推荐使用绝对路径,避免因工作目录差异导致证书加载失败
验证命令示例:openssl x509 -in /etc/letsencrypt/live/blog.example.com/fullchain.pem -text -noout | grep -A1 "Subject Alternative Name"
SSL 公共参数可复用,证书不可上提
像 TLS 版本、加密套件、HSTS 等通用安全策略,可以统一写在 http 块里供所有 HTTPS 站点继承:
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 或 server 外层作用域。
建议按子域名拆分配置文件便于管理
把每个子域名的完整 server 配置单独保存为文件,例如:
/etc/nginx/sites-available/api.example.com/etc/nginx/sites-available/blog.example.com/etc/nginx/sites-available/shop.example.com
然后在 http 块中统一引入:include /etc/nginx/sites-enabled/*;
再为每个文件创建符号链接到 sites-enabled 目录。这样修改某个子域名配置时,不影响其他站点,也方便版本控制和审计。
只要 SNI 正常启用(现代 Nginx + OpenSSL 默认支持),浏览器就能在 TLS 握手阶段告知服务器目标子域名,Nginx 自动选取对应证书,整个过程对用户透明。











