如何使用 MAC 和 ebtables 防止 IP 欺骗?

如何使用 MAC 和 ebtables 防止 IP 欺骗?

我正在尝试创造IP地址配对规则ebtables。有一些教程和相关问题 [1] 可用,但我有一种特定的设置。

环境: 我有许多物理主机。每台主机都有几张以太网卡,这些卡绑定在一起并用作桥接的从属卡。每台主机上都有许多虚拟机(kvm、qemu、libvirt)。每台虚拟机都通过名为 vnet[0-9]+ 的新端口连接到其物理主机的桥接。没有 NAT。网络工作正常,所有物理主机都可以 ping 通,所有虚拟机也可以 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

示例 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

我想要的核心是使用默认策略 DROP,并且只允许来自部署在给定主机上的具有正确 IP-MAC 对的虚拟机的流量。但是,这些解决方案不起作用。

问题:如何仅允许正在运行的虚拟机的指定 IP-MAC 对在桥上进行流量传输,并删除来自端口 vnet[0-9]+ 的所有未知 IP-MAC 对?

非常感谢您的任何回答。

答案1

我最终设法制定出了一个可行的解决方案。

  1. 解决方案使用 ebtables 和 IP-MAC 对。
  2. 唯一需要的表是默认的“过滤器”表。
  3. 无需向 INPUT 链添加任何规则或策略,因为 INPUT 链与正在运行的虚拟机无关。过滤表中 INPUT、OUTPUT 和 FORWARD 链的含义说明位于 ebtables 手册页中。
  4. 由于 ebtables 在以太网级别工作,并且 IP-MAC 配对仅适用于 IP 数据包,因此需要在规则中强调这一点,以免阻止 ARP 帧和其他重要流量。

因此,一开始,没有任何规则,所有策略都设置为“接受”。没有用户定义的链。过滤表如下所示:

Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT

添加了一条新链。此链包含所有允许的 IP-MAC 对。它被称为 VMS。

# ebtables -N VMS

现在到了重点部分。对于从端口 vnet[0-9]+ 通过网桥的每个包含 IP 数据包(或其部分)的帧,应用链策略和链 VMS 规则。换句话说,对于来自任何虚拟机的每个 IP 数据包,应用 VMS 链。

# ebtables -A FORWARD -p ip -i vnet+ -j VMS

链式虚拟机的默认策略必须是 DROP。这样,来自任何虚拟机的每个 IP 数据包都会被默认丢弃。稍后,将添加允许的 IP-MAC 对例外。默认策略 DROP 会导致来自任何具有未知 IP-MAC 对的虚拟机的所有流量被立即丢弃,从而使 IP 欺骗变得不可能。

# ebtables -P VMS DROP

表格过滤器现在如下所示。此外,当没有虚拟机运行时(允许),它看起来也是如此。

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

假设有两台正在运行的机器。如果我们尝试 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

现在,来自允许的虚拟机的流量可以正常流动,并且可以防止 IP 欺骗。

这个解决方案可能不完善,如果您有任何意见或改进,我很乐意听取。

相关内容