使用$ remote_addr的Nginx proxy_pass

dav*_*say 36 nginx proxypass

我试图在我的proxy_pass上包含$ remote_addr或$ http_remote_addr但没有成功.

重写规则有效

location ^~ /freegeoip/ {  
  rewrite ^ http://freegeoip.net/json/$remote_addr last;
}
Run Code Online (Sandbox Code Playgroud)

没有$ 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;
}
Run Code Online (Sandbox Code Playgroud)

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

location ^~ /freegeoip/ {
  proxy_pass http://freegeoip.net/json/$remote_addr;
}
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*don 106

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

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

set $originaddr http://origin.example.com;
proxy_pass $originaddr;
# or even
proxy_pass http://origin.example.com$request_uri;
Run Code Online (Sandbox Code Playgroud)

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

  • 有趣的事实:docker 容器的默认名称服务器位于“127.0.0.11”,请参阅“cat /etc/resolv.conf”。 (7认同)
  • 这是一个更有用和更丰富的答案.谢谢. (3认同)
  • 一些参考? (3认同)
  • 关键是 proxy_pass 值中存在的任何变量,感谢您的正确答案和解释。 (2认同)
  • 如果解析器正在运行 kubernetes,我应该将其设置为什么?没有 resolv.conf 文件。 (2认同)

Rob*_*res 51

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

location ^~ /freegeoip/ {
  #use google as dns
  resolver 8.8.8.8;
  proxy_pass http://freegeoip.net/json/$remote_addr;
}
Run Code Online (Sandbox Code Playgroud)

这个解决方案基于我后来读过的一篇文章 - 代理传递和解析器.值得一读.

  • 不要**使用公共可访问的DNS服务器,例如`8.8.8.8`.[为了防止DNS欺骗,建议在正确安全的受信任本地网络中配置DNS服务器.](http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver) (14认同)

Ama*_*tle 8

如果有人遇到麻烦,对我来说,将 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/;
  }
}
Run Code Online (Sandbox Code Playgroud)