--- tags: [计算机网络, tcpdump, tshark, curl, dig, iptables, Wireshark] create time: 2026-05-18 04:50 --- # 抓包、HTTP 调试与 DNS 诊断工具 ## 概述 在前一章完成了"通不通"的判断之后,本章深入"报文到了没"和"内容对不对"。涵盖 tcpdump 抓包分析、curl HTTP 调试、dig DNS 诊断以及 iptables 规则排查。 ## tcpdump —— 命令行抓包神器 ### 基础语法与 BPF 过滤器精选 ```bash sudo tcpdump -i eth0 # 抓取 eth0 所有流量 sudo tcpdump -nn # -n: 不解析域名, -n: 不解析端口名 sudo tcpdump -c 100 # 抓 100 个包后停止 sudo tcpdump -w capture.pcap # 写入 pcap 文件(Wireshark 打开) sudo tcpdump -A 'port 80' # ASCII 模式打印 HTTP 内容 sudo tcpdump -X 'port 80' # HEX + ASCII 双列输出 ``` ### BPF (Berkeley Packet Filter) 表达式 ```bash # 按 IP 过滤 sudo tcpdump 'host 93.184.216.34' # 只看这个 IP # 按端口过滤 sudo tcpdump 'port 80' # HTTP sudo tcpdump 'port 443' # HTTPS sudo tcpdump 'port range 8000-9000' # 端口范围 # 组合过滤 sudo tcpdump 'src host 10.0.0.1 and dst port 443' # 源 → 目标端口 sudo tcpdump '(src net 192.168.1.0/24) or (dst net 10.0.0.0/8)' # 多网段 # 匹配 TCP 标志位(非常强大!) sudo tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0' # SYN+ACK sudo tcpdump 'tcp[tcpflags] & tcp-syn != 0' # SYN 包(新连接) sudo tcpdump 'tcp[13] & 0x04 != 0' # 同样匹配 SYN sudo tcpdump 'tcp[13] & 0x10 != 0' # ACK 标志位 sudo tcpdump 'tcp[tcpflags] & tcp-rst != 0' # RST 包(异常断开) sudo tcpdump 'tcp[tcpflags] & tcp-fin != 0' # FIN 包(正常关闭) # 排除法 sudo tcpdump 'not host 192.168.1.1 and not port 22' # 排除网关和 SSH ``` ### SYN 包实时观察 ```bash # 实时监控新连接建立 sudo tcpdump -nn 'tcp[tcpflags] & tcp-syn != 0' 08:23:45.123456 IP 192.168.1.100:54321 > 10.0.0.1:8080: S 12345678:12345678(...) 08:23:45.123789 IP 10.0.0.1:8080 > 192.168.1.100:54321: S 87654321:87654321(...) # ↑ 这就是三次握手的前两个包(SYN 和 SYN-ACK) # 监控 RST(异常断开) sudo tcpdump -nn 'tcp[tcpflags] & (tcp-rst) != 0' ``` > [!tip] tcpdump → Wireshark 工作流 > ```bash > # 1. tcpdump 后台抓包 > sudo tcpdump -w /tmp/app.pcap 'host 10.0.0.1 and port 8080' & > # 2. 复现问题 > # 3. Ctrl+C 停止抓包 > # 4. Wireshark 打开分析 > wireshark /tmp/app.pcap > # 5. Wireshark 支持深度解码 HTTP/gRPC/TLS 等协议 > ``` ## tshark —— CLI 版 Wireshark ```bash # 实时过滤 HTTP 请求 $ tshark -i eth0 -Y 'http.request' No. Time Source Destination Protocol Length Info 12 0.123456 10.0.0.1 93.184.xxx HTTP 450 GET /api/users HTTP/1.1 # 导出字段(CSV 风格) tshark -r capture.pcap -Y 'http' \ -T fields -e ip.src -e http.host -e http.request.uri # 只追踪 TLS 握手的 ClientHello tshark -Y 'tls.handshake.type == 1' # 1 = ClientHello, 11 = ServerHello, 12 = Certificate, etc. ``` ## curl —— HTTP 调试利器 ### 详细输出与计时分解 ```bash # -v: verbose 模式,看到完整的握手过程和头部交换 curl -v https://example.com * Trying 93.184.216.34:443... * Connected to example.com (93.184.216.34) port 443 * ALPN, offering h2 * ALPN, offering http/1.1 * TLSv1.3, TLS handshake, Client hello (1): * TLSv1.3, TLS handshake, Server hello (2): * TLSv1.3, Encrypted Extensions (8): * TLSv1.3, Certificate (11): * TLSv1.3, TLS handshake, Finished (5): * TLSv1.3, Encrypted Change Cipher (1): * ... SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 # -w: custom output 精确测量各阶段耗时 💡 curl -w '\nDNS Resolve: %{time_namelookup}s\nTCP Connect: %{time_connect}s\nTLS Handshake: %{time_appconnect}s\nFirst Byte: %{time_starttransfer}s\nTotal: %{time_total}s\n' \ -o /dev/null -s https://example.com # 输出示例: # DNS Resolve: 0.01234s # TCP Connect: 0.01567s # TLS Handshake: 0.04567s # First Byte: 0.15678s # Total: 0.23456s ``` ``` 耗时瓶颈分析: ├─ time_namelookup > 0.1s → DNS 慢 → 考虑 DNS 缓存 ├─ time_connect - time_namelookup > 0.1s → TCP 连接慢 → 距离远/NAT 问题 ├─ time_appconnect - time_connect > 0.2s → TLS 握手慢 → 证书链长/无 session resumption └─ time_starttransfer - time_appconnect > 0.5s → 服务端处理慢 → 查应用日志 ``` ### curl 实战用法 ```bash # 自定义 Header 和认证 curl -H 'Authorization: Bearer token' \ -H 'Content-Type: application/json' \ -X POST -d '{"name":"alice"}' \ https://api.example.com/users # 跟踪重定向(最多 5 层) curl -L --max-redirs 5 https://short.link # 查看响应头(快速判断 CDN/缓存状态) curl -I https://cdn.example.com/style.css HTTP/2 200 cache-control: public, max-age=86400 age: 1234 x-cache: HIT # ← CDN 命中 cf-cache-status: HIT # ← Cloudflare 标记 content-encoding: br # ← Brotli 压缩 # SSL 证书检查 openssl s_client -connect example.com:443 -servername example.com # 关注: # Verify return code: 0 (ok) ✅ # Verify return code: 20 (unable to get local issuer certificate) ❌ # JSON 美化输出 curl https://jsonplaceholder.typicode.com/users/1 | python3 -m json.tool ``` ## dig —— DNS 诊断最强工具 ### 常用查询模式 ```bash # A 记录简洁输出 $ dig example.com +short 93.184.216.34 # AAAA 记录(IPv6) $ dig example.com AAAA +short 2606:2800:220:1:248:1893:25c8:1946 # 权威追踪(从根域名开始逐级查询) $ dig example.com +trace ;; ->>HEADER<<- opcode: QUERY, status: NOERROR ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 300 IN A 93.184.216.34 # 指定 DNS 服务器对比 $ dig @8.8.8.8 example.com # Google DNS $ dig @1.1.1.1 example.com # Cloudflare DNS $ dig @local_dns_server example.com # 本地 DNS(可能被污染) # TXT 记录(SPF / DKIM 验证邮件配置) $ dig example.com TXT +short "v=spf1 include:_spf.google.com ~all" # MX 记录(邮件服务器) $ dig example.com MX +short 10 mail.example.com. 20 mail2.example.com. # SRV 记录(服务发现,gRPC/Kafka 常用) $ dig _grpc._tcp.service.consul SRV +short 0 100 8080 api.service.consul. # 查看 CNAME 链全貌 $ dig www.example.com +multiline ``` ### dig 高级用法 ```bash # 区域传输(AXFR,通常被禁止) $ dig @ns1.example.com example.com axfr # EDNS Client Subnet(CDN 优化用户体验的关键) $ dig +ecs=203.0.113.0/24 example.com @1.1.1.1 # DNS resolver 把自己的子网发给 authoritative server # → authoritative server 返回离用户最近的 CDN 节点 IP # DoH(DNS over HTTPS)检测 $ curl https://dns.google/resolve?name=example.com&type=A {"Status":0,"Answer":[{"name":"example.com","type":5,"data":"93.184.216.34",...}]} ``` ## iptables / nftables 规则排查 ```bash # iptables 规则排查步骤 sudo iptables -L -n -v # 列出 FILTER 表所有规则及计数器 sudo iptables -t nat -L -n -v # 查看 NAT 表(SNAT/DNAT/MASQUERADE) sudo iptables -t mangle -L -n -v # 查看 MANGLE 表(TOS/TTL 修改) # 关键排查命令 sudo iptables-save | grep -A 5 INPUT # 只看 INPUT chain 的上下文 sudo iptables -L FORWARD -n -v --line-numbers # 转发规则(容器/代理场景必查) # 常见规则导致的"假故障" # ❌ 忘记放行容器的桥接流量 iptables -I FORWARD -i docker0 -j ACCEPT # ❌ 没有启用 IP forwarding sysctl net.ipv4.ip_forward=1 # nftables(iptables 的现代替代品) sudo nft list ruleset # 列出所有 nft 规则 sudo nft add rule inet filter input tcp dport 22 accept ``` ## 关联笔记 - [[hhs/NETWORK/连通性与状态探测工具]] — 先看 ping/ss/telnet 再决定要不要抓包 - [[hhs/NETWORK/ICMP与Ping-Traceroute]] — ping/traceroute 协议原理 - [[hhs/NETWORK/DNS与DHCP与WebSocket]] — DNS 递归查询流程补充 dig 实操 - [[hhs/NETWORK/TCP三次握手与四次挥手]] — tcpdump 中观察 SYN/ACK 交互细节