刚接手一台服务器就发现网络异常?应用突然出现高延迟却找不到原因?这类问题在实际运维中太常见了。传统的ping/traceroute只能告诉我们"有问题",但具体是什么包被丢弃、哪个环节出问题,往往需要更专业的工具。
tcpdump作为网络分析领域的"瑞士军刀",能在数据链路层捕获原始报文。与Wireshark这类图形化工具相比,它的优势在于:
我在处理跨国网络问题时,曾用tcpdump在30秒内定位到是某中间节点错误分片导致的问题。下面分享我的标准排查流程。
大多数系统已预装tcpdump,如需安装:
bash复制# RHEL/CentOS
sudo yum install -y tcpdump
# Ubuntu/Debian
sudo apt-get install -y tcpdump
注意:普通用户使用时需要sudo权限,生产环境建议通过sudoers精确控制权限:
code复制Cmnd_Alias NETWORK = /usr/sbin/tcpdump
%admin ALL=(ALL) NOPASSWD: NETWORK
最简捕获命令(需root权限):
bash复制sudo tcpdump -i any -w capture.pcap
-i any 监听所有网卡-w 保存原始数据包按Ctrl+C停止捕获后,用下面命令查看统计:
bash复制tcpdump -r capture.pcap -q -nn -t | awk '{print $3}' | sort | uniq -c | sort -n
先捕获ICMP协议(ping使用的协议):
bash复制sudo tcpdump -i eth0 icmp -nn -v
在另一个终端执行ping测试:
bash复制ping -c 4 8.8.8.8
健康情况下应看到类似输出:
code复制IP (tos 0x0, ttl 64, id 1234, offset 0, flags [DF], proto ICMP (1), length 84)
192.168.1.100 > 8.8.8.8: ICMP echo request, id 1234, seq 1, length 64
IP (tos 0x0, ttl 118, id 5678, offset 0, flags [none], proto ICMP (1), length 84)
8.8.8.8 > 192.168.1.100: ICMP echo reply, id 1234, seq 1, length 64
如果只有request没有reply,说明:
对于Web服务等TCP应用,捕获特定端口:
bash复制sudo tcpdump -i eth0 'tcp port 80 and (tcp-syn|tcp-rst|tcp-ack)' -nn -v
关键标志位解读:
[S] SYN:连接请求[.] ACK:确认响应[R] RST:连接重置[F] FIN:连接终止典型问题模式:
使用时间戳分析延迟:
bash复制sudo tcpdump -i eth0 -tttt -nn 'host 1.2.3.4 and port 443' -w https.pcap
然后用Wireshark分析TCP握手时序:
我曾用这个方法发现某云厂商的负载均衡器在TCP窗口缩放协商时增加了200ms延迟,最终通过调整内核参数解决:
bash复制echo 0 > /proc/sys/net/ipv4/tcp_slow_start_after_idle
常用过滤条件示例:
bash复制# 捕获特定子网的DNS查询
tcpdump -i eth0 'udp port 53 and net 192.168.1.0/24'
# 捕获HTTP GET请求
tcpdump -i eth0 'tcp port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
# 排除SSH流量
tcpdump -i eth0 'not port 22'
大流量场景下的优化:
bash复制sudo tcpdump -i eth0 -B 4096 -s 96 -G 300 -W 5 -w /var/tmp/cap-%H-%M.pcap
-B 设置缓冲区大小(单位KB)-s 限制每个包捕获长度-G 按时间分割文件(秒)-W 最大文件轮转数Docker容器网络捕获方法:
bash复制# 查找容器PID
docker inspect --format '{{.State.Pid}}' nginx
# 进入容器网络命名空间
nsenter -n -t <PID> tcpdump -i eth0
bash复制ip link show eth0 | grep -i promisc
ip addr 确认实际使用的网卡报错:tcpdump: eth0: You don't have permission...
解决方法:
bash复制sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
报错:dropped packets
调整缓冲区大小:
bash复制sudo sysctl -w net.core.rmem_max=26214400
-c参数限制包数量-G参数轮转文件bash复制tcpdump -i eth0 -w /tmp/cap.pcap 'not (port 22 or port 3306)'
bash复制watch -n 1 'cat /proc/net/dev | grep eth0'
某电商API平均响应从50ms突增到800ms,通过以下步骤定位:
捕获问题时段流量:
bash复制sudo tcpdump -i eth0 'port 8080' -G 60 -w /tmp/api-%H-%M.pcap
分析发现:
最终定位:
ethtool -S eth0 确认error计数增长这个案例展示了tcpdump与其他工具(ethtool)的配合使用方法。实际网络问题往往需要多维度数据交叉验证。