从 Apache 2.4开始,我开始使用mod_remoteip而不是mod_extract_forwarded来重写来自前端服务器(varnish、squid、apache 等)提供的x-forwarded-for 的客户端地址。
到目前为止,所有模块都可以正常工作,即 php、cgi、wsgi 等...... - 客户端地址显示为它们应有的样子,但我无法在访问日志中写入客户端地址(%a、%h、%{c }一种)。不走运 - 我总是得到 127.0.0.1(本地主机转发前)。
使用mod_remoteip时如何记录客户端的IP地址?
更新:IT WORKS O_O - 请参阅下面的答案
我的环境有用户请求通过多个系统:
[客户端] --> [ELB] ---> [nginx] --> [网络]
(ELB = AWS 弹性负载均衡器)
多亏了这个答案,我让 nginx 确定并将正确的客户端 IP 地址传递给带有X-Forwarded-For
和X-Real_IP
标头的上游服务器(Web)。相关的 nginx 配置:
real_ip_header X-Forwarded-For;
set_real_ip_from 10.0.0.0/8;
real_ip_recursive on;
proxy_set_header X-Real-IP $remote_addr;
Run Code Online (Sandbox Code Playgroud)
我的问题是,nginx 中的 Real IP 模块用$remote_addr
其X-Forwarded-For
计算结果替换了现有变量。这为我提供了原始客户端 IP,但我丢失了实际将请求发送到代理(即 ELB)的系统的 IP 地址。
总的来说,拥有客户端 IP 对我来说更重要,但我希望能够记录完整的请求链,以便我可以了解(和调试)流量是如何流动的。目前,我只能让 nginx 记录客户端 IP、它自己的 IP 和上游服务器 IP。我也希望能够记录 ELB IP。
我有一个由我们的托管服务提供商管理的 F5 Big-IP。它专用于我们的专用 VLAN 等。效果很好:)
我们要求他们添加 X-Forwarded-For HTTP-Header 字段。他们已经这样做了,我们现在可以在代码中访问它。惊人的 :)
但是..对于我们的IIS日志,它仍然是F5机器的IP。我想我被告知我们需要对 IIS 服务器应用 ISAPI 过滤器(畏缩!)。
在设置自己的头文件之前,我可以在 nginx 配置中使用什么来清除任何现有的 X-Forwarded-For 头文件?我目前正在使用 Nginx 在将流量传递到 HAProxy 以进行负载平衡之前终止 SSL。
现在,我有:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Run Code Online (Sandbox Code Playgroud)
但是,这会将新的 IP 地址附加到任何现有 X-Forwarded-For IP 地址的末尾。有没有办法只保留Nginx看到的地址?
我们有 IIS7 服务器位于 nginx 反向代理后面。
反向代理发送带有访问者 IP 地址的标准“HTTP_X_FORWARDED_FOR”标头,但 IIS7 日志记录仅记录 nginx 服务器的 IP 地址(这是有道理的,但这不是我想要的)。
如何告诉 IIS7 改为记录“HTTP_X_FORWARDED_FOR”标头(或另外记录它)?
(注意:我是 linux 管理员,而不是 windows 管理员,因此真诚地感谢明确的说明和链接)
我在 HAPROXY 设置后面有几台 Apache 2 机器,我尝试在这些 Apache 机器上设置 mod_evasive,同时还使用 mod_rpaf 来获取真正的 X-FORWARDED 客户端 IP。
出于某种原因,mod_evasive 获取并阻止了一些 ips(使用 ApacheBench 进行测试),但有些可以继续打开更多连接,并且基本上对我的服务器进行 DOS 处理。
知道什么可以在 mod_evasive 中从另一个 ip 中排除一个 ip 吗?考虑到它位于代理后面并且真实的客户端 ip 在 apache 日志中可见?
mod_evasive的定义是默认值时,DOSWhitelist设定为我们的子网掩码(192.168 。例如)。
rpaf 模块有 RPAFproxy_ips 定义和我们的 HAPROXY ip。有任何想法吗?
在我的 HAProxy 负载均衡器中,我有以下配置块:
defaults
mode http
log global
option httplog clf
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
frontend main_http *:80
option forwardfor except 127.0.0.1
option httpclose
default_backend backend_http
backend backend_http
balance roundrobin
option httpchk
server node1 10.0.0.64:80 check port 80
server node2 10.0.0.65:80 check port 80
server node3 10.0.0.66:80 check port 80
Run Code Online (Sandbox Code Playgroud)
在节点 (Tomcat) 上,我以这种格式记录请求(与第一个字段中的 x-forwarded-for 和真正的 REMOTE_ADDR 相结合):
pattern='%{X-Forwarded-For}i - %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %a'
Run Code Online (Sandbox Code Playgroud)
这似乎适用于大多数请求,但在某些情况下,我假设客户端位于代理后面,我看到第一个字段包含这些值的请求(每行代表一个真实请求,我破坏了真实 IP隐私):
10.83.103.44, 10.83.103.44
10.83.198.52, 10.83.198.52
10.53.109.36, …
Run Code Online (Sandbox Code Playgroud) 我有一个 Haproxy 实例,它Host
使用http-request set-header
.
http-request set-header Host internal.example
Run Code Online (Sandbox Code Playgroud)
但是,我仍然希望后端能够访问原始Host
标头。我认为这X-Forwarded-Host
是一个很好的候选人,但是我正在努力弄清楚如何做到这一点。
我正在使用这个,它有效:
capture request header Host len 64
http-request set-header X-Forwarded-Host %hrl
Run Code Online (Sandbox Code Playgroud)
但当然,这是一个巨大的黑客 - 不能超过 64 个字符,如果我需要捕获另一个标题,它将无法工作。
有没有更好的办法?
为了隐藏我的网站 IP,我在另一个 VPS 上用 nginx 代理了主服务器。我正在尝试将访问者的真实 IP 发送到我的网站,这是我在 conf.d 文件夹中的配置:
proxy_cache_path /etc/nginx/cacheddata levels=1:2 keys_zone=staticfilecache:180m max_size=500m;
proxy_temp_path /etc/nginx/cacheddata/temp;
proxy_connect_timeout 30;
proxy_read_timeout 120;
proxy_send_timeout 120;
#IMPORTANT - this sets the basic cache key that's used in the static file cache.
proxy_cache_key "$scheme://$host$request_uri";
upstream wordpressapache {
#The upstream apache server. You can have many of these and weight them accordingly,
#allowing nginx to function as a caching load balancer
server 127.0.0.1:8080 weight=1 fail_timeout=120s;
}
server {
listen 80;
server_name XXXXXX.com;
access_log off;
error_log …
Run Code Online (Sandbox Code Playgroud) IETF RFC 2616 第 4.2 节允许请求包含具有相同字段名称的多个标头,只要保留插入的时间顺序,并且它们的值可以转换为具有逗号分隔值列表的单个标头。
http://tools.ietf.org/html/rfc2616#section-4.2
当且仅当该头字段的整个字段值被定义为逗号分隔列表[即,#(values)] 时,消息中可能存在具有相同字段名的消息头字段。通过将每个后续字段值附加到第一个字段值,每个字段值用逗号分隔,必须可以将多个标题字段组合成一个“字段名称:字段值”对,而不改变消息的语义。因此,接收具有相同字段名的头字段的顺序对组合字段值的解释很重要,因此当转发消息时,代理不得更改这些字段值的顺序。F5 不会覆盖任何现有的 X-Forwarded-For。它也不会将现有的 X-Forwarded-For 连接成一个逗号分隔的值。反而,
但是,如果环境中有多个客户端、代理、CDN、流量管理器、参与操作X-Forwarded-For
集合的服务器呢?
执行统一的做法似乎有好处。但最佳实践是什么?
F5 BIG-IP 默认 http 配置文件插入标头X-Forwarded-For
在请求的预先存在的 XFF 标头集合的末尾累积一个附加标头,以保留顺序。
AWS ELB 鼓励将传入请求的多个X-Forwarded-For
合并到一个包含以逗号分隔的 XFF IP 列表以及用户主机地址的单个标头中,以保留顺序。
其他设备可以采用其他变体。
是否存在针对异构环境的商定建议或事实上的标准?
此外,是否提供了任何时间戳数据,以允许代码X-Forwarded-For
在先前对 XFF 标头的操作可疑的情况下按添加的时间顺序对标头进行明确排序。
x-forwarded-for ×10
haproxy ×4
nginx ×4
logging ×3
amazon-elb ×2
apache-2.2 ×2
f5-big-ip ×2
http-headers ×2
iis-7 ×2
ip ×1
isapi ×1
proxy ×1
ssl ×1
tomcat ×1