Nginx通过Host请求头匹配server_name实现多域名虚拟主机;支持精确、通配符、正则匹配,并需配置default_server兜底,避免未匹配请求落入错误站点。
当一台服务器需要托管多个网站时,Nginx 通过
Host 请求头
来识别用户想访问的是哪个站点,从而将请求路由到对应的虚拟主机配置。这不需要额外端口或 IP,仅靠 HTTP 协议自带的 Host 字段就能实现多站共存。
Host 请求头是怎么起作用的?
浏览器发起 HTTP 请求时,无论访问 example.com 还是 blog.example.com,只要都指向同一台 Nginx 服务器的 IP 和 80/443 端口,请求体里就会带上
Host: example.com
或
Host: blog.example.com
。Nginx 在读取请求头后,会逐个比对 server 块里的
server_name
指令,找到第一个完全匹配(或通配符匹配)的配置块来处理该请求。
基础配置:用 server_name 匹配 Host
每个
块必须明确声明
,它支持精确匹配、通配符和正则表达式:
精确匹配
:
—— 只响应 Host 为
example.com
的请求
通配符匹配
:
—— 匹配
blog.example.com
、
api.example.com
,但不匹配
example.com
多域名写法
:
—— 一行写多个,空格分隔
正则匹配(慎用)
:
—— 捕获子域名为变量供后续使用
必须设置 default_server 防止误匹配
如果没有 Host 头(比如直接用 IP 访问、或某些异常客户端),Nginx 会把请求交给第一个被加载的
块。更稳妥的做法是在监听语句中显式指定默认虚拟主机:
—— 表示这个 server 是 80 端口的兜底配置
—— HTTPS 同理,同时需配好证书
建议单独建一个最小化 default_server,返回 444(关闭连接)或 404,避免信息泄露
常见陷阱与验证方法
实际部署中容易出问题的地方:
DNS 未解析或 hosts 未配
:本地测试时,记得在
添加
server_name 写错大小写或多余空格
:Nginx 中域名匹配是大小写不敏感的,但空格会导致语法错误
HTTPS 下 Host 匹配正常,但证书报错
:server_name 只影响路由,SSL 证书是否生效取决于
是否覆盖该域名
用 curl 测试时忘记加 -H "Host: xxx"
:直接 curl IP 默认不带 Host,可用
模拟
serverserver_nameserver_name example.com;server_name *.example.com;server_name example.com www.example.com;server_name ~^([a-z]+)\.example\.com$;serverlisten 80 default_server;listen 443 ssl http2 default_server;/etc/hosts127.0.0.1 example.com blog.example.comssl_certificatecurl -H "Host: example.com" http://127.0.0.1