nginx中server_name写多个域名只生效一个,根本原因是sni协商仅匹配首个域名以加载ssl证书;http层支持空格分隔多域名,但https需san证书覆盖全部域名且listen指令须严格一致。

一个 Nginx 实例可以同时响应多个域名,但必须明确区分“共用一个 server 块”和“分设多个 server 块”两种场景——它们适用条件、配置逻辑和排错路径完全不同。
server_name 写多个域名时为什么只生效一个?
常见错误现象:在 server_name 后写 example.com www.example.com,结果只有第一个域名能正确加载 HTTPS 证书或触发 if ($host) 判断。
根本原因不是语法错,而是 SNI(Server Name Indication)协商发生在 TLS 握手阶段,Nginx 在该阶段只能根据首个 server_name 匹配 SSL 证书。如果证书不包含其余域名,浏览器就会报证书错误。
- HTTP 请求无此限制,
server_name example.com www.example.com完全可用,$host变量也能取到真实值 - HTTPS 下必须用 SAN(Subject Alternative Name)证书,且所有域名都得出现在
-d参数里,例如:certbot -d example.com -d www.example.com -d shop.example.com - 证书文件本身不区分域名顺序,但 Nginx 加载时只校验首个
server_name是否在证书 SAN 列表中;其余域名靠 HTTP 层的$host处理
多个域名必须分设独立 server 块的典型场景
当你要为不同域名提供完全不同的服务(比如跳转规则、证书来源、root 路径、日志文件),就不能塞进同一个 server 块里。
常见错误现象:访问 blog.example.com 却显示 shop.example.com 的首页,或者 curl -H "Host: test.example.com" http://ip 能命中,但浏览器输域名不行。
- 每个
server块必须有独立的server_name,不能靠空格拼一堆域名来“模拟”多站点 - 所有
server块的listen指令要一致,比如都是listen 443 ssl或都是listen 80;混用listen 443和listen 443 ssl会导致匹配失败 - DNS 或本地
/etc/hosts必须把域名解析到服务器 IP,否则 Host 头根本送不到 Nginx - 泛域名
*.example.com不匹配根域名example.com,需额外加一个server_name example.com块
如何让 www 和非 www 域名自动跳转?
不要用 JavaScript 或 meta refresh,Nginx 原生 return 301 最可靠,也避免混合内容问题。
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
典型写法(强制跳转到 www):
server {
listen 80;
server_name example.com;
return 301 https://www.php.cn/link/59386272857f013b167191da57f9eb91;
}
<p>server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
return 301 <a href="https://www.php.cn/link/59386272857f013b167191da57f9eb91">https://www.php.cn/link/59386272857f013b167191da57f9eb91</a>;
}</p><p>server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;</p><h1>正常网站配置</h1><p>}</p>
-
$request_uri必须带上,否则带查询参数或路径的请求会丢失 - HTTP 和 HTTPS 都要单独写跳转块,因为
listen 80和listen 443 ssl是两个完全独立的监听上下文 - 证书路径在跳转块里也要写全,否则 Nginx 启动会报
ssl_certificate缺失错误
Apache 中 VirtualHost 配置后返回 403 Forbidden 怎么办?
这不是权限太严,而是权限不够——Apache 进程用户(如 www-data)对整个路径缺少执行(x)权限。
关键点:
-
DocumentRoot /var/www/site_a要求/var、/var/www、/var/www/site_a每一级目录都对 Apache 用户有x权限,否则进不去 -
<directory></directory>块里必须有Require all granted(Apache 2.4+),旧版是Order allow,deny+Allow from all - 别忘了运行
a2ensite site_a.conf启用配置,否则它只是躺在sites-available里没加载 - 检查语法:
sudo apache2ctl -t;看日志:tail -f /var/log/apache2/error.log,出现client denied by server configuration就是上面两点漏了
最易被忽略的是:HTTPS 场景下,SNI 协商和 HTTP Host 匹配是两层逻辑,证书兼容性和配置结构必须同步验证;光改 server_name 不补 SAN 证书,或漏掉某个 server 块的 ssl_certificate,都会导致部分域名白屏或证书告警。










