HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 代理技术全栈手册

    • 代理技术全栈手册 - HiHuo
    • 原理篇

      • 第01章 代理是什么:正向 / 反向 / 透明 / 隧道的统一模型
      • 第02章 代理与网络层级:L3 / L4 / L5 / L7 在哪里截断流量
      • 第03章 一个请求穿过代理的一生:连接生命周期全景
    • 协议篇

      • 第04章 HTTP 代理协议:绝对 URI、CONNECT 隧道、转发头与连接池
      • 第05章 HTTPS 与 TLS 代理:终止 / 透传 / MITM / SNI / mTLS
      • 第06章 SOCKS 协议:SOCKS4/4a/5 与 UDP ASSOCIATE 报文级解析
      • 第07章 HTTP/2、gRPC 与 HTTP/3(QUIC) 代理的挑战
      • 第08章 代理自动配置:PAC / WPAD / 系统代理 / NO_PROXY
    • 层级与转发篇

      • 第09章 L4 代理:TCP/UDP 转发与连接级负载均衡
      • 第10章 L7 代理:协议感知与基于内容的路由
      • 第11章 透明代理:iptables REDIRECT/DNAT、TPROXY 与 eBPF 劫持
      • 第12章 数据搬运的艺术:splice / sendfile / 零拷贝 / io_uring
    • 组件横评篇

      • 第13章 Nginx / OpenResty:反向代理、upstream 与 Lua 可编程
      • 第14章 HAProxy:L4/L7、ACL、健康检查与 stick table
      • 第15章 Envoy:xDS 动态配置与 filter chain,为何是云原生数据面
      • 第16章 Traefik / Caddy:自动服务发现与自动 HTTPS
      • 第17章 Squid 与正向/缓存代理:企业出网、缓存与审计
      • 第18章 mitmproxy:抓包、改包、脚本化调试
      • 第19章 内网穿透与隧道:frp / gost / SSH 隧道 / ngrok
      • 第20章 科学上网生态的技术原理(技术中立)
    • 多语言手写篇

      • 第21章 Go:100 行手写 HTTP/CONNECT + SOCKS5 代理
      • 第22章 Rust:基于 tokio 的高性能 TCP 代理
      • 第23章 Python:asyncio 实现,适合调试与脚本
      • 第24章 C:epoll 裸写与零拷贝,及语言选型对比
    • 容器与K8s篇

      • 第25章 Docker 里的代理:HTTP_PROXY、build/pull 与 daemon 配置
      • 第26章 Sidecar 与流量劫持:Istio init-container 的 iptables 原理
      • 第27章 Ingress 与南北流量:Ingress-nginx 与 Gateway API
      • 第28章 Egress 与出网治理:出口网关、registry mirror、审计
      • 第29章 Service Mesh 数据面:Envoy Sidecar 全链路
    • 进阶篇

      • 第30章 可编程代理:Lua / Wasm / eBPF / xDS,代理的"软件定义"
      • 第31章 性能调优:并发模型、连接池、超时与重试、压测
      • 第32章 排错决策树:502 / 504 / 握手失败 / 环路 / 泄漏
      • 第33章 代理安全:开放代理、SSRF、凭证泄漏与攻击面
    • 底层机制篇

      • 第34章 代理的背压与流控:一个代理最难的部分
      • 第35章 socket 与 TCP 状态机:半关闭、超时、连接生命周期
      • 第36章 HTTP/2 帧、流控与 HPACK:h2 代理的内部机制
      • 第37章 负载均衡算法推导与韧性状态机
      • 第38章 Capstone:把玩具代理改造成生产级骨架
    • 综合实战篇

      • 第39章 企业多跳转发链:拓扑、协议矩阵与贯穿性难题
      • 第40章 端到端实战:把 6 类流量全代理通
      • 第41章 更刁钻的流量:gRPC、长轮询、WebRTC、大文件、双向流
      • 第42章 可落地完整参考实现:一套能跑的多协议转发栈
    • 附录

      • 附录 A:代理协议报文速查(HTTP / SOCKS / PAC / PROXY protocol)
      • 附录 B:组件选型决策树
      • 附录 C:抓包与命令速查

第32章 排错决策树:502 / 504 / 握手失败 / 环路 / 泄漏

学习目标

  • 掌握代理排错的总方法论:沿生命周期分段二分定位
  • 备齐排错工具箱,知道每个工具看什么层
  • 用一棵决策树,从症状快速定位到根因
  • 把全书各章的故障场景收口成可操作的排查路径

前置知识

  • 第03章 连接生命周期与阶段故障(本章的骨架)
  • 全书各章的"排错"小节

原理

总方法论:分段二分

代理把一条连接拆成两段(第01章):客户端→代理 和 代理→源站。排错第一步永远是确定故障在哪一段:

  客户端 ──①── 代理 ──②── 源站

  在代理上直接 curl 源站:
    通 → 问题在 ① 段(客户端到代理)
    不通 → 问题在 ② 段(代理到源站)

然后沿 第03章 的生命周期阶段(DNS→连接→认证→连源站→转发→回写)逐段二分,用 curl -w 的分段计时锁定是哪一步慢/断。

工具箱:每个工具看哪一层

工具看什么用于
curl -v -w分段计时、请求/响应头定位慢在哪段(第03章)
tcpdump/tshark字节流、TLS 握手、SNI连不连得通、握手对不对(第01章/第02章)
mitmproxy应用层明文请求内容对不对(第18章)
ss/netstat连接状态/数量CLOSE_WAIT、TIME_WAIT、连接泄漏
dig/nslookupDNS 解析DNS 错/泄漏(第03章)
openssl s_client证书链、ALPN、SNITLS 握手失败、MITM(第05章)
代理日志错误码、上游状态代理视角的真相

排错决策树(从症状出发)

症状?
├─ 502 Bad Gateway ──────────▶ 代理→源站这一跳"坏了"
│   ├─ 代理上 curl 源站不通? → 源站宕/端口错/网络(②段,第03章)
│   ├─ DNS 解析失败?        → 代理侧 DNS/内网域名(第03/08章)
│   └─ 源站返回非法响应?     → 协议不匹配(如 h2 后端配成 h1,第07章)
│
├─ 504 Gateway Timeout ──────▶ 代理→源站"超时"
│   └─ 源站慢/负载高,或 read timeout 太短(第31章)
│
├─ 503 Service Unavailable ──▶ 无健康后端 或 限流
│   ├─ Envoy "UH"?          → 无健康 upstream(第15章)
│   └─ 触发了限流/熔断?      → stick table/ratelimit(第14/31章)
│
├─ 407 / 401 ────────────────▶ 认证
│   ├─ 407? → 代理认证缺 Proxy-Authorization(第04章)
│   └─ 401? → 源站认证(与代理无关)
│
├─ Connection refused ───────▶ 代理没起/端口错/防火墙(①段)
│
├─ TLS 握手失败 ─────────────▶ 证书/SNI/版本/MITM
│   ├─ "unable to get local issuer"? → 被 MITM 或缺 CA(第05章)
│   ├─ SNI 不匹配/拿不到?     → 证书选错/ECH(第02/05章)
│   └─ 版本/算法不兼容?       → TLS 版本协商
│
├─ CONNECT 403/405 ──────────▶ 端口白名单(Safe_ports,第04/17章)
│
├─ CPU 100% / 无限循环 ───────▶ 透明代理没放过自己(环路,第11章)
│
├─ CLOSE_WAIT 大量堆积 ───────▶ 半关闭处理不当/连接泄漏(第21章)
│
├─ 慢 / 尾延迟高 ─────────────▶ 连接池小/缓冲/后端/协调遗漏(第31章)
│
├─ DNS 泄漏(被看到访问谁)────▶ 本地 vs 远端解析(第03章 socks5 vs socks5h)
│
└─ 间歇性"串味"/响应错配 ─────▶ 请求走私(hop-by-hop 头,第04/33章)

️ 实现 / 命令

实验一:502 分段二分实战

# 第1步:在代理机上,绕过代理直接连源站——区分是哪一段坏的
curl -v http://源站IP:端口/ --resolve 源站域名:端口:源站IP
#   通 → 问题在"客户端→代理"段或代理配置;不通 → "代理→源站"段(源站/网络)

# 第2步:看代理日志的上游错误
tail -f /var/log/nginx/error.log     # connect() failed / no live upstreams / SSL handshake...

# 第3步:DNS?在代理机上解析源站域名
dig +short 源站域名                   # 解析不出 → 代理侧 DNS 问题(第03章)

实验二:用分段计时定位"慢"

curl -w "DNS:%{time_namelookup} 连接:%{time_connect} TLS:%{time_appconnect} 首字节:%{time_starttransfer} 总:%{time_total}\n" \
     -s -o /dev/null -x http://proxy:3128 https://源站/
# 哪段数值大,瓶颈就在哪(第03章):
#   TLS 大 → 握手/会话复用(第31章);首字节-TLS 大 → 源站处理慢(504 前兆)

实验三:连接状态体检

ss -tanp | awk '{print $1}' | sort | uniq -c     # 各状态连接数
# 大量 CLOSE_WAIT → 应用没关连接(第21章半关闭)
# 大量 TIME_WAIT  → 短连接太多(第31章,连接池/tw_reuse)

实验四:TLS 握手失败定位

openssl s_client -connect 源站:443 -servername 源站域名 </dev/null 2>&1 | head -20
# Verify return code 非 0 → 证书链问题
# issuer 是 mitmproxy/企业 CA → 被 MITM(第05章)
# no peer certificate / alert → SNI 不匹配或版本不兼容

排错速查(症状→首查项)

症状第一步查相关章
502代理上直连源站 + 代理 error 日志03/04
504源站响应时间、read timeout31
503upstream 健康、限流配置15/14
握手失败openssl s_client 看证书/SNI05
环路/CPU 满透明代理 uid 排除规则11
CLOSE_WAIT 堆积半关闭/连接关闭逻辑21
慢/尾延迟curl -w 分段 + wrk231
DNS 泄漏socks5 vs socks5h03
内部调用全超时NO_PROXY 是否含集群内08/25

系统化的网络排错决策树参见 网络手册 · 故障排查方法论。


本章小结

  • 排错第一性原理:先分段二分(代理上直连源站,判断故障在客户端→代理还是代理→源站),再沿生命周期定位阶段。
  • 工具按层分工:curl -w 看分段时间、tcpdump 看握手字节、openssl s_client 看证书、ss 看连接状态、mitmproxy 看明文。
  • 记住核心因果:502=代理→源站坏、504=超时、503=无后端/限流、环路=没放过自己、CLOSE_WAIT=半关闭。

最后一章 第33章 代理安全,看代理作为攻击面的全部风险:开放代理、SSRF、请求走私、凭证泄漏,及加固清单——全书收尾。

Prev
第31章 性能调优:并发模型、连接池、超时与重试、压测
Next
第33章 代理安全:开放代理、SSRF、凭证泄漏与攻击面