[三板斧]使用charles和tcpdump和wireshark的规律
2025/12/30大约 7 分钟
[三板斧]使用charles和tcpdump和wireshark的规律
总结的规律:
注意
- 搞http、https开发工作,一律使用charles(或者Fiddler),方便易用够用,他们是利器
- 遇到tcp被关闭,ssl不正常,奇怪的502从http和https日志找不到逻辑,则使用tcpdump抓包【也可以用tshark】
- wireshark仅用于对tcpdump抓到的.pacp文件包进行可视化排查!
- wireshark的可视化后,有个开挂级别的工具:“专家信息(Expert Info)”他是进行网络问题排查的利器
● 打开方式:Wireshark 菜单栏 → 分析 → 专家信息(或快捷键 Ctrl + Shift + E)
● 按严重等级过滤,快速聚焦 Error / Warning。
● 对应 packet 号可直接跳转,定位问题。
● 多数 warning 可结合 TCP stream 分析上下文。
1、一文熟练tcpdump命令
掌握
1、必备参数
2、必备表达式
就可以解决 90%+的抓包问题了,可以说进入了网络工程师进阶阶段!
注意
注意事项
1、需要sudo权限
2、需要等待tcpdump抓一会儿,你再停止
0.必备参数
| 参数 | |
|---|---|
-D : 显示所有可用网络接口的列表【Device(设备)】 | |
-i <interface>:指定监听的网络接口==【interface,接口】== | -i any:监听所有接口【】-i eth0:仅监听 eth0 接口 |
-c <count>:捕获指定数量的数据包后自动停止==【count,数目】== | 示例:-c 100:仅捕获 100 个数据包 |
-w <file>:将捕获的数据包保存到文件中,以供后续分析==【write(写入)】== | -w demo.pcap:保存为 demo.pcap 文件 |
-w demo:保存为名为 demo 的文件(默认扩展名为 .pcap)这样会生成一个文件叫做【capture_file】只是没有自己加个.pcap后缀而已,你下载下来,其实wireshark还是可以解析出来的 | |
-nn:不将地址和端口号解析为域名或服务名,加快抓包速度,适合调试分析。 | 不加 -nn:IP 地址可能被解析成域名,端口号可能显示为服务名(如 HTTP) |
| 【-nn 看起来就很“反直觉”,其实它背后是一个逐级关闭解析功能的设计】第一个 n: 不做主机名解析(DNS)第二个 n: 不做端口 → 服务名解析(/etc/services) | 加了 -nn:保持原始格式,比如显示 192.168.0.1.443 而不是 example.com.https |
| -n # 不解析 IP → 主机名 | -nn # 不解析 IP,也不解析端口号 |
- tcpdump 虽然强大,但确实有一些常见的“坑点”与误解,尤其是与高层协议过滤、内容解析、精度控制相关。下面是整理的常见误区与示例:
1. 不能直接过滤 HTTP、HTTPS、DNS、MySQL 等高层协议**【只能间接】**
注意
原因:tcpdump 只能过滤数据包的头部信息(L2~L4),不能识别应用层协议字段。
所以,下面这些L2-L4的流量你可以直接过滤
- 使用
tcp、udp、icmp等各种协议 - tcpdump icmp
- tcpdump tcp
- tcpdump udp
:::
- 但是下面的应用层的是错误的!
tcpdump http # ❌ 无效
tcpdump https # ❌ 无效
tcpdump mysql # ❌ 无效
tcpdump dns # ❌ 无效正确方式:使用端口过滤作为代理手段==【这也是为什么学习的时候,让我们背诵端口号的原因!】==
tcpdump -i any -nn port 80 # HTTP
典型的:经常需要将包存在文件中以便将来分析。这些文件叫做PCAP(PEE-cap)【比如.pcap】文件,它们可以被许许多多的工具进行分析,当然也包括tcpdump自己【但是我一般习惯扔给wireshark】
tcpdump port 80 -w myhttp.pacap
tcpdump -i any -nn port 443 # HTTPS
tcpdump -i any -nn port 53 # DNS
tcpdump -i any -nn port 3306 # MySQL2. 不能解密 HTTPS 内容
- 原因:HTTPS 是基于 TLS 加密的,tcpdump 只能抓到加密后的数据,无法查看明文内容。
- 解决方法(仅限你能控制客户端或服务端):
- 在浏览器设置 SSLKEYLOGFILE,配合 Wireshark 解密
- 拿到服务器私钥 + 用 Wireshark 解密(只对 RSA 握手有效,TLS 1.3 已不行)
3. 不能按 URL、Host、User-Agent 等字段过滤
- 原因:这些字段存在于 TCP payload 的 HTTP 数据中,tcpdump 不解析这些字段。
- 解决方法:
- 抓包后用
tcpdump -A或-X显示包内容再用grep过滤
- 抓包后用
tcpdump -i eth0 -nn -A port 80 | grep "User-Agent"4. 不能识别 TCP 流或重组 HTTP 请求
注意
- tcpdump 不自动“拼接”多个 TCP 段,无法还原完整的请求或响应内容。
- 需要使用
Wireshark或tshark来进行 TCP 流重组
5. 不支持复杂表达式逻辑
tcpdump使用的是 BPF 表达式语法,不支持像正则、模糊匹配、包体中搜索特定内容等。- 补救:搭配
grep、awk、sed做简单匹配,但依旧无法代替协议解析器。
总结
| 想做什么 | 能否直接用 tcpdump | 推荐方式 |
|---|---|---|
| 抓 HTTP/HTTPS 请求 | 可以通过端口过滤 | port 80/ port 443 |
| 过滤 URL、Host、User-Agent | ❌ | 抓包后结合 grep过滤,或者扔给wireshark |
| 抓 DNS 查询内容 | 部分可见 | port 53,但仅限明文 DNS |
| 抓 HTTPS 明文内容 | ❌ | 用 Wireshark + 私钥或 SSLKEYLOGFILE |
| 过滤应用名如 “mysql” | ❌ | 用 port 3306等端口匹配 |
| 抓包后还原完整 TCP 流 | ❌ | 用 Wireshark、tshark 分析 |
2、tcpdump常用表达式!
| 表达式类型 | 选项 | 例子 | |
|---|---|---|---|
| 主机过滤 | host、src host、dst host、portrange | tcpdump -nn host 192.168.1.10 | host = “只要沾边就算” |
| tcpdump -nn src host 192.168.1.10 | |||
| tcpdump -nn dst host 192.168.1.10 | |||
| tcpdump -nn portrange 1024-65535 | 只要源端口或目的端口在这个范围内,就匹配 | ||
| 端口过滤 | port、src port、dst port | ||
| 网络过滤 | net 192.168.1.0/24 | IP 网络范围过滤 | |
| 协议过滤 | ip、ip6、arp、tcp、udp、icmp | 注意,只能直接L2-L4层 | 应用层的http之类请使用端口过滤 |
| 逻辑表达式 | and、or、not | ||
| 特定状态的 tcp 包!【学习】 | tcp[tcpflages] | tcpdump -nn 'tcp[13] & 0x12 = 0x02' |
附录1.tcpdump的参数
参考鸟窝的文章即可直接copy:https://colobu.com/2019/07/16/a-tcpdump-tutorial-with-examples/
-X: 同时显示包内容的ascii和十六进制数据-XX: 同上,但是还显示 ethernet header.-D: 显示所有可用网络接口的列表【最常用】-l: 基于行(line)的输出,便于你保存查看,或者交给其它工具分析-q: 使用较少的信息(more quiet),显示较少的协议信息-t: 便于查看的时间戳-tttt: 最容易查看的时间戳-i eth0: 监听eth0网络接口-vv: 更多输出信息 (v越多输出信息越多).-c== : 只捕获 x 个包【count,数目,数到对应的数目】,然后就停止==-s: 定义包获取的字节大小.使用**==-s0==获取完整的包**-S: 打印出绝对sequence numbers-e: 还获取ethernet header-E: 揭秘IPSEC数据
附录2.如果你硬要选择tcpdump抓包https解密【其实很别扭】
原理-✅ 解密步骤总结
- 1.发请求的客户端支持
**SSLKEYLOGFILE**并继承该变量 - 2.使用
tcpdump抓包:
sudo tcpdump -i any -w demo.pcap port 443 and host ark.cn-beijing.volces.com- 3.Wireshark 加载
sslkeys.log进行解密:- Preferences → Protocols → TLS →
(Pre)-Master-Secret log filename设置为~/sslkeys.log
- Preferences → Protocols → TLS →
如果是在本地 chrome 浏览器
步骤 1:关闭你的 chrome 浏览器,否则会出问题
步骤 2:【同一个终端】
设置环境变量
export SSLKEYLOGFILE=~/sslkeys.log步骤 3:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome如果是使用命令行工具(如 curl)
这个方式对抓包 + 解密最稳定。【你可以从 postman 抄 1 个 curl 来】
export SSLKEYLOGFILE=~/sslkeys.log
curl -v https://ark.cn-beijing.volces.com/api/xx注意
总结!!!还是 charles 方便
sudo tcpdump -i any -nn host baidu.com这都抓不了chrome的包,因为这个命令有几个问题和误区:
- 域名过滤无效:tcpdump 过滤表达式里是基于 IP 地址的,
host baidu.com其实是让 tcpdump 解析 baidu.com 的域名,得到一个或多个 IP,然后过滤这些 IP。但是:- Chrome 访问的其实是具体的某个 IP,可能和解析出来的 IP 不完全对应。
- tcpdump 的
host过滤是基于 IP,不能直接用域名做实时过滤。
- HTTPS流量加密,内容不可见
你抓包是能抓到包的,但 HTTPS 是加密的,tcpdump 无法直接解密里面的内容。 - 没有指定端口,可能抓不到想要的流量
Chrome访问baidu,大多是443端口,tcpdump过滤加上端口更准确。 - any接口抓包限制
-i any是抓所有接口,macOS上这个接口捕获的包结构是 PKTAP,可能有兼容性问题。- 建议直接指定具体网络接口,比如
en0。