Nginx proxy_pass不支持直接拼接变量URL,应采用map+upstream、resolver动态解析或map提取路径等安全机制实现动态路由,严禁用户输入直拼URL以防SSRF。

Nginx 的 proxy_pass 本身不支持在 URL 中任意拼接变量(比如 http://$host:$port/api),配置会直接报错。真正可行的动态后端,必须绕开“运行时拼 URL”这个误区,转而用 Nginx 原生支持的安全机制来实现。
用 map + upstream 实现参数/请求头驱动的路由
这是最推荐、最稳定、无需额外模块的方式。把判断逻辑提前到配置加载阶段,避免注入和空值风险。
- 在
http块中定义upstream组,例如:upstream backend_prod { server 10.0.1.10:8080; }upstream backend_staging { server 10.0.2.20:8080; } - 用
map将请求特征映射为 upstream 名称:map $arg_env $backend_cluster {<br> default "backend_prod";<br> "prod" "backend_prod";<br> "staging" "backend_staging";<br>} - 在 location 中引用:
location /api/ {<br> proxy_pass http://$backend_cluster;<br> proxy_set_header Host $host;<br>}
注意:proxy_pass后不能加路径(如/api),否则变量失效;结尾也不加斜杠(/)以免触发 URI 替换。
用 resolver + 变量实现动态域名解析
适用于后端是 Kubernetes Service、云服务域名等 IP 经常变化的场景,需要每次请求前查 DNS。
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
-
resolver必须和set、proxy_pass在同一作用域(建议写在location内):resolver 114.114.114.114 valid=15s; -
set只存纯域名(不含协议、端口、路径):set $svc "auth-svc.default.svc.cluster.local"; -
proxy_pass显式写出协议和可选端口,结尾带斜杠或留空:proxy_pass https://$svc/;
Nginx 会自动补默认端口并执行 DNS 查询。
用 map 提取路径或参数构造后端路径前缀
当需要按租户、版本等动态调整后端路径(而非主机),优先用 rewrite 改写 URI,再转发给固定 upstream。
- 例如按路径提取租户:
rewrite ^/t-(\w+)/(.*)$ /$1/$2 break;
然后proxy_pass http://backend_upstream; - 或用
map提取并拼接前缀:map $uri $prefix { ~^/t-(\w+)/ $1; default ""; }proxy_pass http://backend$prefix$request_uri;
此时backend是预定义的 upstream 或合法域名,$prefix仅用于路径部分,符合变量使用规范。
安全底线:禁止用户输入直接参与拼接
所有变量来源必须可控,否则可能引发 SSRF 或 502 错误。
-
map的 key 要加正则约束,拒绝..、://、空格等非法字符 - 禁用
if块内赋值(set在if中不可靠) - 不接受来自
$arg_xxx或$http_xxx的原始值直接拼 URL,必须经过map白名单过滤

















