网络抓包分析实战: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=RST

  • seq:序列号

  • 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 80tcp.port == 80

示例:过滤 IP

host 10.0.1.50ip.addr == 10.0.1.50

示例:过滤协议

tcptcp

(碰巧相同)

修改时机

抓包前设置,抓包中不可改

随时修改,实时生效

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}"

# 后台定期清理
whilekill -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 outcurl 请求目标服务超时。

抓包定位:

# 在客户端抓取发往目标的 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,说明包在路径上被丢弃。依次检查:

  1. 目标主机防火墙:iptables -L -n | grep 8080

  2. 中间网络设备 ACL:在目标主机同时抓包确认 SYN 是否到达

  3. 安全组/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

whiletrue; 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} | whileread -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} | whileread -r f; do
    shred -fz "$f"
    echo"[$(date)] 删除: $(basename "$f")"
done
5.3.2 抓包环境快速部署
#!/bin/bash
set -euo pipefail

# 一键部署抓包分析环境
# 支持 Debian/Ubuntu 和 RHEL/CentOS

echo"=== 抓包环境快速部署 ==="

ifcommand -v apt-get &>/dev/null; then
    sudo apt-get update -qq
    sudo apt-get install -y -qq tcpdump tshark ngrep mtr-tiny
elifcommand -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 进阶学习方向

  1. eBPF/XDP 高性能抓包

  • 传统 tcpdump 基于 libpcap,数据从内核拷贝到用户态开销大。eBPF 可以在内核态直接完成过滤和聚合,XDP 在网卡驱动层处理,性能提升 10 倍以上

  • 工具推荐:bpftracepwru(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 的内核层过滤,在抓包时生效,减少数据量

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐