来自本地主机的 DNAT(127.0.0.1)

来自本地主机的 DNAT(127.0.0.1)

我想在 Linux 3.x(目前为 3.2.52,但如果需要我可以升级)上设置从 127.0.0.1、端口 4242 到 11.22.33.44、端口 5353 的 TCP DNAT。

看起来简单的 DNAT 规则设置不起作用,telnet 127.0.0.1 4242挂起一分钟Trying 127.0.0.1...,然后超时。可能是因为内核正在丢弃返回的数据包(例如 SYN+ACK),因为它认为它们是火星的。我不需要解释为什么简单的解决方案不起作用,我需要一个解决方案,即使它很复杂(例如它涉及创建许多规则)。

我可以从网络外的另一个本地 IP 地址设置常规 DNAT 127.0.0.0/8,但现在我需要 127.0.0.1 作为目标地址。我知道我可以设置用户级端口转发过程,但现在我需要一个可以使用iptables且不需要辅助进程的解决方案。

我在 Google 上搜索了这个问题一个小时。这个问题被问过很多次,但我找不到任何可行的解决方案。

另外,关于 DNAT 到 127.0.0.1 也有很多问题,但我不需要那样,我需要相反的。

请注意,单个iptables -j REDIRECT规则不起作用,因为我需要将传出数据包的 IP 地址从 127.0.0.1 更改为 11.22.33.44,但-j REDIRECT无法更改 IP 地址。

答案1

这对我有用,将流量从localhost:8081路由到172.17.0.1:80,其中172.17.0.1是桥接接口后面的 veth,名为docker0

sysctl -w net.ipv4.conf.docker0.route_localnet=1
iptables -t nat -A OUTPUT -o lo -p tcp -m tcp --dport 8081 -j DNAT --to-destination 172.17.0.1:80
iptables -t nat -A POSTROUTING -o docker0 -m addrtype --src-type LOCAL --dst-type UNICAST -j MASQUERADE

这个难题的一个关键部分是MASQUERADE规则。

进一步的启发:

答案2

您必须运行以下三个命令才能使其工作:

iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport 4242 -j DNAT --to 11.22.33.44:5353
sysctl -w net.ipv4.conf.eth0.route_localnet=1
iptables -t nat -A POSTROUTING -p tcp -s 127.0.0.1 -d 11.22.33.44 --dport 5353 -j SNAT --to $your-eth0-ip

以下是详细解释。

第一个命令将按预期执行 DNAT。但是,如果您尝试仅使用此规则集捕获数据包,您会发现什么也得不到:

tcpdump -i any -n port 5353

127.0.0.0/8这是因为,如果数据包的一端是外部 IP 地址,另一端是外部 IP 地址,则 Linux 内核默认丢弃这种数据包。

第二条命令修改了内核参数,让这种数据包通过(当然,你应该eth0相应地进行修改)。之后,当你在 eth0 上捕获数据包时,你会看到数据包被发出,但带有源地址127.0.0.1和目标地址11.22.33.44。无论这个数据包是否能到达目标服务器(中间路由器会丢弃这个数据包),这个数据包都无法返回。所以你应该添加一条SNAT规则,将源地址更改为你的 eth0 的地址。现在它应该可以正常工作了。

答案3

您需要这样的东西吗?iptables 端口重定向不适用于本地主机

iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 443 -j REDIRECT --to-ports 8080

阿德里安

相关内容