Web 服务器上的 VPN 客户端会破坏它的响应吗?
基于源地址的路由规则可以恢复一个已发布的站点,同时豁免你从未打算豁免的流量。在扩大例外之前,先读懂选择器。
站点在同一网络内的笔记本电脑上能打开,从其他任何地方访问却会超时,而主机同时还在为自己的出站流量运行 VPN 客户端。这种组合会产生一种特定的故障:入站连接到达了,响应却从错误的路径离开,外面的客户端永远看不到回复。两半都出现在同一份数据包捕获里,所以真正值得读的是事件的先后顺序。
基于源地址的路由规则常常能修好症状。它通常还会豁免比当初促使你加规则的那个站点更多的流量,而这正是保存规则之前值得弄明白的部分。
症状:本地能应答,外部不应答
在网络内部,响应不必穿过隧道,所以页面能打开,服务看起来一切正常。从外部看,请求到达了主机,响应却被路由进 VPN,而远端没有理由接受它。浏览器看到的是超时而不是拒绝,这是一条单向路径的特征,而不是端口被关闭。
在改动路由之前先确认形态:监听器在运行,本地请求成功,外部请求则完全得不到响应。这三点合在一起指向返回路径,而不是 Web 服务器配置。如此干净的不对称比任何日志行都更有用,因为它在读第一条错误信息之前就排除了监听器。
操作时保留一条独立的管理通道。一条会切断你自己 SSH 会话的规则,会把十分钟的修复变成一次现场跑腿。
源选择器究竟匹配什么
在 Linux 策略路由中,像 from 192.168.50.2 这样的规则匹配源地址为该地址的数据包。它并不编码“这个数据包在延续一条从家用路由器进来的会话”这一事实,也不知道是哪个进程创建的它。那个例子里的地址只是示意,请换成你主机实际使用的地址。请把这一行理解为关于地址的陈述,仅此而已。
如果选中的表提供了一条普通的默认路由,那么每个携带该源地址的数据包都能走上同一个例外。绑定到同一地址的另一个服务会继承它,故意绑定到该地址的应用程序也会继承它。策略规则参考把源、目的、协议、端口、标记和优先级列为彼此独立的选择器,这提醒我们:单看源地址是现有选择器里最粗的一个。
优先级决定结果。查找按顺序进行,而第一个给出结果的表就可能结束查找,所以放得太早的规则会掩盖后面那张表本可提供的更具体的路由。要读整份有序列表,而不只是你加进去的那一行。从不匹配的规则没有任何代价,而匹配得太早的规则会悄悄改变它身后的一切。
检查返回路径,以及你并不打算豁免的流量
先读规则和表,再问内核:某个特定的源地址与目的地址组合会走哪条路由。从主机本身测试和从外部测试并不相同,所以两者都要做。
ip rule show
ip route show table 100
ip route get 203.0.113.44 from 192.168.50.2
ss -ltnp '( sport = :443 )'
然后接受一条新的外部连接,另外再发一个仍须经 VPN 出去的请求。如果第二个现在直接出去了,那这个例外就比你当初要解决的问题更宽,而真正重要的测试,恰恰是你并不打算改变的那一个。
浏览器里的公网地址检查只报告该浏览器发出的请求。它对 Web 服务器的响应、对另一个本地应用的源地址选择、对下一次 VPN 重连之后管理流量会怎样,什么也说明不了。
决定这个例外能收得多窄
有两种设计都站得住脚,而且应当有意识地选择。如果这台主机存在的意义就是发布这个服务,而出站流量并不重要,那么一个只走 WAN 的专用本地地址是合理的安排——前提是你接受它的全部范围。如果只有特定的入站连接才应放行,那么按地址选择就太粗了,前面应该放一个能识别连接的设计。
把你所依赖的约定记录下来:公网映射、请求被投递到的主机地址,以及响应预期要走的路径。通过 VPN 提供商发布的入站服务,与通过家用路由器发布的是不同的约定,从一个例子照搬来的例外,对另一个例子往往是错的。
把策略保存在真正拥有路由的组件里,而不是把命令粘贴进启动文件。规则顺序、网络变更后的清理、重启后的重放都必须活下来,而未经测试的启动文件通常会在你没盯着的那一刻失效。最后以你能站得住脚的验收结果收尾:一个已发布的站点恢复,一条无关的流量保持不变。