这个假设很容易被接受,却很难被察觉:VPN 连接钩子以 root 运行,于是它启动的挂载也应该按 root 安排。这种推理会带来桌面用户打不开的团队目录、触发服务重启后就消失的挂载,以及没人能应答的认证提示。钩子和挂载是两件不同的事,只有其中一件需要权限。

误解:网络权限意味着挂载权限

抬起接口与向文件服务器认证是互不相关的能力,通常属于不同的账户。VPN 组件需要足够的权限来修改路由和接口。文件服务器账户需要密钥或密码、一个主机密钥方面的决定,以及要挂载进去的主目录。把第二件事的凭据交给第一种身份,正是网络服务最终持有用户密钥的方式。

在单用户笔记本上,它们可能是同一个账户,但这种巧合不是设计。

一旦有权限的钩子执行挂载,三件事会悄悄出错。挂载归 root 所有,用户代理不在那个环境里,失败出现在网络服务的日志里而不是在意它的会话里。这些都不是靠给挂载命令加选项能修好的。它们要靠把工作交给拥有该身份的会话来修好。

为什么挂载属于已登录用户

SSHFS 挂载是由创建它的进程拥有的 FUSE 挂载,访问权限取决于这种所有权,而不是父目录的模式。参考文档建议使用普通用户,并且挂载点归该用户所有,这正是 root 进程创建的挂载对其他人都不方便的原因。修改挂载点上的权限并不能修复,因为障碍是挂载本身的所有者。

从用户会话中的手动基线开始:主目录下已有的空挂载点、服务器上的授权账户,以及已经通过你认可的流程验证过的主机密钥。先手动挂载一次并使用它,因为这证明在任何自动化出现之前身份路径是通的。记下命令需要什么:账户名、导出路径和私有主机名。把这份完全相同的上下文留给自动化版本,因为能工作的手动挂载就是触发器必须复现的规格。

sshfs [email protected]:/exports/team "$HOME/mnt/team"

把那一行里的每个名称和路径都当作占位符,包括账户和导出。VPN 账户的密码并不自动等于存储账户的凭据。

触发器应该请会话做什么

受支持的安排是 从网络事件向用户会话发出请求,而不是借用凭据。把触发器限定在你所指的连接上,按名称或 UUID,而不是限定在任何碰巧叫 tun0 的接口上。仅这一处改动就能阻止第二个配置文件、一条测试隧道或同事的调试会话启动挂载。

会话侧的动作应该先寻找预期的现有挂载,然后做一次有边界的尝试。

不要在每次轮询时重试,也不要在服务器不可达时反复索要凭据,因为这两者都会把暂时中断变成账户锁定。无人值守服务是另一套设计,它有自己的获批凭据,并在自己的执行上下文里做主机验证,不能指望有人解锁过图形代理。在决定代码放在哪里之前,先想清楚你要建的是哪一种。这里的大部分混乱都来自建了其中一种却期待另一种。

断开是文件系统事件,不是钩子事件

计划内的断开应该结束文件操作,并用该文件系统类型受支持的命令,从执行挂载的用户会话中卸载。为了让钩子快速返回而强制分离,正是应用失去工作目录、用户失去对自动化信任的方式。忙碌的挂载需要应用层的决定,比如关闭文件或停止写入,而不是更强的信号。钩子的退出状态不是被优化的对象。

fusermount3 -u "$HOME/mnt/team"

意外丢失是另一种情况,SSHFS 文档指出被中断的操作可能在传输重连期间阻塞。

重连选项会恢复传输,但在重连之前打开的文件仍可能返回错误并需要重新打开。VPN 恢复并不能证明之前的句柄或未保存的工作如何。选择你在中断时想要的行为——暂停、显示错误或有意重新挂载——并在任何东西依赖它之前,用一次性文件测试。

相关文章