关于 iptables NAT 转发后端服务器获取客户端真实 IP 的问题。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
Anonym0u5
V2EX    Linux

关于 iptables NAT 转发后端服务器获取客户端真实 IP 的问题。

< href="Javascript:" Onclick="upVoteTopic(972111);" class="vote">
  •  
  •   Anonym0u5 2023-09-08 17:32:14 +08:00 2950 次点击
    这是一个创建于 765 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请教一个关于 iptables NAT 转发后端服务器获取客户端真实 IP 的问题。

    以下与我测试的真实环境不同只有 IP 和端口,以下是一个场景:

    两台服务器 A,B 均为 Linux:

    • A 服务器 IP 180.101.50.242
    • B 服务器 IP 183.3.203.119

    需求:通过请求 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; } } 
    18 条回复    2023-09-11 10:57:24 +08:00
    son012
        1
    son012  
       2023-09-08 17:51:35 +08:00
    转发不要做 snat 啊,你做了 snat 伪装了,肯定获取的就是 B 服务器的 IP 了
    son012
        2
    son012  
       2023-09-08 17:54:01 +08:00
    也看不懂你既然用 nginx ,直接用 nginx 转发不好了,还要做一层 nat
    Anonym0u5
        3
    Anonym0u5  
    OP
       2023-09-08 17:54:30 +08:00
    @son012 不做 snat ,就是第二条不加?不加的话,无法访问到 B 机器的端口了。
    Anonym0u5
        4
    Anonym0u5  
    OP
       2023-09-08 17:55:08 +08:00
    @son012 是有这么个需求
    son012
        5
    son012  
       2023-09-08 17:57:14 +08:00
    @Anonym0u5 最简单的办法,就是 a 上也加 nginx 做反向代理,两条 iptables 规则都不加
    honmaple
        6
    honmaple  
       2023-09-08 17:57:57 +08:00
    iptables 用`TPROXY`,nginx 用`transparent`
    fangpeishi
        7
    fangpeishi  
       2023-09-08 19:09:53 +08:00
    leonshaw
        8
    leonshaw  
       2023-09-08 19:52:55 +08:00 via Android
    7 层方案:nginx 加头
    4 层方案:A 不做 SNAT ,B 默认路由(或者基于端口策略路由)配到 A (不在一个子网还需要打个隧道)。
    jakes
        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 了。
    lovelylain
        10
    lovelylain  
       2023-09-08 20:40:57 +08:00 via Android
    既然是 http 建议在 A 服务器上做反代,这样比较容易透传客户端 ip ,A 反代是设置 xff 就行,用 iptables 很麻烦的,而且不能跨 ipv4 v6 。
    julyclyde
        11
    julyclyde  
       2023-09-08 20:46:00 +08:00
    1 不要用 SNAT
    2 为了让 nginx 返回的数据和收到的数据组成完整的 TCP 连接,应该把 nginx B 机器的默认网关设置为 A 。具体到你这个情况,还得设置 tunnel 。可以参考一下 LVS 的几个模式的详解
    adoal
        12
    adoal  
       2023-09-08 21:37:26 +08:00   1
    为什么要在 A 上做到 B 的转发?你不如讲一下你的原始问题。
    tool2d
        13
    tool2d   2023-09-08 21:40:45 +08:00 via Android
    一般来说获取不到 nat 修改前的 ip ,楼上都说的很清楚了,可以在 http 转发时做。
    如果一定要获取 nat 修改前的 ip ,那么可以搜一下 getsockopt so_original_dst ,这函数就是专门干这个的。
    salmon5
        14
    salmon5  
       2023-09-09 09:19:19 +08:00
    这个简单:
    A 服务器 IP 180.101.50.242 ,把这个 IP 配到 B 服务器上就行了
    salmon5
        15
    salmon5  
       2023-09-09 09:20:05 +08:00
    找运营商割接下
    littlezzll
        16
    littlezzll  
       2023-09-09 13:33:50 +08:00 via Android
    既然是 http 服务,直接 nginx 7 层转发就是了,应用取 XFF ip
    Anonym0u5
        17
    Anonym0u5  
    OP
       2023-09-11 10:53:42 +08:00
    非常感谢大家的回答,综合了解了一下,不一一回复了。去掉 iptable ,我是可以实现需求。
    Anonym0u5
        18
    Anonym0u5  
    OP
       2023-09-11 10:57:24 +08:00
    然后公网的 IP 不能配置到其他地方,因为一个是云 ,一个是 IDC 。我试试 6 楼说的这个。其他关于设置 B 机器网关的,在我这里需要隧道,网关也要设置多个,默认还有 IDC 有内网。再次感谢各位指点和 idea 。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2792 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 13:22 PVG 21:22 LAX 06:22 JFK 09:22
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86