插着网线却没网:一次 NetworkManager + netplan 的排查记录
网卡、网线、驱动、交换机端口全都正常,问题是NetworkManager 的有线连接配置丢了,而且它被系统永久禁止再自动创建。而配置之所以"丢了就没了",是因为这台机器的 NM 由netplan 托管,连接的真实存储在
/etc/netplan/90-NM-*.yaml,NM 自动生成的连接在重启后会蒸发。
修复只需一条nmcli connection add,但找到它花了十几步。
- 系统:Ubuntu / Linux 6.17.0-19-generic(KDE Plasma, X11)
- 网卡:Realtek RTL8111/8168/8211/8411(
r8169驱动,PCI06:00.0) - 症状:网线插好、链路灯正常,但始终没有 IP,NetworkManager 显示"已断开"
一 现象
$ip-brlinkenp6s0 UP 00:e0:21:9d:65:a0<BROADCAST,MULTICAST,UP,LOWER_UP>wlxe0ad47220334 UP e0:ad:47:22:03:34<BROADCAST,MULTICAST,UP,LOWER_UP>$ip-braddr enp6s0 UP ← 空的,没有 IP wlxe0ad47220334 UP10.193.192.80/17 ← WiFi 正常 $ nmcli device status enp6s0 ethernet 已断开 -- ← 断开了,而且没有任何连接- 注意
LOWER_UP的意思是载波已检测到,也就是物理链路是通的。网卡明明是 UP 的,却"已断开",这就是第一个矛盾点。
二 逐层排除:先证明"不是硬件的问题"
2.1 物理层 / 链路层
$cat/sys/class/net/enp6s0/carrier1$cat/sys/class/net/enp6s0/speed1000$cat/sys/class/net/enp6s0/duplex full $ethtoolenp6s0 Speed: 1000Mb/s Duplex: Full Auto-negotiation: on Link partner advertisedlinkmodes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full- 千兆全双工,对端(交换机)也在正常自协商。网线、水晶头、网卡 PHY、交换机端口——这一层全部健康。
容易忽略的细节:
ethtool里的Link partner advertised link modes是判断"对端是不是活的"的关键。如果只有本机模式、对端那栏是空的,说明对面没通电或者链路是假的。
2.2 驱动 / 认卡
$ethtool-ienp6s0 driver: r8169 version:6.17.0-19-generic firmware-version: rtl8168h-2_0.0.2 02/26/15 bus-info: 0000:06:00.0- 内核原生
r8169驱动,RTL8111/8168/8211/8411系列本来就在支持列表里,不需要额外装r8168-dkms。驱动这层排除。
2.3 有没有可能是网络认证?
- 802.1X 认证(锐捷/深澜那类客户端)。端口在认证通过前不放行 DHCP,症状完全吻合。抓包验证只能,重点看两种报文:
| 报文 | 含义 |
|---|---|
ether proto 0x888e(EAPOL) | 交换机在要求 802.1X 认证 |
udp port 67/68(DHCP) | 有没有 DHCP 请求/回应 |
$sudotcpdump-ienp6s0-nn-e-l'ether proto 0x888e or udp port 67 or udp port 68'09:33:1654:05:db:7a:73:c0>ff:ff:ff:ff:ff:ff DHCP Request from54:05:db:7a:73:c0 09:33:1854:05:db:7a:73:c0>ff:ff:ff:ff:ff:ff DHCP Request from54:05:db:7a:73:c0 09:33:1954:05:db:7a:73:c0>ff:ff:ff:ff:ff:ff DHCP Request from54:05:db:7a:73:c0结论:
- 能收到别的机器的 DHCP 广播报文→ 这个端口的二层广播域是通的,没有把我们隔离。
- 45 秒里一个
0x888e都没有→ 交换机没有要求 802.1X 认证。
所以:不是物理层,不是驱动,不是认证。问题在本机。
三 一个不用 root 的小技巧:看收发计数器
/sys/class/net/<iface>/statistics/是普通用户可读的,这个在排查时极其好用:
$forfinrx_packets tx_packets rx_dropped tx_errors;doprintf"%-12s %s\n""$f""$(cat/sys/class/net/enp6s0/statistics/$f)"donerx_packets24297tx_packets0← 一个包都没发出去过 rx_dropped2377tx_errors0- 等 12 秒再看:
rx_packets 24401 ← 涨了 104,在收包 rx_dropped 2401- 收得到,发不出(
tx_packets = 0)。配合前面的抓包结论,等于直接指出:本机压根没在发 DHCP 请求。
这是个很好的分诊器:
rx涨、tx为 0 → 本机没动作(配置问题),或者发送路径坏了rx/tx都不涨 → 链路/抓包位置有问题rx_dropped持续涨 → 驱动 ring buffer 或过滤规则的问题
四 分析日志:挖出真正的坑
- 前面都是"现在时",真正的答案在历史日志里。
$ journalctl-uNetworkManager|grep-ienp6s0- 关键几段:
09:04:19 device (enp6s0): state change: config -> ip-config 09:04:19 dhcp4 (enp6s0): activation: beginning transaction (timeout in 45 seconds) 09:05:04 device (enp6s0): state change: ip-config -> failed (reason 'ip-config-unavailable') 09:05:04 device (enp6s0): Activation: failed for connection '有线连接 1' 09:05:04 dhcp4 (enp6s0): activation: beginning transaction (timeout in 45 seconds) ← 自动重试 09:05:34 device (enp6s0): state change: ip-config -> deactivating (reason 'user-requested') 09:06:15 device (enp6s0): state change: ip-config -> deactivating (reason 'user-requested') 09:06:54 device (enp6s0): state change: disconnected -> unavailable (reason 'carrier-changed') 09:06:58 device (enp6s0): carrier: link connected- 然后,什么都没有了。09:08 之后 NM 重启,这块网卡就再也没被碰过。时间线还原:
| 时间 | 事件 |
|---|---|
| 前一天 21:30 | 有线还好的,拿到过租约10.193.9.80(在/var/lib/NetworkManager/*.lease里能看到) |
| 09:04:19 | 链路起来,NM 用自动生成的有线连接 1发 DHCP |
| 09:05:04 | 45 秒超时,没收到 OFFER(ip-config-unavailable),自动重试 |
| 09:05:34 / 09:06:15 | 用户在图形界面手动断开两次 |
| 09:06 | 用户把这条连接删掉了 |
| 09:08 | NM 重启,自动连接没被持久化 → 从此网卡孤零零地"已断开",连 DHCP 都不试 |
4.1no-auto-default.state:隐形黑名单
$cat/var/lib/NetworkManager/no-auto-default.state 00:E0:21:9D:65:A0 ← 正是这块网卡的 MAC- 这个文件是整件事里最阴的一环。NetworkManager 在载波出现时会自动为网卡生成一个默认连接(就是那个"有线连接 1")。但如果用户把它删了,NM 会认为"这个人不想要自动连接",于是把这个 MAC 记进
no-auto-default.state,从此永久不再为它自动建连接。于是形成了一个死锁:
没有配置 → 发不了 DHCP → 拿不到 IP →"用不了"↑ │ └────── 被 no-auto-default 禁止自动创建 ←──┘4.2 配置丢失的原因:netplan 的锅
$ls-la/etc/NetworkManager/system-connections/ 总计8drwxr-xr-x2root root40969月3009:33.drwxr-xr-x8root root40965月1320:04..← 空的!- 系统连接目录完全是空的,但
nmcli connection show明明能看到 WiFi 和一堆 docker 网桥。那它们存哪了?
$ls-l/run/NetworkManager/system-connections/ -rw------- netplan-NM-3fc07062-...-ZZU-WLAN.nmconnection -rw------- netplan-NM-78c11d47-....nmconnection -rw------- docker0.nmconnection -rw------- virbr0.nmconnection...全在/run里——那是tmpfs,重启即失。文件名前缀netplan-NM-说明了问题。再看 NM 的生效配置:
$ NetworkManager --print-config|head-5# NetworkManager configuration: /etc/NetworkManager/NetworkManager.conf# (lib: ...) (run: 10-globally-managed-devices.conf, netplan.conf) (etc: ...)↑ 就是这里- 以及 netplan 侧:
$ls/etc/netplan/ 01-network-manager-all.yaml ← network:{version:2, renderer: NetworkManager}90-NM-3fc07062-...yaml ← 从 NM 导出的 WiFi 连接90-NM-e55ada30-...yaml90-NM-78c11d47-...yaml ← 我新建的 wired,已自动导出- 真相是这台机器的网络由 netplan 托管,数据流是这样的:
nmcli connectionadd│ ├─→ /etc/netplan/90-NM-<uuid>.yaml ← 真身,持久化 ✅ │ └─ netplan generate │ └─→ /run/NetworkManager/system-connections/ ← 生成物,tmpfs ❌ netplan-NM-<uuid>.nmconnection │ └─→ NetworkManager 读取两个关键推论:
- 判断"有没有配置",不能只看
/etc/NetworkManager/system-connections/(它永远是空的),要看/etc/netplan/90-NM-*.yaml。 - NM 自动生成的连接(如"有线连接 1")不会被导出到 netplan,所以只活在内存/
/run里,NM 一重启就消失。这正是 09:08 之后配置凭空蒸发的原因。
附赠一个冷知识:为什么这台机器上有线能被 NM 管理?
$cat/usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf[keyfile]unmanaged-devices=*,except:type:wifi,except:type:gsm,except:type:cdmaUbuntu 默认只让 NM 管 WiFi,其余设备一律 unmanaged。
$cat/run/NetworkManager/conf.d/10-globally-managed-devices.conf(空文件)netplan 在
/run里放了一个同名空文件,靠更高的配置目录优先级把它覆盖成空,从而解除了这条限制。
五 修复
- 修复只有一条命令。
sudonmcli connectionaddtypeethernet ifname enp6s0 con-name wired\ipv4.method auto ipv6.method auto connection.autoconnectyes- 结果,40 毫秒就拿到了租约:
09:33:44 dhcp4 (enp6s0): activation: beginning transaction (timeout in 45 seconds) 09:33:44 dhcp4 (enp6s0): state changed new lease, address=10.193.19.5, acd pending 09:33:44 dhcp4 (enp6s0): state changed new lease, address=10.193.19.5 09:33:44 device (enp6s0): Activation: successful, device activated.- 抓包也印证了完整的四步握手:
09:33:44.841 34:dc:99:3e:68:02 > 00:e0:21:9d:65:a0 DHCP Reply 09:33:46.914 00:e0:21:9d:65:a0 > ff:ff:ff:ff:ff:ff 0.0.0.0.68 > 255.255.255.255.67 DHCP Request 09:33:46.933 34:dc:99:3e:68:02 > 00:e0:21:9d:65:a0 DHCP Reply- 收尾三件事:
# 1. 清掉那个隐形黑名单(先备份)sudocp-a/var/lib/NetworkManager/no-auto-default.state{,.bak}sudotruncate-s0/var/lib/NetworkManager/no-auto-default.state# 2. 修掉 netplan 的权限告警(配置文件应为 0600)sudochmod600/etc/netplan/01-network-manager-all.yaml# 3. 重启 NM,验证"开机能否自动连上"sudosystemctl restart NetworkManager六 验证
| 检查项 | 结果 |
|---|---|
| 重启 NM 后自动激活 | ✅enp6s0自己连上了wired |
| 地址 / 路由 | ✅10.193.19.5/17,默认路由 metric100(优先于 WiFi 的 20600) |
| 强制走有线 | ✅curl --interface enp6s0→ HTTP 200,源 IP10.193.19.5,30ms |
| 吞吐 | ✅ 38.4 MB / 0.573s ≈67 MB/s(≈537 Mbps) |
| Portal 劫持 | ✅ 无(204 探测直通,返回 204) |
| DNS | ✅202.196.64.1解析正常 |
| IPv6 | ✅ DHCPv6 也拿到了240c:cb02:302:1206::/64 |
两个不是问题的现象,避免下次再被误导:
ping网关和ping 223.5.5.5全丢包—— 校园网网关屏蔽 ICMP。三层通不通要看 HTTP/TCP,别用 ping 下结论。rx_packets一直在涨、tx_packets为 0—— 广播域里其他设备的 ARP/DHCP 噪声,不是自己发的。
七 经验总结
排查顺序
物理链路(carrier/speed/duplex/对端自协商)↓ 正常 驱动认卡(ethtool-i/ lspci)↓ 正常 网络认证(抓 0x888e 看有没有 EAPOL)↓ 无 本机配置(nmcli device status / 连接是否存在)↓ 缺配置 ← 本次就是这里 DHCP 交互(抓67/68 看 DISCOVER/OFFER)↓ 三层连通(路由 / DNS / HTTP,别用ping)五条能复用的教训
LOWER_UP≠ 有网。它只说明载波在,物理层通。往上还有配置、DHCP、认证、路由四层。/sys/class/net/*/statistics/不需要 root,rx/tx_packets一对比就能分诊"是没在发,还是发了没人回"。ethtool里的Link partner advertised link modes是验证"对端活着"最直接的证据。/run里的东西都是临时的。看到"配置莫名消失",先想清楚系统的持久化链路到底是什么、由谁托管。- 别删 NM 自动生成的连接。删了会被写进
no-auto-default.state,那块网卡从此不再自动建连接——用nmcli connection modify改,而不是删了重建。
速查
# 这条网卡到底归谁管?nmcli device status NetworkManager --print-config|head-5# 看 (run: ...) / (etc: ...)netplan get# 配置到底存哪了?ls-la/etc/NetworkManager/system-connections/# netplan 托管时这里是空的ls-la/etc/netplan/90-NM-*.yamlls-la/run/NetworkManager/system-connections/# 被拉黑了吗?cat/var/lib/NetworkManager/no-auto-default.state# 直接建一条带 DHCP 的有线连接sudonmcli connectionaddtypeethernet ifname<iface>con-name wired\ipv4.method auto ipv6.method auto connection.autoconnectyes附录:可复用的诊断脚本
- 一次性判定"端口是否需要认证 / DHCP 有没有回应":
#!/usr/bin/env bashset-uIF=enp6s0LOG=/tmp/net-diag.txtCAP=/tmp/net-cap.txtexec>>(tee-a"$LOG")2>&1echo"--- 链路 ---"ip-brlinkshow"$IF";ip-braddr show"$IF"ethtool"$IF"2>/dev/null|grep-E'Speed|Duplex|Link detected'echo"--- 重置计数器 ---"iplinkset"$IF"down;sleep1;iplinkset"$IF"up;sleep2forfinrx_packets tx_packets rx_dropped tx_errors;doprintf' %-12s %s\n'"$f""$(cat/sys/class/net/$IF/statistics/$f)"doneecho"--- 抓包 45s (EAPOL + DHCP) ---"timeout45tcpdump-i"$IF"-nn-e-l\'ether proto 0x888e or udp port 67 or udp port 68'>"$CAP"2>&1&TD=$!;sleep2echo"--- 触发 DHCP ---"nmcli connection up wired2>/dev/null||dhcpcd-1"$IF"||echo"无可用 DHCP 客户端"wait$TD2>/dev/nullecho"--- 结果 ---"ip-braddr show"$IF";iproute show dev"$IF"cat"$CAP"结果怎么读:
| 抓包现象 | 结论 |
|---|---|
有0x888eEAPOL | 端口要802.1X 认证,装学校的认证客户端 |
| DISCOVER 出去、无 OFFER 回来 | 端口没放行 → 多半是MAC 未注册/账号未绑定,找网络中心 |
| 有 OFFER 但没拿到 IP | 系统层被拦 → 查防火墙 /rx_dropped |
| 什么包都没有 | 网线/端口实际不通 → 换线、换口 |
| 秒拿到 OFFER | 配置问题,收工 ✅ |