使用$ remote_addr的Nginx proxy_pass

时间:2013-07-16 19:48:30

标签: nginx proxypass

我正在尝试在我的proxy_pass上包含$ remote_addr或$ http_remote_addr但没有成功。

重写规则有效

location ^~ /freegeoip/ {  
  rewrite ^ http://freegeoip.net/json/$remote_addr last;
}

没有$ remote_addr的proxy_pass有效,但freegeoip没有读取x-Real-IP

location ^~ /freegeoip/ {
  proxy_pass http://freegeoip.net/json/;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $host;
}

然后,我将ip添加到请求的末尾,如下所示:

location ^~ /freegeoip/ {
  proxy_pass http://freegeoip.net/json/$remote_addr;
}

但是nginx报告此错误:没有定义解析器来解析freegeoip.net

5 个答案:

答案 0 :(得分:93)

如果proxy_pass语句中没有变量,那么它将在启动或重新加载期间使用“gethostbyaddr”系统调用,并将永久缓存该值。

如果有任何变量,例如使用以下任一项:

set $originaddr http://origin.example.com;
proxy_pass $originaddr;
# or even
proxy_pass http://origin.example.com$request_uri;

然后nginx将使用内置解析器,并且“resolver”指令必须存在。 “解析者”可能是用词不当;将其视为“内置解析器使用的DNS服务器”。由于nginx 1.1.9,内置解析器将遵循DNS TTL值。在此之前,它使用了5分钟的固定值。

答案 1 :(得分:47)

nginx在运行时而不是在配置时解析域名似乎有点奇怪(因为域名是硬编码的)。向位置块添加resolver声明通常可以修复运行时遇到的dns问题。所以您的位置块可能如下所示:

location ^~ /freegeoip/ {
  #use google as dns
  resolver 8.8.8.8;
  proxy_pass http://freegeoip.net/json/$remote_addr;
}

此解决方案基于我前一段时间阅读的文章 - Proxy pass and resolver。值得一读。

答案 2 :(得分:0)

您还可以在server port中提及您的nginx proxy_pass uri。这解决了我的问题。

答案 3 :(得分:0)

另一种方法是,您可以在 ip 中提供您的主机 port 地址和 URL 编号,而不是主机 proxy_pass,如下所示:

您的代码: proxy_pass http://freegeoip.net/json/;

更新代码 proxy_pass http://10.45.45.10:2290/json/;

答案 4 :(得分:-1)

如果有人遇到麻烦,对我来说它帮助将proxy_pass主机移动到单独的上游,所以我想出了类似的东西

upstream backend-server {
  server backend.service.consul;
}

server {
  listen       80;
  server_name  frontend.test.me;

  location ~/api(.*)$  {
    proxy_pass http://backend-server$1;
  }
  location / {
    # this works mystically! backend doesn't...
    proxy_pass http://frontend.service.consul/;
  }
}