Nginx子域名的配置,本质上是让同一台服务器根据请求头里的Host字段,把不同域名流量分发给不同的虚拟主机。浏览器请求blog.ipipp.com和api.ipipp.com时,即使它们解析到同一个IP地址,Nginx也能识别出Host的差异,并交给对应的server块处理。把这个机制搞清楚,后续关于server_name、default_server以及匹配顺序的设置就不会再感到混乱。

一、Nginx子域名配置的本质:Host头与虚拟主机
Nginx的虚拟主机功能通过server块实现。每个server块代表一个独立的站点配置,listen指令决定它监听哪个端口,server_name指令则声明这个站点响应哪些域名。当客户端发起HTTP请求时,请求头中会携带一个Host字段,比如Host: blog.ipipp.com。Nginx拿到这个值后,会与所有server_name进行匹配,找到最合适的server块来生成响应。因此,子域名配置并不是真正的网络层子域划分,而是应用层根据域名做的路由选择。
匹配规则有明确的优先级:精确域名匹配优先于前导通配符,前导通配符优先于后导通配符,通配符之后才轮到正则表达式。需要特别注意的是,如果没有任何server_name匹配成功,Nginx会使用默认服务器处理请求。默认服务器通常由listen指令后面的default_server参数标记;如果没有任何server块显式设置default_server,则监听该端口的第一个server块会成为默认服务器。这个默认行为是很多配置不生效的根源。
# 示例:两个子域名分别指向不同目录
server {
listen 80;
server_name blog.ipipp.com;
root /var/www/blog;
index index.html;
}
server {
listen 80;
server_name api.ipipp.com;
root /var/www/api;
index index.php;
}
上面的配置中,两个server块监听同一个80端口,但通过server_name区分流量。如果某个请求的Host既不是blog.ipipp.com也不是api.ipipp.com,就会交给最先加载的那个server块处理。要精确控制默认行为,可以在其中一个listen后添加default_server参数,这样无论请求什么未匹配域名,都会稳定落到指定站点。
二、子域名配置的典型应用:多站点与反向代理
子域名在实际项目中最常见的用途是单台服务器承载多个项目。比如一台开发机同时跑着前端项目、接口服务和管理后台,如果每个服务都占用不同端口,访问时要记端口号,非常不方便。通过子域名配合Nginx反向代理,可以把blog.ipipp.com转发到本机的3000端口,把api.ipipp.com转发到4000端口,把admin.ipipp.com指向静态文件目录。这样外部只暴露80或443端口,域名清晰,也便于日后迁移。
反向代理场景下,除了正确设置proxy_pass,还要注意把原始Host头传给后端。Nginx默认会改变一些请求头,而后端框架可能需要知道用户实际访问的域名。通常要在location块中加上proxy_set_header Host $host;以及X-Real-IP、X-Forwarded-For等头信息,避免后端获取到127.0.0.1这样的代理地址。下面是常见配置。
server {
listen 80;
server_name blog.ipipp.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name api.ipipp.com;
location / {
proxy_pass http://127.0.0.1:4000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
如果后端服务需要处理跨域请求,还可以在location块中增加CORS相关响应头。但要注意,Nginx配置中的add_header只有在当前层级没有其他add_header的情况下才全部生效,存在继承覆盖的问题。因此建议把通用头部放在一个独立的配置片段中,通过include引入,减少重复配置,也避免修改时遗漏。
本地开发还可以通过修改hosts文件模拟子域名解析。Windows下文件路径为C:\Windows\System32\drivers\etc\hosts,Linux和macOS一般是/etc/hosts。添加一行如127.0.0.1 blog.ipipp.com,就能在未购买域名的情况下测试Nginx子域名配置。
三、常见误区:为什么配置看起来正确却不生效
第一个误区是把子域名解析和Nginx配置混在一起排查。很多人改完server_name后直接访问,发现跳到了默认站点,就以为配置写错了。实际上可能是DNS尚未生效,或者本地hosts文件中没有添加对应记录。判断方法很简单,先在客户端执行ping或nslookup子域名,确认解析出来的IP是否指向Nginx所在服务器。如果域名解析到了错误地址,Nginx永远不会收到该请求。
第二个误区是对default_server的理解不准确。Nginx在没有显式设置default_server时,会把监听相同端口的第一个server块当作默认服务器。配置文件加载顺序与文件名有关,如果nginx.conf中include了多个配置文件,默认服务器的位置可能并不直观。为了排查方便,建议在每个端口的某个listen指令上显式加上default_server,这样无论配置文件顺序怎样变化,行为都能保持一致。
第三个误区是误以为通配符可以匹配任意层级。例如server_name *.ipipp.com;匹配的是blog.ipipp.com、api.ipipp.com这样的单个子域,但不会匹配ipipp.com本身,也不会直接匹配a.b.ipipp.com这种多级子域。如果需要匹配主域和所有子域,应该同时写下多个域名,或者使用正则表达式,例如server_name ~^(www\.)?ipipp\.com$;。但正则匹配的性能略低于精确匹配和通配符匹配,能用精确域名就尽量用精确域名。
# 显式指定默认服务器,并处理通配符与主域
server {
listen 80 default_server;
server_name _;
return 444;
}
server {
listen 80;
server_name ipipp.com *.ipipp.com;
root /var/www/main;
index index.html;
}
上面的配置用server_name _;配合default_server作为兜底,对未匹配的Host直接返回444关闭连接。这样能避免陌生域名解析到服务器后被当作默认站点返回内容,也减少信息暴露。另一个常见问题是修改配置后没有重载,Nginx不会自动读取新文件。需要执行nginx -s reload或systemctl reload nginx,并通过nginx -t先做语法检查。
四、HTTPS与子域名配置的额外注意点
当子域名需要启用HTTPS时,证书与server_name的匹配就会成为新的坑。Nginx在TLS握手阶段需要根据SNI信息选择合适的证书。如果证书只覆盖了ipipp.com,而用户访问的是api.ipipp.com,浏览器会提示证书不匹配。此时不能只修改Nginx配置,还要确保证书包含所有需要使用的子域名,或者申请通配符证书*.ipipp.com。使用通配符证书时要注意它只匹配一级子域,不能跨级使用。
HTTPS配置中,每个server块通常需要监听443端口并开启ssl,同时指定证书和私钥路径。对于多子域名,可以每个子域使用独立的证书,也可以使用同一张通配符证书。如果使用同一张证书,可以写在一个server块中,利用server_name列出所有子域名;如果证书不同,则需要为每个子域名创建单独的server块,并分别配置ssl_certificate和ssl_certificate_key。下面是一个HTTPS子域名配置示例。
server {
listen 443 ssl;
server_name api.ipipp.com;
ssl_certificate /etc/nginx/ssl/api.ipipp.com.crt;
ssl_certificate_key /etc/nginx/ssl/api.ipipp.com.key;
location / {
proxy_pass http://127.0.0.1:4000;
proxy_set_header Host $host;
}
}
在实际运维中,建议同时配置80端口跳转443,避免用户忘记输入https而访问失败。可以单独创建一个监听80端口的server块,使用return 301 https://$host$request_uri;实现整站跳转。跳转时保留原始Host和URI,这样不同子域名会跳转到对应的HTTPS地址。最后,修改证书或配置后务必执行语法检查和重载操作,确保证书路径可读、私钥权限正确。
Nginx子域名配置server_name反向代理修改时间:2026-09-20 12:00:45