nginx实现二级域名动态转发需用正则捕获子域名并动态proxy_pass:server_name ~^(?1+).example.com$,proxy_pass https://$subdomain.backend.internal/;dns须解析*.example.com至nginx ip;https需resolver、proxy_ssl_server_name on等配置;路径与请求头必须规范设置。. ↩

要让 Nginx 自动把任意二级域名(比如 a.example.com、b.example.com)转发到对应后端服务,关键不是只靠通配符,而是结合 server_name 匹配 + 正则捕获 + 动态 proxy_pass。纯 *.example.com 只能匹配,不能提取子域;真正“自动化”的核心在于用正则提取变量并复用。
用正则捕获子域名并动态转发
在 server 块中使用带命名捕获组的正则表达式匹配 server_name,把子域名存入变量,再在 proxy_pass 中引用:
- 写法示例:
server {
listen 80;
server_name ~^(?[^.]+)\.example\.com$;
location / {
proxy_pass https://$subdomain.backend.internal/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
} -
~^表示开启正则匹配,(?<subdomain>[^.]+)</subdomain>捕获第一个点前的非点字符(即子域名),$subdomain就可在后续指令中直接使用 - 确保 DNS 已将
*.example.com解析到这台 Nginx 服务器 IP,否则请求根本到不了
泛域名通配符仅作兜底或静态匹配
如果不需要动态转发,只是统一代理所有二级域名到同一后端,可用通配符简化配置:
- 写法:
server_name *.example.com;—— 匹配a.example.com、test.example.com等,但不匹配example.com(主域)或a.b.example.com(三级) - 这种写法适合场景:所有子域都指向同一个服务(如 SaaS 多租户平台的统一入口),此时
proxy_pass写死即可,无需变量 - 注意匹配优先级:Nginx 会先尝试精确匹配(如
www.example.com),再试通配符,最后才轮到正则;所以要把泛匹配的server块放在具体域名配置之后,避免被覆盖
HTTPS 场景必须加 resolver 和 SSL 设置
当 proxy_pass 目标是域名(而非 IP)且走 HTTPS 时,Nginx 默认无法解析域名或校验证书,容易报 502:
- 在
server或http块顶部添加 DNS 解析器:resolver 144.144.144.144 valid=30s; - 启用服务器名称指示(SNI),让后端能正确返回证书:
proxy_ssl_server_name on; - 若后端也用自签名或私有 CA 证书,还需加:
proxy_ssl_verify off;(仅限内网可信环境)
路径处理与头信息不能省
动态转发时,路径和请求头极易出错,务必按规范设置:
-
proxy_pass末尾斜杠决定路径重写逻辑:写成https://$subdomain.backend.internal/(有斜杠)才能把/api/user正确转为/api/user;写成无斜杠会拼接错误 - 三行关键头必须存在(放在
location内):proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-Proto $scheme; - 若前端还经过 CDN,
X-Real-IP可能被覆盖,此时应配合set_real_ip_from和$http_x_forwarded_for使用,但基础场景这三行已足够










