我得到了lo ( 127.0.0.1 )和eth0 ( 172.17.0.8 )。 我想redirect到127.0.0.1:80数据包到172.17.42.1:80 (从eth0路由)。
我试过了
iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.1 -j DNAT --to 172.17.42.1:80
但是当我curl localhost:80我没有得到任何回应,当我curl 172.17.42.1:80它只是工作。
当您尝试访问本地主机时,您的源地址是127.0.0.1,您的目标地址也是。 所以,数据包看起来像这样:
| SRC | DST | | 127.0.0.1 | 127.0.0.1 |
由于本地生成的数据包首先遍历OUTPUT链,因此使用DNAT规则修改数据包:
iptables -t nat -A OUTPUT \ -d 127.0.0.1 \ -p tcp --dport 80 \ -j DNAT \ --to 172.17.42.1:80
在OUTPUT链之后,数据包看起来像这样:
| SRC | DST | | 127.0.0.1 | 172.17.42.1 |
所以,你看到的第一个错误是,即使这个数据包被路由到源设备之外,目的地也不知道如何正确地返回它。 因此,你还需要添加额外的SNAT规则:
iptables -t nat -A POSTROUTING \ -d 172.17.42.1 \ -p tcp --dport 80 \ -j SNAT \ --to-source <your_ip_addr>
现在,在networking上退出数据包看起来非常正确(源地址将是该设备的公共地址,而不是本地主机地址)。
但是,这还不能解决你的痛苦。
在本地计算机上生成的数据包的路由决策分为两个地方。
决定这个数据包将在第二阶段,在POSTROUTING链中重写源IP之前做出。
因此,内核安全机制会丢弃数据包,因为默认情况下,内核拒绝路由src为127.0.0.1的数据包。 这意味着,即使与fwmark结合在一起也无济于事。 这需要做什么工作是启用route_localnet。 这是一个per-ifacevariables,可以使用127/8作为本地路由(默认值为0 – 也被禁用)。
sysctl -w net.ipv4.conf.all.route_localnet=1
您可以安全地在您的案例中更改“全部”输出接口的名称。
现在,数据包将按照表中以前的规则进行路由,并且由于我们有了POSTROUTING SNAT,我们将修复127.0.0.1的源IP并重写它。
希望这可以帮助。
PS。 对不起,2-3编辑之前,这是凌晨5点,我仍然醒着:)
在直接跳入防火墙规则之前,还应执行简单的转发检查。 而不是在拆开硬件之前检查电源线是否插入。
跑:
cat /proc/sys/net/ipv4/ip_forward
如果你得到一个零,IPv4将不会转发。 你需要打开这个。
要立即将其打开并短暂地validation行为:
echo 1 > /proc/sys/net/ipv4/ip_forward
上面的代码为机器打开了它,但是只是简单地修改一个内核设置,不会被“保存”。
编辑sysctl.conf文件以进行适当的永久更改并确保以下设置:
net.ipv4.ip_forward = 1