根本原因是nfs权限映射失败而非网络问题:nfsv4默认root_squash且依赖domain一致的用户名映射,若domain不匹配或uid不同、服务端未配nohide、客户端未加suid选项,均导致permission denied。

为什么 nfsd 服务启动后客户端挂载却提示 Permission denied
根本原因常不在 NFS 导出配置本身,而在内核级权限检查被绕过或误配。NFSv4 默认启用 root_squash,但若服务端 /etc/exports 中对目录用了 no_root_squash,而客户端用户 UID 不匹配服务端文件所有者,就会触发拒绝——不是网络不通,是权限映射失败。
- 确认服务端实际生效的导出项:
exportfs -v,注意输出中是否含root_squash或no_root_squash - 检查客户端挂载时是否显式指定
sec=sys(NFSv3)或sec=krb5(NFSv4),默认 NFSv4 会尝试sec=krb5,没配置 Kerberos 就直接失败 - 临时验证:在客户端用
sudo mount -t nfs4 -o sec=sys server:/path /mnt强制降级认证方式
noac 和 actimeo 对 NFS 文件一致性的影响
NFS 客户端默认开启属性缓存(ac),导致 ls -l 看到的 mtime、size 可能滞后,甚至 stat 返回旧值。这不是 bug,是设计取舍:缓存提升性能,但破坏强一致性。
-
noac彻底禁用属性缓存,每次stat都走网络请求,适合开发环境或需要实时感知文件变更的场景,但 I/O 延迟明显上升 -
actimeo=N把缓存时间设为 N 秒(如actimeo=1),比noac温和,适合多数生产服务 - 注意:
noac与sync无关,它不控制写入行为;写缓存由soft/hard和rw/ro控制
如何让 NFS 挂载点支持 Linux 文件权限位(如 setuid、sticky bit)
默认 NFS 挂载会丢弃特殊权限位,chmod u+s 后再 ls -l 看不到 s,是因为服务端 /etc/exports 缺少 nohide 或客户端未启用 mount -o suid。
- 服务端导出必须带
nohide(尤其嵌套导出时),否则内核跳过权限位透传 - 客户端挂载需显式加
suid选项:mount -t nfs4 -o rw,suid server:/path /mnt;默认是nosuid,这是安全策略,不是 bug - 验证:挂载后运行
touch /mnt/test && chmod u+s /mnt/test && ls -l /mnt/test,应显示-rwsr--r--
NFSv3 和 NFSv4 在权限模型上的关键差异
NFSv3 权限完全依赖 UID/GID 数字映射,服务端和客户端必须用户 ID 一致;NFSv4 引入用户/组名字符串映射(user@domain),但默认 domain 是主机名,若服务端和客户端 domain 不同,就无法解析用户名,退化成 UID 匹配失败。
- 强制统一 domain:服务端
/etc/idmapd.conf中设Domain = local.domain,客户端同样配置并重启rpcbind和rpc.idmapd - NFSv4 不支持
no_root_squash的等效参数,root 用户始终映射为nobody,除非用all_squash+anonuid手动指定 - 调试命令:
rpc.idmapd -f -v查看域名解析过程,showmount -e server只对 NFSv3 有效,NFSv4 必须用mount server:/查根导出
真正卡住人的从来不是“怎么挂上”,而是 UID 映射断在哪一层、缓存没关干净、或者 domain 名字对不上——这些地方一漏,日志里连像样的错误都不会报。










