需求:通过请求 A 服务器 IP 端口可以转发访问到 B 服务器 IP 端口,B 服务器服务可以获取到真实客户端的 IP 地址。 实操:在 A 服务器上做 iptable NAT 转发 8088 端口到 B 服务器 8099 端口,用了以下命令
iptables -t nat -A PREROUTING -p tcp --dport 8088 -j DNAT --to-destination 183.3.203.119:8099;
iptables -t nat -A POSTROUTING -p tcp -d 183.3.203.119 --dport 8099 -j MASQUERADE -to-source 180.101.50.242;
问题:在 B 服务器的 Nginx 里面无法获取到真实的客户端 IP ,一直获取到的是 A 服务器的 IP ,如果想要获取真实客户端 IP ,iptable 这块规则该如何处理。
说明:Nginx 相关的获取客户端 IP 配置都加过了(没有效果,大概率判断问题不在 Nginx 这一侧):
server {
listen 80 default_server;
server_name _;
location / {
default_type text/html;
set_real_ip_from <NAT 服务器 IP>;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
# 使用$remote_addr 获取客户端真实 IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
content_by_lua_file /etc/nginx/print_ngx_var.lua;
}
}
1
son012 2023-09-08 17:51:35 +08:00
转发不要做 snat 啊,你做了 snat 伪装了,肯定获取的就是 B 服务器的 IP 了
|
2
son012 2023-09-08 17:54:01 +08:00
也看不懂你既然用 nginx ,直接用 nginx 转发不好了,还要做一层 nat
|
6
honmaple 2023-09-08 17:57:57 +08:00
iptables 用`TPROXY`,nginx 用`transparent`
|
7
fangpeishi 2023-09-08 19:09:53 +08:00
|
8
leonshaw 2023-09-08 19:52:55 +08:00 via Android
7 层方案:nginx 加头
4 层方案:A 不做 SNAT ,B 默认路由(或者基于端口策略路由)配到 A (不在一个子网还需要打个隧道)。 |
9
jakes 2023-09-08 20:12:13 +08:00
你做了 NAT ,在 B 机器看来就 A 发出的,NAT 不会修改 HTTP 请求内容,所以你在 B 用 NGINX 获取的就是 A 的 IP 。
你可以在 A 机器用代理转发流量,这个时候 A 的代理就可以加入 X-Forwarded-For 这些请求头,B 就可以知道访问者的 IP 了。 |
10
lovelylain 2023-09-08 20:40:57 +08:00 via Android
既然是 http 建议在 A 服务器上做反代,这样比较容易透传客户端 ip ,A 反代是设置 xff 就行,用 iptables 很麻烦的,而且不能跨 ipv4 v6 。
|
11
julyclyde 2023-09-08 20:46:00 +08:00
1 不要用 SNAT
2 为了让 nginx 返回的数据和收到的数据组成完整的 TCP 连接,应该把 nginx B 机器的默认网关设置为 A 。具体到你这个情况,还得设置 tunnel 。可以参考一下 LVS 的几个模式的详解 |
12
adoal 2023-09-08 21:37:26 +08:00 1
为什么要在 A 上做到 B 的转发?你不如讲一下你的原始问题。
|
13
tool2d 2023-09-08 21:40:45 +08:00 via Android
一般来说获取不到 nat 修改前的 ip ,楼上都说的很清楚了,可以在 http 转发时做。
如果一定要获取 nat 修改前的 ip ,那么可以搜一下 getsockopt so_original_dst ,这函数就是专门干这个的。 |
14
salmon5 2023-09-09 09:19:19 +08:00
这个简单:
A 服务器 IP 180.101.50.242 ,把这个 IP 配到 B 服务器上就行了 |
15
salmon5 2023-09-09 09:20:05 +08:00
找运营商割接下
|
16
littlezzll 2023-09-09 13:33:50 +08:00 via Android
既然是 http 服务,直接 nginx 7 层转发就是了,应用取 XFF ip
|
17
Anonym0u5 OP 非常感谢大家的回答,综合了解了一下,不一一回复了。去掉 iptable ,我是可以实现需求。
|
18
Anonym0u5 OP 然后公网的 IP 不能配置到其他地方,因为一个是云 ,一个是 IDC 。我试试 6 楼说的这个。其他关于设置 B 机器网关的,在我这里需要隧道,网关也要设置多个,默认还有 IDC 有内网。再次感谢各位指点和 idea 。
|