经 VPN 访问托管数据库,失败的常见原因在手册里往往没有写:隧道终止在你的网络边界上,而服务从来就不在这条隧道的你这一侧。路由表看起来是对的,隧道报告已建立,连接却照样超时。请按顺序走完下面四项检查,遇到第一个不成立的就停下,因为后面的每一项都以前面成立为前提。

检查一:端点究竟住在哪里?

VPN 网关连接的是两张你掌握寻址的网。托管服务运行在服务商自己的门前,而那扇门随产品不同有三种形态。如果你不清楚面对的是哪一种,再怎么折腾路由也没用,因为故障可能根本不是路由故障。

ShapeWhat it meansPass condition
Software on your VMOrdinary subnet addressingRoute and security group permit the client
Attached to your VPCPrivate, but only inside that VPCEndpoint associated, source allowed, route present
Provider-hosted, public endpointOptional private link, not private by defaultA private endpoint exists and DNS points at it

大部分白耗掉的下午,都来自跳过这步分类、直接去看路由表。带公网端点的服务商托管服务,无论图上怎么画,都不在你的隧道后面;挂在 VPC 上的那种,也永远不会出现在公网 DNS 应答里。

检查二:像 ElastiCache 这样挂在 VPC 上的服务

这类缓存在你自己的 VPC 内部寻址,根本没有面向公网的监听端口。在同一个 VPC 里终止的客户端 VPN 可以够到它们,但必须三个条件同时成立。缓存端点要关联到你隧道看得见的子网,其安全组要 放行客户端来源的地址,客户端一侧还要有一条覆盖缓存子网的路由。

常见错误是以为附近某处的连通也算数。把 VPN 挂到另一个 VPC,或者只靠对等连接,并不会把缓存的安全组或它所在子网的路由表延伸到你的客户端。现有隧道终止在别处时,通常的退路是在那个 VPC 里放一台跳板机或 VPN 服务器。那只是绕行,不是设计,手册里应当如实标注。

检查三:只有公网名字的 PaaS 端点

Azure Database for PostgreSQL 提供的是一个公网服务器名。它不会给你一个能写进 hosts、再经网关转发的私网地址。虚拟网络服务终结点限制的是哪些子网可以访问资源,它并不授权从 VPN 进来的本地客户端。

要拿到私网访问,就得引入专用终结点或专用链接方案,再加一个专用 DNS 区域,让公网名字改答那个端点而不是公网。VPN 加服务终结点规则的组合是另一套架构,只在图上长得像。App Service 的逻辑正好相反:VNet 集成只让应用能向外调用进 VNet,并不会从你的隧道造出一条入站私网通路。因此入站私网访问需要专用终结点、App Service 环境,或在应用前面加一道网关,能用哪种取决于套餐。

检查四:自有门前的产品

Firebase Hosting 无法挂到 Cloud VPN 上,因为这一层托管是全球性的前端,不是项目 VPC 里的东西。文档给出的替代方案是自己搭受控入口:用一个代理实例,或用存储桶支撑的负载均衡。无论哪种,站点都不再是纯托管产品,而变成要你自己运维的基础设施。在有人承诺隧道能覆盖它之前,这笔账值得先讲清楚。

Private API Gateway 更靠近 VPC 服务那一侧:interface 型 VPC 终结点发布的主机名,解析结果是私网地址,来自你机房的流量走隧道或专线进来。终结点必须关联到 API,证书和主机名必须与调用方使用的自定义域名一致。

Google Cloud VPN 的隧道绑定的是对端 IP 地址,不是名字。DNS 转发要单独配置,所以隧道可以完全健康,而远端专用区域的解析照样失败。

然后定位边界

从 VPC 内的一台 VM 跑同样的连接。在那儿通、从 VPN 客户端不通,缺口就在客户端路径和服务端点之间:一条路由、一个安全组、一条端点策略,或者一个名字。两边都不通,说明那张网里没有任何东西能到达该服务,问题从来不在 VPN。

getent hosts db.internal.example
nc -vz db.internal.example 5432

把名字解析和端口探测分开做,因为失败原因不同,而这一对结果能告诉你是路径的哪一半坏了。名字解析到公网地址,说明 专用 DNS 区域根本没生效。

相关文章