传统 ping 和 traceroute 的局限:
ping:只能看端到端通断,不知道哪一跳出了问题traceroute:单次采样,无法反映网络抖动和丢包规律MTR(My Traceroute) = ping + traceroute + 持续统计,实时显示每一跳的延迟和丢包率。
展开代码┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ 本地主机 │ ──→ │ 路由器1 │ ──→ │ 路由器2 │ ──→ │ 目标主机 │ │ MTR发送 │ │ TTL=1 │ │ TTL=2 │ │ TTL=到达 │ │ ICMP包 │ │ 返回ICMP │ │ 返回ICMP │ │ 返回ICMP │ │ │ │ Time Exceeded │ Time Exceeded │ Echo Reply │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ ↑_________________________________________________| 持续发送,实时统计
展开代码# Debian/Ubuntu sudo apt install mtr-tiny # 精简版,无GTK依赖 sudo apt install mtr # 完整版,带图形界面 # RHEL/CentOS sudo yum install mtr # macOS brew install mtr # 注意:macOS需要sudo运行 sudo mtr google.com
基础命令:
展开代码# 默认ICMP模式(需要root) sudo mtr google.com # TCP模式(绕过ICMP限制,更真实) sudo mtr -T -P 80 google.com # UDP模式(模拟DNS等UDP流量) sudo mtr -U -P 53 8.8.8.8 # 指定发包数量和间隔 sudo mtr -c 100 -i 0.5 google.com # 发100个包,间隔0.5秒 # 报告模式(非交互,适合脚本) mtr -r -c 100 google.com > mtr_report.txt
展开代码Keys: Help Display mode Restart statistics Order of fields quit Packets Pings Host Loss% Snt Last Avg Best Wrst StDev 1. 192.168.1.1 0.0% 10 0.5 0.6 0.4 1.2 0.2 2. 10.10.10.1 0.0% 10 1.2 1.5 1.1 2.3 0.3 3. 172.16.0.1 0.0% 10 2.1 2.8 2.0 5.4 1.0 4. ??? 5. 202.97.1.1 0.0% 10 15.2 18.5 14.8 45.6 8.2 6. 202.97.2.2 0.0% 10 16.8 19.2 15.5 52.3 10.1 7. 72.14.221.34 0.0% 10 185.2 190.5 182.3 250.6 20.3 8. 108.170.246.1 0.0% 10 186.5 188.2 184.1 210.4 7.8 9. 142.250.4.46 0.0% 10 185.8 187.6 183.9 205.2 6.2 10. google.com 0.0% 10 184.3 186.1 182.5 198.7 5.1
| 字段 | 含义 | 排查要点 |
|---|---|---|
Loss% | 丢包率 | 关键指标,>5%需关注 |
Snt | 已发送包数 | 样本量,建议>100 |
Last | 最后一个包延迟 | 实时参考 |
Avg | 平均延迟 | 基准性能 |
Best | 最小延迟 | 理论最优 |
Wrst | 最大延迟 | 抖动程度 |
StDev | 标准差 | >10说明抖动严重 |
展开代码现象:访问国外网站慢,MTR显示: 3. 202.97.1.1 0.0% 50 15.2 16.5 14.8 45.6 8.2 4. ??? 100.0 50 0.0 0.0 0.0 0.0 0.0 5. 72.14.221.34 5.0% 50 185.2 190.5 182.3 250.6 20.3 分析: - 第4跳显示???,可能是路由器禁ICMP - 但第5跳开始丢包5%,延迟跳到185ms - 结论:第4-5跳之间(国际出口)是瓶颈
展开代码5. 202.97.1.1 0.0% 100 15.2 45.6 14.8 200.5 52.3 关键:StDev=52.3极大,Best=14.8但Wrst=200.5 结论:该路由器负载不均或存在拥塞
展开代码# 客户端执行 sudo mtr -r -c 100 server_ip > client_mtr.txt # 服务器端执行(同时) sudo mtr -r -c 100 client_ip > server_mtr.txt # 对比两份报告,确定是上行还是下行问题
展开代码# 显示AS号(运营商自治系统) mtr -z google.com # 显示IP地理位置 mtr -g google.com # 需要GeoIP库 # JSON输出(自动化处理) mtr -j -c 10 google.com | jq '.report.hubs[] | {host: .host, loss: .Loss%}' # 持续监控并告警 while true; do mtr -r -c 10 target | awk '/target/{if($(NF-4)+0>5) print "ALERT: Loss > 5%"}' sleep 60 done
| 特性 | Wireshark | TShark |
|---|---|---|
| 界面 | GTK/Qt图形界面 | 纯命令行 |
| 适用场景 | 交互式分析 | 服务器远程排查、脚本自动化 |
| 资源占用 | 高(需X11) | 极低 |
| 输出格式 | 可视化 | 文本/JSON/PostScript |
| 实时过滤 | 图形点选 | 命令行表达式 |
TShark 是 Wireshark 的 CLI 版本,底层引擎相同,过滤语法完全一致。
展开代码# Debian/Ubuntu sudo apt install tshark # 安装时会提示是否允许非root用户抓包,生产环境建议选No # RHEL/CentOS sudo yum install wireshark-cli # macOS brew install wireshark # 包含tshark
权限配置(非root使用):
展开代码# 方法1:添加到wireshark组 sudo usermod -a -G wireshark $USER sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/dumpcap # 方法2:sudo运行(推荐生产环境) sudo tshark ...
展开代码# 列出可用网卡 tshark -D # 输出: # 1. eth0 # 2. any (Pseudo-device that captures on all interfaces) # 3. lo # 基础抓包(默认eth0,持续输出) sudo tshark -i eth0 # 指定抓包数量后停止 sudo tshark -i eth0 -c 100 # 保存到文件(pcap格式,Wireshark可打开) sudo tshark -i eth0 -w capture.pcap # 读取pcap文件分析 tshark -r capture.pcap
展开代码# 只抓特定主机 sudo tshark -f "host 192.168.1.100" # 只抓特定端口 sudo tshark -f "port 80" sudo tshark -f "tcp port 443" # 特定网段 sudo tshark -f "net 10.0.0.0/24" # 排除特定流量 sudo tshark -f "not port 22" # 过滤掉SSH # 复杂组合 sudo tshark -f "host 192.168.1.1 and (port 80 or port 443)"
展开代码# 只显示HTTP GET请求 tshark -r capture.pcap -Y "http.request.method == GET" # 特定HTTP状态码 tshark -r capture.pcap -Y "http.response.code == 500" # DNS查询 tshark -r capture.pcap -Y "dns.flags.response == 0" # TCP重传(网络质量指标) tshark -r capture.pcap -Y "tcp.analysis.retransmission" # 慢响应(>1秒) tshark -r capture.pcap -Y "frame.time_delta > 1"
展开代码# 提取特定字段(HTTP host和URI) tshark -r capture.pcap -T fields \ -e http.host \ -e http.request.uri \ -Y "http.request" # 输出示例: # www.example.com /api/users # api.example.com /v1/orders # 统计TOP 10访问IP tshark -r capture.pcap -T fields -e ip.src | sort | uniq -c | sort -rn | head -10 # 统计HTTP状态码分布 tshark -r capture.pcap -Y "http.response" -T fields -e http.response.code | sort | uniq -c # 计算平均响应时间(需启用TCP时间戳) tshark -r capture.pcap -q -z io,stat,0.1,"tcp.analysis.ack_rtt"
展开代码sudo tshark -i eth0 -f "tcp port 80" -Y "http.response.code >= 500" \ -T fields -e ip.src -e http.response.code -e http.response.phrase
展开代码# 统计SYN包数量(无ACK) sudo tshark -i eth0 -f "tcp" -Y "tcp.flags.syn == 1 and tcp.flags.ack == 0" -c 1000 | wc -l # 正常应远小于总连接数,若接近则可能是攻击
展开代码sudo tshark -i eth0 -f "tcp port 443" -Y "tls.handshake.type == 2" \ -T fields -e ip.src -e tls.handshake.version
展开代码sudo tshark -i eth0 -f "tcp port 3306" \ -Y "mysql.query and frame.time_delta > 1" \ -T fields -e ip.src -e mysql.query
展开代码# JSON格式(便于程序处理) tshark -r capture.pcap -T json -Y "http.request" > http_requests.json # EK格式(Elasticsearch直接导入) tshark -r capture.pcap -T ek -Y "http" > http_ek.json # 生成统计报告 tshark -r capture.pcap -q -z conv,ip > ip_conversations.txt tshark -r capture.pcap -q -z io,phs > protocol_hierarchy.txt
完整案例:用户反馈访问慢
展开代码# 步骤1:MTR定位网络层 sudo mtr -T -P 80 -c 100 slow.example.com # 发现第5跳丢包10%,延迟抖动大 # 步骤2:TShark抓包分析应用层 sudo tshark -i eth0 -f "host slow.example.com" -w slow_traffic.pcap -a duration:60 # 步骤3:分析抓包文件 # 查看TCP重传 tshark -r slow_traffic.pcap -Y "tcp.analysis.retransmission" | wc -l # 查看HTTP响应时间分布 tshark -r slow_traffic.pcap -Y "http.response" \ -T fields -e frame.time_delta -e http.response.code | sort -n # 步骤4:结论 # - MTR显示网络层某跳丢包 # - TShark显示大量TCP重传和HTTP 504 # - 综合判断:该跳路由器拥塞导致应用层超时
| 场景 | 推荐工具 | 关键命令 |
|---|---|---|
| 网络不通/延迟高 | MTR | mtr -T target |
| 偶发性网络抖动 | MTR + TShark | mtr -i 0.1 + 持续抓包 |
| HTTP API故障 | TShark | tshark -Y "http" |
| DNS解析问题 | TShark | tshark -Y "dns" |
| TLS/SSL握手失败 | TShark | tshark -Y "tls.handshake" |
| 带宽占用分析 | TShark | tshark -q -z conv,ip |
| DDoS攻击溯源 | TShark + MTR | 统计来源IP + 路径追踪 |
| 自动化监控 | TShark JSON输出 | tshark -T json |
展开代码#!/bin/bash # network_diagnose.sh - 综合网络诊断 TARGET=${1:-google.com} PORT=${2:-80} INTERFACE=${3:-eth0} OUTPUT_DIR="./diag_$(date +%Y%m%d_%H%M%S)" mkdir -p $OUTPUT_DIR echo "========== 网络诊断报告 ==========" echo "目标: $TARGET:$PORT" echo "时间: $(date)" echo "==================================" # 1. 基础连通性 echo "[1/5] 基础连通性测试..." ping -c 10 $TARGET > $OUTPUT_DIR/ping.txt 2>&1 # 2. MTR路径分析 echo "[2/5] MTR路径追踪..." sudo mtr -r -c 100 -T -P $PORT $TARGET > $OUTPUT_DIR/mtr.txt 2>&1 # 3. TShark抓包(30秒) echo "[3/5] TShark抓包30秒..." sudo timeout 30 tshark -i $INTERFACE -f "host $(dig +short $TARGET | head -1)" \ -w $OUTPUT_DIR/capture.pcap 2>/dev/null || true # 4. 分析抓包 echo "[4/5] 分析抓包文件..." if [ -f $OUTPUT_DIR/capture.pcap ]; then tshark -r $OUTPUT_DIR/capture.pcap -q -z io,stat,1 > $OUTPUT_DIR/io_stats.txt tshark -r $OUTPUT_DIR/capture.pcap -Y "tcp.analysis.retransmission" 2>/dev/null | wc -l > $OUTPUT_DIR/retrans_count.txt fi # 5. 生成摘要 echo "[5/5] 生成摘要..." cat > $OUTPUT_DIR/summary.txt << EOF 诊断摘要 ======== 目标: $TARGET:$PORT MTR关键指标: $(grep -A1 "Host" $OUTPUT_DIR/mtr.txt | tail -1) 丢包最严重的一跳: $(awk 'NR>2 && $3!="???" {print $3, $4}' $OUTPUT_DIR/mtr.txt | sort -k2 -rn | head -1) TCP重传次数: $(cat $OUTPUT_DIR/retrans_count.txt 2>/dev/null || echo "N/A") 建议: $(if [ $(cat $OUTPUT_DIR/retrans_count.txt 2>/dev/null || echo 0) -gt 10 ]; then echo "- 检测到大量TCP重传,建议检查网络质量或增加应用层超时" else echo "- 网络层无明显异常,建议检查应用层日志" fi) EOF echo "诊断完成,结果保存在: $OUTPUT_DIR" cat $OUTPUT_DIR/summary.txt
本文作者:zzz
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!