这个应用每天都在办公室连它的数据库。后来有人在同一台笔记本上开了商业 VPN 客户端,握手之后连接开始被重置。应用没有任何改动,隧道自报健康,而你控制的防火墙也没有任何拦截规则。真正改变的是出口路径:服务商的服务器是共享的高流量端点,而服务商会过滤出站端口以减少滥用。数据库和邮件提交端口首当其冲,因为正是这些端口最容易从匿名地址池招来扫描和垃圾邮件。

五分钟测试:把端口过滤和其他原因分开

在同一台机器上,对同一主机分别探测一个必须开放的端口和出问题的端口,先开着隧道测一次,再关掉隧道测一次。两次都用同一条命令,让隧道成为唯一的变量:

Test-NetConnection db.example.com -Port 443
Test-NetConnection db.example.com -Port 5432
nc -vz -w3 db.example.com 5432

四种结果几乎覆盖所有情况。如果 443 通、5432 只在开隧道时失败,你看到的就是出口路径上的端口过滤。如果开隧道时两个都不通、关掉后两个都通,问题在路由或 DNS,而不是端口策略。如果两个端口都能连上但应用仍然失败,错在认证或 TLS,而不是可达性。如果只有一家服务商的某个服务器位置失败,那是按服务器设定的策略,所以在改任何配置之前先换一个位置试试。

方案一:把数据库所在子网排除出隧道

如果这台笔记本只是为其他用途才需要商业 VPN,就把数据库的地址段排除在隧道之外,让流量根本不进共享出口。当两条路径确实不需要交汇时,这是最干净的做法,成本只有一条可以写进文档的路由规则。代价是:拆分隧道会引入第二个策略面——被排除在隧道之外的东西必须是有意为之,而不是后来有人加了一个子网留下的副作用。

一旦数据库就在 VPN 本应到达的网络内部,这个方案立刻失效,所以在决定之前先确认这一点。

方案二:自建端点,自建出口

在 VPS 上运行一个小型 VPN 端点,出口策略就握在你自己手里,也不涉及任何共享池。这才是值得与商业客户端认真比较的方案:你得到可预测的源地址,失去服务商的全球覆盖和便利。对于整天需要数据库和邮件端口的团队,这笔交易通常偏向自建端点,因为故障模式变成了你自己的配置错误,而不是别人的防滥用策略。

从源地址稳定性、谁能读取你的流量、以及端点服务商某天改变自己的过滤规则时会发生什么这三个方面去比较两者。

方案三:把笔记本挪出这条路径

CI 任务、定时容器,或允许网段内的堡垒机,都不依赖某个人的隧道状态。从已被允许的主机通过 SSH 隧道连到数据库,笔记本就永远不直接跟端口对话。当多个人撞上同一条限制时,这个方案能规模化,而且它是在消除问题,而不是绕过问题。

它的前期工作量比一条拆分隧道规则大,也帮不了那个现在就需要交互式会话的人。

为什么把服务商地址加进白名单是错误的比较

把服务商的出口地址加进数据库白名单确实有效,但它同时也把访问权给了此刻共用该地址的所有其他订阅者。对一个只读副本、背后是权限收得很紧的应用账号,这种暴露或许能容忍一天。对任何可写的东西,这根本不是值得命名的取舍,而轮换的出口地址让它更糟:每次换服务器规则就断,维护又会诱使人们写入宽泛的 CIDR,从而彻底毁掉白名单的意义。

专用地址或静态地址,在服务商出售的地方,才是这件事唯一能规模化的形态。把白名单绑在只属于你的地址上,或者干脆别绑。

无论你选哪一种,都把路径和理由写下来。下一个人会遇上同样的连接重置,并且会先从应用开始怀疑。

相关文章