排查Linux一处网络设备命名问题
我的小主机接入了两个网络:一个是通过网线有线接入的(流量有限,速度较快),一个是通过WiFi无线接入的(流量较多,速度较慢)。这样的网络配置我用了很久,但是某天重启了系统后,突然发现处于同一有线网络内的SSH居然连不上它了。以下排查问题过程。
背景
文件“/etc/network/interfaces”的内容如下:
1 2 3 4 5 6 7 8 9 10 |
|
简单解释一下:
eth0和wlan0分别是有线和无线网络;- 均设置成DHCP自动获取IP地址;
- 无线网络的优先级更高(metric更低);
有线网络网段是192.168.10.0/24,无线网络网段是192.168.0.0/24。
现象
SSH走TCP连接不上后,我尝试用SSH走蓝牙连接1,查看当前的IP地址时,发现两个IP地址均在192.168.0.0/24。太神奇了不是吗?我的eth0明明是走有线连接到路由器的,路由器完全正常工作(有子网、有DHCP……)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
让Codex排查了一番,它居然跟我说是因为我的路由器把小主机的DHCP请求转发/桥接给了路由器的上级,所以IP是来自……上级的上级。我网络中上级的上级的IP网段确实在192.168.0.0/24,这一度让我差点信以为真。我最终没有相信Codex的说法,因为:
- 我目前的路由器网络中已有很多设备在正常工作中,完全没有出现过此类问题;
- 我在路由器上抓包并没有抓到来自小主机的DHCP请求(包含转发/桥接的)。
排查
对比小主机的eth0和路由器的eth1(它们“物理”相连)的ifconfig后我发现,路由器的eth1显示“NO-CARRIER”。也就是说,路由器的LAN口并没有“承载网络”————没有和任何设备相连。所以,Codex前面说路由器转发/桥接了小主机的DHCP请求完全是一派胡言。
斩断这条路线后,我马上有了自己的结论:这两个IP地址都来自无线网络。
等等,eth0一听就是有线网络设备(例如:RJ45端口)的名字啊,怎么可能也来自无线网络?好问题,我“隐瞒”了一个事实:此无线网络是一个USB随身WiFi设备,是插在小主机的USB上供电的。
也就是说,我这个便宜的随身WiFi设备可能支持USB供网;同时,我的小主机也安装了USB CDC 以太网络驱动。
然后我再次让Codex根据我的思路重新查了一下,果然不出我所料:
因为 Linux 里的 eth* 不等于“RJ45 口”。任何看起来像以太网的设备都可能叫 ethX。
我查到小主机上实际是:
1 2 3 4 5 6 7 8 9 10eth0: USB CDC Ethernet driver: cdc_ether device: ZTE CDC Ethernet Device / USB Mobile Broadband MAC: 34:4b:50:00:00:00 state: up eth1: 板载 Intel 有线网卡,也就是外壳上的 RJ45 driver: e1000e MAC: 1c:69:7a:6d:27:2e state: down所以答案是:你的 eth0 不是那个 RJ45 口,而是一个 USB 设备暴露出来的“虚拟以太网”接口,看起来像 ZTE 移动宽带/USB 网络设备。它先被内核注册,所以拿到了名字 eth0;真正的 RJ45 反而叫 eth1。
另外,一开始我没主动意识到这个问题还有另外一个原因:ifconfig不会显示“DOWN”状态的网卡,而ip link会显示。我第一次用的是前者,没有想到这一层问题。
我好奇Codex查了什么数据库知道那个eth0的详细描述信息的。发现它查了以下信息:
1
|
|
然后查到了这是个USB CDC(Communications Device Class)设备,然后就查了驱动描述符信息,找到了设备厂商等较详细的信息。
如此一来,我前面配置在/etc/network/interfaces中的带具体名字的配置就可能已经失效了。
网络接口名字被抢占的问题
我的小主机物理自带一个RJ45网口,挂在PCIe上。按理说会被内核极早地识别并加载(然后命名),为什么会被插入的USB抢了先?难以理解。
所以,我觉得手动永久地给我的RJ45端口绑定一个固定的名字。
我用的系统是AlpineLinux,Codex告诉内核的接口热插拔管理是mdev负责的:
1 2 3 4 |
|
mdev会读取/etc/mdev.conf文件,其中配置了网络接口如何管理,如下:
1 2 3 4 5 |
|
其中的/etc/mactab文件用于列出接口名与MAC地址的对应规则,nameif命令按此规则给新的接口命名。
当然,不再建议使用ethX这种命名规则,太容易冲突了。所以我选择了“lanX”:
1 2 |
|
重启系统或者网络后,一切就回归正常了。