![使用 iptables (或其他 lartc 命令)将多播限制到所需的输出接口](https://linux22.com/image/654580/%E4%BD%BF%E7%94%A8%20iptables%20%EF%BC%88%E6%88%96%E5%85%B6%E4%BB%96%20lartc%20%E5%91%BD%E4%BB%A4%EF%BC%89%E5%B0%86%E5%A4%9A%E6%92%AD%E9%99%90%E5%88%B6%E5%88%B0%E6%89%80%E9%9C%80%E7%9A%84%E8%BE%93%E5%87%BA%E6%8E%A5%E5%8F%A3.png)
我让 unifi 服务器为网络上的所有接入点运行。控制器主机位于几个网络上,但 unifi 只能使用其中一个网络。当然,服务器没有选项来控制它使用哪些接口。而且它会将多播溢出到错误的网络上。
我尝试阻止所有非白名单多播,如下所示:
iptables -A OUTPUT -d 224.0.0.0/4 -j DROP
对我来说这似乎是一件轻而易举的事,而且它确实有效,只是最终 unifi 控制器会进入循环(其中显然没有 sleep())并不断尝试填充我不想让它与之通信的接口的套接字 — 感谢 strace 提供的这一启示。因此,服务器的 CPU 占用率达到 100%,仅仅是因为 iptables 中的 -j DROP 规则。太棒了。
我正在寻找一种不阻塞地丢弃数据包的方法(即,让 unifi 认为数据包已经发出)或将它们重定向到可接受的接口。即使数据包来源不明,也比让它溢出到错误的网络上要好。
为此,我还尝试将它们改写并路由到环回,但数据包从错误的接口发出,忽略了路由。我猜他们直接在接口上打开套接字或类似的东西。
iptables -t mangle -A PREROUTING -d 224.0.0.0/4 -j MARK --set-mark 666
ip rule add fwmark 666 table 666
ip route add 224.0.0.0/4 dev lo table 666
我正在使用路由表和 fw 标记来确保不会将任何想要的多播(在其他地方列入白名单)路由为空。
我认为 unifi 完全绕过了路由表。设置标记正在触发(大量数据包),但数据包继续从不需要的接口发出。其他多播的类似规则似乎运行良好。unifi 正在做一些可怕的事情(可能是原始 ip 套接字?)。
这确实不是什么重要问题。我只是将服务移到了只有一个接口的其他虚拟机上;但出于学术原因,我想知道如何做到这一点。似乎应该有一种方法可以将应用程序限制到您希望它们限制的接口上。
答案1
实现此目的的一种方法是将unshare -n
进程放入其自己的网络命名空间中。这将有效地限制它可以绑定的接口,以便它只能发送通过命名空间导出的接口。
这相当于将其放在只有一个接口的 VM 上,但在不需要额外的 VM 开销的意义上更“便宜”。
您可能还想尝试将 PREROUTING 规则放入 OUTPUT 链中,因为这些数据包是在主机本地生成的(我假设)。路由只是被绕过,因为 netfilter 不会分析 PREROUTING 链中本地来源的数据包。
另外,一些指定您允许并通过其进行多播的接口的 iptables 规则也会很有用。
iptables -o ethX -d 224.0.0.0/4 -j DROP
将有助于确保数据包确实通过您关心的网络发出。