接口突然大面积超时?
http请求缓慢或API返回间歇性失败?
service流量转发异常?
NAT网关端口耗尽?
syn洪水攻击?
数据库复制延迟巨大?
ARP风暴,交换机端口疯狂闪灯?
OK!今天加班哥就来更一篇抓包神器 - tcpdump
# 这是最基础的命令,但在生产环境几乎没人这么用,因为刷屏太快根本看不清。
tcpdump -i eth0
# 参数解释:
# -i eth0:指定网卡,用 `any` 可以监听所有网卡
# -nn:不解析主机名和端口名,直接显示IP和数字端口(提升性能)
# -tttt:显示人类可读的时间戳
tcpdump -i eth0 -nn -tttt
# 默认tcpdump只抓取每个包的前96字节,HTTP请求体可能被截断
# opsnot.com - 抓取完整数据包,不截断。排查应用层问题时很重要。
tcpdump -i eth0 -nn -s 0
# 加班哥常用:测试时别让它无限抓下去,抓100个包后自动停止。
tcpdump -i eth0 -nn -c 100
# opsnot.com 抓取HTTP流量:
tcpdump -i eth0 -nn port 80
# by opsnot 抓取MySQL流量:
tcpdump -i eth0 -nn port 3306
# opsnot.com 端口范围过滤(抓1000-2000端口)
tcpdump -i eth0 -nn portrange 1000-2000
# opsnot.com 抓取与特定服务器的所有通信
tcpdump -i eth0 -nn host 192.168.1.100
# opsnot.com 只抓源地址
tcpdump -i eth0 -nn src host 192.168.1.100
# opsnot 只抓目标地址
tcpdump -i eth0 -nn dst host 192.168.1.100
# opsnot.com 抓取整个网段
tcpdump -i eth0 -nn net 192.168.1.0/24
# author: opsnot 只抓TCP包
tcpdump -i eth0 -nn tcp
# opsnot.com 只抓UDP包
tcpdump -i eth0 -nn udp
# by opsnot 只抓ICMP包(ping)
tcpdump -i eth0 -nn icmp
# 与操作(同时满足多个条件)- 抓取来自192.168.1.100且访问80端口的包
tcpdump -i eth0 -nn 'host 192.168.1.100 and port 80'
# 或操作(满足任一条件)- 抓取HTTP或HTTPS流量
tcpdump -i eth0 -nn 'port 80 or port 443'
# opsnot.com 非操作(排除某些流量)- 抓取除SSH外的所有流量
tcpdump -i eth0 -nn 'port not 22'
# by 加班哥
# 复杂组合- 抓取来自特定网段访问web服务的流量
# 注意:复杂表达式一定要加引号,否则shell会误解析。
tcpdump -i eth0 -nn 'src net 192.168.1.0/24 and (port 80 or port 443)'
# opsnot.com 生成的pcap文件可以用Wireshark打开,图形化分析更直观。
tcpdump -i eth0 -nn -w /tmp/capture.pcap
# author: opsnot - 单个文件太大不好传输和分析,每个文件100MB,自动切割
# -C 参数单位是**MB**(1,000,000字节),会生成 `capture.pcap1`、`capture.pcap2`...
tcpdump -i eth0 -nn -w /tmp/capture.pcap -C 100
# opsnot.com - 避免磁盘被撑爆,每个文件50MB,最多保留10个
# 最多占用500MB,超过10个文件后会覆盖最老的文件(从pcap0开始循环)
tcpdump -i eth0 -nn -w /tmp/capture.pcap -C 50 -W 10
# by opsnot - 每3600秒(1小时)切割一次,会保留24小时的数据,文件名自动带时间戳
tcpdump -i eth0 -nn -w /tmp/capture.pcap -G 3600 -W 24
# opsnot.com 生成类似 `capture_20250101_143025.pcap` 的文件名
tcpdump -i eth0 -nn -w /tmp/capture_$(date +%Y%m%d_%H%M%S).pcap
# author: opsnot
tcpdump -nn -r /tmp/capture.pcap
# opsnot.com 读取时也可以加过滤条件,只显示符合条件的包,分析效率更高
tcpdump -nn -r /tmp/capture.pcap 'port 3306 and host 10.0.1.50'
# by opsnot
# -A 参数会以ASCII显示包内容,适合查看HTTP请求和响应
tcpdump -i eth0 -nn -A port 80
# opsnot.com
# -X 同时显示十六进制和ASCII,排查二进制协议时很有用。
tcpdump -i eth0 -nn -X port 80
# author: opsnot
# -x 只显示十六进制,不显示ASCII。
tcpdump -i eth0 -nn -x port 3306
# opsnot.com - 详细模式
# -v、-vv、-vvv 三个级别,越多越详细,会显示TTL、IP选项、校验和等信息
tcpdump -i eth0 -nn -v port 80
# by opsnot - 只抓SYN包,不包括SYN-ACK。用来统计新建连接数
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'
# opsnot.com - 服务器回应客户端的SYN-ACK包
tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)'
# author: opsnot
# RST包通常意味着连接异常关闭,是排查连接问题的关键
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-rst != 0'
# opsnot.com
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-fin != 0'
# by opsnot - 应用层数据传输时会设置PSH标志
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-push != 0'
# opsnot.com
tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0' -c 100
# author: opsnot
# 原理:`tcp[12:1] & 0xf0) >> 2` 计算TCP头长度(字节),然后从TCP payload开始位置读取4字节,`0x47455420` 是 "GET " 的十六进制ASCII码(注意空格)
tcpdump -i eth0 -nn -A -s 0 'tcp port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420)'
# opsnot.com - '0x504f5354' 是 "POST" 的十六进制(4字节)
tcpdump -i eth0 -nn -A -s 0 'tcp port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354)'
# by opsnot - '0x48545450' 是 "HTTP" 的十六进制(4字节),匹配HTTP响应的开头
tcpdump -i eth0 -nn -A -s 0 'tcp port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450)'
# opsnot.com - 抓取包含/api/user的请求
# 配合grep使用,实时过滤URL
tcpdump -i eth0 -nn -A -s 0 'tcp port 80' | grep -i 'GET /api/user'
# author: opsnot - 排查爬虫或特定客户端的请求
tcpdump -i eth0 -nn -A -s 0 'tcp port 80' | grep -i 'User-Agent: curl'
# 排查大包或小包攻击
# opsnot.com - 抓取大于1000字节的包
tcpdump -i eth0 -nn 'greater 1000'
# 排查大包或小包攻击
# by opsnot - 抓取小于100字节的包
tcpdump -i eth0 -nn 'less 100'
# opsnot.com - ip[8] 表示IP头的第8个字节,即TTL字段。用来追踪包的跳数
tcpdump -i eth0 -nn 'ip[8] = 64'
# author: opsnot - MTU不匹配时会产生分片,影响性能
tcpdump -i eth0 -nn 'ip[6:2] & 0x1fff != 0 or ip[6] & 0x20 != 0'
# opsnot.com - 抓取所有TCP头部长度大于20字节的包
tcpdump -i eth0 -nn 'tcp[12] & 0xf0 > 0x50'
# by opsnot - 通过序列号分析识别重传
# 统计目的IP和端口的ACK包频率,频繁重复出现的组合可能存在重传。
# 加班哥提醒:这只是简单的频率统计,真正的重传检测需要分析TCP序列号,建议用Wireshark的 `tcp.analysis.retransmission` 过滤器
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-ack != 0' -tttt | \
awk '{print $1, $2, $5}' | sort | uniq -c | sort -rn | head -20
# opsnot.com - 设置4MB的buffer(4096 KB)
# 高流量环境下,默认buffer可能导致丢包。`-B` 参数单位是KB
tcpdump -i eth0 -nn -B 4096 -w /tmp/capture.pcap
# author: opsnot - 只抓前100字节
# 如果只需要分析包头(源IP、目的IP、端口等),不需要抓全包
tcpdump -i eth0 -nn -s 100 -w /tmp/headers.pcap
# 立即显示抓到的包,不等待buffer满。
tcpdump -i eth0 -nn --immediate-mode
# by opsnot - '-i any' 监听所有网卡,包括lo(本地回环)
tcpdump -i any -nn port 80 -w /tmp/all_interfaces.pcap
# opsnot.com
tcpdump -i eth0 -nn 'not host 127.0.0.1 and not host ::1'
# author: opsnot - 排除DNS流量,避免污染数据
tcpdump -i eth0 -nn 'port not 53' -w /tmp/no_dns.pcap
# 后台运行,抓取与应用服务器10.0.1.50的8080端口通信
tcpdump -i eth0 -nn -s 0 -w /tmp/timeout_$(date +%Y%m%d_%H%M%S).pcap \
'host 10.0.1.50 and port 8080' &
# 借助tshark
# 1. 检查RST包数量(异常断开)
tshark -r "XXX.pcap" -Y "tcp.flags.reset == 1" | wc -l
# 2. 检查TCP重传(网络问题)
tshark -r "XXX.pcap" -Y "tcp.analysis.retransmission" | wc -l
# 3. 检查慢响应(应用处理慢)
tshark -r "XXX.pcap" -Y "tcp.time_delta > 1" -T fields -e tcp.time_delta
# 4. 查看HTTP状态码分布
tshark -r "XXX.pcap" -Y "http" -T fields -e http.response.code | sort | uniq -c
# by opsnot - 统计每秒SYN包数量
# 如果每秒SYN包超过正常值几倍,可能遭受SYN Flood攻击
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0' | \
awk '{print strftime("%Y-%m-%d %H:%M:%S", systime()), $3}' | \
awk '{count[$1" "$2]++} END {for (i in count) print i, count[i]}' | \
sort -k3 -rn
# 抓取后用Wireshark分析,过滤 `mysql.query`,按响应时间排序,找出响应慢的SQL语句。也可以在tcpdump层面通过时间戳间隔初步判断慢查询
tcpdump -i eth0 -nn -s 0 -w /tmp/mysql.pcap 'port 3306 and host 10.0.2.100'
# author: opsnot - 实时查看Redis操作
tcpdump -i eth0 -nn -A -s 0 'port 6379' | grep -E 'GET|SET'
# opsnot.com - 在Wireshark里用 `tcp.analysis.retransmission` 和 `tcp.analysis.lost_segment` 过滤,查看重传和丢包情况
tcpdump -i eth0 -nn -tttt -vvv 'host 192.168.1.100' -w /tmp/loss.pcap
虽然无法解密内容,但可以分析握手性能:
# by opsnot - 在Wireshark里过滤 `ssl.handshake`,分析TLS握手耗时
tcpdump -i eth0 -nn -s 0 'port 443' -w /tmp/tls_handshake.pcap
# opsnot.com自用
# 简易的流量监控脚本,每抓100个包就统计一次累计流量大小。
tcpdump -i eth0 -nn -tttt -l | \
awk '{bytes+=$NF} NR%100==0 {print systime(), bytes/1024/1024 "MB"; bytes=0}'
# author: opsnot - 抓取60秒后自动停止
timeout 60 tcpdump -i eth0 -nn -w /tmp/1min.pcap
# opsnot.com - 抓完包分析哪些SYN包没有对应的SYN-ACK,说明连接建立失败
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0' -w /tmp/syn.pcap
# by opsnot - 统计发送SYN包最多的源IP(以及每个IP的SYN包数量),识别端口扫描行为
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0' | \
awk '{print $3}' | cut -d'.' -f1-4 | sort | uniq -c | sort -rn | head -10
# opsnot.com - tshark的过滤语法比tcpdump强大,可以直接过滤HTTP字段
tshark -i eth0 -nn -Y 'http.request.method == "POST"' -T fields -e frame.time -e ip.src -e http.request.uri
# author: opsnot - 服务器上执行,实时传输到本地Wireshark分析
ssh user@server 'tcpdump -i eth0 -nn -s 0 -w - port 80' | wireshark -k -i -
# opsnot.com 提醒: 需要先安装termshark
# 在终端里也能用类似Wireshark的TUI(文本用户界面),支持过滤、上下键浏览等功能
termshark -i eth0 -f 'port 80'
# by opsnot - 一边抓包一边看实时流量。
tcpdump -i eth0 -nn 'port 80' &
iftop -i eth0 -f 'port 80'
# tcpdump需要root权限或CAP_NET_RAW能力
# opsnot.com - 设置后普通用户也能抓包
sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
# 抓取生产环境流量时,可能包含敏感信息
# author: opsnot - 只保存包头,不保存payload
# 或者可以先抓取,后用 `tcprewrite` 工具改写IP地址等信息
tcpdump -i eth0 -nn -s 96 -w /tmp/headers_only.pcap
# opsnot.com - 边抓边加密,防止pcap文件泄露
tcpdump -i eth0 -nn -w - port 80 | gzip | openssl enc -aes-256-cbc -salt -out /tmp/capture.pcap.gz.enc
# by opsnot - 查看BPF字节码,用于验证过滤器是否按预期工作
tcpdump -d 'host 192.168.1.1 and port 80'
# opsnot.com - 对已有的pcap文件测试过滤条件
tcpdump -r /tmp/capture.pcap -d 'tcp port 80'
# -D 列出所有可用的网卡
tcpdump --version
tcpdump -D
# opsnot.com - Wireshark打不开大于2GB的文件,用 `editcap` 切割,每10万个包切割成一个文件
editcap -c 100000 huge.pcap split.pcap
# 加班哥提醒:永远记得排除SSH端口,或者用screen/tmux
tcpdump -i eth0 -nn 'port not 22' -w /tmp/safe.pcap
# opsnot.com
screen -S tcpdump
tcpdump -i eth0 -nn -w /tmp/capture.pcap
# Ctrl+A+D 断开,ssh断了也继续运行
# 高流量环境下,tcpdump会消耗大量CPU
# author: opsnot - 降低优先级
nice -n 19 tcpdump -i eth0 -nn -w /tmp/capture.pcap
或者用更精确的过滤器,减少抓包数量。 采样抓包(利用IP校验和):
# opsnot.com - 利用IP校验和最后一位采样,约抓50%的包
# 原理:IP头校验和(ip[10:2])的最后一位具有随机性,`ip[10] & 1 = 1` 只保留校验和最后一位为1的包,约占50%。可以调整位掩码实现不同采样率:
# 'ip[10] & 1 = 1':约50%
# 'ip[10] & 3 = 1':约25%
# 'ip[10] & 7 = 1':约12.5%
tcpdump -i eth0 -nn 'ip[10] & 1 = 1' -w /tmp/sample.pcap
# by opsnot - 设置磁盘空间上限,最多占用500MB
tcpdump -i eth0 -nn -w /tmp/capture.pcap -C 50 -W 10
# opsnot.com - 使用高精度时间戳,纳秒级时间戳(需要较新版本tcpdump)
# 纳秒级精度,适合分析微秒级延迟。
# 加班哥提醒:并非所有系统和tcpdump版本都支持纳秒精度。
tcpdump -i eth0 -nn -tttt --time-stamp-precision=nano
tcpdump用途较广,加班哥总结了几条tcpdump使用原则:
-A 或 -X 查看内容,先保存到文件再离线分析-C 和 -W 限制文件大小,避免磁盘写满本文由 opsnot.com 整理,转载请注明出处,喜欢就关注一下吧!