Mar*_*tin 10 networking virtual-machines bridge filter spoofing
我正在尝试在ebtables 中创建IP-MAC配对规则。可用的教程和相关问题 [1] 很少,但我有一些特定的设置。
环境: 我有很多物理主机。每个主机都有很少的以太网卡,以绑定方式加入并用作桥接器的从属设备。每个主机上有很多虚拟机(kvm、qemu、libvirt)。每个虚拟机都通过名为 vnet[0-9]+ 的新端口连接到其物理主机的网桥。没有 NAT。网络工作正常,所有物理主机都可以 ping 通,所有虚拟机也可以。每个虚拟机都有自己的 IP 地址和 MAC 地址。
问题:在虚拟机内部,IP 地址可以更改为另一个。
找到的解决方案:在 ebtables 站点 [2] 上有已知的解决方案,但是当仅使用一台主机时,此解决方案适用。它允许所有流量,如果来自 IP 的数据包的 MAC 不是允许的,则数据包将被丢弃。如果有多个主机,则需要在所有主机上注册所有现有的 IP-MAC 对。需要逆向策略解决方案。
精心设计的解决方案:我试图以相反的方式使用 ebtables。这是我尝试过的示例。
例 1
Bridge table: filter
Bridge chain: INPUT, entries: 2, policy: DROP
-i bond0 -j ACCEPT
-p IPv4 -s 54:52:0:98:d7:b6 --ip-src 192.168.11.122 -j ACCEPT
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
Run Code Online (Sandbox Code Playgroud)
例2
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 1, policy: DROP
-p IPv4 -s 54:52:0:98:d7:b6 --ip-src 192.168.11.122 -j ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
Run Code Online (Sandbox Code Playgroud)
我想要的核心是拥有默认策略 DROP,并且只允许来自在给定主机上部署了正确 IP-MAC 对的虚拟机的流量。但是,这些解决方案不起作用。
问题:如何仅允许正在运行的虚拟机的指定 IP-MAC 对的网桥流量并丢弃来自端口 vnet[0-9]+ 的所有未知 IP-MAC 对?
非常感谢您提供任何答案。
Mar*_*tin 12
我终于设法制定了一个可行的解决方案。
因此,一开始,没有任何规则,所有策略都设置为 ACCEPT。没有用户定义的链。过滤表如下所示:
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
Run Code Online (Sandbox Code Playgroud)
添加了一个新链。该链包含所有允许的 IP-MAC 对。它被称为 VMS。
# ebtables -N VMS
Run Code Online (Sandbox Code Playgroud)
现在,重要的部分。对于每个包含从 vnet[0-9]+ 端口通过网桥的 IP 数据包(或其部分)的帧,应用链策略和链 VMS 规则。换句话说,对于来自任何虚拟机的每个 IP 数据包,应用 VMS 链。
# ebtables -A FORWARD -p ip -i vnet+ -j VMS
Run Code Online (Sandbox Code Playgroud)
链式 VMS 的默认策略必须是 DROP。这样,来自任何虚拟机的每个 IP 数据包都会在默认情况下被丢弃。后来,添加了允许的 IP-MAC 对例外。默认策略 DROP 会立即丢弃来自任何具有未知 IP-MAC 对的虚拟机的所有流量,从而无法进行 IP 欺骗。
# ebtables -P VMS DROP
Run Code Online (Sandbox Code Playgroud)
表过滤器现在看起来像这样。此外,当没有虚拟机运行(允许)时,它会以这种方式显示。
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 1, policy: ACCEPT
-p IPv4 -i vnet+ -j VMS
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
Bridge chain: VMS, entries: 0, policy: DROP
Run Code Online (Sandbox Code Playgroud)
假设有两台正在运行的机器。如果我们尝试 ping 到/从它们,流量将被丢弃并且目的地无法到达。这是预期的结果,因为该流量尚未被允许。只需一个命令就足以允许每个虚拟机流量。
# ebtables -A VMS -p ip --ip-src 192.168.11.125 -s 54:52:00:cc:35:fa -j ACCEPT
# ebtables -A VMS -p ip --ip-src 192.168.11.122 -s 54:52:00:98:d7:b6 -j ACCEPT
Run Code Online (Sandbox Code Playgroud)
现在,来自允许的虚拟机的流量正常流动并且防止了 IP 欺骗。
此解决方案可能不完美,如果您有任何意见或改进,我会很高兴听到。