AWS Client VPN 的 DNS:用 VPC 解析器,而不是子网
AWS Client VPN 终端节点的解析器是 VPC 主网段加二,不是每个子网加二。先设好它,再放行路由,然后检查客户端。
终端节点位于 10.0.8.0/24,所以解析器必须是 10.0.8.2。这是我听到最多的推理,它错了两处。Route 53 Resolver 在 VPC 主 IPv4 网段加二的地址上应答,对于 10.0.0.0/16 的 VPC,无论终端节点使用哪个子网,这个地址都是 10.0.0.2。第二个错误更安静:把正确地址填进终端节点,并不代表客户端的操作系统会真的去问它。两个错误产生同一个症状:域名解析在部分客户端上可用,在另一部分上失败。
误区始于子网关联
关联讲的是客户端连接所用的弹性网络接口放在哪里,而不是哪个解析器地址存在。终端节点的子网给客户端一个 VPC 内的地址,它们并不各自携带一个解析器。
把这两个概念分开之后,算术就不再神秘,排查方向也转向客户端——大多数这类问题实际终结在那里。
用 VPC 主网段算出地址
取 VPC 的主 IPv4 CIDR,在网络地址上加二。10.0.0.0/16 得到 10.0.0.2,172.31.0.0/16 得到 172.31.0.2,带次要网段的 VPC 仍把解析器留在主网段。其中 10.0.8.0/24 的子网不会让它移位。在动终端节点之前,先把地址写在 VPC ID 旁边,因为这是 VPC 的属性,不是连接的属性。
VPC 也会在 link-local 地址 169.254.169.253 上应答。该地址在 VPC 内部可达,但它不是隧道另一端笔记本的通用路由目标。
因此有两个有效解析器地址,而它们都不是子网加二。
终端节点设置做了什么、没做什么
Client VPN 终端节点有 DNS 服务器字段,控制台提供 VPC 解析器选项的地方填的就是同一个思路。设置它们改变的是服务在建立连接时交给客户端的内容。它不改变未受管的 OpenVPN 客户端对这个值的处理,因为客户端仍需把它应用到操作系统。正是这个缺口造成了「我的 Mac 能用,Linux 机器不行」。
在 Linux 上,解析器集成归连接管理器所有,而不归用户。手动编辑 /etc/resolv.conf 只能证明地址在一个会话里有效,重连后就消失——所以许多「修好了」的案例第二天早上又回来了。
连接之后要在客户端上检查当前生效的解析器,而不是看终端节点的配置页。
拆分隧道可能让正确的解析器失效
启用拆分隧道时,只使用被推入隧道的路由。如果解析器地址没有被任何路由覆盖,查询会从本地接口出去,由家里的路由器来回答。终端节点里的地址仍然正确,解析仍然失败。为解析器补上路由,然后重新测试。
本地网段重叠会以更麻烦的方式给出同样结果:查询有人应答,只是答的人不对。
不要为 Amazon DNS 地址开放安全组
解析超时时的本能反应是加一条允许 UDP 53 到解析器地址的规则。AWS 的文档说明,安全组和网络 ACL 并不会像过滤到自建 DNS 实例的流量那样过滤 Amazon DNS 流量。打开这些规则对 VPC 解析器毫无帮助,只是无端扩大了边界。自己运维的解析器是另一种情况,确实需要自己的规则。
如果设计里两者都有,先确认客户端到底指向哪一个,再去改任何规则。
先验证路径,再测别的指标
解析一个公网名称,解析一个登记在与该 VPC 关联的私有托管区里的私有名称,并在两步之间读取客户端当前生效的解析器。这个顺序能把「解析器地址错了」「托管区没关联」「客户端忽略了设置」区分开。三者修法各不相同,且没有一个是吞吐问题。
一次成功的解析不能说明持续传输速度,所以汇报时要把这两件事分开说。