校园网有线网络排查(NetworkManager与netplan的坑)

插着网线却没网:一次 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 驱动,PCI 06: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

结论:

  1. 能收到别的机器的 DHCP 广播报文 → 这个端口的二层广播域是通的,没有把我们隔离。
  2. 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 读取

两个关键推论:

  1. 判断"有没有配置",不能只看 /etc/NetworkManager/system-connections/ (它永远是空的),要看 /etc/netplan/90-NM-*.yaml。
  2. 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:cdma

Ubuntu 默认只让 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)

五条能复用的教训

  1. LOWER_UP ≠ 有网。 它只说明载波在,物理层通。往上还有配置、DHCP、认证、路由四层。
  2. /sys/class/net/*/statistics/ 不需要 root ,rx/tx_packets 一对比就能分诊"是没在发,还是发了没人回"。
  3. ethtool 里的 Link partner advertised link modes 是验证"对端活着"最直接的证据。
  4. /run 里的东西都是临时的。 看到"配置莫名消失",先想清楚系统的持久化链路到底是什么、由谁托管。
  5. 别删 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 配置问题,收工 ✅
相关推荐
大鹏的NLP博客15 小时前
WSL Ubuntu 26.04 升级与环境整理记录
linux·ubuntu·wsl
忆挽篱笙歌17 小时前
gdb/cgdb
linux·ubuntu
成为你的宁宁20 小时前
【Ubuntu 18.04安装Gitlab】
ubuntu·gitlab
MicrosoftCloud1 天前
性能排查 02|vmstat、iostat、mpstat、sar 怎么读?性能四件套的分工与判读阈值
linux·ubuntu·vmstat·性能监控·iostat·sysstat
承渊政道1 天前
Linux网络学习【UDP Socket编程实战:网络命令与客户端访问Linux验证】
linux·网络·学习·ubuntu·编程实战·udp socket
奔跑的大白啊2 天前
多容器共享目录权限踩坑记
linux·ubuntu·共享目录·linux权限·docker 容器化部署
缘友一世3 天前
银河护卫队在steam(linux Proton GE-Proton10-34)上启动无窗口问题修复
linux·ubuntu·steam·proton
刘胡子大叔3 天前
repo 与 index:站点目录该怎么切
ubuntu·php
zhangrelay4 天前
用ROS2Lyrical实验报告册思路重做蓝桥云课ROS1实验并改进
linux·笔记·学习·ubuntu·机器人