Iptables NAT 问题..

2019-03-16 00:05:45 +08:00
 Trumeet

先打预防针:还没有仔细阅读 Arch Linux Wiki 的 iptables 页面( xd

情况是这样的,有 A (代理)和 B (主机)两个 VPS,A 挂在 DNS 进行代理,通过 iptables dnat/snat 把指定端口的入战流量转发到 B 的端口上。目前使用的命令如图所示:(好吧没有图)


$ iptables -t nat -A PREROUTING -d <B IP> -p tcp --dport <B port> -j DNAT --to-destination <A IP>:<A Port>

$ iptables -t nat -A POSTROUTING -d <A IP> -p tcp --dport <B port> -j SNAT --to-source <B IP>

目前的问题是,B 里面通过 Nginx 反代的后端程式拿到的客户端 IP 永远是 的 IP,而不是真实的客户端 IP。请问 V2 各位诸神难呢个否提供点思路呢?多谢。

1322 次点击
所在节点    问与答
8 条回复
LGA1150
2019-03-16 00:17:58 +08:00
SNAT 之后源 IP 自然就是 A 的地址了
隧道了解一下
Trumeet
2019-03-16 00:29:18 +08:00
@LGA1150 隧道 是什么
nfroot
2019-03-16 00:40:11 +08:00
@Trumeet
协议层是这样的
A 直接向 C 发送数据,数据包里有 A 的 IP,因为数据传输是互相的,没有来源对方不知道怎么和你回数据包。
A 通过 B 向 C 发送数据,数据包里的来源 IP 会改为 B 的,C 根本不知道 A 是谁,需要回传数据的时候会把数据往 B 的 IP 发送,全程只有 AB 知道 ABC,C 只知道 B。这个技术就叫 NAT

但是如果 ABC 都属于公网 IP 并且可以互访,理论上 A 可以从 B 转发数据,并保留源 IP,就是不做 NAT,只通过路由把数据包指向 C。
nfroot
2019-03-16 00:43:38 +08:00
如果是 HTTP 协议,可以考虑在 B 上面把 HTTP 请求包加上 A 的 IP。
LGA1150
2019-03-16 00:45:03 +08:00
@Trumeet 可以看成 VPN
A B 之间建立一个 IPIP 隧道
A 的 iptables DNAT 到 B 的隧道端 IP,不要做 SNAT
B 上设置策略路由,使从隧道来的数据,从隧道回

鉴于对新手不友好,你可以在 A 上也运行个 nginx 反向代理
LGA1150
2019-03-16 00:56:50 +08:00
@nfroot #3 “理论上 A 可以从 B 转发数据,并保留源 IP ”
不用隧道的话,要 A B 在同一个广播域才可以,否则在公网转就是 IP spoofing 会被反向路由策略丢弃
electric
2019-03-16 12:16:05 +08:00
客户端拿 IP 是通过 nginx 的 http 协议键值对拿到的,前台 real-ip 请求头配置,后端读取。
Trumeet
2019-03-17 23:28:02 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/545164

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX