整个上午共享都正常,中午隧道重连后,同一个 UNC 路径开始超时,而对服务器的 ping 仍然有回应。共享定义没有任何变化,VPN 也在运行。变化的是 Samba 绑定的本地地址,接口重建之后它已不存在。这种故障模式是监听器的生命周期问题,不是权限问题。

共享一直正常,直到隧道重新启动

把服务绑定到某个地址,就把它的套接字绑在了该地址的生命周期上。当隧道接口被销毁并重建时,旧地址消失,绑定在它上面的套接字也随之消失。服务仍在运行,但客户端被路由到的地方已经没有东西在监听。

如果新地址能响应 ICMP,ping 仍然会成功,所以共享已经失效而连通性看起来正常。正是这个误导性的成功把人引向防火墙。

连通性不等于绑定地址

这里混在一起的是三个决定。路由决定客户端的数据包能否到达。监听套接字决定本地地址上是否有东西接收它。共享配置和文件系统权限决定之后发生什么。接口重建时坏掉的只有第二个。

VPN 池里的地址也不会自动成为本地绑定地址。它属于客户端,不属于文件服务器。对文件服务来说,ping 是个糟糕的测试。

在文档里也要把这些责任分开。将来修改 VPN 池不应该需要改 Samba,修改共享权限也不应该需要重启隧道。

改为绑定到稳定地址

更稳定的设计让 Samba 停留在固定地址上,由 VPN 把客户端送到那里。隧道抖动时服务器地址不变,监听器因此永远不必跟随接口。准入由 VPN 路径和主机防火墙来强制执行,它们正是为此而建。

如果必须绑定到隧道,就要理解所装版本的行为约定。interfaces 和 bind interfaces only 参数并不是一回事,绑定文档也提醒了时断时续的接口。某些平台确有动态监听器处理,但这是需要验证的能力,而不是可以假设的。在抖动前后各读一次表,再比较两次输出。

ss -ltnp | grep ':445'

测试重连,而不是看绿灯

在重连之后验证监听器,而不只是服务启动之后。重建隧道,然后读取监听表,确认套接字存在于客户端被路由到的地址上。绿色的隧道指示灯和通过的配置检查都证明不了这一点。

smbclient -L //files.corp.example -U alice

然后从客户端执行一个允许的操作和一条被拒绝的路径,并在第二次重连后再做一遍。如果共享只在第一次抖动前可用,绑定就仍然与接口的生命周期绑在一起,设计并没有修好。改掉绑定或服务地址,症状就不会再回来。

相关文章