1. TLS
我们学过 HTTP 明文,这个TLS 可以当成:同一件事,只是内容被锁进保险箱里了。
之前 curl http://www.example.com 时:
- 连的是 80 端口
- Wireshark 里能直接看到
GET / HTTP/1.1、200 OK
如果改成 https://:
- 连的是 443 端口
- 数据先 加密,再放进 TCP
- Wireshark 看不到 GET 和网页,只能看到 TLS 和 Application Data
HTTP: 明信片,谁都能读
HTTPS: 封信封,里面写了什么抓包看不到
TLS: 就是那只信封和锁
1.1 抓包 + 查看
终端 1:开始抓 443
bash
sudo tcpdump -i any -nn -s 0 -w ~/Desktop/https-beginner.pcap port 443
只抓 443,比抓全部包干净很多。
终端 2:关掉代理,访问 HTTPS
bash
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY
curl -v https://www.example.com
curl 之后会出现一个ip,大概在如下位置:

用Wireshark打开刚刚的这个.pcap包,然后在顶部过滤刚刚你查出来的这个IP。

可以看到如下三个点:
- Protocol 多是 TLS 或 TLSv1.2 / TLSv1.3
- Source/Destination 是你的电脑和 example 服务器来回
- 端口 一边是自己,另一边是 443
总过程为4段:
- No.8--10 TCP 三次握手(先接通 443)
- No.11--20 TLS 握手(商量加密、交换证书、切换密文)
- No.21--34 加密传数据(Application Data,里面是 HTTP)
- No.35--39 TCP 四次挥手(断开连接)
1.2 找 TLS 握手
| 包号 | 过程 |
|---|---|
| 11 | Client Hello:你开始 TLS 握手,声明访问 www.example.com(SNI) |
| 14 | TCP ACK:服务器确认收到 Client Hello |
| 15 | Server Hello + Change Cipher Spec:服务器选定加密方式,并通知后续改用密钥加密 |
| 16--17 | 服务器继续发握手内容(证书、握手结束等,TLS 1.3 中常已加密或打包) |
| 18--19 | 你发 TCP ACK,确认收到服务器握手数据 |
| 20 | Change Cipher Spec:你这边也切换为加密通信,TLS 握手基本完成 |
这一阶段: 在 TCP 之上建立 HTTPS 安全通道,还没传(或刚开始传)业务网页数据。
过滤条件再加一个 tls.handshake 。

直接看Info字段:
| Info | 谁发给谁 | 白话解释 |
|---|---|---|
| Client Hello | 你 → 服务器 | 我想用 HTTPS 连你,我支持这些加密方式 |
| Server Hello | 服务器 → 你 | 好,我们用这一种加密 |
|-----------------------------|---------|-----------------|
| Certificate | 服务器 → 你 | 这是我的证书,证明我是正规网站 |
| Server Hello Done | 服务器 → 你 | 我这边说完了 |
| Client Key Exchange 等 | 你 → 服务器 | 交换密钥(细节可先不管) |
| Change Cipher Spec | 双方 | 后面开始加密 |
| Encrypted Handshake Message | 双方 | 加密的握手收尾 |
Client Hello 包:
SNI 里通常是访问的域名。
含义:虽然 HTTP 还没开始传,但客户端会先告诉服务器「我要访问 www.example.com」。
这是 HTTPS 抓包里少数还能直接看到域名的字段之一。

此时还没有传 HTTP GET,只是在商量怎么加密。
Change Cipher Spec(切换加密)
含义: 通知对方:
从下一刻起,后面数据都用刚商量好的密钥加密
就像双方说好密码后说:好,从现在开始用这套密码说话。
界面上可能写 Version: TLS 1.2 (0x0303),这是兼容写法,你这次整体仍是 TLS 1.3,不用纠结这个显示。
1.3 加密业务数据
| 包号 | 过程 |
|---|---|
| 21、22、23、25、27--30、33、34 | Application Data:加密的 HTTP 请求、响应和网页内容 |
| 24、26、31、32 | TCP ACK:确认上面数据已收到 |
这一阶段: 真正的 HTTPS 访问发生在这里。里面是 GET、200 OK、HTML,但被 TLS 加密,Wireshark 只能显示 Application Data。
1.4 和 HTTP 明文对照
之前学过的 HTTP(80 端口)
bash
TCP 三次握手
↓
明文 HTTP GET(Wireshark 直接看到)
↓
明文 HTTP 200 OK + HTML(Wireshark 直接看到)
↓
TCP 四次挥手
现在的 HTTPS(443 端口)
bash
TCP 三次握手(和 HTTP 一样,还是 TCP)
↓
TLS Client Hello / Server Hello / Certificate...(多出来的 TLS 握手)
↓
TLS Application Data(加密的 GET,看不见)
↓
TLS Application Data(加密的 200 OK + HTML,看不见)
↓
TCP 四次挥手
多出来的就是 TLS 握手 + 全程加密。
2. tcpdump常见命令
1. 基础结构
bash
sudo tcpdump [选项] [过滤表达式]
抓包一般要 sudo。不写过滤表达式 = 抓所有流量(噪音大,初学建议加过滤)。
2. 最常用选项
| 选项 | 含义 | 示例 |
|---|---|---|
-i any |
指定网卡,any 为所有网卡 |
tcpdump -i en0 |
-w 文件.pcap |
保存到文件(给 Wireshark) | -w ~/Desktop/out.pcap |
-r 文件.pcap |
读已有 pcap(不抓新包) | tcpdump -r out.pcap |
-c 数字 |
抓满 N 个包就停 | -c 100 |
-n |
不把 IP 转成主机名 | 输出更快、更干净 |
-nn |
不把 IP、端口转成名字 | 推荐常用 |
打开已存在的 .pcap 包进行查看,如 ping-gateway.pcap 。
步骤 1:终端中 只看 ICMP
bash
tcpdump -r ~/Desktop/ping-gateway.pcap -nn icmp
你应该看到类似:
bash
10.2.73.219 > 10.2.72.1: ICMP echo request
10.2.72.1 > 10.2.73.219: ICMP echo reply
顺便看一下加 -nn 和不加 -nn 的区别。

中间可能夹杂 unreachable 报错,正常。
步骤 2:终端中 只看和网关有关的
bash
tcpdump -r ~/Desktop/ping-gateway.pcap -nn host 10.2.72.1
只保留和 10.2.72.1 有关的包,噪音少很多。
bash
# 出现类似如下结果
reading from PCAP-NG file /Users/liyijun/Desktop/ping-gateway.pcap
13:53:35.444034 IP 10.2.73.219 > 10.2.72.1: ICMP echo request, id 4782, seq 0, length 64
13:53:35.453132 IP 10.2.72.1 > 10.2.73.219: ICMP echo reply, id 4782, seq 0, length 64
13:53:36.449209 IP 10.2.73.219 > 10.2.72.1: ICMP echo request, id 4782, seq 1, length 64
13:53:36.454207 IP 10.2.72.1 > 10.2.73.219: ICMP echo reply, id 4782, seq 1, length 64
13:53:37.454194 IP 10.2.73.219 > 10.2.72.1: ICMP echo request, id 4782, seq 2, length 64
13:53:37.477599 IP 10.2.72.1 > 10.2.73.219: ICMP echo reply, id 4782, seq 2, length 64
13:53:38.456592 IP 10.2.73.219 > 10.2.72.1: ICMP echo request, id 4782, seq 3, length 64
13:53:38.468613 IP 10.2.72.1 > 10.2.73.219: ICMP echo reply, id 4782, seq 3, length 64
在Wireshark中其实就是如下的过滤条件(之前演示过,很好理解):
bash
icmp
ip.addr == 10.2.72.1
icmp && ip.addr == 10.2.72.1
如果要捕捉指定端口 ,在tcpdump里直接使用 port 端口号 就行。
比如打开之前捕捉百度dns解析过程的文件进行演示:
bash
tcpdump -r ~/Desktop/dns-test.pcap -nn port 53
bash
# 结果如下
reading from PCAP-NG file /Users/liyijun/Desktop/dns-test.pcap
15:34:16.634264 IP 10.2.73.219.57470 > 10.2.255.2.53: 8489+ A? www.baidu.com. (31)
15:34:16.648031 IP 10.2.255.2.53 > 10.2.73.219.57470: 8489* 3/0/0 CNAME www.a.shifen.com., A 110.242.69.21, A 110.242.70.57 (138)
但是在Wireshark里不能直接用port字段,需要指定是tcp还是udp,dns是udp,所以要输入的过滤条件是:
bash
udp.port == 53

若tcp也要,那就在顶部同时过滤:
bash
udp.port == 53 || tcp.port == 53
|-----------------------|---------------|------------|
| -v / -vv / -vvv | 更详细输出 | 终端直接看时用 |
| -A | 以 ASCII 显示包内容 | 看明文 HTTP 等 |
| -X | 十六进制 + ASCII | 比 -A 更全 |
| -s 0 | 抓完整包(默认可能截断) | 生产环境建议加上 |
-s 0 是 tcpdump 的抓包长度选项,意思是每个包都完整抓取,不截断。
-s:snaplen,单个包最多抓多少字节0:不限制,抓整包
常见用法:
bash
sudo tcpdump -i any -nn -s 0 -w ~/Desktop/capture.pcap
抓包存文件时习惯加上 -s 0,保证 pcap 里是完整包。读已有文件用 -r 时一般不需要再加 -s 0。
3. 常见抓包组合(可直接复制)
抓所有包,存文件
bash
sudo tcpdump -i any -w ~/Desktop/all.pcap
只抓某种协议的包,如 ICMP(ping)
cpp
sudo tcpdump -i any icmp -w ~/Desktop/ping.pcap
只抓 50 个包( -c 选项后面加数字)
bash
sudo tcpdump -i any -c 50 -w ~/Desktop/test.pcap
终端直接看,不存文件(如 ping )
bash
sudo tcpdump -i any -nn icmp
抓完整包 + 不解析名字
bash
sudo tcpdump -i any -nn -s 0 -w ~/Desktop/full.pcap
4. 过滤表达式(重点)
按主机
和某 IP 有关的所有包(源或目的)
bash
sudo tcpdump -i any host 10.2.72.1
只抓源是该 IP
bash
sudo tcpdump -i any src host 10.2.73.219
只抓目的是该 IP
bash
sudo tcpdump -i any dst host 172.66.147.243
按网段
整个网段
bash
sudo tcpdump -i any net 10.2.73.0/24
按端口
端口 80(HTTP)
bash
sudo tcpdump -i any port 80
端口 443(HTTPS)
bash
sudo tcpdump -i any port 443
源端口 / 目的端口
bash
sudo tcpdump -i any src port 57872
sudo tcpdump -i any dst port 80
按协议
bash
sudo tcpdump -i any tcp
sudo tcpdump -i any udp
sudo tcpdump -i any icmp
组合(与 / 或 / 非)
某 IP 的 TCP
bash
sudo tcpdump -i any host 172.66.147.243 and tcp
80 或 443
bash
sudo tcpdump -i any port 80 or port 443
排除某 IP
bash
sudo tcpdump -i any not host 127.0.0.1
某 IP 的 HTTP(端口80)
bash
sudu tcpdump -i any host 172.12.32.78 and port 80
TCP 标志(进阶)
SYN 包(握手第一步)
sudo tcpdump -i any 'tcptcpflags & tcp-syn != 0'
SYN 且非 ACK(纯 SYN)
sudo tcpdump -i any 'tcptcpflags & tcp-syn != 0 and tcptcpflags & tcp-ack == 0'
5. 读已有 pcap
读文件并过滤
bash
tcpdump -r 文件路径/文件名.pcap port 80
读文件,只看前 20 个
bash
sudo tcpdump -r 文件路径/文件名.pcap -c 20
读文件,ASCII 显示 HTTP
bash
tcpdump -r ~/Desktop/tcp-http.pcap -A port 80
6. tcpdump 与 Wireshark 过滤对照
| 目的 | tcpdump | Wireshark |
|---|---|---|
| 某 IP | host 10.2.72.1 |
ip.addr == 10.2.72.1 |
| 源 IP | src host 10.2.73.219 |
ip.src == 10.2.73.219 |
| 端口 80 | port 80 |
tcp.port == 80 |
| 只要 TCP | tcp |
tcp |
| 只要 ICMP | icmp |
icmp |
| 只要 DNS | port 53 |
dns |
3. Wireshark 常见显示过滤器
显示过滤器只在已经抓好的 pcap 里筛选,不改变抓包内容。语法错了会红色,对了是绿色。
1. 逻辑运算符
| 符号 | 含义 | 示例 |
|---|---|---|
&& 或 and |
并且 | tcp and port 80 |
| ` | 或or` |
|
! 或 not |
非 | not arp |
2. IP 相关
源或目的包含该 IP
bash
ip.addr == 10.2.73.21
源 IP
bash
ip.src == 10.2.73.21
目的 IP
bash
ip.des == 10.2.34.56
某网段(部分版本支持)
bash
ip.addr == 10.2.73.0/24
3. 端口与协议
过滤协议的话直接输入就行:
bash
tcp # 所有 TCP
udp # 所有 UDP
icmp # 所有 ICMP
dns # DNS
http # HTTP(明文)
tls # TLS/HTTPS
过滤端口需要指定协议:
bash
tcp.port == 80 # TCP 端口 80
tcp.port == 443 # HTTPS
tcp.srcport == 57872 # 源端口
tcp.dstport == 80 # 目的端口
udp.port == 53 # DNS 端口
4. TCP 标志(握手 / 挥手 / 异常)
- 含 SYN:tcp.flags.syn == 1
- 含 ACK:tcp.flags.ack == 1
- 含 FIN(挥手):tcp.flags.fin == 1
- RST(连接被拒或重置):tcp.flags.reset == 1
- 纯 SYN(握手第 1 步):tcp.flags.syn == 1 && tcp.flags.ack == 0
- SYN+ACK(握手第 2 步):tcp.flags.syn == 1 && tcp.flags.ack == 1
5. DNS
下面的 qry专门指 query 部分 的字段- 只显示 查询域名里包含 baidu 的 DNS 包:dns.qry.name contains "baidu"
- 只显示 DNS 查询里,域名完全等于 www.example.com 的包:dns.qry.name == "www.example.com"
- 只要 query:dns.flags.response == 0
- 只要 response:dns.flags.response == 1
6. HTTP(明文)
- http
- http.request # 只要请求
- http.response # 只要响应
- 只看请求方法为 GET:http.request.method == "GET"
- Host 头包含 example 的请求或响应:http.host contains "example"

- 只看 HTTP 响应状态码是 200 的包:http.response.code == 200
- 4xx、5xx 错误:http.response.code >= 400
7. HTTPS / TLS
- tls
- Client Hello: tls.handshake.type == 1
- Server Hello:tls.handshake.type == 2
- tcp.port == 443 && tls
8. Wireshark 实用操作(非过滤,但常用)
| 操作 | 作用 |
|---|---|
| 右键包 → Follow → TCP Stream | 看一次 TCP 会话完整内容 |
| 右键包 → Follow → HTTP Stream | 看 HTTP 请求+响应全文 |
| Statistics → Conversations | 看哪些 IP/端口通信最多 |
| 点击包 → Response in frame / Request in frame | 跳到配对的请求/响应 |
4. 按场景选命令(速查)
| 场景 | tcpdump 抓包 | Wireshark 查看 |
|---|---|---|
| ping 网关 | tcpdump -i any icmp -w ping.pcap |
icmp && ip.addr == 网关IP |
| DNS 查询 | tcpdump -i any port 53 -w dns.pcap |
dns |
| HTTP 访问 | tcpdump -i any port 80 -w http.pcap |
tcp.port == 80 然后 http |
| HTTPS 访问 | tcpdump -i any port 443 -w https.pcap |
tcp.port == 443 然后 tls |
| 排查连不上 | tcpdump -i any host 目标IP -w fail.pcap |
tcp.flags.reset == 1 |
| 减少噪音 | 抓包时就加 host / port |
!ip.addr == 127.0.0.1 |