【学习笔记】tcpdump+Wireshark抓包(3)

这是一个异常包与排障实操博客。

我们会按「先认异常长什么样 → 再自己制造 → 最后用固定套路排障」一步一步来。每关都是:抓包 → 产生问题 → Wireshark 里找 → 得出结论。

排障总口诀(先记住)

打不开 / 很慢 / 不对 → 从上到下查四层:

  1. DNS 域名有没有解析成 IP?
  2. TCP 连没连上?有没有 RST、重传?
  3. TLS HTTPS 握手成没成?(若是 https)
  4. HTTP 状态码是不是 200?

1. 连接被拒绝

本机或对方 端口上没有程序在监听,TCP 会直接拒绝,常见 RST。

1.1 实操

终端 1:

bash 复制代码
sudo tcpdump -i any -nn -s 0 -w ~/Desktop/fail-refused.pcap

终端 2:

bash 复制代码
curl -v http://127.0.0.1:9999

让本机去连 本机 127.0.0.1 的 9999 端口, 9999 端口一般没人监听,所以系统会 拒绝连接。

终端2 会报错:Connection refused(连接被拒绝)。终端 1: Ctrl+C 停抓。

1.2 Wireshark 里看包

过滤器:tcp.flags.reset == 1 或 tcp.port == 9999

No.21 --- 第一次 SYN(我们自己想连)

复制代码
50842 → 9999 [SYN]

你的 curl 从临时端口 50842 向 9999 发 SYN:「有人在 9999 吗?我想连。」

这是 三次握手的第一步,和正常访问网站一样。


No.22 --- SYN 重传(黑色行)

复制代码
[TCP Retransmission] 50842 → 9999 [SYN]

第一次 SYN 没收到正常回复,TCP 又发了一次 SYN。

Wireshark 标成 Retransmission(重传),说明:等了一下,还是没连上。

注意:这里重传的是 SYN,不是 已经连上后的数据重传,含义是 「连都连不上,我在重试拨号」。


No.23 --- RST, ACK(红色行,关键)

复制代码
9999 → 50842 [RST, ACK]

9999 端口一侧(实际是内核协议栈)回复:RST + ACK。

RST(Reset) 表示:这个连接不行,直接重置/拒绝。

对 SYN 收到 RST 的典型含义:

主机在,但这个端口没有服务在监听 → Connection refused

不是「网络不通」,而是 「端口没人接」。

Wireshark 用 红色 标 RST,表示异常终止。


No.24 --- 又一次 RST, ACK

复制代码
9999 → 50842 [RST, ACK]

多半是对 No.22 重传的 SYN 再回一次 RST。

同一个拒绝,可能出现 2 次,正常。

1.3 总结

为什么会出现 Connection refused?

问题 答案
网通不通? 通,127.0.0.1 是本机
DNS? 不涉及,直接用 IP
原因? 9999 端口没有进程 listen
谁回的 RST? 操作系统 TCP 栈(没有应用接 SYN 时由内核回 RST)

常见真实场景:

  • 服务没启动
  • 服务监听了别的端口(如 8080 不是 9999)
  • 防火墙较少在本机 loopback 上拦 refused(一般是 RST)

1.3.1 和「超时」的区别

Connection refused 超时 / 一直重传
响应速度 很快(毫秒级) 很慢(几秒)
典型包 RST 多次 SYN,没有 RST,也没有 SYN+ACK
含义 端口没人监听 包到不了或被中间设备丢掉
curl Connection refused Connection timed out

图中的这次是 快 + RST → 典型的 refused。

1.3.2 排障结论怎么写

① 停在哪一层:TCP 层(没到 HTTP)

② 证据:SYN 后有 RST,ACK,无 SYN+ACK

③ 原因:目标端口 9999 无服务监听,应检查进程是否启动、端口是否配置正确

2. DNS 解析失败

域名根本 解析不出 IP,后面 TCP、HTTP 都不会正常发生。

2.1 实操

终端 1:

复制代码
sudo tcpdump -i any -nn -s 0 -w ~/Desktop/fail-dns.pcap port 53

终端 2:

复制代码
nslookup this-domain-does-not-exist-12345.com

终端 1: 停抓。

2.2 Wireshark看包

在 Wireshark 打开,.pcap 文件,过滤可输入 udp.port == 53 或 dns.qry.name contains "does-not-exist" ,我这里就不过滤了,现象如下。

这张图,一共 4 个包,前 2 个是我的 Cursor 后台正常 DNS,后 2 个才是刚刚故意造的 DNS 解析失败的包,正好放在一起可以对比一下DNS解析 正确 和 失败 的情况。

No.1 --- DNS 查询(Cursor,成功案例)

字段 内容
Source 10.2.73.219(你的电脑)
Destination 10.2.255.2(DNS 服务器)
Info Standard query 0x73a6 A api2.cursor.sh

含义: 你的电脑向 DNS 问:api2.cursor.sh 的 IPv4(A 记录)是多少?

0x73a6 是这次查询的编号,用来和回复配对。

这是 Cursor 编辑器 在后台查域名,不是你 nslookup 的那次,但格式和正常 DNS 查询一样。


No.2 --- DNS 响应(Cursor,解析成功)

字段 内容
Source 10.2.255.2(DNS 服务器)
Destination 10.2.73.219(你的电脑)
Info Standard query response 0x73a6 ... CNAME api2geo.cursor.sh ...

含义: DNS 回答编号 0x73a6 的查询:api2.cursor.sh 是别名(CNAME),指向 api2geo.cursor.sh 等,并带上 IP。

结果:解析成功。 有 query 就有 response,且没有 "No such name"。


No.3 --- DNS 查询(你造的失败案例)

字段 内容
Source 10.2.73.219
Destination 10.2.255.2
Info Standard query 0x6ab5 A this-domain-does-not-exist-12345.com

含义: 你执行 nslookup 不存在的域名时,电脑问 DNS:这个假域名 IP 是多少?

编号是 0x6ab5(和 No.1 的 0x73a6 不同,是另一次查询)。

方向: 你 → DNS,和 No.1 一样,是 query(提问)。


No.4 --- DNS 响应(解析失败,重点)

字段 内容
Source 10.2.255.2
Destination 10.2.73.219
Info Standard query response 0x6ab5 No such name ...

含义: DNS 回答 0x6ab5:No such name(没有这个名字)。

在 DNS 里这叫 NXDOMAIN(Non-Existent Domain):

域名在 DNS 系统里不存在,解析失败。

注意:

  • 不是 DNS 服务器挂了(服务器正常回了包)
  • 不是网络不通(有 query 也有 response)
  • 是 这个域名本身不存在

终端 nslookup 通常会显示 NXDOMAINcan't find

2.3 总结:

对比 No.2(成功) No.4(失败)
查询 ID 0x73a6 0x6ab5
域名 api2.cursor.sh this-domain-does-not-exist-12345.com
Info 关键词 CNAME、A 记录(有 IP) No such name
结果 解析成功 NXDOMAIN,解析失败
后面 TCP 可以连该 IP 不会有 向该域名的正常 TCP

2.3.1 四个包串成两条线

线 1(Cursor,正常):

线 2(你的测试,失败):

2.3.2 排障时怎么写结论

针对 No.3 + No.4:

① 停在哪一层:DNS 层

② 证据:有 query 和 response,但 response 里是 No such name(NXDOMAIN)

③ 原因:域名不存在或写错,不是 TCP/HTTP 问题

3. 重传

快重传和超时重传都是 TCP 发现数据可能丢了之后,再发一遍 的机制。在 Wireshark 里能直接看到,但要 先有过丢包或迟迟收不到 ACK 的场景,下面分 怎么认 和 怎么抓 两部分说。

3.1 两种重传有什么区别

类型 什么时候发生 Wireshark 常见标记
超时重传 等 ACK 超过一定时间(RTO),还没收到 TCP Retransmission
快重传 连续收到 3 个重复 ACK(Dup ACK) 后立刻重传 先 TCP Dup ACK,再 TCP Fast Retransmission

超时重传: 发数据 → 等很久没 ACK → 再发一次(慢)

快重传: 发数据 → 对方连发 3 个相同 Ack → 马上补发丢失的那段(快)

你 Connection refused 里 No.22 的 SYN 重传,属于 超时重传的一种(等 SYN+ACK 超时,重发 SYN),只是发生在 建连阶段,不是传 HTTP 数据时。


3.2 Wireshark 里用什么过滤器

打开 pcap 后,在顶部试这些(变绿就对了):

所有 TCP 重传(含超时重传、快重传、SYN 重传):

复制代码
tcp.analysis.retransmission

只要 快重传:

复制代码
tcp.analysis.fast_retransmission

重复 ACK(快重传的前兆):

cpp 复制代码
tcp.analysis.duplicate_ack

三种异常一起看:

cpp 复制代码
tcp.analysis.duplicate_ack || tcp.analysis.fast_retransmission || tcp.analysis.retransmission

Wireshark 推断 可能有段丢失(常和重传一起出现):

cpp 复制代码
tcp.analysis.lost_segment

3.3 超时重传过程

3.3.1 典型过程

  • 你 → 目标 SYN 第一次拨号
  • 你 → 目标 TCP Retransmission SYN 等不到回复,超时后再拨
  • 目标 → 你 RST, ACK 被拒绝(refused 场景)

或 一直没人回 时:

SYN

TCP Retransmission SYN

TCP Retransmission SYN

TCP Retransmission SYN

... 多次后 curl 才 Timeout

3.3.2 数据阶段的超时重传

PSH, ACK Seq=100 发数据

... 等很久,没收到 Ack ...

TCP Retransmission Seq=100 同一序号再发一次

认法: 同一个 Seq 出现两次及以上,第二次标 Retransmission,且中间 没有 先出现 3 个 Dup ACK。


3.4 快重传过程

3.4.1 典型顺序(传数据过程中丢了一包)

  1. 正常传包:Seq=1, 100, 200, 300 ...
  2. 假设 Seq=200 那段丢了
  3. 对方收到 300,发现缺 200,会反复发:Ack=200(我要 200 之后的数据)
  4. Wireshark 标:TCP Dup ACK #1、#2、#3(Ack 号相同)
  5. 你这边连收 3 个 Dup ACK 后:TCP Fast Retransmission Seq=200 立刻补发 200,不等超时

3.4.2 Info 列大概会看到

... ACK Ack=200

... TCP Dup ACK #1

... TCP Dup ACK #2

... TCP Dup ACK #3

... TCP Fast Retransmission Seq=200

认法: 先有 至少 3 个 Dup ACK,紧接着 Fast Retransmission,且重传的 Seq 和丢的那段一致。


3.5 对照表:在图上怎么读

你想看 过滤器 看什么
所有重传 tcp.analysis.retransmission Info 里 Retransmission
快重传 tcp.analysis.fast_retransmission 紧跟 Dup ACK 之后
重复 ACK tcp.analysis.duplicate_ack 同一 Ack 连出现 3 次
SYN 超时重传 tcp.flags.syn == 1 多个 SYN,Seq 相同
某次连接 ip.addr == x && tcp.port == y 再加上面过滤器 缩小范围

4. HTTP 层错误

连接建好了,但 HTTP 状态码不是 2xx。

4.1 实操

练的 HTTP 404 场景,属于 应用层错误:网络和连接都正常,但我们故意要一个不存在的页面。

终端 1:

bash 复制代码
sudo tcpdump -i any -nn -s 0 -w ~/Desktop/fail-http404.pcap port 80

终端 2:

bash 复制代码
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY

curl -v http://www.example.com/this-page-does-not-exist-404

终端 1: 停抓,终端2这里会出现一个ip,过滤的时候用这个ip。

4.2 Wireshark 里看包

过滤部分输入 http 或 http.response.code >= 400,或者是看整个过程就用 ip.addr == 172.66.147.243(前面出现过的),就能看到 404 Not Found。

看整个过程,关注Info字段:

  • No.5--7 TCP 三次握手 接通 80 端口
  • No.8 HTTP GET 要 /this-page-does-not-exist-404
  • No.9 TCP ACK 服务器确认收到请求
  • No.10 服务器发数据 带 404 页面内容
  • No.11 HTTP 404 Not Found 应用层报错:页面不存在
  • No.12 TCP ACK 你确认收到响应
  • No.13--15 TCP 四次挥手 断开连接

4.3 总结

4.3.1 和 Connection refused、DNS 失败对比

阶段 你这次 404
DNS 已成功(否则不会有 172.66.147.243)
TCP No.5--7 握手成功
HTTP No.8 请求发出,No.11 返回 404
结论 应用层 URL 错,不是网络层连不上

4.3.2 常见 HTTP 错误码(了解)

状态码 含义
200 成功
404 页面/路径不存在
403 禁止访问(权限)
500 服务器内部错误
502/503 网关错误 / 服务不可用

过滤器:http.response.code >= 400

可看所有 4xx、5xx 错误响应。

4.3.3 结论模板

① 停在哪一层:HTTP 层

② 证据:TCP 握手完整,有 GET,响应为 404 Not Found

③ 原因:请求路径不存在,检查 URL 是否正确

5. HTTPS / TLS 握手失败

TCP 443 通了,但 TLS 握手没完成,看不到正常 Application Data。

常见情况(了解即可)

  • 证书错误(curl 会报错)
  • 用 HTTP 去连 HTTPS 端口(协议不对)
  • 中间设备劫持

终端 1:

bash 复制代码
sudo tcpdump -i any -nn -s 0 -w ~/Desktop/fail-tls.pcap port 443

终端 2:

bash 复制代码
# 故意用明文 HTTP 去连 443(很多服务器会断开或乱码)
curl -v http://www.example.com:443

没有看到handshake环节

怎么认

现象 含义
有 TCP 握手,无正常 TLS TLS 层失败
curl 报 SSL/TLS error 加密协商或证书问题
明文 HTTP 打 443 协议用错

结论模板

TCP 通了,TLS 没建好:查 https/http 是否混用、证书、代理。