Nginx通过server_name正则(如~^(\w+).example.com$)动态捕获二级域名到$1,用于root、proxy_pass等指令;需转义点号、排除非法子域、设default_server,并用curl和error_log验证。

用 Nginx 实现海量二级域名的动态匹配,核心不是为每个子域单独写 server 块,而是靠 server_name 的正则能力 + 变量提取,让一个配置通吃所有子域。
正则匹配二级域名的基本写法
Nginx 的 server_name 支持 PCRE 正则,需以波浪号 ~ 开头。匹配形如 blog.example.com、api.example.com 这类二级域名,常用模式:
-
~^([a-z0-9_-]+)\.example\.com$—— 捕获子域名为变量$1,只允许小写字母、数字、下划线和短横线 -
~^(\w+)\.example\.com$—— 更简洁,\w等价于[a-zA-Z0-9_],但注意它不包含短横线 - 务必转义点号:
\.,否则.会匹配任意字符
把子域名映射到对应目录或服务
捕获到的子域名(如 $1)可直接用于路径拼接、反向代理或重写逻辑:
- 静态站点:用
root /var/www/sites/$1;,自动指向/var/www/sites/blog/、/var/www/sites/api/ - PHP 应用:配合
fastcgi_param SCRIPT_FILENAME /var/www/sites/$1$fastcgi_script_name; - 反向代理:如
proxy_pass http://backend-$1;,再配合 upstream 动态解析(需开启 resolver) - 注意:确保
$1不为空,可在 location 中加if ($1 = "") { return 404; }防止空匹配
处理泛解析与安全边界
DNS 泛解析(如 *.example.com → IP)让所有子域都可达,但 Nginx 需主动过滤非法或保留名称:
- 在正则中排除:例如
~^((?!(www|admin|dev|staging)).+)\.example\.com$,用负向先行断言跳过敏感子域 - 更稳妥的做法是先匹配白名单,再 fallback 到通用规则,例如用多个
server_name按顺序匹配(Nginx 优先匹配最长、最具体的 server_name) - 始终设置
default_server拦截未匹配请求,避免被恶意绑定或信息泄露
调试与验证技巧
正则易错,上线前必须验证:
- 用
nginx -t检查语法,但不会验证正则逻辑是否符合预期 - 临时加
return 200 "subdomain: $1\n";到 location 中,curl 测试不同子域看输出 - 开启
error_log /var/log/nginx/rewrite.log notice;,配合rewrite_log on;查看重写过程(仅 debug 环境启用) - 浏览器访问时注意 Host 头是否正确发送;本地测试可用
/etc/hosts或 curl -H "Host: test.example.com" http://127.0.0.1

















