使用Python/iptables拦截通过Linux桥接的UDP数据包
我正在尝试在一个运行Linux的二层桥接上使用iptables
,目的是获取从以太网端口进来的UDP数据包,并将它们通过wlan0接口发送出去,同时重定向到本地的一个端口(比如说,10000)。
举个例子,如果设备1(10.0.0.2)通过以太网发送UDP数据包到桥接(10.0.0.1),然后桥接再通过无线接口将这个数据包传递给设备2(10.0.0.3),我该如何将这些数据包重定向到本地(桥接)上,以便在桥接上运行的Python脚本可以处理它们呢?
我尝试过这个命令:iptables -t nat -A PREROUTING -d 10.0.0.3 -p udp --dport 10000 -j REDIRECT --to-ports 10000
,但是似乎没有效果。数据包根本没有被重定向。
我还试过这个命令:iptables -t nat -A PREROUTING -d 10.0.0.3 -p udp --dport 10000 -j DNAT --to-destination 127.0.0.1:10000
,但也没有成功。
有没有办法用iptables
来实现这个,或者用其他方法?如果不行,是否有其他方法可以仅用Python来拦截这些数据包?现在它只是简单地在监听UDP数据包,代码如下:
socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
socket.bind(('', 10000))
谢谢。
1 个回答
你提到的规则可以稍微调整一下就能正常工作。虽然在iptables
的手册里没有说明,但你必须把协议作为第一个参数来匹配,像这样:
iptables -t nat -A PREROUTING -p udp -d 10.0.0.3 --dport 10000 -j REDIRECT --to-ports 10000
iptables -t nat -A PREROUTING -p udp -d 10.0.0.3 --dport 10000 -j DNAT --to-destination 127.0.0.1:10000
第一个规则应该是可以用的,不过根据这个回答,第二个规则就不行了,你需要执行下面这个命令:
sysctl -w net.ipv4.conf.all.route_localnet=1
你可以把all
替换成你具体的网络接口。默认情况下,这个值是0,这意味着系统会丢弃所有发往127.0.0.0/8
的外部流量。这是出于安全考虑,因为这样的流量是不正常的。
route_localnet
-BOOLEAN
在路由时,不要把回环地址当作外部源或目的地。这使得
127/8
可以用于本地路由。
默认值是FALSE
请注意,这个选项只适用于3.5以上(不包括3.5)的内核。