Nginx 的 server_name 通配符与 catch-all 怎么配?

Nginx server_name 通配(*.example.com)、正则与 catch-all(server_name _ + default_server)配置方法;匹配优先级规则、泛域名证书搭配与 FAQ。

最佳实践
Nginx 的 server_name 通配符与 catch-all 怎么配?封面

三种写法:前缀通配 *.example.com 匹配所有子域;正则 ~^(?<sub>.+)\.example\.com$ 可捕获子域名;catch-all 用 listen 80 default_server; server_name _; 兜住一切未匹配的请求。

1. 通配符匹配所有子域

server {
    listen 80;
    server_name *.example.com;        # 匹配 www./blog./shop. 等一切一级子域

    root /var/www/wildcard;
    ...
}
  • *.example.com 只匹配一级子域;example.com 本身不匹配,需要并列写上:server_name example.com *.example.com;
  • 开头通配(*.)是合法位置;www.*.com 这种中间通配不合法。
  • 另一种等价写法:.example.com(点开头)同时匹配裸域和一级子域。

2. 正则 server_name(要捕获子域时)

server {
    listen 80;
    server_name ~^(?<tenant>.+)\.example\.com$;

    root /var/www/tenants/$tenant;    # 捕获组可直接当变量用
}

多租户 SaaS 的经典用法:acme.example.com/var/www/tenants/acme

3. Catch-all(兜底 server)

server {
    listen 80 default_server;         # 这个 listen 地址的默认 server
    server_name _;                    # "_" 只是个占位无效名,不是真正的通配

    return 444;                       # 直接断连;或 return 301 到主站
}

原理澄清:让某 server 成为兜底的关键是 default_server,不是 server_name _。当请求的 Host 没匹配到任何 server_name 时,该 listen 地址的默认 server 接管。return 444 是 Nginx 特有的"无响应关闭连接",常用于丢弃扫描器/非法 Host 流量。

匹配优先级

同一 listen 地址上多个 server 块时:

精确名 > 前通配(*.example.com)> 后通配(www.example.*)> 正则 > default_server

nginx -T 可以确认实际加载的 server 块及顺序。

配套:泛域名证书

HTTPS 场景下通配 server_name 需搭配泛域名证书*.example.com)。Let's Encrypt 的泛域名证书只能走 DNS-01 验证(certbot 配 DNS 插件自动续期)。

观测云对照

catch-all 块的流量日志是金矿——里面全是"你不知道谁在访问你"的请求:扫描器、错误 DNS 指向、盗链。把 Nginx 访问日志接入观测云,按 host 聚合,非业务域名的访问量、UA 分布一目了然;非法 Host 的突增可配告警,盗链和恶意扫描无所遁形。

常见问题(FAQ)

Q:server_name _ 里的下划线有特殊含义吗?
A:没有。它只是个不可能合法的域名,用来占住"永远不会被主动匹配"的位置;真正起兜底作用的是 default_server

Q:正则 server_name 有什么性能开销吗?
A:有,每次请求都要跑正则。高并发站点尽量用精确名和前通配,正则留给确实需要的场景。

Q:一个 server 块能写多个 server_name 吗?
A:可以,空格分隔:server_name example.com www.example.com *.example.net;,混合精确与通配都行。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台