我使用 nginx 作为我们应用 Web 服务器(gunicorn;这是一个 Django 应用)前面的反向代理。访问此 Web 应用的大多数用户实际上是通过转发代理。
由于请求通过正向代理服务器,因此这些情况下的 IP 地址始终来自代理服务器,而不是来自原始请求者。我想纠正这种情况。
所有来自转发代理的请求都包含一个标头via:proxy
。在此类请求中,原始请求者 IP 会在名为 的单独 HTTP 标头字段中发送X-IORG-FBS-UIP
(还有X-FORWARDED-FOR
)。
我的问题是,如何配置 nginx,以便它检测请求是否有via:proxy
标头,如果有,则从标头记录原始请求者 IP X-IORG-FBS-UIP
? 一个说明性示例会很棒;提前谢谢! 我的 nginx 是 v 1.4.6
请注意我不要有正向代理使用的 IP 范围。如果我有,解决这个问题的一种方法是设置etc/nginx/conf.d/proxies_acl.conf
:
set_real_ip_from 1.2.3.0/22;
set_real_ip_from 23.22.20.0/22;
real_ip_header X-IORG-FBS-UIP;
答案1
试试这个。想知道它是否有效。如果你有任何未翻译的客户端,它就会破坏这一点。
set_real_ip_from 0.0.0.0/0;
real_ip_header X-IORG-FBS-UIP;
上面的 set_real_ip_from 和 real_ip_header 语句是执行此操作的标准方法。您的情况与大多数人的情况的唯一区别在于您不知道代理的 IP 地址。0.0.0.0/0 表示“每个 IP 地址”,因此上面的语句表示“对于每个请求,从 X-IORG-FBS-UIP 标头获取日志的客户端 IP”。我的猜测如果该标头不存在,它将使用实际 IP。
在大多数情况下,您可以获取代理的 IP 地址。AWS、CloudFlare 等。您为什么不知道代理的 IP?
我还注意到几个月前你问过一个几乎相同的问题,并接受了答案。如果有人没有回答你的问题,请不要将其标记为答案。
请求的替代方法 - 不起作用
您要求根据 via:proxy 标头的存在提供替代方法。我认为这是不可能的。我写了这个
if ($http_X_via:proxy) {
set_real_ip_from $remote_addr;
real_ip_header X-IORG-FBS-UIP;
}
但失败了。Nginx 说 set_real_ip_from 不能进入 if 块。这意味着您必须提前知道您的 IP,或者使用我上面的其他解决方案。
答案2
指定代理的 IP 地址是有充分理由的。任何人都可以将代理标头发送到您的服务器,并将“真实 IP”设置为某个任意 IP 地址,如果您依赖这些标头中传递的地址,则可能会出现潜在的安全漏洞。这就是为什么real_ip模块配置为让您指定值得信赖转发代理。
如果你的目标只是让 nginx 记录假定的真实 IP,则无需更改请求者的 IP。你只需要记录 headersX-IORG-FBS-UIP
和中的内容X-FORWARDED-FOR
。正如描述在这里,您可以配置 nginx 记录器来捕获X-FORWARDED-FOR
如下内容:
add the following line in your general nginx.conf in the http {} section.
log_format main '$http_x_forwarded_for - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent"' ;
我思考添加第二个记录器指令X-IORG-FBS-UIP
将允许您同时处理这两个。有关配置 nginx 记录器的更多信息这里。