两套权限模型并存
传统 Unix 权限用 9 个位加属主/属组描述,最多再叠加 POSIX ACL 给个别用户开例外;而 NFSv4 协议内生一套 ACL:按主体(用户或组)逐个给允许或拒绝条目,带继承标志,还能做拒绝优先的判定。服务端既要能存这件事(ext4/XFS 上的 nfs4 ACL),客户端也要在挂载时协商到 v4 才能读写到协议层面。实际环境里常常是两套都在,于是产生「用 chmod 改了没效果」或「用 setfacl 加了条目在客户端看不见」的现象。
基本信息
| 适用平台 | Linux NFSv4 服务端与客户端 |
|---|---|
| NFSv4 工具 | nfs4_getfacl、nfs4_setfacl(nfs-utils 提供) |
| POSIX 工具 | getfacl、setfacl(acl 包) |
| 前提条件 | 挂载协商为 vers=4.x 且导出未禁用 ACL 支持 |
| 要点 | 同一目录上两套 ACL 的实际生效顺序由服务端文件系统实现决定 |
两套模型对照
| 维度 | NFSv4 ACL | POSIX 权限位与 ACL |
|---|---|---|
| 表达粒度 | 任意主体逐条允许或拒绝 | 属主/属组/其他人三位,ACL 仅做例外 |
| 继承方式 | 条目自带继承标志,向下复制 | 目录默认 ACL 影响新建子项 |
| 拒绝语义 | 显式拒绝条目优先 | 没有拒绝概念,只能靠位与掩码 |
| 命名方式 | 主体可用 user@domain 形式 | UID/GID 数字或本地名 |
| 常见现象 | chmod 之后结果不直观 | setfacl 在 v4 客户端可能不可见 |
两类命令示例
两类命令示例
# 查看 NFSv4 ACL:A 允许、D 拒绝,@ 表示主体是特殊标识
nfs4_getfacl /srv/data
# 给项目组放行读写,并对子目录设置继承
nfs4_setfacl -a A:g:project@example.com:rwx:d:fd:allow /srv/data
# 传统位与 POSIX ACL 的对照查看
getfacl -m g:project:rwx /srv/data && getfacl /srv/data典型使用场景
- 跨平台共享目录既服务 Windows 客户端又服务 Linux 客户端,需要一套能表达继承的权限模型
- 项目目录要求「某个组可写、其他人只读、且新建文件自动继承」,权限位表达不了
- 排查「服务端看得到权限、客户端看不到」的差异,需要判断当前用的到底是哪套 ACL
- 已有大量 setfacl 规则的环境引入 NFSv4,需要评估规则是否会被新模型覆盖
只看传统位往往不够:在没有扩展 ACL 的朴素实现里,NFSv4 ACL 会先被压缩成 rwx 位;而支持完整 ACL 的文件系统会保留完整语义。判断办法是对同一路径分别运行 ls -l、getfacl 与 nfs4_getfacl,三者一致说明当前实现只维护位,三者出现差异说明完整的 v4 ACL 在起作用。
不要在共享目录正在被人写入时批量重写 ACL。NFSv4 的拒绝条目一旦覆盖了某个主体的读权限,正在运行的业务进程会立刻收到 Permission denied,而这类故障在客户端侧只表现为应用报错,很容易被判成应用问题。