EC2 上的 Access Server 全隧道:为什么一个复选框远远不够
在 EC2 上关闭源/目标检查只是转发修复,不是客户端的互联网策略。先设置 Access Server 全隧道,再追踪 AWS 的出口路径。
在 EC2 实例上关闭源/目标检查,是关于 Access Server 互联网出口的问题里被重复最多的一句话,而它本身对客户端毫无作用。该检查是 AWS 的转发限制:它让实例接受源地址或目标地址并非自身的报文。它不会让客户端把互联网流量送进隧道,不会创建上游路由,也不会添加 NAT。误区在于把这个复选框当成了功能本身。
这项检查真正控制的是什么
每块 EC2 网卡都会丢弃不是发给自己的流量,除非实例充当路由器、NAT 设备或 VPN 网关,并且你关闭了该检查。关闭只是授予转发许可。许可不等于配置:实例仍然需要通往互联网网关或 NAT 设备的路由,VPC 路由表仍然需要匹配的条目,安全组仍然必须放行该流量,服务器仍然必须对返回流量做地址转换或路由。
改动之前,先用 aws ec2 describe-instance-attribute --instance-id i-0123456789abcdef0 --attribute sourceDestCheck 核对当前取值。如果你在控制台里修改它,理由应当是实例在为他人转发,而不是某个客户端上不了网。
客户端路由策略归 Access Server 管
在 Access Server 3 中打开 Access Controls,找到 Internet Access and DNS 区域。Internet Gateway 选项提供全隧道或拆分隧道;全隧道让客户端把默认流量送进 VPN,拆分隧道则把互联网流量留在客户端本地路径上。通过产品的工作流保存并应用,然后重新连接测试客户端,因为该策略是在连接时下发的。
较早版本使用不同的菜单,某些 Community OpenVPN 构建没有等价控制项。寻找一个并不存在的界面之前,先确认已安装的主版本。然后确认客户端实际拿到了什么:全隧道配置应当安装一条经隧道的默认路由,拆分隧道配置则不应如此。
隧道之后追踪报文
客户端把互联网流量送进隧道后,服务器必须转发它,通常还要做地址转换。Access Server 自行管理 NAT 与路由规则,所以应读取实际生效的配置,而不是往生成的文件里追加 Community OpenVPN 规则;未受管理的规则会在下次产品更新时被覆盖或冲突。sudo iptables -t nat -L -n -v 或 nftables 的等价命令能看出真正在做转换的是什么。
AWS 侧是另一条路径。公有子网中的实例直接到达互联网网关,并保留其公网地址或弹性 IP。私有子网中的实例需要通往 NAT 网关或 NAT 实例的路由,而 NAT 设备自身又需要通往互联网网关的路由。把互联网网关挂到 VPC 上,本身并不会给任何私有源一个公网回程地址,这就是同一套 Access Server 配置在一个子网能用、在另一个子网却静默失败的原因。
要检查与实例子网关联的路由表,而不只是 VPC 主路由表。子网关联会覆盖主表,而过期的关联是重建之后原本可用的配置停摆的常见原因。
把 IP 出口和 DNS 分开看
先用同一个客户端应用测试字面地址,再测试域名。如果 curl -4 https://checkip.amazonaws.com 返回公网地址但主机名解析失败,说明隧道和 NAT 路径都正常,问题在 DNS:下发的解析器、客户端的解析器状态,或者拦截解析器的安全组。Access Server 的 DNS 设置位于同一个 Internet Access 区域,但走的是另一条代码路径。
把返回的地址与你预期的出口做对比。如果是实例的公网地址,说明流量由实例做转换;如果是 NAT 网关地址,说明走的是私有子网路径。两者都可能正确。你不能由此断定的是:服务器上的浏览器证明了客户端在被转发。
别让一个复选框终结排查
IPv6 是另一个独立决策。针对 IPv4 的全隧道策略,并不说明 IPv6 是被承载、被阻断还是被泄漏,双栈客户端完全可以在 IPv4 走隧道的同时继续使用本地 IPv6 路径。要测试你真正关心的地址族,并明确决定另一个是否应当禁用。
最后,测试断开状态。全隧道选择描述的是连接状态下的路由策略,而不是隧道掉线时会发生什么。如果要求是任何流量都不得逃出 VPN,那是 kill-switch 与防火墙的问题,需要单独测试,而不是从路由表推断。