假设TCP数据包被发送到目标ip(dest_ip),可以通过以下命令丢弃:
iptables -A INPUT -d dest_ip -p tcp -j DROP
但是当我尝试使用 iptables NAT 将数据包重定向到不同的 ip(diff_ip)时,数据包仍然到达旧的目的地(dest_ip):
iptables -t nat -A PREROUTING -d dest_ip -p tcp -j DNAT --to-destination diff_ip
这里有些关于 iptables 的东西我不太明白,因为我预计数据包不会再到达 dest_ip。有人能解释一下为什么会这样吗?谢谢。
可能相关的其他信息:
/proc/sys/net/ipv4/ip_forward 已设置为 1
ifconfig 显示两个接口:eth0 和 lo;dest_ip 在 eth0 上,diff_ip 是远程 ip
更新 1:使用 telnet 进行进一步测试
在12800上建立使用socat的监听器,接收telnet消息:
socat -u TCP-LISTEN:12800,reuseaddr,keepalive,reuseaddr OPEN:/tmp/output.txt,creat,append
Telnet 连接是通过随机消息建立的:
telnet 127.0.0.1 12800
1)测试使用:
iptables -A INPUT -p tcp --dport 12800 -j DROP
结果:计数器确认所有来自 telnet 的消息均被丢弃:
iptables -L INPUT -v -n
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2 120 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:12800
2)测试使用:
iptables -t nat -A PREROUTING -p tcp --dport 12800 -j DNAT --to-destination remote_ip
结果:所有消息均到达端口 12800,未被重定向,计数器证实了这一点:
iptables -L PREROUTING -t nat -v -n
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:12800 to:remote_ip
更新 2:使用 telnet 进行进一步测试(参见上文),但在 OUTPUT 链上使用 iptables 规则:
iptables -t nat -A OUTPUT -p tcp --dport 12800 -j DNAT --to-destination remote_ip
结果:所有消息均已成功重定向,计数器确认:
iptables -L OUTPUT -t nat -v -n
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
3 180 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:12800 to:remote_ip
这开始变得有意义了,因为 telnet 是一个本地进程,它的输出应该直接进入 OUTPUT 链。然而,这又引发了另一个问题:根据更新 1,telnet 消息也可以被丢弃在 INPUT 链中,那么数据包究竟是如何传输的呢?OUTPUT -> INPUT?
答案1
你的所有测试都指出了你应该弄清楚的事情。处理 Netfilter/iptables 时,如果没有数据包流心里。
如您所见,本地进程从不经过PREROUTING
链,而只经过OUTPUT
和POSTROUTING
。这就是为什么telnet
当您将规则放入时,您的进程会被重定向OUTPUT
,而当您将其放入时则不会重定向PREROTUING
。但是,此规则适用于穿越您机器的外部数据包。