文章总结: 本文档系统讲解了利用Wireshark和tcpdump进行网络故障排查的实战技术。内容详细对比工具特性,解析BPF过滤语法、TCP握手异常与重传分析、HTTP及TLS流量解读等核心技能。通过丰富的命令示例与排障逻辑,帮助运维人员精准定位连接超时、丢包等问题,具有较高的实操参考价值。 综合评分: 89 文章分类: 网络安全,实战经验,安全工具,安全运营
网络抓包分析实战:Wireshark与tcpdump定位网络故障
点击关注👉 点击关注👉
马哥网络安全
2026年3月1日 17:01 河南
网络抓包分析实战:Wireshark与tcpdump定位网络故障
一、概述
1.1 背景介绍
网络抓包是运维排障的终极手段。当监控告警只告诉你”连接超时”、日志只记录了”connection refused”,而你需要搞清楚到底是客户端没发 SYN、服务端没回 SYN-ACK、还是中间防火墙吞了包——这时候只有抓包能给出确定性答案。
抓包分析的本质是在 OSI 模型的不同层级截获原始数据包,还原网络通信的真实过程。L2 层看 ARP 和 VLAN 标签,L3 层看 IP 路由和 TTL,L4 层看 TCP 握手/重传/窗口,L7 层看 HTTP 请求/DNS 查询。不同层级的故障对应不同的过滤器和分析方法,搞清楚问题在哪一层是高效排障的前提。
抓包工具的底层都依赖 libpcap(Linux)或 WinPcap/Npcap(Windows)。libpcap 通过 BPF(Berkeley Packet Filter)在内核态过滤数据包,只将匹配的包拷贝到用户态,避免了全量抓包对性能的冲击。BPF 过滤器被编译为字节码在内核虚拟机中执行,这也是为什么 tcpdump 的过滤表达式效率远高于抓完再 grep。
三大工具的定位对比:
| 工具 | 使用场景 | 优势 | 局限性 | 适用环境 | | — | — | — | — | — | | tcpdump | 服务器实时抓包、快速定位 | 轻量、无需 GUI、几乎所有 Linux 预装 | 分析能力有限,复杂协议解析弱 | 生产服务器、容器、嵌入式 | | tshark | 服务器端深度分析、自动化脚本 | Wireshark 的全部解析能力、支持管道 | 学习曲线陡峭,内存占用较高 | 服务器、CI/CD 管道 | | Wireshark | 离线深度分析、协议学习 | GUI 直观、协议解析最全、统计功能强 | 需要图形界面,不适合生产服务器 | 运维工作站、开发环境 |
1.2 技术特点
- 零侵入:抓包不修改任何网络配置,不影响现有流量,随时可以开始和停止
- 全栈可见:从以太网帧头到应用层载荷,每个字节都可以检查,不存在日志遗漏的问题
- 精确时间戳:微秒级时间戳精度,可以精确计算 RTT、重传间隔、DNS 解析耗时
- 可回放:pcap 文件可以反复分析,不同工程师可以独立验证结论,适合事后复盘
- BPF 内核过滤:在内核态完成包过滤,高流量环境下也能精准抓取目标流量
1.3 适用场景
- TCP 连接建立失败(SYN 超时、RST、握手异常)
- DNS 解析异常(解析慢、NXDOMAIN、DNS 劫持)
- HTTP/HTTPS 请求调试(状态码异常、TLS 握手失败、证书问题)
- 网络延迟定位(区分客户端延迟、网络延迟、服务端处理延迟)
- 丢包与重传分析(定位丢包发生的位置和原因)
- 安全事件取证(异常流量、端口扫描、数据泄露检测)
1.4 环境要求
| 组件 | 版本要求 | 说明 |
| — | — | — |
| tcpdump | 4.99.x | 大多数 Linux 发行版预装,apt install tcpdump |
| Wireshark | 4.4.x | 工作站安装,用于离线分析 pcap 文件 |
| tshark | 4.4.x | 随 Wireshark 安装,apt install tshark |
| libpcap | 1.10.x | tcpdump 依赖库,通常随 tcpdump 一起安装 |
| 操作系统 | Ubuntu 22.04+ / CentOS 8+ | 内核 4.x+ 支持完整的 BPF 特性 |
| 权限 | root 或 CAP_NET_RAW | 抓包需要原始套接字权限 |
二、详细步骤
2.1 tcpdump 核心用法
2.1.1 基础语法与常用参数
tcpdump 的基本语法:
tcpdump [选项] [BPF过滤表达式]
常用参数速查:
# 核心参数
-i eth0 # 指定网卡,-i any 抓所有网卡
-n # 不解析主机名(IP 直接显示)
-nn # 不解析主机名和端口名(80 而不是 http)
-v / -vv / -vvv # 详细程度递增,-vv 显示 TTL、IP ID 等
-c 100 # 抓 100 个包后自动停止
-s 0 # 抓完整包(默认 262144 字节,够用)
-w capture.pcap # 写入 pcap 文件(后续用 Wireshark 分析)
-r capture.pcap # 读取 pcap 文件
-A # 以 ASCII 显示包内容(适合 HTTP 明文)
-X # 同时以十六进制和 ASCII 显示
-e # 显示链路层头部(MAC 地址、VLAN 标签)
-q # 精简输出,只显示协议摘要
-t # 不显示时间戳
-tttt # 显示完整日期时间格式
2.1.2 BPF 过滤表达式
BPF 过滤器在内核态执行,写好过滤表达式是高效抓包的关键。语法由原语(primitive)和逻辑运算符组成:
# 按主机过滤
tcpdump -nn -i eth0 host 10.0.1.50 # 源或目的 IP
tcpdump -nn -i eth0 src host 10.0.1.50 # 仅源 IP
tcpdump -nn -i eth0 dst host 10.0.1.50 # 仅目的 IP
# 按端口过滤
tcpdump -nn -i eth0 port 443 # 源或目的端口
tcpdump -nn -i eth0 src port 3306 # 仅源端口
tcpdump -nn -i eth0 portrange 8000-8080 # 端口范围
# 按网段过滤
tcpdump -nn -i eth0 net 10.0.1.0/24 # 整个子网
# 按协议过滤
tcpdump -nn -i eth0 tcp # 仅 TCP
tcpdump -nn -i eth0 udp # 仅 UDP
tcpdump -nn -i eth0 icmp # 仅 ICMP
# 组合过滤(and / or / not)
tcpdump -nn -i eth0 host 10.0.1.50 and port 80 # 指定主机的 80 端口
tcpdump -nn -i eth0 tcp and not port 22 # TCP 流量排除 SSH
tcpdump -nn -i eth0 'src 10.0.1.50 and (dst port 80 or dst port 443)' # 括号需要引号
# 按 TCP 标志位过滤(高级用法)
tcpdump -nn -i eth0 'tcp[tcpflags] & (tcp-syn) != 0' # 包含 SYN 的包
tcpdump -nn -i eth0 'tcp[tcpflags] & (tcp-rst) != 0' # 包含 RST 的包
tcpdump -nn -i eth0 'tcp[tcpflags] == tcp-syn' # 仅 SYN(不含 SYN-ACK)
tcpdump -nn -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0' # SYN 或 FIN
# 按包大小过滤
tcpdump -nn -i eth0 'greater 1000' # 大于 1000 字节的包
tcpdump -nn -i eth0 'less 64' # 小于 64 字节的包(可能是空 ACK)
2.1.3 输出格式解读
tcpdump 默认输出格式:
14:32:05.123456 IP 10.0.1.50.45678 > 10.0.1.100.80: Flags [S], seq 1234567890, win 65535, options [mss 1460,sackOK,TS val 123456 ecr 0,nop,wscale 7], length 0
各字段含义:
14:32:05.123456:时间戳(微秒精度)10.0.1.50.45678:源 IP.源端口10.0.1.100.80:目的 IP.目的端口Flags [S]:TCP 标志位,S=SYN, .=ACK, P=PSH, F=FIN, R=RSTseq:序列号win:TCP 窗口大小options:TCP 选项(MSS、SACK、时间戳、窗口缩放)length:载荷长度
常见标志位组合:[S]=SYN, [S.]=SYN-ACK, [.]=ACK, [P.]=PSH-ACK, [F.]=FIN-ACK, [R.]=RST-ACK
2.1.4 保存与读取 pcap 文件
# 抓包写入文件(生产环境推荐加 -c 或 -G 限制)
tcpdump -nn -i eth0 -w /tmp/capture.pcap -c 10000 host 10.0.1.50
# 按时间轮转(每 3600 秒一个文件,保留最近 24 个)
tcpdump -nn -i eth0 -w /tmp/capture_%Y%m%d_%H%M%S.pcap -G 3600 -W 24 port 80
# 按文件大小轮转(每 100MB 一个文件,保留 10 个)
tcpdump -nn -i eth0 -w /tmp/capture.pcap -C 100 -W 10 port 443
# 读取 pcap 文件并过滤
tcpdump -nn -r /tmp/capture.pcap 'tcp[tcpflags] & (tcp-rst) != 0'
tcpdump -nn -r /tmp/capture.pcap -c 20 # 只看前 20 个包
2.2 Wireshark/tshark 分析技巧
2.2.1 tshark 命令行分析
生产服务器没有 GUI,tshark 是 Wireshark 的命令行版本,拥有完整的协议解析能力:
# 实时抓包并显示(类似 tcpdump,但解析更详细)
tshark -i eth0 -f "port 80" -c 50
# 读取 pcap 文件,指定显示过滤器
tshark -r capture.pcap -Y "tcp.analysis.retransmission"
# 只显示特定字段(-T fields + -e)
tshark -r capture.pcap -Y "http.request" \
-T fields -e frame.time -e ip.src -e http.host -e http.request.uri
# 统计 HTTP 响应码分布
tshark -r capture.pcap -Y "http.response" \
-T fields -e http.response.code | sort | uniq -c | sort -rn
# 统计每个 IP 的流量
tshark -r capture.pcap -q -z endpoints,ip
# 统计 TCP 会话
tshark -r capture.pcap -q -z conv,tcp
# 导出为 JSON 格式(便于脚本处理)
tshark -r capture.pcap -Y "dns" -T json > dns_packets.json
2.2.2 捕获过滤器 vs 显示过滤器
这两者语法完全不同,混淆是新手最常犯的错误:
| 对比项 | 捕获过滤器(Capture Filter) | 显示过滤器(Display Filter) |
| — | — | — |
| 语法体系 | BPF 语法(同 tcpdump) | Wireshark 专有语法 |
| 执行位置 | 内核态,抓包时过滤 | 用户态,抓包后过滤 |
| 性能影响 | 减少抓包量,降低 CPU/IO | 不影响抓包量,仅影响显示 |
| 示例:过滤端口 | port 80 | tcp.port == 80 |
| 示例:过滤 IP | host 10.0.1.50 | ip.addr == 10.0.1.50 |
| 示例:过滤协议 | tcp | tcp (碰巧相同) |
| 修改时机 | 抓包前设置,抓包中不可改 | 随时修改,实时生效 |
2.2.3 常用显示过滤器
# TCP 分析类(排障核心)
tcp.analysis.retransmission # TCP 重传
tcp.analysis.fast_retransmission # 快速重传
tcp.analysis.duplicate_ack # 重复 ACK
tcp.analysis.zero_window # 零窗口(接收方缓冲区满)
tcp.analysis.window_update # 窗口更新
tcp.analysis.reset # RST 包
tcp.analysis.lost_segment # 丢包(序列号跳跃)
tcp.analysis.out_of_order # 乱序包
# HTTP 分析
http.request.method == "POST" # POST 请求
http.response.code >= 400 # 4xx/5xx 错误
http.response.code == 502 # 502 Bad Gateway
http.time > 1 # 响应时间超过 1 秒
# DNS 分析
dns.flags.rcode != 0 # DNS 查询失败
dns.qry.name contains "example.com" # 查询特定域名
dns.time > 0.5 # DNS 响应超过 500ms
# TLS 分析
tls.handshake.type == 1 # Client Hello
tls.handshake.type == 2 # Server Hello
tls.alert_message # TLS 告警
2.2.4 统计功能
Wireshark 的统计功能在排障时非常有用,tshark 也能通过 -z 参数实现:
# 协议层级统计(快速了解流量构成)
tshark -r capture.pcap -q -z io,phs
# IO 图表数据(每秒包数/字节数)
tshark -r capture.pcap -q -z io,stat,1
# TCP 流统计(找出有问题的连接)
tshark -r capture.pcap -q -z conv,tcp
# HTTP 请求统计
tshark -r capture.pcap -q -z http,tree
# DNS 响应时间统计
tshark -r capture.pcap -q -z dns,tree
2.3 TCP 三次握手与四次挥手分析
2.3.1 正常握手与挥手
正常三次握手的抓包特征:
# 三次握手
Client -> Server: [S] seq=0 win=65535 # 第一次:客户端发 SYN
Server -> Client: [S.] seq=0 ack=1 win=65535 # 第二次:服务端回 SYN-ACK
Client -> Server: [.] seq=1 ack=1 win=65535 # 第三次:客户端发 ACK
# 四次挥手
Client -> Server: [F.] seq=100 ack=200 # 客户端发 FIN
Server -> Client: [.] seq=200 ack=101 # 服务端 ACK
Server -> Client: [F.] seq=200 ack=101 # 服务端发 FIN
Client -> Server: [.] seq=101 ack=201 # 客户端 ACK
抓取握手包的命令:
# 抓 SYN、SYN-ACK、RST(排查连接建立问题)
tcpdump -nn -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-rst) != 0' and host 10.0.1.100
2.3.2 SYN 超时分析
客户端发了 SYN 但收不到 SYN-ACK,内核会按指数退避重传 SYN。Linux 默认重传 6 次(net.ipv4.tcp_syn_retries=6),总耗时约 127 秒:
14:00:01.000 Client -> Server: [S] seq=100 # 第 1 次 SYN
14:00:02.000 Client -> Server: [S] seq=100 # 1 秒后重传
14:00:04.000 Client -> Server: [S] seq=100 # 2 秒后重传
14:00:08.000 Client -> Server: [S] seq=100 # 4 秒后重传
14:00:16.000 Client -> Server: [S] seq=100 # 8 秒后重传
看到这种模式,说明 SYN 包或 SYN-ACK 包在网络中被丢弃了。常见原因:防火墙 DROP 规则、安全组未放行、目标端口未监听(但这种通常会回 RST)、SYN flood 防护触发。
2.3.3 RST 包分析
RST 是 TCP 的”强制终止”信号,不同场景的 RST 特征不同:
# 抓所有 RST 包
tcpdump -nn -i eth0 'tcp[tcpflags] & (tcp-rst) != 0' -c 100
# 常见 RST 场景:
# 1. 端口未监听:SYN -> RST-ACK(立即返回,说明端口没有服务)
# 2. 防火墙拒绝:SYN -> RST(可能带有特定 TTL,区别于服务端的 RST)
# 3. 连接被中间设备切断:数据传输中突然收到 RST
# 4. 应用层主动关闭:SO_LINGER=0 时 close() 发 RST 而不是 FIN
区分 RST 来源的技巧:对比 RST 包的 TTL 和正常包的 TTL,如果 TTL 不同,RST 很可能来自中间设备(防火墙、负载均衡器)而非真正的目标服务器。
2.3.4 TCP 重传与乱序分析
# 用 tshark 统计重传包数量
tshark -r capture.pcap -Y "tcp.analysis.retransmission" | wc -l
# 统计重传率
total=$(tshark -r capture.pcap -Y "tcp" | wc -l)
retrans=$(tshark -r capture.pcap -Y "tcp.analysis.retransmission" | wc -l)
echo "重传率: $(echo "scale=4; $retrans/$total*100" | bc)%"
# 重传率参考值:
# < 0.1% 正常
# 0.1%-1% 轻微丢包,可能影响性能
# > 1% 严重丢包,需要排查网络链路
# > 5% 网络基本不可用
2.4 HTTP/HTTPS 流量分析
2.4.1 HTTP 明文抓包
# 抓 HTTP 请求和响应(-A 显示 ASCII 内容)
tcpdump -nn -i eth0 -A -s 0 'tcp port 80 and host 10.0.1.100' | grep -E "^(GET|POST|PUT|DELETE|HTTP/)"
# 用 tshark 提取完整 HTTP 信息
tshark -r capture.pcap -Y "http.request" \
-T fields -e frame.time -e ip.src -e ip.dst \
-e http.request.method -e http.host -e http.request.uri -e http.content_length
2.4.2 HTTPS 加密流量分析
HTTPS 流量加密后无法直接看到内容,但 TLS 握手过程是明文的:
# 抓 TLS 握手(Client Hello 中包含 SNI,可以看到访问的域名)
tshark -r capture.pcap -Y "tls.handshake.type == 1" \
-T fields -e ip.src -e tls.handshake.extensions_server_name
# 检查 TLS 版本
tshark -r capture.pcap -Y "tls.handshake.type == 2" \
-T fields -e ip.src -e tls.handshake.version
# 检查证书信息
tshark -r capture.pcap -Y "tls.handshake.type == 11" \
-T fields -e tls.handshake.certificate
调试环境下解密 HTTPS(通过 SSLKEYLOGFILE):
# 设置环境变量,让客户端导出 TLS 会话密钥
export SSLKEYLOGFILE=/tmp/tls_keys.log
# 用 curl 发请求(会自动写入密钥)
curl https://api.example.com/health
# tshark 使用密钥文件解密
tshark -r capture.pcap -o "tls.keylog_file:/tmp/tls_keys.log" -Y "http2"
# Wireshark 中:Edit -> Preferences -> Protocols -> TLS -> (Pre)-Master-Secret log filename
2.5 DNS 流量分析
2.5.1 DNS 查询与响应抓包
# 抓所有 DNS 流量
tcpdump -nn -i eth0 port 53
# 用 tshark 解析 DNS 详情
tshark -r capture.pcap -Y "dns" \
-T fields -e frame.time -e ip.src -e ip.dst \
-e dns.qry.name -e dns.qry.type -e dns.a -e dns.flags.rcode
# DNS rcode 含义:
# 0 = NoError(正常)
# 2 = ServFail(服务器故障)
# 3 = NXDomain(域名不存在)
# 5 = Refused(拒绝查询)
2.5.2 DNS 解析延迟定位
# 统计 DNS 响应时间
tshark -r capture.pcap -Y "dns.flags.response == 1" \
-T fields -e dns.qry.name -e dns.time | sort -t$'\t' -k2 -rn | head -20
# 正常 DNS 响应应在 10ms 以内(同机房 DNS 服务器)
# 超过 100ms 需要排查:DNS 服务器负载、网络延迟、递归查询链路
2.5.3 DNS 劫持检测
# 对比不同 DNS 服务器的解析结果
# 先抓包,然后分别向内网 DNS 和公网 DNS 查询
dig @10.0.1.2 example.com A
dig @8.8.8.8 example.com A
# 在 pcap 中检查是否有非预期的 DNS 响应源
tshark -r capture.pcap -Y "dns.flags.response == 1" \
-T fields -e ip.src -e dns.qry.name -e dns.a | sort -u
# 如果出现非配置的 DNS 服务器 IP 返回了响应,可能存在 DNS 劫持
三、示例代码和配置
3.1 自动化抓包分析脚本
3.1.1 定时抓包与自动轮转脚本
#!/bin/bash
# 文件名:auto_capture.sh
# 功能:定时抓包,自动轮转,磁盘空间保护
set -euo pipefail
# ========== 配置区 ==========
IFACE="${1:-eth0}" # 网卡,默认 eth0
FILTER="${2:-tcp port 80 or tcp port 443}" # BPF 过滤器
CAPTURE_DIR="/data/pcap" # 抓包文件存储目录
ROTATE_SEC=3600 # 每小时轮转一个文件
MAX_FILES=48 # 最多保留 48 个文件(2天)
MAX_DISK_PERCENT=80 # 磁盘使用超过 80% 停止抓包
SNAP_LEN=0 # 抓完整包,设为 96 可只抓包头
# =============================
mkdir -p "${CAPTURE_DIR}"
# 磁盘空间检查
check_disk() {
local usage
usage=$(df "${CAPTURE_DIR}" | awk 'NR==2 {gsub(/%/,""); print $5}')
if [[ ${usage} -ge ${MAX_DISK_PERCENT} ]]; then
echo "[$(date '+%F %T')] 磁盘使用率 ${usage}% 超过阈值,清理旧文件"
# 删除最旧的文件,直到低于阈值
ls -1t "${CAPTURE_DIR}"/capture_*.pcap 2>/dev/null | tail -n +$((MAX_FILES/2)) | xargs -r rm -f
fi
}
# 清理超出保留数量的旧文件
cleanup_old_files() {
local count
count=$(ls -1 "${CAPTURE_DIR}"/capture_*.pcap 2>/dev/null | wc -l)
if [[ ${count} -gt ${MAX_FILES} ]]; then
ls -1t "${CAPTURE_DIR}"/capture_*.pcap | tail -n +$((MAX_FILES+1)) | xargs -r rm -f
echo "[$(date '+%F %T')] 清理旧文件,当前保留 ${MAX_FILES} 个"
fi
}
# 启动前检查
check_disk
echo "[$(date '+%F %T')] 开始抓包: 网卡=${IFACE}, 过滤器='${FILTER}'"
echo "[$(date '+%F %T')] 轮转间隔=${ROTATE_SEC}s, 最大文件数=${MAX_FILES}"
# tcpdump -G 按秒轮转,-W 限制文件数,-z 轮转后执行命令
tcpdump -nn -i "${IFACE}" \
-s "${SNAP_LEN}" \
-w "${CAPTURE_DIR}/capture_%Y%m%d_%H%M%S.pcap" \
-G "${ROTATE_SEC}" \
-W "${MAX_FILES}" \
-Z root \
${FILTER} &
TCPDUMP_PID=$!
echo "[$(date '+%F %T')] tcpdump 进程启动: PID=${TCPDUMP_PID}"
# 后台定期清理
while kill -0 ${TCPDUMP_PID} 2>/dev/null; do
sleep 300
check_disk
cleanup_old_files
done
echo "[$(date '+%F %T')] tcpdump 进程已退出"
3.2 TCP 连接质量分析脚本
3.2.1 从 pcap 提取关键指标
#!/bin/bash
# 文件名:tcp_quality_report.sh
# 功能:分析 pcap 文件,输出 TCP 连接质量报告
set -euo pipefail
PCAP_FILE="${1:?用法: $0 <pcap文件路径>}"
if [[ ! -f "${PCAP_FILE}" ]]; then
echo "错误: 文件不存在 - ${PCAP_FILE}"
exit 1
fi
echo "=============================="
echo " TCP 连接质量分析报告"
echo " 文件: ${PCAP_FILE}"
echo " 时间: $(date '+%F %T')"
echo "=============================="
echo ""
# 总包数
total_packets=$(tshark -r "${PCAP_FILE}" -Y "tcp" 2>/dev/null | wc -l)
echo "[基础统计]"
echo " TCP 总包数: ${total_packets}"
# 重传统计
retrans=$(tshark -r "${PCAP_FILE}" -Y "tcp.analysis.retransmission" 2>/dev/null | wc -l)
fast_retrans=$(tshark -r "${PCAP_FILE}" -Y "tcp.analysis.fast_retransmission" 2>/dev/null | wc -l)
if [[ ${total_packets} -gt 0 ]]; then
retrans_rate=$(echo "scale=4; ${retrans}/${total_packets}*100" | bc)
else
retrans_rate="0"
fi
echo ""
echo "[重传分析]"
echo " 重传包数: ${retrans}"
echo " 快速重传: ${fast_retrans}"
echo " 重传率: ${retrans_rate}%"
# 零窗口
zero_window=$(tshark -r "${PCAP_FILE}" -Y "tcp.analysis.zero_window" 2>/dev/null | wc -l)
echo ""
echo "[窗口分析]"
echo " 零窗口事件: ${zero_window}"
# RST 统计
rst_count=$(tshark -r "${PCAP_FILE}" -Y "tcp.flags.reset == 1" 2>/dev/null | wc -l)
echo ""
echo "[连接异常]"
echo " RST 包数: ${rst_count}"
# 乱序包
ooo=$(tshark -r "${PCAP_FILE}" -Y "tcp.analysis.out_of_order" 2>/dev/null | wc -l)
dup_ack=$(tshark -r "${PCAP_FILE}" -Y "tcp.analysis.duplicate_ack" 2>/dev/null | wc -l)
echo " 乱序包数: ${ooo}"
echo " 重复ACK: ${dup_ack}"
# TOP 10 重传最多的连接
echo ""
echo "[TOP 10 重传连接]"
tshark -r "${PCAP_FILE}" -Y "tcp.analysis.retransmission" \
-T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport 2>/dev/null \
| sort | uniq -c | sort -rn | head -10 \
| awk '{printf " %5d 次 %s:%s -> %s:%s\n", $1, $2, $3, $4, $5}'
# 质量评估
echo ""
echo "[质量评估]"
if (( $(echo "${retrans_rate} < 0.1" | bc -l) )); then
echo " 状态: 正常 - 重传率低于 0.1%"
elif (( $(echo "${retrans_rate} < 1.0" | bc -l) )); then
echo " 状态: 警告 - 重传率 ${retrans_rate}%,存在轻微丢包"
elif (( $(echo "${retrans_rate} < 5.0" | bc -l) )); then
echo " 状态: 严重 - 重传率 ${retrans_rate}%,网络质量差"
else
echo " 状态: 危险 - 重传率 ${retrans_rate}%,网络基本不可用"
fi
3.3 常见故障场景抓包命令速查
3.3.1 场景命令对照表
#!/bin/bash
# 文件名:capture_cheatsheet.sh
# 功能:常见故障场景的抓包命令集合,按需执行
set -euo pipefail
IFACE="${1:-eth0}"
OUTPUT_DIR="/tmp/captures"
mkdir -p "${OUTPUT_DIR}"
case "${2:-help}" in
# 场景1:TCP 连接建立失败
conn-fail)
echo "抓取 SYN/SYN-ACK/RST 包,排查连接建立问题"
tcpdump -nn -i "${IFACE}" -w "${OUTPUT_DIR}/conn_fail.pcap" \
'tcp[tcpflags] & (tcp-syn|tcp-rst) != 0' -c 1000
;;
# 场景2:DNS 解析异常
dns)
echo "抓取所有 DNS 流量"
tcpdump -nn -i "${IFACE}" -w "${OUTPUT_DIR}/dns.pcap" \
'port 53' -c 500
;;
# 场景3:HTTP 5xx 错误排查
http-err)
TARGET="${3:?需要指定目标 IP}"
echo "抓取与 ${TARGET} 的 HTTP 流量"
tcpdump -nn -i "${IFACE}" -w "${OUTPUT_DIR}/http_err.pcap" \
"host ${TARGET} and tcp port 80" -c 2000
;;
# 场景4:TLS 握手失败
tls-fail)
TARGET="${3:?需要指定目标 IP}"
echo "抓取与 ${TARGET} 的 TLS 握手包"
tcpdump -nn -i "${IFACE}" -w "${OUTPUT_DIR}/tls_fail.pcap" \
"host ${TARGET} and tcp port 443" -c 1000
;;
# 场景5:网络延迟分析
latency)
TARGET="${3:?需要指定目标 IP}"
echo "抓取与 ${TARGET} 的全部 TCP 流量(含时间戳)"
tcpdump -nn -i "${IFACE}" -w "${OUTPUT_DIR}/latency.pcap" \
-tttt "host ${TARGET} and tcp" -c 5000
;;
# 场景6:丢包与重传
retrans)
echo "抓取全部 TCP 流量,后续用 tshark 分析重传"
timeout 60 tcpdump -nn -i "${IFACE}" -w "${OUTPUT_DIR}/retrans.pcap" tcp
echo "分析重传情况:"
tshark -r "${OUTPUT_DIR}/retrans.pcap" -Y "tcp.analysis.retransmission" \
-T fields -e frame.time -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport \
| head -50
;;
# 场景7:特定端口的全量抓包
port)
PORT="${3:?需要指定端口号}"
echo "抓取端口 ${PORT} 的全部流量"
tcpdump -nn -i "${IFACE}" -w "${OUTPUT_DIR}/port_${PORT}.pcap" \
"port ${PORT}" -c 5000
;;
# 场景8:ICMP 问题排查(ping 不通)
icmp)
echo "抓取 ICMP 流量(ping/traceroute)"
tcpdump -nn -i "${IFACE}" -w "${OUTPUT_DIR}/icmp.pcap" \
'icmp or icmp6' -c 200
;;
*)
echo "用法: $0 <网卡> <场景> [参数]"
echo ""
echo "可用场景:"
echo " conn-fail TCP 连接建立失败"
echo " dns DNS 解析异常"
echo " http-err <IP> HTTP 错误排查"
echo " tls-fail <IP> TLS 握手失败"
echo " latency <IP> 网络延迟分析"
echo " retrans 丢包与重传分析"
echo " port <端口> 特定端口全量抓包"
echo " icmp ICMP 问题排查"
;;
esac
四、最佳实践和注意事项
4.1 最佳实践
4.1.1 抓包策略设计
生产环境抓包的核心矛盾:既要抓到足够信息用于定位问题,又不能对业务造成可感知的性能影响。
性能影响控制:
# 1. 使用 -s 截断包体,只抓包头(绝大多数网络层问题只需要前96字节)
tcpdump -i eth0 -s 96 -w /tmp/headers_only.pcap
# 2. 限制抓包数量,避免无限制运行
tcpdump -i eth0 -c 10000 -w /tmp/limited.pcap
# 3. BPF 过滤器在内核层过滤,比抓全量再 grep 高效几个数量级
# 只抓目标 IP 的 TCP 流量,排除 SSH(避免抓到自己的会话)
tcpdump -i eth0 'tcp and host 10.0.1.50 and not port 22' -w /tmp/target.pcap
# 4. 组合使用:截断 + 限量 + 精确过滤
tcpdump -i eth0 -s 128 -c 50000 \
'tcp port 443 and host 10.0.1.50' \
-w /tmp/precise.pcap
抓包文件轮转(长时间抓包必备):
# -C 100:每个文件 100MB 自动切割
# -W 10:最多保留 10 个文件,循环覆盖
# -G 3600:每 3600 秒(1小时)轮转一次
# -z gzip:轮转后自动压缩
# 方案一:按大小轮转(适合流量不均匀场景)
tcpdump -i eth0 -w /data/capture/trace.pcap \
-C 100 -W 10 'tcp port 80'
# 方案二:按时间轮转(适合定时分析场景)
tcpdump -i eth0 -w /data/capture/trace_%Y%m%d_%H%M.pcap \
-G 3600 -W 24 'tcp port 80'
| 策略 | 适用场景 | 优点 | 缺点 |
| — | — | — | — |
| -C 按大小轮转 | 流量波动大、磁盘空间有限 | 磁盘占用可控 | 时间跨度不固定 |
| -G 按时间轮转 | 需要按时段回溯分析 | 时间对齐便于检索 | 高峰期单文件可能很大 |
| -C + -W 组合 | 长期后台抓包 | 自动循环覆盖,无需人工清理 | 早期数据会被覆盖 |
4.1.2 高效分析方法论
逐包看 pcap 是最低效的分析方式。推荐从宏观到微观的四步分析法:
# 第一步:协议分布概览 —— 快速了解流量构成
tshark -r capture.pcap -q -z io,phs
# 第二步:会话统计 —— 找出流量最大的通信对
tshark -r capture.pcap -q -z conv,tcp
# 第三步:过滤异常流 —— 聚焦问题流量
# 重传统计
tshark -r capture.pcap -q -z io,stat,1,"tcp.analysis.retransmission"
# HTTP 错误码统计
tshark -r capture.pcap -q -z http,stat,
# 第四步:定位到具体异常流后,再用显示过滤器做单包分析
tshark -r capture.pcap -Y "tcp.stream eq 42" -T fields \
-e frame.time_relative -e ip.src -e ip.dst \
-e tcp.flags.str -e tcp.len -e tcp.analysis.retransmission
tshark 批量统计替代 GUI 的典型场景:
# 统计每秒请求数(QPS)
tshark -r capture.pcap -q -z io,stat,1,"http.request"
# 统计 DNS 查询耗时分布
tshark -r capture.pcap -Y "dns.flags.response == 1" \
-T fields -e dns.qry.name -e dns.time | \
sort -t$'\t' -k2 -rn | head -20
# 导出所有 HTTP 请求的 URL 和响应码
tshark -r capture.pcap -Y "http.response" \
-T fields -e http.request.uri -e http.response.code | \
sort | uniq -c | sort -rn
4.1.3 安全与合规
生产环境抓包涉及用户隐私数据,必须建立规范流程:
- 权限控制:tcpdump 需要
CAP_NET_RAW权限,禁止给普通用户直接授予 root。推荐通过setcap精细授权:
# 仅授予抓包权限,不给完整 root
sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
- 敏感数据脱敏:抓包文件可能包含明文密码、Cookie、Token 等。分析完成后及时清理,传输时加密:
# 加密存储 pcap 文件
openssl enc -aes-256-cbc -salt -in capture.pcap -out capture.pcap.enc
# 安全删除原始文件
shred -vfz -n 3 capture.pcap
- 审批流程:生产环境抓包建议走工单审批,记录抓包人、时间、目的、涉及的 IP 范围,事后归档备查。
4.1.4 远程抓包方案
| 方案 | 命令示例 | 适用场景 | 局限性 |
| — | — | — | — |
| SSH 管道实时分析 | ssh root@server tcpdump -U -w - | wireshark -k -i - | 临时排查、流量小 | 带宽占用大、SSH 断开即丢失 |
| 远程抓包本地分析 | ssh root@server tcpdump -c 5000 -w /tmp/cap.pcap && scp ... | 常规排查 | 需要两步操作 |
| 容器环境 nsenter | 见下方命令 | K8s Pod 网络排查 | 需要节点 root 权限 |
# 容器环境抓包:通过 nsenter 进入目标 Pod 的网络命名空间
# 第一步:获取容器 PID
CONTAINER_ID=$(crictl ps --name <容器名> -q)
PID=$(crictl inspect "$CONTAINER_ID" | jq .info.pid)
# 第二步:进入网络命名空间抓包
nsenter -t "$PID" -n tcpdump -i eth0 -s 128 -c 5000 \
-w /tmp/pod_capture.pcap 'tcp port 8080'
# 一行式写法(适合快速排查)
nsenter -t $(crictl inspect $(crictl ps --name myapp -q) | jq .info.pid) \
-n tcpdump -nn -i eth0 -c 1000 -w /tmp/pod.pcap
4.2 注意事项
4.2.1 配置注意事项
⚠️ 警告:生产环境抓包的三大风险
- ❗ 磁盘空间耗尽:不加
-C/-W限制的 tcpdump 在高流量接口上可以在几分钟内写满磁盘,直接导致服务宕机。务必提前检查df -h,并使用轮转参数。 - ❗ CPU 开销:万兆网卡全量抓包时,tcpdump 的 BPF 编译和包拷贝会占用 5%-15% CPU。高峰期抓包前评估余量,优先使用精确的 BPF 过滤器减少内核态到用户态的数据拷贝。
- ❗ 混杂模式安全隐患:
-p参数可关闭混杂模式。在共享网络环境中,混杂模式会捕获非本机流量,可能触发安全审计告警。
4.2.2 常见错误
| 错误现象 | 原因分析 | 解决方案 |
| — | — | — |
| tcpdump: permission denied | 非 root 用户且无 CAP_NET_RAW | sudo tcpdump 或 setcap cap_net_raw+eip /usr/sbin/tcpdump |
| 抓包文件 0 字节 | BPF 过滤器语法错误,无匹配流量 | 先不加过滤器测试,逐步添加条件 |
| pcap_loop: recv: Network is down | 抓包过程中网卡被 down 或重置 | 检查网卡状态 ip link show,排除网卡闪断 |
| Wireshark 打开 pcap 报 truncated | -s 截断长度过小或写入时磁盘满 | 增大 -s 值,检查磁盘空间 |
| tshark 显示过滤器无输出 | 捕获过滤器(BPF)与显示过滤器语法混淆 | BPF 用 port 80,显示过滤器用 tcp.port == 80,不可混用 |
| 容器内 tcpdump: command not found | 精简镜像未安装 tcpdump | 使用 nsenter 从宿主机抓包,或临时 apt install tcpdump |
4.2.3 兼容性问题
- Linux 发行版差异:CentOS 7 自带 tcpdump 4.9.x 不支持
--print参数;Ubuntu 22.04+ 默认 tcpdump 4.99.x 支持更多协议解析。建议统一升级到 4.99+ 版本。 - 容器/K8s 环境:Docker 默认的
bridge网络模式下,宿主机抓docker0可以看到容器流量;但 K8s 的 CNI(Calico/Cilium)使用 veth pair,需要找到对应的 veth 接口或用nsenter进入 Pod 网络命名空间。 - 云环境 VPC:AWS VPC Flow Logs 只记录五元组元数据,不含包体。需要完整抓包时,使用 VPC Traffic Mirroring 将流量镜像到专用分析实例。阿里云/腾讯云有类似的流量镜像功能。
五、故障排查和监控
5.1 故障排查
5.1.1 经典案例一:TCP 连接超时(SYN 无响应)
故障现象:应用日志报 Connection timed out,curl 请求目标服务超时。
抓包定位:
# 在客户端抓取发往目标的 SYN 包
tcpdump -nn -i eth0 'tcp[tcpflags] & (tcp-syn) != 0 and host 10.0.2.100' \
-c 50 -w /tmp/syn_debug.pcap
# 实时查看(不写文件)
tcpdump -nn -i eth0 'tcp[tcpflags] & (tcp-syn) != 0 and host 10.0.2.100'
典型输出解读:
# 只有 SYN,没有 SYN-ACK —— 对端未收到或未响应
14:23:01.001 IP 10.0.1.10.45678 > 10.0.2.100.8080: Flags [S], seq 123456
14:23:02.003 IP 10.0.1.10.45678 > 10.0.2.100.8080: Flags [S], seq 123456 # 1秒后重传
14:23:04.007 IP 10.0.1.10.45678 > 10.0.2.100.8080: Flags [S], seq 123456 # 2秒后重传
14:23:08.015 IP 10.0.1.10.45678 > 10.0.2.100.8080: Flags [S], seq 123456 # 4秒后重传(指数退避)
排查路径:SYN 重传间隔呈指数退避(1s → 2s → 4s)是 Linux 内核默认行为。只有 SYN 无 SYN-ACK,说明包在路径上被丢弃。依次检查:
- 目标主机防火墙:
iptables -L -n | grep 8080 - 中间网络设备 ACL:在目标主机同时抓包确认 SYN 是否到达
- 安全组/NACL 规则(云环境)
5.1.2 经典案例二:间歇性丢包(TCP 重传分析)
故障现象:业务偶发超时,监控显示 TCP 重传率周期性升高。
抓包与统计:
# 持续抓包 5 分钟,只抓 TCP
tcpdump -i eth0 -s 96 -w /tmp/retrans.pcap \
'tcp and host 10.0.2.100' -G 300 -W 1
# 用 tshark 统计重传包数量和时间分布
tshark -r /tmp/retrans.pcap -q -z io,stat,10,"tcp.analysis.retransmission"
输出解读:
| Interval | tcp.analysis.retransmission |
|----------------|-----------------------------|
| 0 <> 10 | 2 |
| 10 <> 20 | 3 |
| 20 <> 30 | 47 | ← 这个时段重传突增
| 30 <> 40 | 52 | ← 持续异常
| 40 <> 50 | 5 |
进一步定位:
# 提取重传包的源目IP,找出哪对通信最严重
tshark -r /tmp/retrans.pcap \
-Y "tcp.analysis.retransmission" \
-T fields -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport | \
sort | uniq -c | sort -rn | head -10
排查路径:重传集中在特定时段 → 检查该时段交换机端口错误计数(ethtool -S eth0 | grep error);重传集中在特定 IP 对 → 检查链路 MTU 是否一致(ping -M do -s 1472 目标IP)。
5.1.3 经典案例三:HTTP 502/504 网关超时
故障现象:Nginx 返回 502/504,upstream 日志显示 upstream timed out。
在 Nginx 所在机器同时抓取前端和后端流量:
# 抓 Nginx 到 upstream 的流量(假设 upstream 端口 8080)
tcpdump -nn -i eth0 -s 0 \
'tcp port 8080 and host 10.0.3.50' \
-w /tmp/upstream.pcap -c 10000
用 tshark 分析请求-响应时间差:
# 提取 HTTP 请求和对应响应的时间差
tshark -r /tmp/upstream.pcap \
-Y "http.request or http.response" \
-T fields -e frame.time_relative -e ip.src -e ip.dst \
-e http.request.method -e http.request.uri \
-e http.response.code -e http.time
关键判断:如果 http.time(请求到响应的间隔)> Nginx 的 proxy_read_timeout,说明 upstream 处理慢导致 504。如果 TCP 层出现 RST,说明 upstream 进程崩溃导致 502。
5.1.4 经典案例四:DNS 解析慢
故障现象:应用启动慢、HTTP 请求首次访问延迟高,dig 查询耗时 > 1 秒。
抓包分析 DNS 查询链路:
# 抓取所有 DNS 流量
tcpdump -nn -i eth0 'udp port 53' -w /tmp/dns.pcap -c 500
# 用 tshark 统计每个查询的耗时
tshark -r /tmp/dns.pcap -Y "dns.flags.response == 1" \
-T fields -e dns.qry.name -e dns.time -e dns.flags.rcode | \
sort -t$'\t' -k2 -rn | head -20
典型输出:
api.example.com 2.105 No error ← 解析耗时 2.1 秒,异常
cdn.example.com 0.003 No error ← 正常
db.internal.local 5.002 Server failure ← 5 秒超时,SERVFAIL
排查路径:dns.time > 1s 的记录重点关注。Server failure 通常是递归 DNS 无法解析该域名(内部域名配置错误、上游 DNS 不可达)。检查 /etc/resolv.conf 的 nameserver 顺序,确认第一个 DNS 是否可达。
5.2 性能监控
5.2.1 网络质量基线指标
日常运维中,建立网络质量基线是发现异常的前提。以下四个指标覆盖了绝大多数网络层问题:
| 指标名称 | 正常范围 | 告警阈值 | 说明 |
| — | — | — | — |
| RTT(往返时延) | 同机房 < 1ms,跨机房 < 10ms | > 50ms 或突增 5 倍 | 通过 TCP 握手的 SYN→SYN-ACK 时间差计算 |
| TCP 重传率 | < 0.1% | > 1% | tcp.analysis.retransmission 包数 / 总 TCP 包数 |
| 零窗口频率 | 极少出现 | > 10次/分钟 | 接收端缓冲区满,tcp.analysis.zero_window |
| RST 比例 | < 0.5% | > 2% | 异常连接终止,可能是端口未监听或防火墙拦截 |
5.2.2 监控指标采集
# 快速查看当前网络质量快照
tshark -i eth0 -a duration:60 -q \
-z io,stat,60,"tcp.analysis.retransmission","tcp.analysis.zero_window","tcp.flags.reset==1"
5.2.3 基于 tshark 的持续网络质量监控脚本
#!/bin/bash
set -euo pipefail
# 网络质量监控脚本 —— 每分钟采集一次指标,输出 Prometheus 格式
# 用法: ./net_monitor.sh <网卡> [Prometheus pushgateway 地址]
IFACE="${1:-eth0}"
PUSHGW="${2:-}"
INTERVAL=60
TMPFILE=$(mktemp /tmp/netmon.XXXXXX.pcap)
cleanup() { rm -f "$TMPFILE"; }
trap cleanup EXIT
while true; do
# 抓包 60 秒
timeout "${INTERVAL}" tcpdump -i "${IFACE}" -s 96 -w "$TMPFILE" \
'tcp' 2>/dev/null || true
# 统计各项指标
TOTAL=$(tshark -r "$TMPFILE" -T fields -e frame.number 2>/dev/null | wc -l)
RETRANS=$(tshark -r "$TMPFILE" -Y "tcp.analysis.retransmission" \
-T fields -e frame.number 2>/dev/null | wc -l)
ZERO_WIN=$(tshark -r "$TMPFILE" -Y "tcp.analysis.zero_window" \
-T fields -e frame.number 2>/dev/null | wc -l)
RST_COUNT=$(tshark -r "$TMPFILE" -Y "tcp.flags.reset==1" \
-T fields -e frame.number 2>/dev/null | wc -l)
# 计算比率(避免除零)
if [ "$TOTAL" -gt 0 ]; then
RETRANS_RATE=$(awk "BEGIN{printf \"%.4f\", $RETRANS/$TOTAL}")
RST_RATE=$(awk "BEGIN{printf \"%.4f\", $RST_COUNT/$TOTAL}")
else
RETRANS_RATE="0"
RST_RATE="0"
fi
TIMESTAMP=$(date +%s)
# 输出 Prometheus 格式指标
cat <<METRICS
# HELP net_tcp_total 采集周期内 TCP 包总数
net_tcp_total{iface="${IFACE}"} ${TOTAL} ${TIMESTAMP}
# HELP net_tcp_retrans_rate TCP 重传率
net_tcp_retrans_rate{iface="${IFACE}"} ${RETRANS_RATE} ${TIMESTAMP}
# HELP net_tcp_zero_window 零窗口事件数
net_tcp_zero_window{iface="${IFACE}"} ${ZERO_WIN} ${TIMESTAMP}
# HELP net_tcp_rst_rate RST 比例
net_tcp_rst_rate{iface="${IFACE}"} ${RST_RATE} ${TIMESTAMP}
METRICS
# 推送到 Prometheus Pushgateway(如果配置了地址)
if [ -n "$PUSHGW" ]; then
cat <<METRICS | curl -s --data-binary @- "http://${PUSHGW}/metrics/job/net_monitor/instance/$(hostname)"
net_tcp_total{iface="${IFACE}"} ${TOTAL}
net_tcp_retrans_rate{iface="${IFACE}"} ${RETRANS_RATE}
net_tcp_zero_window{iface="${IFACE}"} ${ZERO_WIN}
net_tcp_rst_rate{iface="${IFACE}"} ${RST_RATE}
METRICS
fi
# 清理临时文件,进入下一轮
rm -f "$TMPFILE"
done
5.3 备份与恢复
5.3.1 pcap 文件管理策略
pcap 文件体积大、包含敏感信息,需要明确的生命周期管理:
#!/bin/bash
set -euo pipefail
# pcap 文件自动清理脚本
# 建议加入 crontab: 0 2 * * * /opt/scripts/pcap_cleanup.sh
PCAP_DIR="/data/capture"
ARCHIVE_DIR="/data/capture/archive"
RETAIN_DAYS=7
ARCHIVE_DAYS=30
mkdir -p "$ARCHIVE_DIR"
# 超过 7 天的 pcap 压缩归档
find "$PCAP_DIR" -maxdepth 1 -name "*.pcap" -mtime +${RETAIN_DAYS} | while read -r f; do
gzip -9 "$f"
mv "${f}.gz" "$ARCHIVE_DIR/"
echo "[$(date)] 归档: $(basename "$f")"
done
# 超过 30 天的归档文件安全删除
find "$ARCHIVE_DIR" -name "*.pcap.gz" -mtime +${ARCHIVE_DAYS} | while read -r f; do
shred -fz "$f"
echo "[$(date)] 删除: $(basename "$f")"
done
5.3.2 抓包环境快速部署
#!/bin/bash
set -euo pipefail
# 一键部署抓包分析环境
# 支持 Debian/Ubuntu 和 RHEL/CentOS
echo "=== 抓包环境快速部署 ==="
if command -v apt-get &>/dev/null; then
sudo apt-get update -qq
sudo apt-get install -y -qq tcpdump tshark ngrep mtr-tiny
elif command -v yum &>/dev/null; then
sudo yum install -y -q tcpdump wireshark-cli ngrep mtr
else
echo "不支持的包管理器,请手动安装" >&2
exit 1
fi
# 创建抓包目录
sudo mkdir -p /data/capture
sudo chmod 750 /data/capture
# 验证安装
echo "--- 版本信息 ---"
tcpdump --version 2>&1 | head -1
tshark --version 2>&1 | head -1
echo "=== 部署完成 ==="
六、总结
6.1 技术要点回顾
- ✅ BPF 过滤器是抓包效率的关键:在内核层过滤流量,比抓全量再筛选高效几个数量级,生产环境必须精确指定过滤条件
- ✅ 从宏观到微观的分析流程:Protocol Hierarchy → Conversations → 异常流过滤 → 单包分析,避免陷入逐包查看的低效模式
- ✅ tshark 是批量分析的核心工具:统计、导出、过滤一条命令搞定,配合
-z统计模块可以替代大部分 GUI 操作 - ✅ 生产环境抓包必须有约束:
-s截断包体、-c限制数量、-C/-W文件轮转,三重保险防止磁盘写满 - ✅ 容器环境用 nsenter 而非容器内安装:通过宿主机进入 Pod 网络命名空间抓包,不污染容器镜像,不依赖容器内工具链
6.2 进阶学习方向
- eBPF/XDP 高性能抓包
- 传统 tcpdump 基于 libpcap,数据从内核拷贝到用户态开销大。eBPF 可以在内核态直接完成过滤和聚合,XDP 在网卡驱动层处理,性能提升 10 倍以上
- 工具推荐:
bpftrace、pwru(Cilium 出品的内核网络路径追踪工具) - 实践建议:从
bpftrace -e 'kprobe:tcp_retransmit_skb { printf("retrans: %s\n", ntop(((struct sock *)arg0)->sk_daddr)); }'开始体验
- Packet Capture as a Service
- 大规模集群中,逐台 SSH 抓包效率极低。可以构建集中式抓包服务:Agent 部署在每个节点,通过 API 触发抓包,pcap 文件自动上传到对象存储
- 开源方案参考:Arkime(原 Moloch)提供全流量索引和检索能力
- AI 辅助流量分析
- 将 tshark 导出的结构化数据(JSON 格式)输入 LLM,辅助识别异常模式、生成分析报告
tshark -r capture.pcap -T json导出后,可以让 AI 分析 TCP 会话状态机异常、识别重传模式等
6.3 参考资料
- tcpdump 官方手册 – BPF 过滤器语法权威参考
- Wireshark 显示过滤器参考 – 完整的显示过滤器字段列表
- Wireshark Wiki – TCP Analysis – TCP 分析标记的含义详解
- Arkime 全流量分析平台 – 大规模 pcap 索引和检索
- pwru – eBPF 网络路径追踪 – 内核网络栈数据包路径可视化
附录
A. 命令速查表
tcpdump BPF 捕获过滤器(内核层过滤,抓包时使用):
# 基础过滤
tcpdump 'host 10.0.1.50' # 指定主机(源或目的)
tcpdump 'src host 10.0.1.50' # 仅源地址
tcpdump 'dst host 10.0.1.50' # 仅目的地址
tcpdump 'net 10.0.1.0/24' # 指定网段
tcpdump 'port 80' # 指定端口(TCP/UDP)
tcpdump 'tcp port 443' # 仅 TCP 443
tcpdump 'portrange 8000-9000' # 端口范围
# 协议过滤
tcpdump 'tcp' # 仅 TCP
tcpdump 'udp' # 仅 UDP
tcpdump 'icmp' # 仅 ICMP
# TCP 标志位过滤
tcpdump 'tcp[tcpflags] & (tcp-syn) != 0' # 包含 SYN 的包
tcpdump 'tcp[tcpflags] & (tcp-rst) != 0' # 包含 RST 的包
tcpdump 'tcp[tcpflags] == tcp-syn' # 仅 SYN(不含 SYN-ACK)
tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)' # SYN-ACK
# 组合过滤
tcpdump 'tcp port 80 and host 10.0.1.50 and not port 22'
tcpdump '(dst port 80 or dst port 443) and src net 192.168.0.0/16'
tshark 显示过滤器(用户层过滤,分析时使用):
# 基础过滤
tshark -Y "ip.addr == 10.0.1.50" # 指定 IP
tshark -Y "tcp.port == 80" # 指定端口
tshark -Y "tcp.stream eq 5" # 指定 TCP 流编号
# TCP 分析标记
tshark -Y "tcp.analysis.retransmission" # 重传包
tshark -Y "tcp.analysis.fast_retransmission" # 快速重传
tshark -Y "tcp.analysis.zero_window" # 零窗口
tshark -Y "tcp.analysis.duplicate_ack" # 重复 ACK
tshark -Y "tcp.analysis.lost_segment" # 丢包标记
tshark -Y "tcp.flags.reset == 1" # RST 包
# HTTP 过滤
tshark -Y "http.request" # HTTP 请求
tshark -Y "http.response.code >= 400" # HTTP 错误响应
tshark -Y "http.request.uri contains \"/api\"" # URL 包含 /api
# DNS 过滤
tshark -Y "dns.qry.name contains \"example.com\"" # 指定域名查询
tshark -Y "dns.flags.rcode != 0" # DNS 错误响应
tshark -Y "dns.time > 0.5" # DNS 响应超过 500ms
B. 配置参数详解
tcpdump 关键参数:
| 参数 | 说明 | 常用值 | 示例 |
| — | — | — | — |
| -i | 指定网卡 | eth0 、any | -i eth0 |
| -nn | 不解析主机名和端口名 | – | 加速输出,生产环境必加 |
| -s | 截取包长度(字节) | 0 =完整、96=仅包头 | -s 96 减少磁盘写入 |
| -c | 抓包数量上限 | 视需求 | -c 10000 |
| -w | 写入 pcap 文件 | 文件路径 | -w /tmp/cap.pcap |
| -r | 读取 pcap 文件 | 文件路径 | -r /tmp/cap.pcap |
| -C | 文件大小轮转(MB) | 100 | -C 100 每 100MB 切割 |
| -W | 最大文件数(配合 -C) | 10 | -W 10 循环覆盖 |
| -G | 按时间轮转(秒) | 3600 | -G 3600 每小时切割 |
| -A | 以 ASCII 打印包内容 | – | 快速查看 HTTP 明文 |
| -X | 以 HEX + ASCII 打印 | – | 调试二进制协议 |
| -p | 关闭混杂模式 | – | 安全环境下使用 |
tshark 关键参数:
| 参数 | 说明 | 示例 |
| — | — | — |
| -r | 读取 pcap 文件 | -r capture.pcap |
| -Y | 显示过滤器 | -Y "tcp.analysis.retransmission" |
| -T fields | 字段输出模式 | 配合 -e 指定字段 |
| -e | 指定输出字段 | -e ip.src -e ip.dst -e tcp.port |
| -q | 安静模式(仅输出统计) | 配合 -z 使用 |
| -z | 统计模块 | -z io,stat,1 、-z conv,tcp、-z http,stat, |
| -a duration:N | 抓包 N 秒后停止 | -a duration:60 |
| -T json | JSON 格式输出 | 用于程序化处理 |
| -V | 详细解码输出 | 查看完整协议解析 |
C. 术语表
| 术语 | 英文 | 解释 | | — | — | — | | BPF | Berkeley Packet Filter | 内核层包过滤机制,tcpdump 的过滤器语法基于此实现 | | 三次握手 | TCP Three-way Handshake | TCP 建立连接的过程:SYN → SYN-ACK → ACK | | RTT | Round-Trip Time | 数据包从发送到收到确认的往返时间 | | 重传 | Retransmission | 发送端未收到 ACK 超时后重新发送数据包 | | 零窗口 | Zero Window | 接收端通告窗口大小为 0,表示缓冲区已满,要求发送端暂停 | | RST | Reset | TCP 连接异常终止标志,表示一方强制关闭连接 | | MSS | Maximum Segment Size | TCP 单个报文段的最大数据长度,通常 1460 字节(MTU 1500 – IP头20 – TCP头20) | | MTU | Maximum Transmission Unit | 链路层单帧最大传输字节数,以太网默认 1500 字节 | | PCAP | Packet Capture | 网络抓包文件的标准格式,由 libpcap 库定义 | | 混杂模式 | Promiscuous Mode | 网卡接收所有经过的数据帧,而非仅目标为本机的帧 | | 显示过滤器 | Display Filter | Wireshark/tshark 的用户层过滤语法,作用于已捕获的数据 | | 捕获过滤器 | Capture Filter | 基于 BPF 的内核层过滤,在抓包时生效,减少数据量 |
今日福利
为了帮助大家早日习得网络安全核心知识,快速入行网络安全圈,给大家整理了一套【2026最新网安资料】网络安全工程师必备技能资料包(文末一键领取),内容有多详实丰富看下图!
Web安全👇
渗透测试👇
安全面试题👇
代码审计👇
红队笔记👇
入门视频👇
以上所有资料获取请扫码
识别上方二维码
备注:2026安全合集
100%免费领取
(是扫码领取,不是在公众号后台回复,别看错了哦)
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:马哥网络安全 点击关注👉 点击关注👉《网络抓包分析实战:Wireshark与tcpdump定位网络故障》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论