OpenVPN 的 LAN 访问失效?检查区域、路由与回程路径
路由器会应答,因为它本身是本地设备。要访问它后方的主机,需要转发规则、客户端上的前缀,以及应答的回程路径。
隧道报告连接成功,路由器自身的页面也能打开,但映射到其后方某台机器的网络驱动器仍然超时。这个组合并不矛盾:路由器是在以自身身份应答,而访问它后方的东西是在另一处做出的另一个决定。请按顺序执行下面的检查,并在第一处失败时停下,因为每一项都建立在前一项之上。四项全部通过时,故障在隧道之上,而不在隧道之内。
哪个过滤器看到发往 LAN 的数据包
发往路由器的数据包会被本机消费;发往其后方主机的数据包必须被转发,防火墙分别判定这两种情况。因此,能够访问路由器并不说明能够穿过路由器。隐藏规则集的固件仍然实现两者,通常表现为一个选择器,提供 LAN、互联网或两者。如果选择器漏掉了 LAN,后面任何检查都不再重要。
OpenWrt 让这种区分可以检查,值得读一遍。终结隧道的区域需要一条指向 LAN 区域的转发规则,而输入规则只管理路由器自身运行的服务。管理页面正常而 LAN 已死,通常就是那条转发规则缺失的结果。
uci show firewall | grep -E "zone\[[0-9]+\]\.(name|input|forward|output)"查看承载隧道的区域的转发目标:accept 是这道梯子需要的值,reject 则解释了下方所有的超时。相邻的两个设置会产生同样的症状,既然在这里就一并排除。无线隔离会让无线客户端看不到有线主机,而把空闲 LAN 主机当作离线处理的路由器,即便转发生效也可能丢弃应答。
为什么拆分隧道需要推送前缀
把所有流量都走隧道的客户端,其默认路由已经包含 LAN 前缀,所以无需添加。拆分隧道才是需要明确写出前缀的情形,因为配置里再没有别处提到它。把该指令加入服务端配置并重新加载服务。
push "route 192.168.50.0 255.255.255.0"包含 route-nopull 的配置文件会忽略推送的路由,因此同一前缀应放进客户端文件。无论如何,要确认条目确实到达,而不是想当然,因为静默覆盖看起来与防火墙问题完全一样。
ip route show | grep 192.168.50站点到站点的对端要求不止一次推送。服务端必须知道该对端背后有哪些前缀,这由它的 client-config-dir 文件里的 iroute 行完成;同时服务端自己的表也需要一条通往隧道的匹配路由。
应答需要一个它能到达的地址
转发请求只是交换的一半,因为 LAN 主机必须向隧道地址池中的地址应答。小型路由器通常通过 在隧道区域上做源地址转换 来安排这一点,于是应答发往路由器,其他地方无需配置。去掉这层转换,主机就需要自己通往地址池的路由;当路由器是它的默认网关时,这条路由是免费的。而手动设置地址、使用另一个网关的主机则会经由那个网关应答,客户端就会看到会话打开后又卡住。
tcpdump -ni tun0 host 192.168.50.20在客户端重复请求时于路由器上运行这条命令,读的是应答的目的地,而不是请求本身。发往地址池的应答说明回程路径通畅,故障在更里面。完全没有任何应答,说明主机从未接受该数据包,这会把您送回规则集。
一道在正确位置结束的梯子
四项检查定位层次,每一项都是一条命令,而不是一次判断。按顺序执行,并在第一处失败时停下。顺序比命令更重要,因为后面通过的一步会掩盖前面失败的原因。
ping -c1 10.8.0.1
ping -c1 192.168.50.20
nc -vz 192.168.50.20 445
getent hosts nas.local名称应当在梯子的末端,绝不能在开头。某个共享以 192.168.50.20 应答却不以 nas.local 应答,指向的是名称解析或搜索后缀,防火墙的修改无法改变其中任何一个。
记下第一个失败的步骤,然后单独检查服务端口,因为监听进程和主机放行是两个独立条件。文件共享、远程桌面和摄像头串流都需要两者,只信任 LAN 子网却不信任隧道地址池的主机防火墙,会在 ping 仍然成功时把客户端丢掉。当所有检查都通过而应用仍然失败时,故障在隧道之上:服务只绑定在一个接口上,或者客户端配置了代理。