我尝试在proxy_pass上包含$remote_addr或$http_remote_addr,但没有成功。
重写规则起作用
location ^~ /freegeoip/ {
rewrite ^ http://freegeoip.net/json/$remote_addr last;
}
没有$remote_addr的proxy_pass可以工作,但freegoip无法读取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
7条答案
按热度按时间a11xaf1n1#
如果proxy_pass语句中没有变量,则它将在启动或重新加载期间使用“gethostbyaddr”系统调用,并将永久缓存该值.
如果有任何变数,例如使用下列其中一项:
然后nginx将使用一个内置的解析器,并且“resolver”指令 * 必须 * 存在。“resolver”可能是一个用词不当;可以把它想象成“内置解析器将使用哪个DNS服务器”。2从nginx 1.1.9开始,内置解析器将接受DNS TTL值。3在此之前,它使用的是一个固定值5分钟。
y0u0uwnf2#
nginx在运行时而不是在配置时解析域名似乎有点奇怪(因为域名是硬编码的)。在location块中添加一个
resolver
声明通常可以修复运行时遇到的dns问题。因此,您的location块可能如下所示:这个解决方案是基于我不久前读过的一篇文章-Proxy pass and resolver。值得一读。
aiazj4mn3#
如果有人仍然遇到问题,* 对我来说,将proxy_pass主机移到一个单独的上游有助于 *,所以我想出了这样的方法
gwo2fgha4#
另一种方法是,您可以在
proxy_pass
中提供您的主机ip
地址和port
编号,而不是主机URL
,如下所示:您的验证码:
proxy_pass http://freegeoip.net/json/;
更新的代码
proxy_pass http://10.45.45.10:2290/json/;
vbkedwbf5#
你也可以在
proxy_pass uri
中提到你的nginxserver port
。这为我解决了这个问题。56lgkhnf6#
尝试使用dig / nslookup来确定这仍然是nginx的问题。在我的例子中,问题是我的nginx和根dns之间的一个dns服务器不尊重小到1秒的TTL值。
Nginx不会在Docker中重新解析DNS名称
fhity93d7#
所以你想这样做:
但是作为Chris Cogdon的pointed out,它失败了,因为在运行时,nginx没有解析域名,因此
proxy_pass
需要一个解析器(另请参见proxy_pass docs)。看起来可行的方法(虽然可能是黑客!)是在启动时触发nginx解析域名并缓存。
因此,请更改config以包含一个不带任何变量的位置(对于同一主机)(以及您的位置 * 带 * 变量):
现在将在启动时解析主机(并且其缓存值将在运行时用于第二个位置)。您可以通过更改主机名来验证此启动解析行为(
freegeoip.net
)到不存在的东西,当您运行nginx -t
或nginx -s reload
时,将出现紧急错误([emerg] host not found in upstream
)。当然,您可以通过忽略任何resolver
,命中您的location
块,并在日志中观察到没有错误,来验证缓存的值是否在运行时使用。