插着网线却没网:一次 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 显示"已断开"
一 现象
bash
$ ip -br link
enp6s0 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 -br addr
enp6s0 UP ← 空的,没有 IP
wlxe0ad47220334 UP 10.193.192.80/17 ← WiFi 正常
$ nmcli device status
enp6s0 ethernet 已断开 -- ← 断开了,而且没有任何连接
- 注意
LOWER_UP的意思是载波已检测到,也就是物理链路是通的。网卡明明是 UP 的,却"已断开",这就是第一个矛盾点。
二 逐层排除:先证明"不是硬件的问题"
2.1 物理层 / 链路层
bash
$ cat /sys/class/net/enp6s0/carrier
1
$ cat /sys/class/net/enp6s0/speed
1000
$ cat /sys/class/net/enp6s0/duplex
full
$ ethtool enp6s0
Speed: 1000Mb/s
Duplex: Full
Auto-negotiation: on
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
- 千兆全双工,对端(交换机)也在正常自协商。 网线、水晶头、网卡 PHY、交换机端口------这一层全部健康。
容易忽略的细节:
ethtool里的Link partner advertised link modes是判断"对端是不是活的"的关键。如果只有本机模式、对端那栏是空的,说明对面没通电或者链路是假的。
2.2 驱动 / 认卡
bash
$ ethtool -i enp6s0
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 请求/回应 |
bash
$ sudo tcpdump -i enp6s0 -nn -e -l 'ether proto 0x888e or udp port 67 or udp port 68'
09:33:16 54:05:db:7a:73:c0 > ff:ff:ff:ff:ff:ff DHCP Request from 54:05:db:7a:73:c0
09:33:18 54:05:db:7a:73:c0 > ff:ff:ff:ff:ff:ff DHCP Request from 54:05:db:7a:73:c0
09:33:19 54:05:db:7a:73:c0 > ff:ff:ff:ff:ff:ff DHCP Request from 54:05:db:7a:73:c0
结论:
- 能收到别的机器的 DHCP 广播报文 → 这个端口的二层广播域是通的,没有把我们隔离。
- 45 秒里一个
0x888e都没有 → 交换机没有要求 802.1X 认证。
所以:不是物理层,不是驱动,不是认证。 问题在本机。
三 一个不用 root 的小技巧:看收发计数器
/sys/class/net/<iface>/statistics/是普通用户可读的,这个在排查时极其好用:
bash
$ for f in rx_packets tx_packets rx_dropped tx_errors; do
printf "%-12s %s\n" "$f" "$(cat /sys/class/net/enp6s0/statistics/$f)"
done
rx_packets 24297
tx_packets 0 ← 一个包都没发出去过
rx_dropped 2377
tx_errors 0
-
等 12 秒再看:
rx_packets 24401 ← 涨了 104,在收包
rx_dropped 2401 -
收得到,发不出(
tx_packets = 0)。 配合前面的抓包结论,等于直接指出:本机压根没在发 DHCP 请求。
这是个很好的分诊器:
rx涨、tx为 0 → 本机没动作(配置问题),或者发送路径坏了rx/tx都不涨 → 链路/抓包位置有问题rx_dropped持续涨 → 驱动 ring buffer 或过滤规则的问题
四 分析日志:挖出真正的坑
- 前面都是"现在时",真正的答案在历史日志里。
bash
$ journalctl -u NetworkManager | grep -i enp6s0
-
关键几段:
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.1 no-auto-default.state:隐形黑名单
bash
$ cat /var/lib/NetworkManager/no-auto-default.state
00:E0:21:9D:65:A0 ← 正是这块网卡的 MAC
- 这个文件是整件事里最阴的一环。 NetworkManager 在载波出现 时会自动为网卡生成一个默认连接(就是那个"有线连接 1")。但如果用户把它删了 ,NM 会认为"这个人不想要自动连接",于是把这个 MAC 记进
no-auto-default.state,从此永久不再为它自动建连接。于是形成了一个死锁:
bash
没有配置 → 发不了 DHCP → 拿不到 IP → "用不了"
↑ │
└────── 被 no-auto-default 禁止自动创建 ←──┘
4.2 配置丢失的原因:netplan 的锅
bash
$ ls -la /etc/NetworkManager/system-connections/
总计 8
drwxr-xr-x 2 root root 4096 9月 30 09:33 .
drwxr-xr-x 8 root root 4096 5月 13 20:04 ..
← 空的!
- 系统连接目录完全是空的 ,但
nmcli connection show明明能看到 WiFi 和一堆 docker 网桥。那它们存哪了?
bash
$ 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 的生效配置:
bash
$ NetworkManager --print-config | head -5
# NetworkManager configuration: /etc/NetworkManager/NetworkManager.conf
# (lib: ...) (run: 10-globally-managed-devices.conf, netplan.conf) (etc: ...)
↑ 就是这里
- 以及 netplan 侧:
bash
$ ls /etc/netplan/
01-network-manager-all.yaml ← network: {version: 2, renderer: NetworkManager}
90-NM-3fc07062-...yaml ← 从 NM 导出的 WiFi 连接
90-NM-e55ada30-...yaml
90-NM-78c11d47-...yaml ← 我新建的 wired,已自动导出
- 真相是这台机器的网络由 netplan 托管,数据流是这样的:
bash
nmcli connection add
│
├─→ /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 管理?
bash$ 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。
bash$ cat /run/NetworkManager/conf.d/10-globally-managed-devices.conf (空文件)netplan 在
/run里放了一个同名空文件 ,靠更高的配置目录优先级把它覆盖成空,从而解除了这条限制。
五 修复
- 修复只有一条命令。
bash
sudo nmcli connection add type ethernet ifname enp6s0 con-name wired \
ipv4.method auto ipv6.method auto connection.autoconnect yes
-
结果,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 -
收尾三件事:
bash
# 1. 清掉那个隐形黑名单(先备份)
sudo cp -a /var/lib/NetworkManager/no-auto-default.state{,.bak}
sudo truncate -s 0 /var/lib/NetworkManager/no-auto-default.state
# 2. 修掉 netplan 的权限告警(配置文件应为 0600)
sudo chmod 600 /etc/netplan/01-network-manager-all.yaml
# 3. 重启 NM,验证"开机能否自动连上"
sudo systemctl restart NetworkManager
六 验证
| 检查项 | 结果 |
|---|---|
| 重启 NM 后自动激活 | ✅ enp6s0 自己连上了 wired |
| 地址 / 路由 | ✅ 10.193.19.5/17,默认路由 metric 100(优先于 WiFi 的 20600) |
| 强制走有线 | ✅ curl --interface enp6s0 → HTTP 200,源 IP 10.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 噪声,不是自己发的。
七 经验总结
排查顺序
bash
物理链路 (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改,而不是删了重建。
速查
bash
# 这条网卡到底归谁管?
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-*.yaml
ls -la /run/NetworkManager/system-connections/
# 被拉黑了吗?
cat /var/lib/NetworkManager/no-auto-default.state
# 直接建一条带 DHCP 的有线连接
sudo nmcli connection add type ethernet ifname <iface> con-name wired \
ipv4.method auto ipv6.method auto connection.autoconnect yes
附录:可复用的诊断脚本
- 一次性判定"端口是否需要认证 / DHCP 有没有回应":
bash
#!/usr/bin/env bash
set -u
IF=enp6s0
LOG=/tmp/net-diag.txt
CAP=/tmp/net-cap.txt
exec > >(tee -a "$LOG") 2>&1
echo "--- 链路 ---"
ip -br link show "$IF"; ip -br addr show "$IF"
ethtool "$IF" 2>/dev/null | grep -E 'Speed|Duplex|Link detected'
echo "--- 重置计数器 ---"
ip link set "$IF" down; sleep 1; ip link set "$IF" up; sleep 2
for f in rx_packets tx_packets rx_dropped tx_errors; do
printf ' %-12s %s\n' "$f" "$(cat /sys/class/net/$IF/statistics/$f)"
done
echo "--- 抓包 45s (EAPOL + DHCP) ---"
timeout 45 tcpdump -i "$IF" -nn -e -l \
'ether proto 0x888e or udp port 67 or udp port 68' > "$CAP" 2>&1 &
TD=$!; sleep 2
echo "--- 触发 DHCP ---"
nmcli connection up wired 2>/dev/null || dhcpcd -1 "$IF" || echo "无可用 DHCP 客户端"
wait $TD 2>/dev/null
echo "--- 结果 ---"
ip -br addr show "$IF"; ip route show dev "$IF"
cat "$CAP"
结果怎么读:
| 抓包现象 | 结论 |
|---|---|
有 0x888e EAPOL |
端口要 802.1X 认证,装学校的认证客户端 |
| DISCOVER 出去、无 OFFER 回来 | 端口没放行 → 多半是 MAC 未注册/账号未绑定,找网络中心 |
| 有 OFFER 但没拿到 IP | 系统层被拦 → 查防火墙 / rx_dropped |
| 什么包都没有 | 网线/端口实际不通 → 换线、换口 |
| 秒拿到 OFFER | 配置问题,收工 ✅ |