第33章 代理安全:开放代理、SSRF、凭证泄漏与攻击面
学习目标
- 认清代理作为攻击面的核心风险:开放代理、SSRF、请求走私、凭证泄漏
- 理解
X-Forwarded-For信任边界与 Host 头攻击 - 掌握 MITM/WPAD 滥用的防御(HSTS、证书锁定、受控配置)
- 拿到一份可操作的代理加固清单
前置知识
原理
代理处在流量咽喉、又经常处理不可信输入,是高价值攻击面。以下是必须知道的风险。
风险一:开放代理(Open Proxy)
未授权就能使用的代理 = 任何人都能借你的 IP 和网络出口。攻击者用它做跳板扫描、攻击第三方(日志里是你的 IP)、访问你的内网。CONNECT(第04章)若不限制,代理就成了任意 TCP 跳板。
防御:
风险二:SSRF(服务端请求伪造)
当应用/网关代客户端发起请求(本质是个代理行为)时,若目标可被用户控制,攻击者就能诱导它访问内部资源:
攻击者 → [你的网关/应用] ──被诱导──▶ http://169.254.169.254/...(云元数据,偷密钥!)
──▶ http://内网管理后台/
──▶ http://localhost:admin/
反向代理、URL 预览、Webhook、图片抓取等都是重灾区。云元数据 169.254.169.254(第28章)泄漏 = 偷到云凭证,后果严重。
防御:
- 目标白名单(只允许已知外部域名)
- 禁止内网目标:阻断私有网段(10/8、172.16/12、192.168/16、127/8、169.254/16)
- 禁止跟随重定向到内网;解析后再校验 IP(防 DNS rebinding)
- K8s 里用 NetworkPolicy/Egress 限制元数据访问(第28章)
风险三:HTTP 请求走私(Request Smuggling)
当前端代理和后端对请求边界的解析不一致时,攻击者能在一个请求里"偷藏"另一个请求。根源是 Content-Length 与 Transfer-Encoding 的歧义处理(第04章 hop-by-hop 头):
CL.TE:前端按 Content-Length,后端按 Transfer-Encoding → 边界错位
TE.CL:反过来
TE.TE:两端都看 TE 但对混淆的 TE 头处理不同
后果:偷藏的请求"串"到下一个用户的连接 → 越权、缓存投毒、绕过鉴权
防御:
- 前后端统一对 CL/TE 的处理;拒绝同时含两者或畸形的请求
- 严格删除/规范 hop-by-hop 头(第04章)
- 用 HTTP/2 到后端(消除 CL/TE 歧义);及时更新代理修复已知 CVE
风险四:凭证与信息泄漏
Proxy-Authorization转发给源站:你的代理密码泄漏给外部网站。代理必须删除这个 hop-by-hop 头(第04章)X-Forwarded-For伪造(第04章):XFF 是客户端可伪造的普通头。取真实客户端 IP 必须从你信任的代理往外数,绝不能无脑取最左值——否则攻击者伪造 XFF 绕过 IP 限制/污染日志/伪造审计
风险五:Host 头攻击与缓存投毒
反向代理若不校验 Host,或把不可信输入(某些头、参数)纳入缓存键:
- Host 头攻击:伪造
Host导致密码重置链接指向攻击者域名、路由到错误虚拟主机 - 缓存投毒:攻击者让恶意响应被缓存,之后正常用户都拿到污染内容
防御:校验/固定 Host、缓存键只用可信字段、unkeyed input 不进缓存。
风险六:MITM 与 WPAD 滥用
- MITM 滥用(第05章):一旦攻击者让你信任了恶意 CA,HTTPS 就被解密。防御靠 HSTS + 证书锁定 + 用户警惕"装根证书"的要求
- WPAD 劫持(第08章):局域网投毒 PAC 发现 → 全网流量走攻击者代理。防御:内网管控
wpadDNS/DHCP,高安全环境关闭自动检测
X-Forwarded-For 信任边界(重点重申)
Client(真实) → 不可信代理链 → [你信任的代理A] → 你的应用
XFF: 伪造, 伪造, <代理A追加的真实来源>
└── 只有这一段可信 ──┘
取真实 IP:从"你信任的最外层代理"往里数固定跳数,别取最左!
️ 实现 / 加固
实验一:检测自己的代理是不是开放代理
# 从外网机器尝试用你的代理访问第三方——应该被拒绝
curl -x http://你的代理:3128 http://example.com/ -m 5
# 期望:407(要认证)或 403(ACL 拒绝)。若返回 200 = 开放代理,立即整改!
# 测 CONNECT 是否被滥用到任意端口
curl -x http://你的代理:3128 -p telnet://内网IP:22 -m 5
# 期望:CONNECT 到非 443 被拒(Safe_ports,第17章)
实验二:SSRF 防护——阻断元数据与内网
# 反向代理/网关侧:拒绝把请求转发到内网与云元数据
location / {
# 解析后校验目标,禁止私网(示意;实际用 lua/应用层做 IP 校验更稳)
if ($upstream_addr ~* "^(169\.254\.|127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)") {
return 403;
}
proxy_pass http://$validated_backend;
}
K8s 侧用 Egress/NetworkPolicy 阻断 169.254.169.254(第28章)。
实验三:验证 Proxy-Authorization 不外泄
# 经代理访问会回显头的服务,确认源站收不到 Proxy-Authorization(第04章)
curl -x http://user:pass@代理:3128 http://httpbin.org/headers
# 返回的 headers 里不应出现 Proxy-Authorization —— 出现 = 代理有 bug,换合规代理
实验四:正确取真实客户端 IP
# 只信任你自己的代理链,从可信代理之后取真实 IP
set_real_ip_from 10.0.0.0/8; # 你的代理网段(可信)
real_ip_header X-Forwarded-For;
real_ip_recursive on; # 从可信链往外回溯,跳过伪造段
代理加固清单
□ 正向代理:必须认证 + 来源 ACL,绝不裸暴露公网
□ CONNECT:端口白名单(只 443),防任意跳板
□ hop-by-hop 头:严格删除(含 Proxy-Authorization、Connection 点名项)
□ XFF:从可信代理往外取真实 IP,不信客户端传入值
□ SSRF:目标白名单 + 禁私网/元数据 + 禁内网重定向
□ 请求走私:前后端统一 CL/TE 处理,拒绝歧义请求,更新补丁
□ Host 头:校验/固定,缓存键只用可信字段
□ TLS:HSTS、证书锁定(移动端)、及时更新、禁弱算法
□ WPAD:内网管控 wpad 记录,高安全环境关闭自动检测
□ 元数据:阻断 169.254.169.254(云上)
□ 限流/防护:stick table/ratelimit 抗 CC(第14/31章)
□ 日志审计:记录出网/异常,定期审查
本章小结
- 代理是高价值攻击面:开放代理(借你 IP)、SSRF(诱导访问内网/元数据)、请求走私(CL/TE 歧义)、凭证泄漏(Proxy-Authorization/XFF)。
- XFF 可伪造——取真实 IP 必须从可信代理往外数;Host 头/缓存键要防投毒。
- MITM/WPAD 滥用靠 HSTS、证书锁定、受控配置防御。
- 照着加固清单逐项落实,代理才是"安全的咽喉"而非"开放的后门"。
全书结语
至此,《代理技术全栈手册》33 章正文完结。我们从 第01章 的统一模型出发,走过协议(HTTP/TLS/SOCKS/HTTP2-3)、网络层级(L4/L7/透明/零拷贝)、主流组件(Nginx 到 Clash)、多语言手写(Go/Rust/Python/C)、容器与 K8s 落地(Docker/Istio/Ingress/Egress/Mesh),到这里的性能与安全。
你现在应该能做到本书开篇的承诺:看到任何一个"代理",立刻说清它在第几层、说什么协议、是哪种类型、灵活性来自哪里、在容器/K8s 里怎么落地。
继续深入可查三份附录:A 协议报文速查、B 选型决策树、C 抓包与命令速查。
代理的本质,是"在两点之间多一跳,从而获得控制力"。理解了这一跳,你就理解了现代网络架构的半壁江山。