Linux 指定网络接口名称

在 linux 系统中,网络接口的名称不是固化不变的,总有一些情况会导致网络接口名称发生变化,而导致诸多问题。一般有以下情况都可能会导致网络接口名称的变化:

  1. 内核和设备命名规则的变化
    • 传统命名(如 eth0, eth1),缺点:设备的探测顺序可能因硬件更改或热插拔而改变,导致网卡名称的不稳定。
    • 基于一致网络接口命名(Predictable Network Interface Names,PNIN)
      • 基于固件(如 BIOS 或 UEFI)提供的名称:例如 eno1、ens33。
      • 基于 PCIe 总线拓扑的名称:例如 enp2s0、wlp3s0。
      • 基于设备的 MAC 地址:例如 enx<MAC地址>
  1. 操作系统配置变化
    • 使用不同的网络管理工具
      • NetworkManager:可能会覆盖默认的 udev 命名规则。
      • ifupdown/netifrc:传统的网络脚本可能会重新分配接口名称。
    • 内核启动参数的影响
      • 使用内核参数如 net.ifnames=0 或 biosdevname=0,可以禁用一致网络接口命名并回退到传统命名方式。
      • udev 规则配置变化
  2. 硬件变化
    • 新设备添加
      • 添加新的网卡可能会改变现有网卡的设备探测顺序,导致名称变化。
      • 在传统命名方式下,添加设备可能会将原本的 eth0 推后为 eth1。
    • 硬件接口顺序变化
      • 替换主板或更改 PCIe 卡的插槽顺序可能导致设备的硬件位置变化,从而影响基于位置的接口命名。
    • 热插拔设备
      • 热插拔网卡(如 USB 网卡)的接口名称可能根据插入顺序动态分配(如 enx 或 eth2)。
  3. 内核模块或驱动的变化
    • 驱动加载顺序
      • 网络设备驱动的加载顺序可能会影响设备的初始化顺序。
      • 如果更改了内核配置或模块加载顺序(如 /etc/modules-load.d/),可能导致接口名称变化。
    • 使用不同的驱动
      • 如果更换了网卡驱动程序(例如从 r8169 切换到 r8168),接口名称可能会发生变化。
  4. 系统升级
    • 系统更新可能会更改默认的 udev 规则或网络管理工具的行为,导致接口命名方式变化。
    • 升级到支持一致网络接口命名的内核或 systemd 版本时,默认命名规则可能发生变化。
  5. 特殊配置
    • 使用虚拟机或容器
    • 网卡绑定(Bonding)或桥接

为了防止网络接口名称频繁变化,推荐的方法包括:

  • 使用 udev 规则锁定设备名称(基于 MAC 地址或其他属性)。
  • 使用一致网络接口命名(默认情况下启用)。
  • 禁用自动命名特性(通过 net.ifnames=0 biosdevname=0)。

在采用 一致网络接口命名(Predictable Network Interface Names, PNIN)时,网络接口名称仍然发生变化,通常是由于 硬件拓扑结构的变化 导致的。例如,添加 NVMe 硬盘可能改变了 PCI 总线设备的枚举顺序,进而影响基于 PCI 总线命名的网络接口名称。具体原因就不细说了。

通常避免这种问题的发生,可使用 udev 指定来网络名称

1touch /etc/udev/rules.d/70-net-name-use-custom.rules

在此文件中添加以下内容

1SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="a8:b8:e0:03:7b:c5",NAME="enp2s0"
2SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="a8:b8:e0:03:7b:c6",NAME="enp3s0"

其中 ATTR{address} 是网卡的 MAC 地址, NAME 就是你需要指定的名称。

这里需要注意的是,当你添加了指定网络名称的规则后,有可能会发生这种情况,热重启的时候是按你的预期指定的,但是冷启动的时候却不一定是按照预期来的。

发生这样的情况,有可能的原因是:

由于 udev 规则加载顺序、设备初始化时机、或 udev 与其他网络管理工具(如 NetworkManager 或 ifupdown)的交互导致的。通常,冷启动时,设备会早于 udev 规则加载而被初始化,从而导致 udev 规则无法生效。

解决办法:取消由内核或固件自动分配名称

/etc/default/grub 文件中,添加或是修改以下内容

1GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"

然后更新 grub

1sudo update-grub
2
3# gentoo 使用下面这条命令
4sudo grub-mkconfig -o /boot/grub/grub.cfg