系统与运维

Linux 网络排查手册:连通性、丢包、延迟与 DNS 一次讲透

从 ping 不通到慢如爬行、再到域名偶尔解析失败,本文按"链路层→IP→传输→应用"的顺序给出每层该用什么命令、看什么字段,并附随手可跑的对照实验。

作者:巧匠团队·8 分钟阅读·更新于 2026-09-06

先画一条探测路:从本机到对端每一跳

排障最怕没有分层概念。拿到"上不去网"这个症状,先确认是单点还是全链路过不了:本机网卡有没有 IP(ip a)、默认路由是否存在(ip route)、网关能不能 ping 通,再一路往上。每层问题用对应工具,别用 curl 去猜链路丢包。

这里给出从链路到应用的标准命令序列,每步都有明确通过标准:网卡 UP 且有地址、路由存在、网关可达、DNS 能解析、TCP 三次握手成功。哪一步失败,范围就圈到哪一层。

ip a                       # 网卡地址/UP 状态
ip route                   # 默认路由
ping -c 3 192.168.1.1      # 网关
ping -c 3 223.5.5.5        # 公网 IP(阿里 DNS)
dig +short example.com     # 域名解析
curl -vI https://example.com --connect-timeout 5

丢包与延迟:ping 双端 + 关注统计与 ICMP 之外的流量

ping 只测 ICMP,很多运营商会限速或丢弃 ICMP,所以 ping 有轻微丢包很正常;真正要观测的是 TCP 的业务流量。用 ping 时重点看 mdev(抖动)、dup/重复包、TX 端 TXerrors/TXdropped——丢包发生在出口还是对端,注解完全不同。

追到具体链路时用 mtr 逐个跳点看 loss 和 avg,能把它从一个抽象"网络慢"落点成具体某一段路由。TCP 层再用 ss -i 看重传率,对比 id 一致放在 ps 里比对。

ping -c 100 -i 0.5 1.1.1.1 | tail -n 3
mtr -rwbc 50 1.1.1.1
# TCP 重传/丢包视角
ss -it | grep -E "retrans|rto|rtt"
# 网卡出口统计
ethtool -S eth0 | grep -iE "tx_error|tx_dropped|collisions"

传输层卡住:SYN 被丢还是握手超时,用 nc/ss 分诊

当 ping 通但业务连不上,问题多半在端口这一层。先用 ss -ltn 确认端口是否在监听、监听地址是 0.0.0.0 还是只剩回环;很多"端口没通"其实只是服务绑到了 127.0.0.1。再绕开防火墙用 tcping 或 nc 做一次裸的 TCP 探测。

半连接的 SYN 丢包通常指向防火墙或 syncookies;连接能建立但频繁 reset 则可能是 backlog 满了(listen 队列溢出),对应 ss -ltn 下的 Recv-Q 堆积和内核的 tcp_max_syn_backlog。下面给出一轮分诊命令。

ss -ltn | grep -E ":80 |:443 |:3306 "
ss -lnt | awk "! /127.0.0.1/ {print}"  # 排除只回环的服务
nc -vz -w 3 10.0.0.8 3306
# 看 listen 队列是否溢出
ss -lt 'sport = :80' | grep -c SYN-RECV
cat /proc/sys/net/ipv4/tcp_max_syn_backlog

DNS:解析慢、失败、被污染的三种读法

域名问题常表现为"浏览器偶尔打不开"。解析时间用 dig 直接看 query time 和 SRTT,两次查询差异大说明上游 DNS 不稳定;解析失败要区分 NXDOMAIN(真的没有这个域名)和 SERVFAIL(上游出问题或权限不足)。

很多站点的 DNS 坑其实是 search domain 后缀:/etc/resolv.conf 里 options ndots 生效时,`curl good.com` 可能被追加 search 后缀去多查几轮,肉眼看着是慢,实际是查询次数翻倍。用 +trace 能看到完整递归链,用 +short 快速拿 A 记录。

dig +short example.com
dig +trace example.com A
dig example.com | grep -E "Query time|flags:"
nslookup example.com 223.5.5.5
cat /etc/resolv.conf
# 统计每类解析耗时
for d in 223.5.5.5 8.8.8.8 114.114.114.114; do echo "-- $d"; dig +time=2 +tries=1 @$d example.com | grep "Query time"; done

错误示范与修复:别用 iptables -F 给自己挖坑

服务器突然连不上了,第一反应常常是"清空防火墙"。但 iptables -F 只清 filter 表的默认链规则,如果你依赖的是 firewalld/nat 或自定义链,它会留下半吊子状态:INPUT 链空了但 FORWARD 的规则还在,或反向导致本机漂流量。

最稳的做法是明确规则来源:用 systemctl status firewalld 判断是不是 firewalld 在管,若用 ufw 就走 ufw status numbered 逐条查;修改前先备份链规则到文件,改完立刻在另一个终端验证当前会话没被误断,再测业务端口。

# 错误示范:无差别清空惹祸
# iptables -F  # 会清空 filter 现有规则

# 修复对照:先备份再精确操作
iptables-save > /tmp/fw.$(date +%F).bak
# 只对指定链/端口放开,不动其它
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
# 改完立刻验证
ss -lnt | grep :443
curl -sI https://example.com -o /dev/null -w "%{http_code}\n"

验证一套完整链路:tcpdump 抓一把包看握手报文

最后用 tcpdump 收尾最能一锤定音:抓 20 个包看到三条握手(SYN/SYN-ACK/ACK)说明路径和端口都通,问题在上层;只看到 SYN 没回包,问题在防火墙或对端不监听;看到 SYN→ACK 但无后续数据,可能卡在中间设备或 MTU。

抓包时注意 MTU 相关的 DF 报文——大包被分片丢弃常表现为"小请求正常、大响应超时"。验证完随手关掉 tcpdump,别让抓包停在后台喷日志。

sudo tcpdump -i eth0 -n host 10.0.0.8 and tcp port 443 -c 20
sudo tcpdump -i any -n 'tcp[tcpflags] & (tcp-syn) != 0 and host 10.0.0.8' -c 10
# 看 DF 分片
sudo tcpdump -i eth0 -n -e 'and (ip[6] & 0x40)' 2>/dev/null | head

官方参考来源

下方为命令对应的官方权威文档,供你核对最新用法与深入查阅。