客户端能 ping 通网关的地址,而它背后的所有资源都不可达。这两种现象同时出现,说明这台机器在回应你,却没有在转发,也就是同一台机器上的两种不同角色。转发就是两者之间的开关。

这两个角色相互独立,两个地址族也相互独立。

能应答自己的地址,什么也证明不了

数据包发往网关自身时,本地协议栈会直接消费它,不会发生转发决策。因此,能 ping 通隧道地址或管理接口,只能说明守护进程还活着、隧道已建立,对发往这台机器背后网络的流量却一无所知。内核对并非发给自己的数据包,才会走转发路径。

把这一要求理解成角色,而不是一项设置:这台主机必须在两个接口之间搬运数据包。只需要访问远程网络的笔记本从不承担这个角色,而站点到站点的端点总是承担。这样理解,就能解释为什么一份本来好用的客户端配置,搬到网关上就失灵。

同一句话也适用于转发决策前面的防火墙,它对什么可以转发有自己的策略。

分别检查每个地址族

IPv4 转发是一个开关,IPv6 转发是另一个开关,并且按接口各有各的行为。打开前者与后者无关,双栈客户端可能只连通半个网络,另一半仍然一片漆黑。因此,不同地址族的两个客户端可能对同一个网关给出不同结论。改动任何一项设置之前,先问失败的客户端用的是哪个地址族。在断定路由设计有错之前,两个都要确认。

sysctl net.ipv4.ip_forward
sysctl -a --pattern 'net.ipv6.conf.(all|default).forwarding'
nft list ruleset | head -n 40

在许多发行版上,运行时读到的值是由某个服务或配置文件放进去的,因此 用一次性命令做的改动可能在重启后消失。改动运行时的值之前,先找到掌管这项设置的文件。

转发是四项要求之一

一条能工作的转发流同时需要四件事:客户端知道目的地在隧道后面,网关有继续向前的路由,回包有返回的路径,防火墙允许这些流量。源地址转换属于这套设计中的一个选项而非规则,因为路径对称的私有路由网络不需要它,而路径不对称的网络通常需要。四项各自独立失败,所以修好一项很少能让症状移动。动手改任何一项之前,先把四项写下来。

云平台还带来第五个考虑。有些平台会在实例上强制检查源地址和目的地址,无论客户机内核怎么配置,转发流量都会被丢弃。这时以平台自己的网络文档为准,而不是虚拟机里的 sysctl 输出。

从客户端测试,而不是从网关

在网关自己的 shell 里跑测试,根本不会经过你刚启用的转发路径。要从出问题的客户端发起流量,并确认它到达的是网关背后的某个东西,而不是网关本身。这是唯一真正检验你所改角色的测试。

头脑里和变更记录里,都要把监听规则和转发规则分开。打开 VPN 端口只是让客户端进入服务;它并不授予客户端背后网络上的任何权限,而在多年累积的防火墙列表里,这两者看起来一模一样。

如果数据包到了,服务却拒绝该用户,那就已经越过了网络层。接下来该处理应用授权,而不是再一次放宽转发策略。

相关文章