请求到了,服务器也记录了,客户端却仍然报告超时。这种组合说明 应答没有找到回程的路,而这正是少数能同时从两端确认的故障之一。请按顺序逐项检查,任何一项失败就停下来。

先从请求抵达的位置查起

在检查其他任何东西之前,先确认数据包确实到达了服务。服务器侧的日志记录、连接计数,或远端允许的抓包,回答的都是同一个问题;如果这些都没有,就该退回隧道,而不是继续往应答方向走。这就是把转发问题与回程路径问题区分开的检查。

如果请求从未抵达,就停在这里。此时主题是隧道、通往私有前缀的路由或访问规则,回程路径还无关紧要。同时记下服务器看到的源地址。它要么是分配给客户端的地址池地址,要么是转换后的地址,这个差别决定了后面哪几项检查适用。

应答需要一条通往地址池的路由

远程访问客户端通常从地址池获得地址,而私有网络需要一条回到那个地址池的路由。默认路由指向自身网关的服务器,会把数据包交给那个网关,而该网关根本不知道地址池在哪里,应答就在那里消失。客户端看到超时,是因为什么都没回来,这与一个从未发出的请求无法区分。

要检查服务器为客户地址选择的路由,而不是它为自身子网使用的路由。这两次查表可能给出不同结果,这里要紧的是前者。地址转换是另一种设计,它改变了服务器能看到的内容。它可以简化回程路径,同时也会把原始客户端地址从服务器日志里抹掉,从而影响任何以该字段为基础的规则或报表。

把服务器侧抓包与网关侧抓包对照

对照离开服务器的内容与抵达网关的内容。服务器出口接口上的抓包和隧道网关上的抓包,回答的是同一个问题的两半,两者之间的差额就定位了丢包发生的位置。

ip route get 10.90.0.14
tcpdump -ni any host 10.90.0.14 and port 443
ip route show table all | grep 10.90.0.0
Where the reply stopsWhat it proves
Request in the server log, nothing on its outbound captureThe server picked a gateway that cannot reach the pool
Reply leaves the server but never shows up at the gatewayLoss on the LAN path, not on the tunnel
Reply reaches the gateway but not the clientReturn translation or tunnel policy, not the server route

由网关自己生成的请求,不能代替从客户端发起的测试,因为它来自不同地址、会遇到不同规则。这正是一个从网关发出的 ping 成功、而从客户端发出的请求失败,却能同时成立的原因。

路径上有多台路由器时,每一台需要通往地址池路由的设备都要查。站点到站点的设计往往要求在不止一台设备上认识远端前缀,而网关本身必须在隧道与本地网络之间转发; strongSwan 的转发说明 涵盖了其中的 sysctl 与防火墙部分。

记录地址池、前缀与责任人

记录里应包含四项事实:客户端拿到的地址池、它需要的私有前缀、对回程负责的路由器,以及存在时的地址转换规则。有了这些,日后更换网关就是一次对照,而不是一次排查。

然后用普通客户端和真实应用账户复测。扩大应用权限修不好数据包的回程,而在这次排查中途改动账户,只会让下一次对照更混乱。如果设计依赖地址转换,就在别人读服务器日志的地方把它写清楚。在审计记录里看到陌生源地址的人,不应该还要靠工单去重新发现这层映射关系。

相关文章