iptables 端口转发 A -> B -> A

iptables 端口转发 A -> B -> A

A我有一台带有 lxc-container( ) 的主机( B)。 A的本地 IP 地址是 10.0.3.1,公共 IP 假设为 1.2.3.4。 B的本地 IP 地址是 10.0.3.21。

我需要将 1.2.3.4:7999 转发到 10.0.3.1:7999,为此我创建了以下规则:

iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 7999 -j DNAT --to 10.0.3.21:7999
iptables -A FORWARD -p tcp -d 10.0.3.21 --dport 7999 -j ACCEPT

当我从外部世界连接到A(1.2.3.4:7999) 时,我成功连接。但是当我尝试连接到B时,我失败了A(连接超时)。

我应该创建哪些规则才能从 10.0.3.1 连接到 1.2.3.4:7999?

答案1

你有一个NAT 发夹这里的情况是,您当前的 iptables 规则不支持。当容器发送请求时,数据包如下所示:

10.0.3.21:12345 -> 1.2.3.4:7999

然后网关将数据包进行 DNAT 处理,并将其发送回容器:

10.0.3.21:12345 -> 10.0.3.21:7999

容器接收数据包并发送如下响应:

10.0.3.21:7999 -> 10.0.3.21:12345

即它直接指向容器本身。但是端口 12345 不知道与 10.0.3.21:7999 的连接,因为该连接与 1.2.3.4:7999 连接,因此响应被忽略。

解决方案是在网关上对数据包进行 SNAT,以便响应返回网关,然后网关会撤消两个 NAT。尝试添加如下内容:

iptables -t NAT -A POSTROUTING -o lxcbr0 -d 10.0.3.21 -s 10.0.3.21 -j SNAT --to 10.0.3.1

答案2

我认为您遇到的问题是答案出现在不同的界面上。

初始请求

S: 1.2.3.4
D: 1.2.3.4

基因转移酶

S: 1.2.3.4
D: 10.0.3.21

此时,主机A决定10.0.3.21使用私有网络接口进行路由。

回复

S: (IP of default GW interface on B)
D: 1.2.3.4

来自的回复数据包B将穿过默认网关,并且很可能返回到A其公共接口,此时数据包将被丢弃,因为连接跟踪表中没有匹配的条目。


解决方案

添加以下规则以确保答复与请求遍历相同的路径。

iptables -t nat -I POSTROUTING -s 1.2.3.4 -d 10.0.3.21 -o (interface of 10.0.3.1) -j SNAT --to 10.0.3.1

相关内容