使用nginx 1.0动态proxy_pass到$ var

时间:2011-04-21 11:44:26

标签: proxy nginx

我正在尝试根据环境变量将请求代理到不同的目标。我的方法是将目标url放入自定义变量$ target并将其提供给proxy_pass。

但是使用带有proxy_pass的变量似乎不起作用。这个简单的配置导致来自nginx的“502 Bad Gateway”响应。

server {
  listen   8080;
  server_name  myhost.example.com;
  access_log  /var/log/nginx/myhost.access.log;
  location /proxy {
    set $target http://proxytarget.example.com;
    proxy_pass $target;
  }
}

没有变量的相同配置有效:

server {
  listen   8080;
  server_name  myhost.example.com;
  access_log  /var/log/nginx/myhost.access.log;
  location /proxy {
    proxy_pass http://proxytarget.example.com;
  }
}

是否真的不可能以这种方式使用proxy_pass,或者我只是做错了什么?

4 个答案:

答案 0 :(得分:60)

我最近偶然发现了这种需求并发现为了在proxy_pass目的地中使用变量,你需要设置一个解析器,因为你的error.log很可能包含no resolver defined to resolve ...

我的解决方案是使用Google进行DNS解析设置以下内容:

location ~ /proxy/(.*) {
    resolver 127.0.0.1 [::1];
    proxy_pass http://$1;
}

在你的情况下,这应该有效:

location /proxy {
    resolver 127.0.0.1 [::1];
    set $target http://proxytarget.example.com;
    proxy_pass $target;
}

要使解析器127.0.0.1正常工作,您需要在本地安装bind9。 对于Debian / Ubuntu:

  

sudo apt-get install bind9

有关nginx和动态proxy_pass的更多信息:http://www.nginx-discovery.com/2011/05/day-51-proxypass-and-resolver.html

编辑: 将以前的公共DNS替换为本地DNS以确保安全issues

答案 1 :(得分:7)

即使@soulseekah的答案是完整而正确的,我也想为使用Nginx的人们在一个容器集群中(即Kubernetes或Docker Compose中的那些容器)发布一个答案。

基本上,您必须使用实际DNS解析器的地址为Nginx配置解析器。对于Docker,它是127.0.0.11的{​​{3}},对于Kubernetes,请参考always

在docker网络内部,我能够通过以下方式成功配置动态proxy_pass

resolver 127.0.0.11 [::1];
set $bcknd http://$http_XBackend$uri$is_args$args;
proxy_pass        $bcknd;

请注意,this answer添加了$uri$is_args$args,因为否则代理传递不考虑路径和查询字符串。

PS:在我的示例中,我正在使用$http_XBackend变量读取标头。头由客户端以XBackend: host的形式传递,此处host应该是您要转接呼叫的主机名。我尝试使用没有破折号的标头,但必须使用没有破折号的标头。

答案 2 :(得分:0)

偶然发现同样的问题

proxy_pass没有解析我的变量,直到我们发现我们的DNS服务器出现问题

可以使用此cmd检查

nslookup your-domain your-dns-ip

答案 3 :(得分:-1)

 location / {
   if ($args ~ "^url=(.+)") { #gets the "url" get parameter
       set $key1 $1;
     proxy_pass $key1;#use the parameter as proxy address
 }
}