EC2 的弹性 IP 不是实例的私有 VPN 地址
客户机从来看不到弹性 IP。先弄清转换发生在哪里,再选择真正属于你所需路径的地址。
实例有一个私有地址,弹性 IP 与它关联,于是人们把指向该公网 /32 的路由加入 VPN,指望两者变成同一回事。它们并不会。弹性 IP 是客户机之外、由互联网网关在走互联网路径的流量上执行的转换。客户机的操作系统从来看不到该地址被配置在任何网卡上。把它加到隧道接口上并不能复现上游的转换,反而给同一台机器制造了第二个相互冲突的身份。
两个地址,一个实例
实例的网卡持有 VPC 内的私有地址,那才是客户机知道的地址。弹性 IP 关联在同一块网卡上,但存在于映射的公网一侧。
凡经互联网到达实例的流量,都会先被转换成私有地址。凡实例发往互联网的流量,都会以弹性 IP 作为源地址发出,同样是因为那次转换。
客户机内部只有一个地址,外部却有两个。这种不对称解释了这一领域的大部分困惑。客户机无法配置网关转换什么,它只能在自己真正持有的地址上应答。
互联网网关究竟做了什么
AWS 的互联网网关文档描述了这一安排:实例知道自己的私有 IPv4 地址,而网关为互联网路径上的流量提供相应的公网 IPv4 或弹性 IP 转换。
这是网络地址转换,不是别名。映射由网关维护,与关联绑定,并且只对经过它的数据包生效。移除关联,公网身份就会消失,而客户机毫无察觉。
正因如此,发往公网 /32 的私有 VPN 数据包不会被重新解释为发往客户机本地地址的私有数据包。数据包会沿它匹配到的路由走,而该路由把它送往互联网网关,网关的行为取决于这条路径在两个方向上是否都被允许。
隧道接口的把戏为什么行不通
把弹性 IP 分配给隧道接口,等于要求客户机把公网地址当成自己的本地地址。于是有两样东西都声称拥有同一个地址:互联网路径上网关的转换,以及隧道内的本地接口。回程流量无法给出一致的答案。
即便看起来能用,这种设计也掩盖了真正的问题。客户端要么经隧道访问私有地址,要么经互联网访问公网端点,而两条路径的安全组、日志和故障模式都不同。
地址从来不是问题,路径选择才是。
三个目标,三种设计
如果目标是公网 VPN 端点,弹性 IP 就是对的工具:远端对等方经互联网连接它,加密传输在实例上终止,内部应用流量随后使用私有地址。
如果目标是私有访问应用,目的地就是私有地址,或解析到它的私有 DNS 名称,而 VPN 路由、安全组和回程路径必须全部一致。那种设计里根本不会出现弹性 IP。
如果目标是为 VPN 用户提供稳定的公网出口身份,那是出口侧的 NAT 设计,而不是客户端隧道上的地址。三个听起来相似的目标会产生三张不同的图,其中只有一种涉及把弹性 IP 放到新位置。
验证你选择的路径
私有访问方面,确认 VPN 路由覆盖私有前缀、VPC 路由表把流量送回隧道、安全组允许客户端源地址、客户端自己的防火墙允许回包。然后用一次真实请求来验证,而不是 ping。
公网访问方面,确认客户端的互联网出口、公网入口的路由和安全策略。VPN 客户端能否经隧道访问公网端点,取决于隧道的出口和防火墙规则,而不是弹性 IP 关联。
如果公网主机名必须两侧都能用,就采用这样的 DNS 设计:对 VPN 客户端返回私有地址,对其他所有人返回公网地址,并让证书对名称而非地址有效。工作顺序是:先命名目标,再选择属于它的地址,然后验证路由、策略和一次请求。