VPN 上的 NFS clientaddr:按次版本判断,而非按习惯
clientaddr 只为 NFSv4.0 通告回调地址。请阅读协商后的次版本,检查返回路径,并将其与挂载故障区分开。
clientaddr 属于那种在理由早已消失之后仍被复制进命令行的挂载选项。它告诉 NFSv4.0 服务器到哪里回调客户端。它既不选择服务器,也不把每个请求绑定到源地址,更不会把流量推入隧道。在拥有多个地址的笔记本上,要判断它是否适用,需要三个问题。
三个条件决定该选项是否重要
第一是协商后的次版本,因为 4.1 和 4.2 处理回调的方式不同。第二是服务器能否到达你将通告的地址,路由型隧道通常可以,而经过转换的路径通常不行。第三是你所追查的故障究竟是不是回调故障。
| Condition | If yes | If no |
|---|---|---|
| Version is 4.0 | The option can matter | Skip it; inspect the session instead |
| Server can reach the address | Advertise it | Fix reachability first |
| Failure is a callback | Diagnose callback path | Look at mount and export |
不按顺序回答这些问题,正是人们把回调地址加进 4.2 挂载、然后断定该选项有问题的原因。
先读次版本
nfsstat -m
对于现有挂载,它会打印挂载信息和标志,包括生效版本 vers=4.0、vers=4.1 或 vers=4.2。只写着“NFSv4”的说明会略去唯一能决定该选项是否相关的细节。请读数字,而不是读词。
如果版本字符串来自服务器默认值而不是你的命令行,就要问清协商的是哪个次版本。服务器可能拒绝更高的次版本并回退,而正是这种回退让回调突然变得重要。你写下的挂载行可能并不描述你实际拥有的挂载。
对于 4.0,通告服务器能够到达的地址
NFSv4.0 服务器可能需要一条单独的连接回到客户端,例如在收回委派时。存在多个接口或异常路由表时,回调地址的自动发现可能选中服务器无法使用的地址。
mount -t nfs -o vers=4.0,clientaddr=10.8.0.6 10.8.0.1:/export /mnt/share
冒号前的地址是服务器,并且始终是目标。回调地址属于客户端,必须能从隧道的服务器一侧到达。环回地址会让服务器指向自己。没有返回路由的私有客户端地址同样不可用,即使在客户端上看起来正确。
请把它当作示例,而不是降级正常挂载的理由。替换地址和导出路径,并保留服务器要求的认证与其他选项。为了迁就一个示例而丢掉它们,是另一种改动、另一种结果;在强制安全类型的服务器上,它会在任何回调尝试之前就失败。
4.1 和 4.2 不使用该选项
Linux NFSv4.1 和 4.2 通过客户端建立的连接承载回调,4.1 把这种机制称为后向通道。它们不依赖服务器向通告地址发起新连接,因此 clientaddr 不能修复 4.1 或 4.2 的回调路径。
这并不意味着 4.1 和 4.2 没有回调问题。这意味着诊断方式不同:应检查已建立的会话及其后向通道状态,而不是寻找一个本就不该存在的入站回调端口。缺少入站规则是预期状态,而不是需要纠正的缺陷。
把挂载故障与回调故障分开
先确认客户端能否到达 NFS 服务,以及服务器是否接受导出和认证请求。这次交互之前的超时并不能说明回调地址的问题。在挂载仍然失败时改动其中一项,既不会让调查更接近结论,还会把原始错误藏在新挂载选项之后。
只有当证据显示 4.0 回调失败时,通告的地址才重要,同时还要看服务器的返回路径、客户端一侧的监听器以及两者之间的任何过滤。改动挂载选项里的数字无法创造这些路径,只能指向已经存在的一条。请记下你验证了这四者中的哪一个,因为下一份报告到来时不会附带其中任何一个。
早期启动的 NFS 根是一个独立环境,有自己的前提条件:initramfs 需要工具和网络,挂载才能发生。登录后能用的挂载并不能证明这一序列,而启动时的故障很少提到 initramfs 或网络。