2.7.6 典型场景抓包分析与结论输出
6. 典型场景抓包分析与结论输出#
本节以“现象—抓包要点—结论输出—验证/修复”的方式组织,提供可复用的抓包流程、命令示例与练习题。所有抓包示例以 tcpdump 为主,必要时配合 ss、iptables、sysctl 等工具。
6.0 基础环境与抓包位置选择#
安装与准备(任选其一发行版):
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y tcpdump wireshark tshark
# RHEL/CentOS
sudo yum install -y tcpdump wireshark
# 验证
tcpdump --version
抓包位置原则:优先在“问题链路两端 + 中间设备”抓包对比,形成证据链。
基础命令模板:
# 1) 查看网卡
ip -br a
# 2) 基础抓包(显示时间、来源/目的、保存文件)
sudo tcpdump -i eth0 -nn -tttt -s 0 -w /tmp/cap.pcap
# 3) 抓包同时观察(不写文件)
sudo tcpdump -i eth0 -nn -tttt -s 0 'tcp port 80'
原理草图(抓包点选择):
6.1 TCP 三次握手失败#
现象:连接超时或拒绝连接。
抓包要点:过滤 SYN,查看是否有 SYN-ACK、是否重传、是否 RST。
示例抓包:
# 客户端抓包:只看握手
sudo tcpdump -i eth0 -nn -s 0 -vv 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0' -w /tmp/hs_fail.pcap
# 同时查看端口监听情况
ss -lntp | grep ':8080'
分析结论与排错:
- 仅见 SYN 多次重传:防火墙丢弃、路由不可达或端口未监听。
- 有 SYN-ACK 无 ACK:客户端侧丢包或回程被丢。
- 收到 RST:端口未监听或安全策略拒绝。
修复/验证命令:
# 查看防火墙策略是否拦截
sudo iptables -L -n --line-numbers | sed -n '1,120p'
# 验证端口是否开放
nc -vz 10.0.0.12 8080
练习:
1) 关闭服务端端口监听,观察客户端抓包 SYN 重传现象。
2) 开启端口后重新抓包对比。
6.2 TCP 连接被重置(RST)#
现象:短连接异常断开,应用报 “connection reset”。
抓包要点:定位 RST 方向,观察是否紧跟应用数据。
示例抓包:
sudo tcpdump -i eth0 -nn -s 0 -vv 'tcp[tcpflags] & tcp-rst != 0'
分析结论与排错:
- 服务端发 RST:应用进程崩溃、端口关闭或主动拒绝。
- 客户端发 RST:客户端超时关闭或本地安全策略。
- RST 紧跟大包发送:中间设备触发阈值。
修复建议:
- 检查服务端日志与进程存活:systemctl status service。
- 检查中间设备会话超时与 ACL。
练习:
模拟服务端进程退出,确认客户端收到 RST。
6.3 连接建立成功但无响应#
现象:握手完成后业务超时。
抓包要点:确认应用请求是否发出、服务端是否回包,观察重传与窗口。
示例抓包:
# 抓请求与响应,保存 pcap 供 Wireshark 分析
sudo tcpdump -i eth0 -nn -s 0 -w /tmp/app_noresp.pcap 'tcp port 8080'
# 查看应用层是否输出响应
curl -v --max-time 3 http://10.0.0.12:8080/health
结论输出:
- 请求已发送但无响应:服务端应用阻塞或后端依赖故障。
- 响应已回但客户端无 ACK:客户端接收链路问题或丢包。
- 多次重传:链路丢包或拥塞。
修复验证:
# 观察服务端线程或连接池
ss -s
top -H -p $(pidof your_app)
练习:
使用 tc netem 模拟丢包,观察重传与超时。
sudo tc qdisc add dev eth0 root netem loss 10%
# 复现后再清理
sudo tc qdisc del dev eth0 root
6.4 DNS 解析慢或失败#
现象:域名解析超时,业务波动。
抓包要点:过滤 udp.port==53,查看请求/响应延迟与重试。
示例抓包:
sudo tcpdump -i eth0 -nn -s 0 -w /tmp/dns.pcap 'udp port 53'
dig +time=1 +tries=1 example.com @10.0.0.53
结论输出:
- 无响应且重试:DNS 服务器不可达或被防火墙拦截。
- 响应慢且多次切换服务器:上游 DNS 质量差。
- SERVFAIL/NXDOMAIN:配置或域名错误。
排错命令:
# 查看 resolv.conf
cat /etc/resolv.conf
# 直接测试连通性
nc -vzu 10.0.0.53 53
练习:
将 /etc/resolv.conf 临时指向不存在的 DNS,观察抓包中的重试与超时。
6.5 HTTP 访问慢或异常#
现象:网页慢、接口 5xx/4xx。
抓包要点:过滤 80/443,统计请求-响应时间,关注重传与窗口。
示例抓包:
sudo tcpdump -i eth0 -nn -s 0 -w /tmp/http.pcap 'tcp port 80'
curl -w '\nconnect:%{time_connect} ttfb:%{time_starttransfer} total:%{time_total}\n' -o /dev/null -s http://10.0.0.12/
结论输出:
- TCP 正常但 HTTP 响应慢:应用处理慢或后端依赖迟缓。
- 频繁重传且 RTT 增大:链路拥塞或丢包。
- 413/414/431:请求体/头过大。
修复建议:
- 调整 Nginx client_max_body_size、large_client_header_buffers。
练习:
构造超大请求头,验证 431。
6.6 MTU/分片导致的访问异常#
现象:小包正常,大包失败。
抓包要点:观察 DF 位与 ICMP “Fragmentation needed”。
示例抓包:
# 发送带 DF 的大包探测 MTU
ping -M do -s 1472 10.0.0.12
# 抓 ICMP 报文
sudo tcpdump -i eth0 -nn -s 0 'icmp'
结论输出:
- 无 ICMP 返回且大包失败:路径 MTU 黑洞。
- ICMP 返回明确:调整 MTU 或启用 MSS Clamp。
修复示例:
# 临时降低网卡 MTU
sudo ip link set dev eth0 mtu 1400
# 重新探测
ping -M do -s 1372 10.0.0.12
练习:
在两台机器之间设置不同 MTU,观察访问异常的包特征。
6.7 负载均衡后端不稳定#
现象:间歇性 502/504。
抓包要点:在 LB 与后端分别抓包比对。
示例抓包:
# LB 上抓前后端
sudo tcpdump -i eth0 -nn -s 0 -w /tmp/lb_front.pcap 'tcp port 80'
sudo tcpdump -i eth1 -nn -s 0 -w /tmp/lb_back.pcap 'tcp port 8080'
# 访问测试
curl -I http://lb.example.com/
结论输出:
- LB 出口无转发:健康检查失败或粘滞异常。
- 后端响应超时:后端性能不足或连接池耗尽。
- 后端返回正常但 LB 超时:LB 超时配置偏小。
排错建议:
- 检查 LB 超时与重试参数;
- 检查后端线程/连接池。
练习:
降低 LB 超时,观察 504。
6.8 TLS/HTTPS 握手失败#
现象:HTTPS 连接失败或证书错误。
抓包要点:观察 ClientHello/ServerHello、证书链与 Alert。
示例抓包:
sudo tcpdump -i eth0 -nn -s 0 -w /tmp/tls.pcap 'tcp port 443'
openssl s_client -connect 10.0.0.12:443 -servername example.com -tls1_2
结论输出:
- 无 ServerHello:服务端未监听 443 或中间设备拦截。
- handshake_failure:协议版本/加密套件不匹配。
- certificate_unknown:证书链缺失或过期。
修复建议:
- 更新证书链,启用兼容套件。
练习:
禁用 TLS1.2,观察握手失败的 Alert。
6.9 Redis/MySQL 连接抖动#
现象:连接池频繁断开重连。
抓包要点:查看 TCP keepalive、FIN/RST 方向。
示例抓包:
# 观察连接的关闭方向
sudo tcpdump -i eth0 -nn -s 0 -w /tmp/db_conn.pcap 'tcp port 3306 or tcp port 6379'
# 查看服务端超时配置
mysql -e "SHOW VARIABLES LIKE 'wait_timeout';"
redis-cli CONFIG GET timeout
结论输出:
- 服务端先发 FIN:空闲连接被服务器关闭。
- 中间设备发 RST:会话超时。
- 客户端先发 FIN:连接池回收策略激进。
修复示例:
# MySQL 调大 wait_timeout
mysql -e "SET GLOBAL wait_timeout=28800;"
# Linux 开启 TCP keepalive
sudo sysctl -w net.ipv4.tcp_keepalive_time=300
sudo sysctl -w net.ipv4.tcp_keepalive_intvl=30
sudo sysctl -w net.ipv4.tcp_keepalive_probes=5
练习:
调小 MySQL wait_timeout,观察连接断开方向。
6.10 结论输出模板(建议统一格式)#
模板(可直接复用):
现象描述:2024-xx-xx 10:00-10:15,订单服务间歇性超时,影响 20% 请求。
抓包位置:客户端 eth0、LB eth1、后端 eth0;涉及 IP 10.0.0.10/11/12。
证据点:客户端 SYN 重传 3 次,LB 无转发;后端无对应会话。
分析结论:LB 健康检查失败导致未转发;非链路丢包。
建议措施:修复健康检查路径,调整超时;恢复后验证无重传。
练习:
任选一个场景,使用上述模板写出完整结论并标注关键证据包序号。