使用 iptables 和 ebtables 将广播数据包转换为单播数据包

使用 iptables 和 ebtables 将广播数据包转换为单播数据包

我已经为这个问题苦苦挣扎了好几个月,而且我有限的网络知识不允许我取得进一步的进展,所以我在这里寻求建议。

我有一个 OpenWRT 路由器,它有两个子网,分别是 192.168.1.x 和 192.168.2.x。在 192.168.1.x 上,我有一台客户端 PC,它运行着一个我没有来源的应用程序,在 192.168.2.x 上,运行着一个相同软件的服务器。为了发现其他服务器,客户端会在本地网络上发送一个广播,该广播显然不会穿越子网。但由于我知道服务器在哪里,所以我想以某种方式将这种广播“转换”为带有该服务器目标地址的单播 UDP 数据包。

我知道最简单的做法是将客户端和服务器放在同一个子网上,但由于服务器也暴露在互联网上,不同的人使用 TeamViewer 登录,所以我真的希望尽可能保持它的隔离。

所以我想到了

iptables -t mangle -A PREROUTING -p udp -s 192.168.1.0/24 -d 255.255.255.255 -m udp --dport 10308 -j TTL --ttl-set 128 -m comment --comment "Broadcast Traverse Test TTL"
iptables -t nat -A zone_lan_prerouting -p udp -s 192.168.1.0/24 -d 255.255.255.255 -m udp --dport 10308 -j DNAT --to-destination 192.168.2.36:10308 -m comment --comment "Broadcast Traverse Test"

我还添加了一条ebtables规则来覆盖目标 MAC,以便它不被视为广播:

ebtables -t nat -A PREROUTING -p ip --ip-protocol udp -d ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff --ip-destination-port 10308 -j dnat --to-destination 9c:c9:eb:15:dd:ce

这样,数据包实际上就到达了服务器,服务器又发送了回复。不幸的是,仍然有些问题,因为我在链中看到了OUTPUT与回复本身相关的这些日志条目:

IN= OUT=wlan0 MAC source = 9c:c9:eb:15:dd:ce MAC dest = 50:2f:9b:2a:ba:9d proto = 0x0800 IP SRC=255.255.255.255 IP DST=192.168.1.227, IP tos=0x00, IP proto=17 SPT=10308 DPT=51719
IN= OUT=wlan0 MAC source = 9c:c9:eb:15:dd:ce MAC dest = 50:2f:9b:2a:ba:9d proto = 0x0800 IP SRC=255.255.255.255 IP DST=192.168.1.227, IP tos=0x00, IP proto=17 SPT=10308 DPT=51719

我原本期望IP SRC192.168.2.36,数据包会通过FORWARD链而不是OUTPUT链。我担心这与有关conntrack,一旦从路由器收到请求,它就会注册此条目:

[NEW]    udp      17 60 src=192.168.1.227 dst=255.255.255.255 sport=65137 dport=10308 [UNREPLIED] src=192.168.2.36 dst=192.168.1.227 sport=10308 dport=65137
[UPDATE] udp      17 60 src=192.168.1.227 dst=255.255.255.255 sport=65137 dport=10308 src=192.168.2.36 dst=192.168.1.227 sport=10308 dport=65137
[UPDATE] udp      17 60 src=192.168.1.227 dst=255.255.255.255 sport=65137 dport=10308 src=192.168.2.36 dst=192.168.1.227 sport=10308 dport=65137 [ASSURED]

那么...我有机会以某种方式实现我的结果吗?

相关内容