为什么 OpenVPN 客户端无法匹配网关的 IPsec 选择器
来自网关的 ping 只能证明另一条流。沿着推送路由、IPsec 选择器、转发链和回程路径追踪客户端地址池。
从网关 ping 远端 IPsec 隧道后面的主机,它能干净地回应,于是隧道看起来正常,工单继续流转。接着已连接的客户端尝试同一台主机,却什么也收不到。那次 ping 从来不是客户端流的证据,因为它带着网关自己的源地址发出,匹配的是另一个 IPsec 选择器。理解这两种情况为何分道扬镳,就是修复的大部分。
网关的 ping 测试的是客户端从不使用的那条流
源地址决定了适用哪条策略。在网关上生成的报文带着其本地 LAN 或隧道端点的地址发出,与之匹配的策略正是为这种情况写的。客户端的报文则带着客户端地址池中的地址到达 OpenVPN 接口,这是完全不同的选择器。
因此故障看起来像路由问题,实际却是策略范围问题。从网关可达只证明对端在线、提案已协商,对于地址池是否受保护则毫无证明。
推送应用真正需要的远端前缀
以 10.8.0.0/24 供已连接客户端、172.30.239.0/25 供受保护的远端网络为例。客户端需要的是通往第二个前缀的路由,而不是网关的 LAN,也不是别的隧道地址。推送到池中的路由才让客户端把这份流量交给网关。没有它,报文永远到不了你正在调试的那次策略判定。
在接受推送路由的 Community 服务器上,指令使用真实掩码:push "route 172.30.239.0 255.255.255.128"。Access Server 通过所安装版本的专用网络或访问规则设置配置同一目的地,并有意选择路由模式或转换模式。去改生成的防火墙链而不是其归属配置,正是让可用部署变得无法复现的做法。
连接后,读客户端的路由表,而不是服务器的意图。只覆盖池的路由意味着推送从未到达;经隧道的默认路由比这一需求更宽,日后会让你意外。掩码和前缀都要查,因为把 /25 当作 /24 推送,会把相邻地址的流量送进承载不了它的路径。然后再确认客户端为该目的地选择了隧道接口。
让选择器包含客户端地址池
对于保留客户端地址的路由式访问,IPsec 策略必须保护池与远端前缀之间的流量。为网关自身 LAN 写的选择器会放行 ping 却丢弃客户端请求,而这正是引发本次排查的不对称。
既要检查已协商的策略,也要检查已配置的提案,例如在 strongSwan 上用 ipsec statusall,或用你所用实现的等效状态命令。在基于策略的 IPsec 中,普通路由可以指向物理接口,而匹配的流量仍被加密,所以缺少隧道设备并不能说明什么。把选择器对与你记录下的池和前缀做比较。
网关上的通用源 NAT 同样会破坏匹配。如果 masquerade 规则在策略检查之前改写了客户端源地址,报文就不再像你写的选择器。宽泛的 masquerade 规则是糟糕的第二 VPN 修法,原因之一就在于此:它改变了适用哪条策略、对端记录哪个地址。把你打算路由的流量排除在外,或者有意识地做转换并更新选择器。
有意识地选择路由或转换
路由让客户端地址对远端可见,因此远端日志与按源规则仍然有意义,但它要求远端网关知道回到地址池的路径。转换把池藏在一个地址后面,消除了回程路由问题,却摧毁了每个客户端的身份。
选定一种设计并写下来,因为两者需要不同的选择器和不同的防火墙顺序。半途而废的 masquerade 落在两者之间,谁都不满足。写下来的选择也让下一位工程师能区分缺陷与刻意决定。
在转发和回程上闭环
网关必须转发你想要的协议和目的地,这意味着开启 IP 转发,并有一条允许该对的转发链。随后远端必须沿 IPsec 路径把回应送回,而那是他们网关上的路由决定,不是你的。两部分都是普通配置,也都容易半途而废。分开测试,以免缺失的转发规则被误当成隧道故障。
用一次真实的客户端到应用请求来验证,观察它穿过 OpenVPN 接口、IPsec 判定和远端主机。把回应当作独立的观察来看,因为到达的请求和永不返回的回应,从客户端的位置看是一样的。一次被追踪的请求,胜过任意多次网关 ping。
测试时把目的地授权收窄,并确认没有该规则的客户端无法访问服务。已安装的路由加上已建立的关联,并不等于已被授予的访问。