出网代理网关如何抵御DNS重绑定?

1 人参与

DNS 重绑定之所以难防,不在于域名构造得多巧妙,而在于校验点与连接点之间存在时间差。攻击者控制权威 DNS 并把 TTL 设为 0 秒后,第一次解析返回一个合法公网地址,安全拦截器的 IP 校验顺利放行;HTTP 客户端真正建立 TCP 连接时再解析一次,拿到的却是 127.0.0.1 或 10.0.0.1。应用层无论把私网网段黑名单写得多完整,只要它判断的 IP 和最终连上的 IP 不是同一次解析的产物,就存在可被利用的 TOCTOU 裂隙。

网关把判断与连接压缩到同一时刻

出网代理网关的价值正在于此:解析、判定、建连由同一个进程在一次请求生命周期内完成,中间没有留给攻击者的第二次解析窗口。配合网络边界收敛效果更明确——在 Kubernetes 中用 NetworkPolicy 切断业务容器的直接出网链路,只放行对 CoreDNS 的 UDP 53 和对 egress-system 命名空间内代理服务的 TCP 连接,业务侧就失去了绕过网关自行解析目标域名的能力。

出网代理网关如何抵御DNS重绑定?

网关侧则按连接时解析出的目标 IP 匹配 ACL。以 Squid 为例,把 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、127.0.0.0/8 以及云元数据地址 169.254.169.254/32 统一纳入 dst 拒绝列表,同时用 Safe_ports 限定协议端口、要求 CONNECT 只能走 443。这样即便域名在两次请求之间反复翻转,落到连接建立环节时仍然会撞上基于真实 IP 的判断。

几个容易漏掉的细节

网关本身也可能被绕过或被二次利用。代理不要自动跟随 30x 重定向,否则首跳通过校验、次跳指向内网的情况同样成立;重定向目标必须由代理重新走一遍完整判定。DNS 缓存策略需要权衡:全局长缓存会削弱重绑定的时间优势,但高并发 Webhook 场景又确实需要缓存,因此应设置合理而不过长的 TTL,并在网关同机或集群内配套缓存解析。使用 Envoy 时,动态转发代理的缓存配置必须与访问控制策略联合生效,否则缓存命中路径可能跳过判定。

业务接入通常只需注入标准代理环境变量,主流 HTTP 客户端默认尊重这些设置,无需改造业务代码。真正需要提前约定的是错误处理:网关拦截返回 403 或 502 时,业务微服务不得把原始报错堆栈或底层 IP 透传给终端用户,应转换为统一的业务异常提示,避免泄露内网拓扑指纹。

上线节奏建议先以只记录不阻断的观察模式运行,识别被误配为公网调用的正常内网互调,再按服务逐步收紧;同时在 GitOps 配置里保留开关,一旦网关规则误杀或高可用故障,能通过撤销 NetworkPolicy 与代理环境变量快速恢复到直接出网链路。

参与讨论

1 条评论
  • 沙发土豆

    30x跳转确实是个大坑,之前就踩过