Linux 固定设备名称

前面在工作中遇到一个问题,因为产品中需要多路网卡,在原本的硬件直出网口外,还用USB拓展了两路网卡,但是这两路网卡名称总会改变。

之前在USB转串口也遇到类似情况,使用udev规则解决,这里记录下解决方法。

固定USB串口

问题现象
多路USB转串口(如 CH340、CP2102、FT232)插入后,系统默认生成 /dev/ttyUSB0/dev/ttyUSB1……每次重启或插拔后枚举顺序随机变化,导致业务绑定的设备名错乱、通信失败。

串口设备(tty 子系统)不存在系统级命名抢占,可以用udev规则。

获取设备硬件指纹

先插入设备,用以下命令查看详细信息:

1
2
3
4
5
6
7
8
9
10
# 查看所有 USB 设备的 VID/PID
lsusb

# 查看指定设备的完整 Udev 属性树(推荐)
udevadm info -a -n /dev/ttyUSB0 | grep -E "(idVendor|idProduct|serial)"

# 示例输出:
# ATTRS{idVendor}=="1a86"
# ATTRS{idProduct}=="7523"
# ATTRS{serial}=="12345678"

注意:ATTR{idVendor} 和 ATTRS{idVendor}的区别在于作用域。ATTR只匹配当前设备节点,ATTRS会向上遍历父设备链。USB串口设备的VID/PID通常在父级USB设备上,因此规则中常用ATTRS。

编写规则

1
2
3
# 创建规则文件
sudo nano /etc/udev/rules.d/10-usb-serial.rules

场景 A:单设备(唯一 VID/PID)

1
2
# 绑定唯一设备,生成固定软链接,赋予读写权限
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE="0666", SYMLINK+="ttyUSB-CH340"

场景 B:多设备同 VID/PID(最常见)
多块相同型号的 USB 转串口板,VID 和 PID 完全相同,必须用序列号或USB 拓扑位置区分:

1
2
3
4
5
6
7
# 通过序列号区分 
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ATTRS{serial}=="A1234567", SYMLINK+="ttyUSB-LEFT"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ATTRS{serial}=="B7654321", SYMLINK+="ttyUSB-RIGHT"

# 或通过 USB 端口位置区分
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", KERNELS=="1-1.2", SYMLINK+="ttyUSB-PORT1"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", KERNELS=="1-1.3", SYMLINK+="ttyUSB-PORT2"

重载并验证

1
2
3
4
5

# 重载所有udev规则
sudo udevadm control --reload-rules
# 触发规则即时生效(无需重启)
sudo udevadm trigger

修改网卡名称

修改网卡我打算用同样的方式,但是发现不行,重启后网卡名还是被强制修改了。

根因:新版Ubuntu/Debian启用了systemd可预测网卡命名。系统内置的80-net-setup-link.rules73-usb-net-by-mac.link(/lib/udev/rules.d目录下),会在Udev执行完毕后二次覆盖网卡名称。

网卡设备命名权由systemd-networkd接管,需使用.link配置文件(系统最高优先级)固定名称,不与Udev冲突。

在网络服务中添加link配置文件,创建高优先级网卡绑定配置

1
sudo nano /etc/systemd/network/20-usb-eth.link

写入以下内容:

1
2
3
4
5
[Match]
MACAddress=00:e0:4c:68:00:01

[Link]
Name=usb0

Name=usb0 → 替换成你想要的名称(wan0/lan1/eth2 均可)

权限配置并重启生效

1
2
3
sudo chmod 644 /etc/systemd/network/20-usb-eth.link
sudo reboot

验证

1
2
ip link

其他调试命令

1
2
3
4
5
# 查看设备udev详细匹配信息
udevadm info /sys/class/tty/ttyUSB0

# 测试规则是否匹配成功
udevadm test /sys/class/tty/ttyUSB0