VPN 连上了却访问不到 LAN 设备:该检查什么
网关能应答自己的地址,而它身后的设备毫无响应。沿着客户端流量逐跳排查,找出真正失效的边界。
流量进入隧道,网关能应答自己的地址,而它身后的设备毫无响应。这种组合很常见,也并不矛盾:网关的应答证明隧道已经终结,却完全不能说明发往它后方的数据包经历了什么。两项测试走的是同一台机器上不同的代码路径。
从现在起,请测试网关另一侧的东西。无论转发坏成什么样,网关自己的地址都会继续应答。
网关的应答来自它自己的协议栈
发往网关的数据包走的是本地输入路径,由内核判断是否有监听套接字接收它。发往网关后方主机的数据包则走转发路径,那里适用另一套检查。转发可以被完全禁用,也可以由内核启用后被一条从不提及隧道的过滤规则拒绝。这些都不影响网关自身的应答,所以这个症状才如此稳定地误导人。
通过隧道访问的管理页面也属于第一类。它们证明的是隧道,而不是隧道后方的网络。
沿流量追到第一个丢弃它的边界
从客户端出发,确认流量将要使用的路由和源地址。然后在网关上观察这条确切的流量到达,再观察它离开并前往 LAN。如果它从未到达,问题在客户端一侧,或隧道的允许前缀。如果它到达却从不离开,问题在转发或前向路径的过滤,抓包已经说明了是哪一种。
从网关做同样的测试会藏起关键的一半,因为网关自身发出的数据包源地址不同、回程要求也不同。每一步都要用客户端自己的流量和它自己的源地址。在错误接口上抓包,只会得到自信的废话。
回程路由与主机防火墙分别失效
数据包到达主机之后,还要满足三件事。服务必须监听在数据包被发往的地址上,主机防火墙必须接受它,并且 应答必须有回往客户端地址池的路由。最后一项经常失效,因为主机的默认路由指向一台从不知道隧道网段的路由器。结果就是连接从主机角度看建立成功,却在另一个方向上无声死掉。
有意测试回程:从客户端发送并观察返回。单向抓包几秒钟就能定论,而一个小时的猜测做不到。
用客户端的源地址确认每一跳
按顺序执行检查并保留每一份输出,因为价值在对比,而不在任何单独一行。下面的命令固定源地址、显示选中的路由,并同时抓取转发两侧。请换成你自己的 LAN 主机和隧道接口。
ip route get 192.168.50.20 from 10.8.0.2
ping -I 10.8.0.2 -c 3 192.168.50.20
sudo tcpdump -ni tun0 host 192.168.50.20
sudo tcpdump -ni br0 host 192.168.50.20
路由查询显示客户端是否会把该数据包送进隧道,ping 显示主机是否有回应。对比两份抓包可以把到达与离开区分开:隧道接口上有帧、而 LAN 接口上没有对应帧,那是转发决策而非服务故障。当两份抓包都显示请求、只有一份显示应答时,剩下的嫌疑就是回程路由。
记录哪个地址应答了、哪个被转发的目标失败了。这句话让报告可执行,而不是一句“服务器连不上”。