前言:为什么需要多域名虚拟主机与SSL绑定
在实际生产环境中,一台服务器往往需要同时承载多个网站或应用,例如 example.com、api.example.com、admin.example.com。Nginx 的虚拟主机(Server Block)机制允许通过不同的 server_name 来区分请求,并将流量分发到对应的站点目录或上游服务。与此同时,HTTPS 已成为默认要求,每个域名都需要绑定有效的 TLS 证书,以确保通信加密和用户信任。
本文假设读者已安装 Nginx 并具备基础操作能力,将直接围绕配置文件展开,不介绍安装步骤。所有指令均经过实际测试,适用环境为 CentOS 7/8、Ubuntu 20.04/22.04 及主流 Linux 发行版。
一、多域名虚拟主机基础配置
1.1 理解 server_name 匹配规则
Nginx 通过 server_name 指令匹配 HTTP 请求中的 Host 头部。多个域名可以用空格分隔,如:
server_name example.com www.example.com
如果请求的 Host 与任何 server_name 都不匹配,则会落入默认 server 块(通常是监听 80 端口的第一个 server 块)。为了安全,建议显式定义一个默认返回 444 的 server 块:
server {
listen 80 default_server;
server_name _;
return 444;
}
正则匹配使用 ~ 开头,例如 ~^(www.)?mydomain.com$,但一般场景下直接使用精确域名即可。
1.2 创建独立的配置文件
推荐将每个虚拟主机的配置单独存放于 /etc/nginx/conf.d/ 或 /etc/nginx/sites-enabled/ 目录下。例如:
/etc/nginx/conf.d/example.com.conf
/etc/nginx/conf.d/api.example.com.conf
/etc/nginx/conf.d/admin.example.com.conf
每个文件包含一个 server 块,分别定义 root、index、location 等。这种组织方式便于维护和单独启停。
1.3 示例:静态站点与反向代理混合
假设 example.com 为静态站点,api.example.com 为 Node.js 后端。配置如下:
# example.com.conf
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example;
index index.html;
}
# api.example.com.conf
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
二、TLS 证书绑定与 HTTPS 配置
2.1 准备证书文件
使用 Let’s Encrypt 免费证书或商业证书。假设证书文件位于 /etc/ssl/example.com/ 下:
- fullchain.pem - 包含服务器证书与中间证书链
- privkey.pem - 私钥(权限需设为 600)
- 某些情况还需要 chain.pem(中间证书)
私钥安全是底线,务必使用 chmod 600 privkey.pem 并归 owner 为 root 或 nginx。
2.2 配置 HTTPS server 块
修改原有虚拟主机,增加监听 443 端口的 server 块。例如:
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
root /var/www/example;
index index.html;
}
重要参数说明:
ssl开启 SSL/TLS,http2启用 HTTP/2 提升性能ssl_certificate使用 fullchain.pem,而非仅 server.crt- 证书路径不要包含空格或中文字符
2.3 强制 HTTP 重定向到 HTTPS
保留原监听 80 的 server 块,将其改为 301 跳转:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
注意 $host 会保持原始域名,避免将 api.example.com 跳转到 example.com 的情况。如果所有子域名共用同一套跳转逻辑,也可以使用泛域名证书,但需确保每个域名均能通过验证。
三、多域名 TLS 绑定的高级实践
3.1 SNI(服务器名称指示)
Nginx 默认支持 SNI,即一台服务器可以绑定多个不同域名的 SSL 证书。只需为每个域名分别配置独立的 server 块并指定对应的 ssl_certificate 即可。Nginx 根据客户端握手时发送的域名选择正确的证书。
验证 SNI 是否正常工作:
openssl s_client -connect example.com:443 -servername example.com
注意:所有 HTTPS 配置都必须包含 listen 443 ssl,且 server_name 与证书中的 CN 或 SAN 匹配。
3.2 安全加固参数
以下配置可移除老旧协议,启用现代密码套件:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
若使用 ECDSA 证书,需确保密码套件顺序优先 ECDHE-ECDSA。可借助 Mozilla SSL Configuration Generator 生成符合自身需求的配置。
3.3 OCSP Stapling 与 HSTS
开启 OCSP Stapling 可以提升握手速度并减轻 CA 服务器的压力:
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
HSTS(HTTP Strict Transport Security)告知浏览器强制 HTTPS:
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
注意:启用 includeSubDomains 前务必确认所有子域名均已支持 HTTPS,否则可能造成子域名无法访问。
四、配置验证与排错
4.1 测试配置语法
nginx -t
输出 syntax is ok 且 test is successful 后,方可 reload:
systemctl reload nginx
4.2 使用 curl 验证 HTTPS
检查证书链是否完整:
curl -I https://example.com
查看证书信息:
openssl s_client -connect example.com:443 -servername example.com -showcerts
注意 -servername 参数必须与请求域名一致,否则 SNI 不会生效。
4.3 常见问题
- SSL_ERROR_BAD_CERT_DOMAIN:证书中的域名未包含 server_name 中声明的域名,需重新申请证书或使用通配符证书。
- chown: invalid user: ‘nginx’:用户权限问题,检查 nginx worker 进程用户(通常是 nginx 或 www-data),确保私钥可被读取。
- 443 port conflict:多个 server 块未正确绑定不同域名,或默认 server 块配置不当。检查
netstat -tulpn | grep 443。 - 证书链不完整:SSL 握手时浏览器提示“未提供中间证书”。解决方法是将中间证书合并到 fullchain.pem 中,或使用
ssl_trusted_certificate指令。
结语
Nginx 的多域名虚拟主机和 TLS 证书绑定是服务器运维中最常见的任务之一,但细节往往决定成败。从 server_name 的精确匹配、配置文件的结构化组织,到 SSL 协议的现代参数选择,每一步都需要严谨对待。建议在正式上线前使用 SSL Labs 的在线测试工具检查评级,并定期更新证书。
掌握本文所述的方法,你可以在单台服务器上稳定托管数十个域名,同时保证安全性和性能。如果在实践过程中遇到问题,欢迎留言讨论。
延伸阅读
