Linux 平台上每个端口的 MAC 地址数量限制

Linux 平台上每个端口的 MAC 地址数量限制

我希望限制特定端口上允许学习的 MAC 地址数量。L2 交换机上也有类似的功能。例如基于 cisco 的配置。如果达到最大值,则具有新 MAC 地址的数据包预计为:

  1. 没学过Linux bridge
  2. 掉落。

我希望在 bridge 模块中实现这样的功能,但我没有找到任何相关的配置/代码。是否可以使用 iptables/ebtables 实现相同的功能,还有其他选择吗?

谢谢,伊利亚

答案1

iptables发生得太晚,无法发挥作用。ebtables缺乏太多可用功能,而且无论如何都会受到与nftables' 桥梁家族如下所述。

一种可能的方法是使用nftables在里面网络设备家庭和将其大小设置为允许存储它们的最大 MAC 地址数,并且如果需要,将其元素的默认超时设置为桥的老化时间。


先决条件

网络设备家族表要求接口(此处为桥接端口)提前存在,以便创建使用它的基础链。因此,只有在存在此类接口后,才必须加载该表。如果是虚拟接口,则应在创建后立即加载该表,在接口启动之前加载,或者至少在将其设置为桥接端口之前加载,以防止发生学习。

足够新的版本nftables并且应该使用内核:

  • nftables0.9.1 引入了动态的下面存在的关键字(以前的版本仍然可以省略),因此nftables>= 0.9.1 应为首选,
  • nftables 0.8.4 引入了一种新的语法来从数据包路径中添加元素,因此应避免使用 nftables <0.8.4 或重新制定规则,
  • 内核 4.2 引入了对网络设备系列:内核 >= 4.2 是必需的

执行

如果过滤是在桥接层进行的(又称桥梁家庭),这确实会过滤流量,但这不会阻止网桥在过滤器丢弃额外的 MAC 地址之前学习任何 MAC 地址,因为网络过滤器的桥接钩子在桥接器看到这些帧后从桥接器调用(可以通过运行来确认bridge monitor fdb)。可以禁用学习全部桥接端口上的 MAC,但不选择哪些是或不是。

所以应该这样做桥接器,以防止它看到 MAC 地址,这样它就不可能学习它:在接口级别,使用网络设备家庭。网络过滤器目前只能处理入口在里面网络设备家庭,但这没问题,因为我们只对过滤这种情况的入口流量感兴趣:从“外部”到达并进入网桥的流量。

由于这是一个相对简单的过滤器,放置在桥接器之前,因此它不会处理任何花哨的东西。它不会以不同的方式处理 VLAN 标记数据包(这可以在规则集中扩展,添加针对特定 VLAN 的附加设置和检查。它仍然是一个固定的规则集,大多数更改都需要更改设置/链/规则)。

在里面网络设备系列基链与接口绑定。

更新:更改了答案,以便处理老化问题,这样最近未见过的 MAC 地址槽在一段时间后可以自由重复使用(最好是桥的老化时间,或此时间加一秒)。同时放弃“快速路径”规则,因为现在每个数据包无论如何都必须更新源 MAC 的计时器。更新规则表现为添加规则,但它也会将计时器重置为超时值(当规则中没有说明时规则是默认定义的)。如果某个 MAC 地址在这段时间内没有出现,内核会自动将其从集合中删除。只剩下一条规则可以做到这一点:

  • 对于收到的任何帧,使用源 MAC 地址更新集合:
    • 如果集合已满并且尝试添加新的 MAC 地址,则失败,因此不会执行剩余的接受陈述,
    • 否则,在集合中添加新的 MAC 地址,或刷新它(如果已经存在),超时时间为 30 秒,然后执行接受陈述
  • 放弃剩余的所有东西(默认策略)。

规则集

在此示例中,可以使用以下方式加载规则集nft -f portsecmax.nft

  • 桥接端口接口名为swp1(可能是eth0或者ens224等等),并且选择了同名的基础链,

  • 用于记忆 MAC 地址的集合的大小设置为允许的最大 MAC 地址数量:本例中为 3,

  • 集合元素的默认超时时间为 30 秒,这是默认值老化时间在 Linux 桥上,除非发生更改。如果用例是永远保留第一个尺寸(此处有 3 个)看到的 MAC 地址,请从timeout 30s下面删除。

portsecmax.nft

table netdev portsecmax        # for idempotency
delete table netdev portsecmax # for idempotency

table netdev portsecmax {
    set macswp1 {
        type ether_addr
        size 3
        flags dynamic,timeout
        timeout 30s
    }

    chain swp1 {
        type filter hook ingress device "swp1" priority filter; policy drop;
        update @macswp1 { ether saddr } accept comment "false if set is full and adding a new element"
    }
}

重置允许的 MAC 地址列表:

nft flush set netdev portsecmax macswp1

禁用该功能(选择以下三个选项之一):删除表或删除链或将链的默认策略更改为接受

nft delete table netdev portsecmax
nft delete chain netdev portsecmax swp1
nft add chain netdev portsecmax swp1 '{ policy accept; }'

相关内容