如何让Linux为不同PC上的不同桥接设备生成不同的MAC地址?

如何让Linux为不同PC上的不同桥接设备生成不同的MAC地址?

我刚刚升级了两台服务器Debian 10(巴斯特)到Debian 11(靶心)。此后,我再也无法通过网络联系到他们。经过一番排查,发现问题如下:

两台机器都配置了桥接设备。显然,Debian 用于为桥接设备分配 MAC 地址的算法已从版本 10 更改为版本 11。升级后,第一台服务器上的桥接设备与第二台服务器上的桥接设备具有相同的 MAC 地址,以前肯定没有这样的情况。

之一那里有答案声称网桥是纯粹的内部设备,因此网桥的 MAC 地址并不重要。然而,这显然是错误的。至少就我而言,两台机器的数据包均以硬件源地址是网桥的 MAC 地址,两台机器上的网络端口都在处理传入的数据包仅当它们的目的地是网桥的 MAC 地址时。

由于两台机器上的 MAC 地址相同,因此网络变得无法使用,这是完全合乎逻辑且可以理解的。

如何让 Debian 为不同机器上的桥接设备生成不同的 MAC 地址(甚至在同一台机器上,但这不是我的问题)?

答案1

浏览互联网时我发现了这个错误报告systemd-udev与 Debian 11 网桥相关:systemd-udev 会干扰不应该执行的接口的 MAC 地址 #21185

ash.in.ffho.net:~# for n in 0 1 2 3; do ip l add br$n type bridge; done
ash.in.ffho.net:~# ip -br l

br0              DOWN           d2:9e:b3:32:53:42 <BROADCAST,MULTICAST> 
br1              DOWN           e2:00:44:2c:5b:70 <BROADCAST,MULTICAST> 
br2              DOWN           0e:99:b7:42:f0:25 <BROADCAST,MULTICAST> 
br3              DOWN           a6:3f:5f:b5:9a:d6 <BROADCAST,MULTICAST> 
ash.in.ffho.net:~# for n in 0 1 2 3; do ip link del br${n}; done
ash.in.ffho.net:~# for n in 0 1 2 3; do ip l add br$n type bridge; done
ash.in.ffho.net:~# ip -br l

br0              DOWN           d2:9e:b3:32:53:42 <BROADCAST,MULTICAST> 
br1              DOWN           e2:00:44:2c:5b:70 <BROADCAST,MULTICAST> 
br2              DOWN           0e:99:b7:42:f0:25 <BROADCAST,MULTICAST> 
br3              DOWN           a6:3f:5f:b5:9a:d6 <BROADCAST,MULTICAST>

正如您所看到的,网桥是使用低级命令创建的,但它们始终继承相同的 MAC 地址值:组件systemd干扰并设置 MAC 地址。人们可以使用以下命令来查看这一操作ip monitor link

22: brtest0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default 
    link/ether 0a:ae:c3:0d:ec:68 brd ff:ff:ff:ff:ff:ff
22: brtest0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default 
    link/ether 1a:d0:fc:63:c1:71 brd ff:ff:ff:ff:ff:ff
Deleted 22: brtest0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default 
    link/ether 1a:d0:fc:63:c1:71 brd ff:ff:ff:ff:ff:ff
23: brtest0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default 
    link/ether 4e:e9:11:dd:a5:aa brd ff:ff:ff:ff:ff:ff
23: brtest0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default 
    link/ether 1a:d0:fc:63:c1:71 brd ff:ff:ff:ff:ff:ff

您可以看到最初随机的 MAC 地址如何被覆盖为固定地址,对于给定的网桥名称,两次覆盖为相同的值。

另一个副作用是当设置接口时行政上的UP,桥操作因此,状态最初变为 DOWN 而不是 UNKNOWN (请参阅我在 SU 和 SF 上的这些答案,提到有关 DOWN 和 UNKNOWN 的行为:Linux 如何确定桥接设备的默认 MAC 地址?,强制mac地址时linux ipv6桥接地址不起作用)。无论如何,一旦连接了第一个桥接端口,这就不再重要了。

在不干扰的网络命名空间内(例如:在运行上述命令两次之前)进行相同的实验将显示每次具有不同随机地址的ip add netns experiment常见ip netns exec experiment bash -l行为。systemd-udevd

这是一个效果系统生态系统,并且不会发生在未运行 systemd(或旧版本的 systemd)的系统上。一项建议的修复方法是使用:

# /etc/systemd/network/90-bridge.link
[Match]
OriginalName=br*

[Link]
MACAddressPolicy=random

但看来真正的解决方法是更改​​参与生成此“稳定随机”值的文件,如下所述:https://wiki.debian.org/MachineId

每台机器应该有不同的值。这对于从基本模板克隆虚拟机尤其重要。之间的关系machine-id和生成方式在补丁已实现(相当重大的)更改

=== 这个补丁

这个补丁意味着我们将默认为几乎所有虚拟设备设置一个“稳定”的 MAC,其中“稳定”意味着关闭机器 ID 和接口名称

也曾是提及这将会有影响,但这被忽视了。

这不限于类型的接口但对于任何会生成随机MAC地址:例如类型vethmacvlan tuntap也会受到影响。

我可以验证在执行 Debian 链接中描述的操作后,相同的网桥名称将获得不同的“稳定随机”值:

rm -f /etc/machine-id /var/lib/dbus/machine-id
dbus-uuidgen --ensure=/etc/machine-id
dbus-uuidgen --ensure

ip monitor现在在删除和重新创建时为相同的网桥名称提供一个新的 MAC 地址:32:ee:c8:92:9f:e8 而不是 1a:d0:fc:63:c1: 71 brtest0

Deleted 23: brtest0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default 
    link/ether 1a:d0:fc:63:c1:71 brd ff:ff:ff:ff:ff:ff
24: brtest0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default 
    link/ether da:72:b6:63:23:e5 brd ff:ff:ff:ff:ff:ff
24: brtest0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default 
    link/ether 32:ee:c8:92:9f:e8 brd ff:ff:ff:ff:ff:ff

结论:

由于桥接 MAC 地址现在是手动设置的,因此桥接器将不再继承设置为桥接端口的其他接口的 MAC 地址之一,包括通常的永久(物理或虚拟机)接口,这些接口预计具有不同的 MAC 地址。两个系统使用相同machine-id且相同的网桥名称(例如:br0),且此类网桥参与路由(即:网桥上配置了 IP 地址,但即使没有,网桥也可以根据其设置发出与桥接相关的其他帧)同一 LAN 上的网络将发出具有相同源 MAC 地址(网桥)的帧,可能会中断路径中的交换机,并且无论如何都会忽略来自对等方的相同源 MAC 地址。

答案2

您可以使用指令告诉 Debian 克隆 MAC 地址bridge_hw

例如我的/etc/network/interfaces文件:

iface enp2s0 inet manual

auto br0
iface br0 inet dhcp
  bridge_ports enp2s0
  bridge_hw enp2s0

现在两者enp2s0都有br0相同的地址。

$ sudo dmesg | grep 18:d6
[    2.660733] r8169 0000:02:00.0 eth0: RTL8168e/8111e, 18:d6:c7:05:89:07, XID 2c2, IRQ 26

$ ifconfig enp2s0 | grep ether ; ifconfig br0 | grep Description:   Debian GNU/Linux 11 (bullseye)
        ether 18:d6:c7:05:89:07  txqueuelen 1000  (Ethernet)
        ether 18:d6:c7:05:89:07  txqueuelen 1000  (Ethernet)

答案3

首先,AB的答案显示了正确的解决方案。如果您也遇到同样的问题,请按照AB的回答进行正确的解决。

然而,为了完整起见,我想展示一个替代(低劣得多)的解决方案。我压力很大,没想到这么快就得到了正确答案。因此我通过稍微改变自己暂时解决了这个问题/etc/network/interfaces

auto br0
iface br0 inet static
        bridge_ports eno1
        address 192.168.20.11
        netmask 255.255.255.0
        broadcast 192.168.20.255
        gateway 192.168.20.250    
        hwaddress ether 02:01:01:01:11:01

最后一行是关键点。它使操作系统将指示的 MAC 地址分配给网桥。显示的 MAC 地址是半官方私有 MAC 地址范围中的地址。我已经验证,当您在网桥中删除或添加设备时,该 MAC 地址保持不变。

当然,您必须为每个网桥指定不同的 MAC 地址,无论网桥是否位于同一台机器上。

再次强调,上述方法仅解决了网桥MAC地址问题。我相信,如果不同机器上有相同的机器 ID,可能会出现严重错误。 AB 的答案提到了如何创建新的机器 ID,快速测试表明,以这种方式创建的每个机器 ID 都与以这种方式创建的每个其他机器 ID 不同。

相关内容