连上 OpenVPN 却没有 ping 或 SMB 共享?依次检查三道关口
隧道能建立,并不说明转发、SMB 端口或名称解析都没问题。按顺序测试每道关口,在第一道失败处停下来。
隧道建立起来了,客户端拿到了地址,但远端 LAN 上没有任何回应。ping 失败,共享打不开,而 VPN 日志看起来一切正常,因为在它看来会话是健康的。在那个会话与服务器上的文件之间,隔着三道独立的关口:转发策略、服务需要的端口,以及你输入的不是地址而是名称。
每道关口失败的症状都不同,而只有第一道位于 VPN 服务器上。
转发是 FORWARD 链上的策略
OpenVPN 监听器的接受发生在 INPUT 上,这就是为什么隧道能连上,而发往 LAN 的每个数据包都被丢弃。从 tun0 进入、从 LAN 接口发出的流量要经过 FORWARD,那里的默认 DROP 策略会把它悄悄丢掉。在碰其他任何东西之前,先检查 sysctl 和这条链:sysctl net.ipv4.ip_forward 和 iptables -L FORWARD -v -n。
放行你所需要的方向及其对应的回程,例如一条从隧道接口到 LAN 接口的 accept 规则,以及一条针对 established 和 related 流量的 stateful 规则。如果 LAN 在另一台路由器之后,那台路由器需要有回到客户端池的路由,或者在 VPN 服务器上做 source NAT。加更多规则之前,先用一次 ping 确认这条路,因为到不了的规则永远不会出现在计数器里。
SMB 需要的不止一个端口
文件共享不是一条 TCP 445 会话。发现使用 UDP 137 和 138,较旧的 NetBIOS 会话使用 TCP 139,现代 SMB 会话使用 TCP 445。只开 445 的规则会造成那种令人抓狂的情况:映射的驱动器能用,浏览网络却不行,或者反过来。
大文件经隧道传输还会撞上 MSS 问题,看起来就像共享坏了。宣告 LAN 完整段大小的 SYN 会被隧道更小的 MTU 丢弃,连接在握手之后就挂住。在转发路径上钳制 MSS,iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 就能消除这类停顿。用几兆字节的复制来验证,而不是列目录,因为即使大批量传输不过,小回复也能过去。
隧道适配器会以新的网络配置文件出现
Windows 会把每个适配器归入一个网络配置文件,而新的隧道适配器通常落在 Public,那里文件和打印机共享规则是被阻止的。那是文件服务器上主机防火墙的决定,不是 VPN 服务器上的路由问题。确认策略允许后,再用 Set-NetConnectionProfile -InterfaceAlias "Ethernet 3" -NetworkCategory Private 有意改变类别,因为类别也会改变哪些入站规则生效。
同一配置文件也解释了为什么 TCP 445 能通而 ping 失败:在 Public 下回显请求默认被丢弃。
名称不会自己越过一条被路由的隧道
NetBIOS 名称解析和本地发现依赖广播,而被路由的隧道不承载广播。因此输入服务器短名会失败,而其地址却能用;看起来共享坏了,其实只是查找坏了。在隧道下发的解析器上为服务器添加 DNS 记录,或者在快捷方式里使用地址。
如果部署仍依赖 WINS,就在客户端上配置它,而不是指望广播流量会自己出现。先按地址测试,这样名称故障就不会被误当成防火墙故障。
一次测试一层,并读取第一个失败
自下而上推进:先 ping 隧道网关,再按地址 ping 一台 LAN 主机,然后用 Test-NetConnection -ComputerName 10.8.0.5 -Port 445 打开服务端口,最后才对共享做身份验证。第一个失败的步骤就是要修的那一层,在它通过之前每一步都是噪音。端口关着却能 ping 通,指向文件服务器自己的防火墙;ping 不通但端口能开,则指向 ICMP 过滤。改动任何东西之前先记下第一个失败的步骤,因为第二次改动会掩盖第一次的结果。
如果 VPN 服务器不是 LAN 的路由器,就在那台路由器上确认回程路由 然后再给服务器加规则。没有它,请求能到达主机,回复却沿默认路由去了互联网,从客户端看正好和防火墙丢弃一模一样。
在笔记里把共享账户和 VPN 登录分开,因为隧道成功并不说明文件权限。为了绕开缺失的规则而把 SMB 暴露到互联网,不是解决办法。