第31章:网络诊断工具
23 分钟阅读
第三十一章:网络诊断工具
想象一下:你的网站打不开了、SSH连不上了、网页加载转圈了……这时候怎么办?
答案是:网络诊断工具。
网络诊断就像医生的听诊器——先确定"病在哪",再决定"怎么治"。ping看通不通,traceroute看路径,nslookup/dig看DNS,netstat/ss看端口,tcpdump抓包分析……每一把扳手都有它的用武之地。
本章配套视频:你的服务器突然失联?别慌,先ping一下,看看是网络的问题还是你的问题。
31.1 ping 命令:网络连通性测试
ping是网络诊断的"万金油",几乎所有人认识网络的第一个命令就是ping。它的原理很简单:发送ICMP Echo Request包,对方回复ICMP Echo Response包,通过往返时间判断网络是否通畅。
31.1.1 ping -c 4:次数
默认情况下,ping会一直运行下去(Ctrl+C停止)。用-c参数指定发送次数。
| |
| |
输出解读:
icmp_seq=1,2,3,4:ICMP序列号,每个包一个编号ttl=118:生存时间(Time To Live),是剩余值,每经过一个路由器减1,防止数据包在网络中无限循环。TTL收到时是118,说明这个包在到达你之前已经被沿途路由器共减去了一些(常见初始值有64、128、255)time=12.3 ms:往返延迟,12.3毫秒0% packet loss:丢包率,0%表示4个包全部收到,网络畅通rtt min/avg/max/mdev:往返时间统计(最小/平均/最大/标准差)
别踩这个坑:很多人以为"用初始值减去收到的 TTL 就是跳数",但初始 TTL 到底是 64、128 还是 255,并不确定(取决于对端操作系统和对方是否修改过)。所以只能反推一个大致范围:如果对端初始值为 64,收到 118 是不可能的(说明初始值至少 128),此时大约经过了 10 跳。想准确知道跳数,请用
traceroute或mtr,不要靠 TTL 猜。
31.1.2 ping -i 0.2:间隔
-i参数控制ping包的发送间隔(秒)。
| |
权限提示:Linux 下普通用户允许的最小间隔就是
0.2秒,再小会报ping: cannot flood; minimal interval allowed for user is 200ms。只有 root 才能用-f(flood)或更小的-i。另外第一次 ping 里-c 4默认发完约 3 秒(间隔 1 秒),不要拿time 3005ms当延迟。
| |
常见ping结果分析:
判断时要综合丢包率和往返延迟(注意这里的 time 是上一步的 time= 字段,即单次 RTT,不是统计里那个 time 3005ms):
| 丢包率 | RTT | 可能原因 |
|---|---|---|
| 0% | time<1ms | 极低延迟,本地网络或同机房通信 |
| 0% | time=10-50ms | 正常的互联网通信 |
| 0% | time>200ms | 跨国链路或卫星通信,延迟偏高 |
| 部分丢包 | 时快时慢 | 链路拥塞,或对端限速了 ICMP |
| 100% | 无正常回包 | 目标不可达、被防火墙拦截,或对端禁 ping |
| 100% | 报 Name or service not known | 不是网络不通,而是域名解析失败,先查 DNS |
有趣的现象:你ping一个网站,发现丢包率5%。这时候不要急着骂网络质量差——很多服务器故意限制ICMP包速率,防止ping攻击。ping不通不等于网站打不开。
🎯 实际建议:判断网站是否正常,最好用
curl -I http://网站地址看HTTP响应,而不是单纯依赖ping。
31.2 traceroute 命令:路由追踪
traceroute(Linux)/ tracert(Windows)用于追踪数据包从你的电脑到目标主机经过的所有路由节点。
如果说ping是问"你在不在",traceroute就是问"你去那儿的路上都经过了谁"。
31.2.1 traceroute 目标
| |
| |
每一行代表一个"跳"(hop),即经过的一个路由器。
1, 2, 3, 4, 5:跳数序号- 中间的IP:经过的路由器IP
- 最后一行
220.181.38.149:目标服务器IP - 每行三个时间:三次测量的延迟
关键发现:
- 如果某个IP之后没有更多跳,说明目标已经到达
- 如果某个跳出现
* * *(超时),说明那个路由器不返回探测超时消息——可能是防火墙拦截,也可能只是该路由器配置为不回 ICMP 超时。只要后面的跳和最终目标能到达,这一跳的*就不用担心 - 如果某跳延迟突然飙升,说明那一段网络拥塞或路由不佳
判断技巧:如果是"中间的某一跳全是
*,但从这一跳往后一直到目标都正常",那通常不是故障;真正要警惕的是"从某一跳开始后面全部*,且到不了目标"。
31.2.2 traceroute -I:ICMP
默认情况下,Linux的traceroute使用UDP数据包,而Windows的tracert使用ICMP。
-I参数让traceroute使用ICMP包(和Windows的tracert一样)。
| |
为什么都加了 sudo:
-I(ICMP)和-T(TCP SYN)都需要原始套接字权限,普通用户直接跑会报Operation not permitted。默认的 UDP 方式普通用户即可。
部分系统没有 traceroute:Debian/Ubuntu 用
sudo apt install traceroute,RHEL 系用sudo dnf install traceroute。也可以直接用mtr,它自带 traceroute 功能。
traceroute的原理:它发送TTL=1的包,第一个路由器收到后TTL减为0,返回超时消息——这样你就知道了第一跳;然后发送TTL=2的包,知道第二跳……依此类推,直到到达目标。
31.3 mtr 命令:ping 和 traceroute 结合
mtr(My Traceroute)是ping和traceroute的合体金刚,一边持续ping,一边绘制路由路径,实时显示网络质量统计。
31.3.1 mtr 目标
| |
| |
输出解读:
- 每一行是一个跳(路由节点)
Loss%:丢包率Last:最近一次延迟Avg:平均延迟Best:最佳延迟Wrst:最差延迟StDev:标准差(数值越大说明延迟波动越大)
注意列的差异:交互模式(直接运行
mtr)的列是Loss% Last Avg Best Wrst StDev;-r报告模式多了一列Snt(本跳已发送的探测包数),顺序是Loss% Snt Last Avg Wrst StDev。列名对不上时以实际表头为准。
从上面结果看,第4跳(220.181.0.1)有10%的丢包率,但第5跳又恢复到0%——这种"中间跳丢包、后面正常"通常是该路由器对探测包的响应限速,不代表真实故障。真正要关注的是最后一跳(目标)的丢包率,它才反映端到端的真实质量。
31.3.2 mtr -r:报告模式
-r参数生成一份文本报告,适合保存或发送给别人分析。
| |
| |
Snt是"已发送探测包数"(-c 10所以是10),Loss%就是基于它算出来的。注意:-r报告会一次性发完指定次数,比交互模式更适合放进脚本存档、发给同事分析。
31.4 nslookup 命令:DNS 查询
nslookup(Name Server Lookup)是DNS查询的老前辈,功能简单但实用。它的"继任者"是dig,但nslookup在Windows上原生自带,所以依然广泛使用。
31.4.1 nslookup 域名
| |
| |
解读:
Server: 8.8.8.8:当前使用的DNS服务器是Google DNSNon-authoritative answer:非权威应答(说明这个答案是DNS服务器缓存返回的,不是baidu.com的权威DNS服务器直接回答的)canonical name = www.a.shifen.com.:www.baidu.com是别名(CNAME),真正解析到的是www.a.shifen.comwww.a.shifen.com有两个IP:220.181.38.149和220.181.38.150——百度做了负载均衡(同一域名返回多个IP,客户端轮流使用)
示例数据仅作格式示意:域名对应的 IP、CNAME 目标、TTL 都会随时间变化,你自己执行时得到的结果和这里不同是正常的,重点是看懂输出结构。
31.4.2 nslookup -type=MX 域名
-type参数可以查询特定类型的DNS记录。
| |
| |
mail exchanger = 10:优先级是10,数字越小优先级越高。发送邮件时优先尝试10号服务器,如果10号不可用再试20号。
别漏掉结尾的点:
mx.mail.baidu.com.末尾这个.表示它是完全限定域名(FQDN)。如果配置 DNS 时漏掉这个点,解析器可能会自作主张拼上当前域名,变成mx.mail.baidu.com.example.com,导致邮件发不出去。
常见DNS记录类型:
| 类型 | 说明 | 用途 |
|---|---|---|
| A | IPv4地址 | 域名指向IPv4地址 |
| AAAA | IPv6地址 | 域名指向IPv6地址 |
| MX | 邮件交换 | 指定邮件服务器 |
| CNAME | 别名 | 域名别名 |
| NS | 域名服务器 | 指定该域名的DNS服务器 |
| TXT | 文本记录 | SPF、DKIM 等邮件验证 |
| PTR | 反向解析 | 由 IP 反查域名 |
| SOA | 起始授权记录 | 标明该域名的权威 DNS 及其序列号 |
| CAA | 证书颁发授权 | 限定哪些 CA 可以为该域名签发证书 |
31.5 dig 命令:详细 DNS 查询
dig(Domain Information Groper)是DNS查询的"瑞士军刀",比nslookup功能更强大、输出更详细。DNS工程师必备工具。
31.5.1 dig 域名
| |
| |
输出解读:
HEADER里的ANSWER: 3:ANSWER 段共 3 条记录(1 条 CNAME + 2 条 A)QUESTION SECTION:查询的问题(查询www.baidu.com的A记录)ANSWER SECTION:查询结果(www.baidu.com是CNAME别名,指向www.a.shifen.com,后者有两个A记录IP)- 记录行里的
600:TTL,缓存生存时间600秒(www.baidu.com. 600 IN CNAME ...里的 600 就是它) Query time: 12 msec:查询耗时12毫秒SERVER: 8.8.8.8#53:使用的DNS服务器
示例数据仅作示意:应答记录、CNAME 目标、TTL 都会变化,重点理解各分段的含义。
31.5.2 dig +trace:递归查询
+trace参数从根域名服务器开始,完整展示DNS递归查询的整个过程——和traceroute类似,但针对DNS。
| |
| |
可以看到DNS查询的完整链路:根服务器 → .com顶级域服务器 → baidu.com权威DNS → 最终IP。
+trace 的特别之处:它会绕过
/etc/resolv.conf里配置的 DNS 服务器,从根服务器开始一级一级自己问,所以看到的是"真实解析链路",而不是本机 DNS 缓存或转发器给出的结果。排查"某个上游 DNS 返回了错误 IP"这类问题时特别有用。
dig的其他常用参数:
| |
31.6 host 命令:简单的 DNS 查询
host是DNS查询的"简化版",输出比dig简洁,适合快速查看。
| |
| |
| |
| |
更简洁的用法:
host -t MX baidu.com查邮件记录,host -t NS baidu.com查域名服务器,host -v显示和 dig 一样详细的信息。想脚本里取值,用host www.baidu.com | awk '{print $NF}'或直接换dig +short。
31.7 netstat 命令:网络状态统计
netstat(Network Statistics)是查看网络连接、路由表、接口统计的经典工具。它属于 net-tools 软件包,较新的发行版默认不再预装(如 Ubuntu 20.04+、较新的 RHEL/CentOS)。如果执行时报 netstat: command not found,优先直接用下一节的 ss;确实需要 netstat 时再安装:
| |
netstat已被官方标记为废弃(deprecated),维护处于停滞状态,新脚本建议一律用ss。
31.7.1 netstat -tulpn:监听端口
查看本机正在监听的TCP和UDP端口(哪些服务在等着接受连接)。
| |
| |
参数说明:
-t:TCP连接-u:UDP连接-l:仅显示监听状态的socket-p:显示占用端口的进程(通常需要 root 才能看到其他用户的 PID/Program name,非 root 执行对别人的进程只会显示-)-n:显示数字端口(不解析服务名)
解读常见端口监听状态:
| 端口 | 服务 | 说明 |
|---|---|---|
| 22 | sshd | SSH服务器,等待远程登录 |
| 80 | apache2/nginx | Web服务器 |
| 443 | apache2/nginx | HTTPS服务器 |
| 3306 | mysqld | MySQL数据库 |
| 631 | cupsd | 打印机服务 |
| 68 | dhclient | DHCP客户端 |
31.7.2 netstat -an:所有连接
查看所有连接(包括已建立的连接),-a是all,-n是数字形式显示。
| |
| |
输出很长时用
netstat -an | grep ESTABLISHED、netstat -anp | grep :3306之类过滤。LISTEN行是服务端在等连接,ESTABLISHED行是已经建立的连接(每一行对应一条连接,本机看到的"本地地址:端口"和"对端地址:端口"是成对出现的)。
连接状态(State)说明:
| 状态 | 含义 |
|---|---|
| LISTEN | 等待连接(服务端) |
| ESTABLISHED | 已建立连接(正在通信) |
| TIME_WAIT | 等待处理(连接已关闭但还有延迟包) |
| CLOSE_WAIT | 对方关闭了连接,本地还没关 |
| SYN_SENT | 正在发起连接(客户端) |
| SYN_RECEIVED | 收到连接请求,正在握手 |
31.7.3 netstat -r:路由表
| |
| |
和ip route输出的内容一样,只是格式不同。
31.8 ss 命令:Socket Statistics
ss(Socket Statistics)是netstat的现代替代品,来自iproute2工具包,性能更高,信息更详细。
31.8.1 ss -tulpn
查看监听端口,用法类似netstat -tulpn,但更快。
| |
| |
31.8.2 ss -s:统计摘要
-s参数显示各类 socket 的统计摘要(注意:它给的是"各类连接各有多少条"的汇总数字,不会列出具体连接。想列连接请用 ss -tunap)。排查 TIME_WAIT 太多、连接数异常增长这类问题时用它,一眼能看出量级。
| |
| |
解读:
Total: 138:当前总的 socket 数TCP: 12 (estab 1, ... timewait 2):TCP 共 12 条,其中已建立 1 条、TIME_WAIT 2 条- 下半部分按
Transport分类,分别统计 IPv4(IP)和 IPv6 的数量
TIME_WAIT 多是不是故障? 不一定。它表示"主动关闭方"等 2MSL(约 60 秒)以确认最后的包已被对方收到,是 TCP 的正常设计。只有当它暴涨到上万条、耗尽本地端口时才算问题(多见于短连接跑得特别快的服务,比如反向代理)。
ss的高级过滤:
| |
-p显示进程同样需要 root 权限;过滤表达式一定要用单引号包起来,否则( sport = :22 )里的括号和空格会被 shell 抢先解释。
31.9 lsof 命令:查看端口占用
lsof(List Open Files)可以查看所有打开的文件和socket,网络连接也是一种"文件"。
31.9.1 lsof -i :80
查看哪个进程占用了80端口。
| |
| |
输出解读:
COMMAND:进程名(这里是 nginx)PID:进程IDUSER:运行用户TYPE:socket类型(IPv4/IPv6)STATE:状态(LISTEN监听)
一个端口只能被一个监听进程占用:同一时刻同一 IP:端口上通常只有一个服务在 LISTEN。如果你看到两个不同的服务(比如 nginx 和 apache2)都"占着 80",多半是先启动了 nginx、后来 apache2 启动失败——真实占用的是先启动的那个。同一个服务出现多行(如上例中的
root主进程和www-dataworker)是正常的:它们通过 fork 共享同一个监听 socket。想确认到底是哪个进程真正在监听,用sudo ss -tlpn 'sport = :80'最直接。
31.9.2 lsof -p PID
查看指定进程打开了哪些文件/socket。
| |
| |
lsof的条件默认是"或":写lsof -i -u www-data会列出"所有网络连接"加上“www-data 打开的所有文件”(两条条件是 OR)。要表达"既属于 www-data、又要是网络连接",必须加-a(AND)写成lsof -a -i -u www-data。这是 lsof 最常见的一个坑。
31.10 nc/netcat 命令:网络瑞士军刀
nc(netcat)是网络工具中的"瑞士军刀",可以用作端口扫描、连接测试、文件传输、代理等。
31.10.1 nc -zv 主机 端口
测试某个主机的某个端口是否开放(不建立完整连接,只测试)。
| |
| |
-z:zero-I/O模式,只测试连接,不发送数据
-v:verbose,输出详细信息
netcat 有多个"版本",语法并不统一:Ubuntu/Debian 默认装的是 OpenBSD 版(命令名
nc),支持nc -zv 主机 端口和端口范围;而老式的 GNU netcat / nmap 自带的 ncat 对"一次传多个端口"和"范围扫描"的支持各不相同,可能报错或行为不一致。 因此:扫描多个端口或端口范围,最稳妥的是用nmap(nmap -p 22,80,443 192.168.1.1,范围用-p 1-1000),不要依赖nc的范围写法。单端口连通性测试用nc -zv就够了。
31.10.2 nc -l 端口:监听
在一台机器上启动监听,另一台机器连接过来——可以用于简单的聊天或文件传输。
| |
监听写法也不同:OpenBSD 版
nc用nc -l 1234(端口直接跟在-l后);GNU netcat 传统写法是nc -l -p 1234。如果报invalid option或行为异常,先nc -h看它是哪个版本。另外 OpenBSD 版默认在客户端断开后就退出,长时间反复接收要用-k(nc -lk 1234)。
用nc传输文件:
| |
用nc做端口转发(简易代理):
| |
注意这只是"单向"的:上面这条只把客户端发来的数据转发给后端,后端返回的数据不会自动回到客户端。真正的双向转发要用
socat(推荐)或ssh -L,例如socat TCP-LISTEN:8080,fork TCP:192.168.1.1:80。nc的管道写法只能用于临时、简单的场景。
警告:netcat功能强大,但也很危险——它可以用来建立后门。在生产服务器上,如果不需要,请确保nc已卸载或限制访问。
31.11 tcpdump 命令:命令行抓包
tcpdump是Linux下最强大的命令行抓包工具,相当于Wireshark的命令行版。网络工程师用它来"听"网络上的数据包,分析网络问题。
31.11.1 tcpdump -i eth0
抓取eth0网卡上的数据包(需要root权限)。
| |
| |
参数说明:
-i eth0:监听eth0网卡(用tcpdump -D列出所有网卡)-c 20:抓20个包后自动停止-v:verbose,显示更详细的信息
31.11.2 tcpdump -w 文件
将抓到的包保存到文件(.pcap格式),可以用Wireshark打开分析。
| |
-G的真实含义:-G N表示"每 N 秒就把当前文件轮转(rotate)一次,起一个新的文件继续写",不是“抓 N 秒后就停止”。想控制"抓多久就结束",上面两种写法任选其一(-G 300 -W 1或timeout 300)。不加-W时会一直轮转、不断产生新文件,文件越来越多,别忘了清理。 用-w时看不到任何包内容(这是正常的,因为都写进文件了),需要加-v或-U观察进度,或抓完再用 Wireshark /tcpdump -r打开。
常用过滤表达式:
| |
为什么上面那个偏移量写得那么绕:
tcp[20:4]假设 TCP 头正好 20 字节(没有选项)。有 TCP 选项时头部会更长,固定偏移 20 就取错了位置。tcp[((tcp[12] & 0xf0) >> 2):4]先读出"数据偏移"字段算出真实头部长度再定位,才通用。实际工作中通常不折腾这个,直接用-A看内容、或用 Wireshark 过滤。
别忘了
-s0:老版本 tcpdump 默认只抓 68 字节(截断包),分析时看不到完整载荷,加-s0(或-s 262144)抓完整包。新版默认已是抓全包。
31.12 Wireshark:图形化抓包分析
Wireshark是世界上最流行的网络协议分析器,图形界面,操作直观。tcpdump擅长在服务器上抓包,Wireshark擅长在PC上分析抓包结果。
| |
Wireshark的核心功能:
- 实时抓包,边抓边看
- 过滤表达式(比tcpdump更强大)
- 追踪TCP流(Follow TCP Stream)
- 解密HTTPS流量(需要SSLKEYLOGFILE)
- 专家信息分析(自动诊断网络问题)
关于"解密HTTPS":Wireshark 本身不能破解 TLS。它的做法是让浏览器把本次会话的密钥导出到一个文件(环境变量
SSLKEYLOGFILE=~/sslkeys.log),再在 Wireshark 的Preferences → Protocols → TLS里指定该文件。前提是应用支持导出密钥日志(Chrome、Firefox、curl 支持),而且只能解密"你自己机器上、导出了密钥的"那些会话,对别人的流量无效。
抓包权限的安全提醒:把用户加入
wireshark组等价于给了它抓取本机所有网卡流量的权限(包括明文密码、令牌),等于半个 root。只在受信任的个人机器上这么做,服务器上还是用tcpdump按需抓、抓完即删更稳妥。
Wireshark过滤语法示例:
# 只显示HTTP请求
http.request
# 只显示DNS查询
dns
# 只显示TCP RST包(重置连接)
tcp.flags.reset == 1
# 只显示与某个IP相关的包
ip.addr == 192.168.1.100
# 只显示HTTP Host为baidu.com的请求
http.host == "baidu.com"
31.13 iptraf/iftop/nethogs:流量监控
除了抓包,还有一些实时流量监控工具,可以实时查看哪些连接占用了带宽。
iftop:按连接查看实时流量
| |
| |
iftop显示每个连接方向的实时带宽,左边是源IP:端口,右边是目标IP:端口,中间是带宽刻度。
nethogs:按进程查看实时流量
| |
| |
nethogs的好处是能看到哪个进程在占用带宽——有时候带宽跑满了,不知道是谁干的,nethogs一眼就看出来。
iptraf-ng:更全面的流量监控
| |
提供了TCP、UDP、ICMP等各类流量的统计。
iptraf-ng 已比较老旧,不少新版发行版(如 Ubuntu 24.04)的软件源里已经不再打包,安装可能失败。需要"按接口看总流量"时用
nload、bmon(sudo apt install nload bmon);需要在浏览器/终端里看交互式流量图,iftop 和 nethogs 通常够用。
本章小结
本章我们掌握了Linux网络诊断的全套工具:
- ping:测试网络连通性,
-c指定次数,-i指定间隔 - traceroute:追踪路由路径,
-I用ICMP,-T用TCP - mtr:ping和traceroute的结合体,实时统计,
-r生成报告 - nslookup:DNS查询简单版,
-type=MX查邮件记录 - dig:DNS查询详细版,
+trace追踪完整查询路径 - host:DNS查询简化版,输出简洁
- netstat:查看网络状态(连接、端口、路由),
-tulpn查看监听端口。已过时且新系统默认不装,能换就换ss - ss:netstat的现代替代品,更快更详细,
-tulpn看监听、-s看统计、带引号的过滤表达式看指定连接 - lsof:查看进程打开的文件/socket,
-i :端口查占用,多个条件要加-a才是"并且" - nc/netcat:网络瑞士军刀,端口扫描、连接测试、文件传输
- tcpdump:命令行抓包,
-i指定网卡,-w保存文件,-r读取文件 - Wireshark:图形化抓包分析,功能最强大
- iftop/nethogs/nload:实时流量监控工具(按连接/按进程/按接口)
遇到网络问题,建议按这个顺序排查:
- ping:目标通不通?如果报"名称解析失败",说明是 DNS 问题,先跳到第 3 步
- mtr / traceroute:不通或很慢时,看是哪一跳出了问题(关注最后一跳的丢包和延迟)
- nslookup / dig / host:域名解析出来的 IP 对不对
- ss / netstat / lsof:服务端口有没有在正常监听,是哪个进程在监听
- tcpdump / Wireshark:还查不出原因,就抓包看数据到底发出去了没有、有没有被拒绝
一个常见的误区:ping 不通 ≠ 服务有问题。很多服务器出于安全考虑禁用了 ICMP,但 HTTP/SSH 完全正常。判断服务是否可用,用
curl -I http://地址或nc -zv 地址 端口更准确。