网络不通?延迟太高?教你用 tcpdump 三步定位罪魁祸首

📅 发布时间:2026/7/15 10:46:10 👁️ 浏览次数:
网络不通?延迟太高?教你用 tcpdump 三步定位罪魁祸首
Wireshark虽然好用但服务器上通常没有图形界面。tcpdump是Linux下最常用的命令行抓包工具排查网络问题、分析协议、定位连接异常都离不开它。本文整理tcpdump的常用技巧从基础语法到实际问题排查配合真实场景案例。1. 基础用法1.1 最简单的抓包# 抓取eth0网卡的所有流量 tcpdump -i eth0 # 抓取所有网卡 tcpdump -i any # 指定抓取数量 tcpdump -i eth0 -c 1001.2 常用参数# -n不解析主机名速度快 # -nn不解析主机名和端口名 tcpdump -i eth0 -nn # -v/-vv/-vvv详细程度递增 tcpdump -i eth0 -vv # -X同时以十六进制和ASCII显示包内容 tcpdump -i eth0 -X # -A以ASCII显示包内容适合HTTP tcpdump -i eth0 -A # -s0抓取完整数据包默认只抓前96字节 tcpdump -i eth0 -s0 # -w保存到文件可用Wireshark打开 tcpdump -i eth0 -w capture.pcap # -r读取抓包文件 tcpdump -r capture.pcap1.3 组合使用# 常用组合不解析、完整包、保存文件 tcpdump -i eth0 -nn -s0 -w /tmp/capture.pcap # 边抓边看同时保存 tcpdump -i eth0 -nn -U -w /tmp/capture.pcap tail -f /tmp/capture.pcap | tcpdump -r -2. 过滤表达式tcpdump强大之处在于过滤表达式精准抓取需要的流量。2.1 按主机过滤# 抓取与192.168.1.100通信的所有流量 tcpdump -i eth0 host 192.168.1.100 # 抓取源地址为192.168.1.100 tcpdump -i eth0 src host 192.168.1.100 # 抓取目标地址为192.168.1.100 tcpdump -i eth0 dst host 192.168.1.100 # 抓取与多个主机通信 tcpdump -i eth0 host 192.168.1.100 or host 192.168.1.101 # 排除某个主机 tcpdump -i eth0 not host 192.168.1.1002.2 按端口过滤# 抓取80端口流量 tcpdump -i eth0 port 80 # 抓取源端口为80 tcpdump -i eth0 src port 80 # 抓取目标端口为80 tcpdump -i eth0 dst port 80 # 抓取端口范围 tcpdump -i eth0 portrange 8000-9000 # 抓取多个端口 tcpdump -i eth0 port 80 or port 443 or port 80802.3 按协议过滤# 只抓TCP tcpdump -i eth0 tcp # 只抓UDP tcpdump -i eth0 udp # 只抓ICMPping tcpdump -i eth0 icmp # 只抓ARP tcpdump -i eth0 arp2.4 按网段过滤# 抓取192.168.1.0/24网段 tcpdump -i eth0 net 192.168.1.0/24 # 抓取源网段 tcpdump -i eth0 src net 10.0.0.0/82.5 按TCP标志位过滤# 抓取SYN包新连接 tcpdump -i eth0 tcp[tcpflags] tcp-syn ! 0 # 抓取SYNACK包 tcpdump -i eth0 tcp[tcpflags] (tcp-syn|tcp-ack) (tcp-syn|tcp-ack) # 抓取FIN包连接关闭 tcpdump -i eth0 tcp[tcpflags] tcp-fin ! 0 # 抓取RST包连接重置 tcpdump -i eth0 tcp[tcpflags] tcp-rst ! 0 # 简写方式 tcpdump -i eth0 tcp[13] 2 ! 0 # SYN tcpdump -i eth0 tcp[13] 1 ! 0 # FIN tcpdump -i eth0 tcp[13] 4 ! 0 # RST2.6 组合过滤# 抓取到MySQL的流量 tcpdump -i eth0 dst port 3306 and dst host 192.168.1.100 # 抓取HTTP请求排除SSH tcpdump -i eth0 port 80 and not port 22 # 抓取指定IP的TCP SYN包 tcpdump -i eth0 host 192.168.1.100 and tcp[tcpflags] tcp-syn ! 0 # 复杂组合抓取从web服务器到数据库的非SSH流量 tcpdump -i eth0 src host 192.168.1.10 and dst host 192.168.1.20 and not port 223. 输出解读3.1 TCP包格式14:22:31.123456 IP 192.168.1.10.45678 192.168.1.20.80: Flags [S], seq 123456, win 64240, length 0各部分含义14:22:31.123456时间戳192.168.1.10.45678源IP.端口192.168.1.20.80目标IP.端口Flags [S]TCP标志位seq 123456序列号win 64240窗口大小length 0数据长度3.2 TCP标志位标志含义SSYN发起连接.ACK确认FFIN关闭连接RRST重置连接PPSH推送数据S.SYNACKF.FINACK3.3 三次握手示例# 客户端发SYN 14:22:31.001 IP 10.0.0.1.45678 10.0.0.2.80: Flags [S], seq 100 # 服务端回SYNACK 14:22:31.002 IP 10.0.0.2.80 10.0.0.1.45678: Flags [S.], seq 200, ack 101 # 客户端发ACK 14:22:31.003 IP 10.0.0.1.45678 10.0.0.2.80: Flags [.], ack 2014. 实战场景4.1 排查连接超时服务调用超时先确认是不是网络层面的问题。# 抓取到目标服务的SYN包 tcpdump -i eth0 -nn dst host 192.168.1.100 and dst port 8080 and tcp[tcpflags] tcp-syn ! 0如果看到大量SYN但没有SYNACK说明对端服务没起来防火墙拦截了网络不通# 同时看SYN和SYNACK tcpdump -i eth0 -nn host 192.168.1.100 and port 8080 and (tcp[tcpflags] tcp-syn ! 0)4.2 排查连接被重置如果连接频繁被RST抓包分析原因。# 抓取RST包 tcpdump -i eth0 -nn tcp[tcpflags] tcp-rst ! 0常见原因端口没监听连接数超限防火墙策略应用主动关闭4.3 分析HTTP请求# 抓取HTTP请求行 tcpdump -i eth0 -A -s0 tcp port 80 and (((ip[2:2] - ((ip[0]0xf)2)) - ((tcp[12]0xf0)2)) ! 0) # 简单版本 tcpdump -i eth0 -A port 80 | grep -E GET|POST|HTTP4.4 抓取DNS查询# 抓取所有DNS流量 tcpdump -i eth0 -nn port 53 # 只看DNS查询内容 tcpdump -i eth0 -nn -v port 53输出示例14:22:31.123 IP 192.168.1.10.54321 8.8.8.8.53: 12345 A? www.example.com. (33) 14:22:31.145 IP 8.8.8.8.53 192.168.1.10.54321: 12345 1/0/0 A 93.184.216.34 (49)4.5 分析数据库连接# MySQL连接问题排查 tcpdump -i eth0 -nn port 3306 # 看MySQL协议内容 tcpdump -i eth0 -X port 3306 | grep -A5 Error # Redis连接 tcpdump -i eth0 -nn port 6379 -A4.6 排查网络丢包抓取重传包# 抓取TCP重传通过序列号判断 # 方法保存抓包文件用tshark分析 tcpdump -i eth0 -nn -w /tmp/capture.pcap tshark -r /tmp/capture.pcap -Y tcp.analysis.retransmission或者简单判断# 看有没有大量重复的seq tcpdump -i eth0 -nn tcp | awk {print $1,$2,$3,$4,$5} | sort | uniq -c | sort -rn | head5. 高级技巧5.1 抓包文件轮转长时间抓包防止文件过大# 每100MB切一个文件最多保留10个 tcpdump -i eth0 -w /tmp/capture.pcap -C 100 -W 10 # 每小时切一个文件 tcpdump -i eth0 -w /tmp/capture_%Y%m%d_%H%M%S.pcap -G 36005.2 远程抓包本地分析服务器上抓包传到本地用Wireshark分析# 方法1抓完传输 tcpdump -i eth0 -w /tmp/capture.pcap scp server:/tmp/capture.pcap . # 方法2实时传输需要网络稳定 ssh userserver tcpdump -i eth0 -w - port 80 | wireshark -k -i - # 方法3通过管道 ssh userserver tcpdump -i eth0 -nn -U -w - port 80 capture.pcap5.3 多节点同时抓包排查分布式系统问题经常需要在多台机器同时抓包。手动方式# 在多台机器上同时执行用时间戳对齐 tcpdump -i eth0 -nn -tt -w /tmp/capture_$(hostname).pcap port 8080批量方式用Ansible# capture.yml - hosts: all tasks: - name: 开始抓包 shell: | nohup tcpdump -i eth0 -nn -w /tmp/capture_{{ inventory_hostname }}.pcap \ port 8080 async: 60 poll: 0如果机器在不同网络环境逐个SSH登录很麻烦。我一般会用组网工具WireGuard、ZeroTier、星空组网这类先把机器串到一个虚拟网络然后Ansible批量执行。5.4 抓取指定进程的流量tcpdump本身不支持按进程过滤但可以曲线救国# 1. 找到进程监听的端口 ss -tlnp | grep nginx # 2. 按端口抓包 tcpdump -i eth0 port 80 or port 443 # 或者用strace跟踪进程的网络调用 strace -f -e tracenetwork -p $(pgrep nginx)5.5 抓取特定内容的包# 抓取包含error的HTTP响应 tcpdump -i eth0 -A port 80 | grep -i error # 抓取包含特定字符串的包 tcpdump -i eth0 -s0 -A | grep -B5 -A5 password # 使用ngrep更专业的内容过滤 ngrep -d eth0 GET port 806. 常用抓包命令速查# 抓取到某服务的所有连接 tcpdump -i eth0 -nn host 192.168.1.100 and port 8080 # 抓取新建连接 tcpdump -i eth0 -nn tcp[tcpflags] tcp-syn ! 0 and tcp[tcpflags] tcp-ack 0 # 抓取连接关闭 tcpdump -i eth0 -nn tcp[tcpflags] (tcp-fin|tcp-rst) ! 0 # 抓取大于1000字节的包 tcpdump -i eth0 -nn greater 1000 # 抓取HTTPS握手Client Hello tcpdump -i eth0 -nn tcp port 443 and (tcp[((tcp[12] 0xf0) 2)] 0x16) # 抓取ICMP错误包 tcpdump -i eth0 -nn icmp[icmptype] ! icmp-echo and icmp[icmptype] ! icmp-echoreply # 排除干扰流量 tcpdump -i eth0 -nn not port 22 and not arp and not port 537. 性能注意事项7.1 避免影响生产# 限制抓包速率 tcpdump -i eth0 -c 10000 # 只抓10000个包 # 只抓包头不抓内容 tcpdump -i eth0 -s 96 # 默认值够分析协议了 # 用BPF过滤减少内核到用户态的数据量 tcpdump -i eth0 port 80 # 比抓全部再grep好7.2 高流量场景# 增加buffer防止丢包 tcpdump -i eth0 -B 4096 -w capture.pcap # 用pfring等高性能抓包工具 # 或者直接用tc做流量镜像到分析机总结场景命令基础抓包tcpdump -i eth0 -nn抓特定主机tcpdump -i eth0 host 192.168.1.100抓特定端口tcpdump -i eth0 port 80抓TCP连接建立tcpdump tcp[tcpflags] tcp-syn ! 0抓RST包tcpdump tcp[tcpflags] tcp-rst ! 0保存到文件tcpdump -w capture.pcap看HTTP内容tcpdump -A port 80抓DNStcpdump -nn port 53排查思路先明确要抓什么流量构造过滤表达式抓包同时复现问题用Wireshark或tshark分析抓包文件对比正常和异常时的包找出差异tcpdump配合Wireshark基本能搞定大部分网络问题排查。