如何将客户端的真实 IP 发送到代理服务器?
我的设置是:
server {
listen 80;
server_name foo.example.com;
location / {
proxy_pass http://someip;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_request_headers on;
}
}
但该IP仍然来自代理Nginx。
答案1
据我所知,你不能强迫 nginx 将真实的源 ip 放在 ip 标头中。
我建议重构应用程序以读取您在配置中设置的 X-Real-IP 标头。
如果应用程序无法处理 X-Real-IP Header,您可以使用 HAProxy 或 Keepalived 来实现这一点。
对于 HAProxy,您必须在后端配置中设置源:
source 0.0.0.0 usesrc clientip
您必须在 Linux 内核中启用 TPROXY 模块。
并且 HAProxy 系统必须是您的应用服务器的默认网关才能实现此功能。
您还必须配置一些 sysctl 参数:
net.ipv4.conf.all.forwarding => 1
net.ipv4.conf.all.send_redirects => 1
还有一些 iptables 规则:
iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 777
iptables -t mangle -A DIVERT -j ACCEPT
并配置带防火墙标记的路由
ip rule add fwmark 777 lookup 700
ip route add local 0.0.0.0/0 dev lo table 700
答案2
要从 nginx 获取真实 IP 地址,需要两个步骤:
1). 将此地址设置到 nginx 上的 HTTP 标头中(您已经这样做了): https://www.nginx.com/resources/wiki/start/topics/examples/full/?highlight=proxy_set_header#proxy-conf
2). 调整接收此标头的软件以理解它。如果您有 Apache - 标准模块“remoteip”将是此目的的适当选择。如果您正在使用其他东西 - 只需尝试从标头中捕获此字符串 X-Real-IP。
nginx+Apache 示例
对于 Apache:
sudo a2enmod remoteip.load
- 将此行添加
RemoteIPHeader X-Real-IP
到主 Apache conf 中。例如 apache2.conf 或 httpd.conf - 取决于操作系统。您可以在 /etc/apache2 或 /etc/httpd 目录中找到它。 sudo service apache2 restart
对于 nginx:
- 在 nginx.conf 中添加行:
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
sudo service nginx restart
PS 对于没有“remoteip”模块的非常老版本的 Apache,请使用“mod_rpaf” - 它可以通过“apxs”安装。