VPN 背后的 CloudFront 地理封锁:诊断出口
边缘节点依据它看到的地址做判断,而共享出口会同时改变国家和信誉。轮换出口节点前,请分别测试每一项控制。
地理限制是针对 IP 地址的决定,而 VPN 会改变服务看到的地址。仅这一句话就能解释支持队列里大多数令人困惑的报告:「网站在家里能用,走隧道就失败」和「网站在隧道下能用,但办公室其他人打不开」是同一机制产生的相反结果。本手册按排除原因的顺序推进诊断,从边缘节点实际告诉你的信息开始。同一个出口地址可能通过一种控制,却在下一项控制上失败,因为每项控制评估的是该地址的不同属性。
先读懂 403,再改动任何设置
地理封锁和 WAF 封锁都以 403 返回,但修复位置不同。保存响应头和正文第一行,因为 CloudFront 会附带缓存头和原因字符串,说明是哪一层给出的响应:
curl -sS -o /tmp/body.txt -D /tmp/headers.txt https://d111111abcdef8.cloudfront.net/
grep -i "x-cache\|via" /tmp/headers.txt
head -c 300 /tmp/body.txt
当分发本身因地理原因拦截请求时,正文会带有指明国家限制的消息。当 WAF 规则拦截时,正文通常是通用的禁止页面,而响应头中的分发请求 ID 才是你要带到 WAF 日志里的东西。在这里判断错,会让你拿国家允许列表去修一个基于速率的规则问题,那是一天也做不成的工作。
第 1 步:确认分发看到的是哪个地址
从失败浏览器所用的同一台机器、同一条路径,向网络询问外部世界看到的是什么。curl -s https://checkip.amazonaws.com 返回调用方的公网地址;对 VPN 客户端来说,这就是出口,而不是用户家里的宽带:
curl -s https://checkip.amazonaws.com
nslookup d111111abcdef8.cloudfront.net
如果该地址属于你服务商在另一个国家的出口,地理判断已经做出,客户端上任何设置都改不了它。在动设置之前把地址写进工单,因为这是报告里你和服务的唯一都同意的事实。
第 2 步:把国家和信誉分开
CloudFront 依据请求源地址,从第三方 GeoIP 数据库解析观看者位置,这种映射是粗略且按区域划分的,并非精确判定。当位置无法确定时,文档化的默认行为是照常提供内容。因此存在三种状态:出口映射到被封锁的国家、映射到允许的国家,或数据库没有意见、请求放行。
被封锁国家的用户,如果服务商在当地有出口,看起来也可能在允许国家;允许国家的用户,也可能因为出口注册在别处而被封锁。这两种结果都不能证明限制坏了。两者都是限制在它拿到的那个地址上正常工作,正如 CloudFront 地理限制文档所述。
信誉是第二条轴,而且它不受隧道影响。AWS WAF 的匿名 IP 托管规则组专门拦截来自 VPN、代理、Tor 节点和托管服务商的请求,所以通过国家检查的请求仍可能因为地址「是什么」而不是「在哪里」被拒绝。如果封锁是在你把隧道迁到云主机之后才开始的,那多半就是这一层。
第 3 步:检查配额行为
共享出口还有第三种失败方式。按 IP 的速率限制和会话计数把一个地址当成一个客户端,而面向消费者的出口同时承载许多订阅者,于是从家庭宽带看毫无异常的请求模式,从出口看就像自动化。症状是自行消退的限流或临时封禁,而不是地理错误提示。
分发也可以故意按地址统计会话,例如用写入 DynamoDB 的 Lambda@Edge 函数。这并不能识别出口背后的人,但会让一个地址表现得像一个客户端,这往往才是真实意图。在调整任何阈值之前,先记录投诉背后的不同地址,因为两百个工位共享的企业 NAT 从外面看,恰恰就像一条繁忙的出口。要预料到企业 NAT、大学校园网或大家庭共用单一地址带来的误报。
在归咎于地理之前,先看 WAF 的采样请求和基于速率的规则指标。由出口请求量触发的规则会留下清晰特征,它也会告诉你修复方式是调整限额,还是换一条出口路径。
改什么,以及按什么顺序改
先确定这项控制是为什么服务的。维持区域目录、限制滥用和执行合同是三个不同目标,只有第一个是用国家列表解决的。如果目标是滥用控制,出口就是错误的身份单位,再多的允许列表也不会让共享地址变得可信。
如果允许列表确实需要稳定地址,专用或静态出口会有帮助,因为地址可以登记,而且不会轮换。它不会让地址变成住宅地址,也不会改变 GeoIP 数据库判给它的国家。不断换出口直到某一个能用,只是临时的信誉变化,不是对策略的修复。
然后用请求方使用的说法写结论:这个地址是因国家、信誉还是速率被封锁,而要改的是哪一项控制。写得更含糊,下周就会拿着另一个出口再来一张同样的工单。