NFSv4 ACL 详解(基于 linux 原生实现)
NFSv4 ACL与POSIX ACL在权限管理上存在显著差异。POSIX ACL基于owner/group/other模型并引入mask限制,而NFSv4 ACL取消了mask概念,采用OWNER@、GROUP@、EVERYONE@等原则。二者转换时,NFSv4 ACL会转为POSIX ACL存储。NFSv4 ACL通过有序的ACE条目实现权限控制,但需注意deny操作可能产生"误伤&
NFSv4 ACL
NFSv4 ACL 与 POSIX ACL 的区别
POSIX ACL 在 owner、group owner、other 的范围基础上,引入了普通 user 和 group。
POSIX ACL 检查权限时,按下面顺序检查,且只会按第一个匹配的检查条目做检查,其中 mask 指 user、group、group owner 的权限最大集。
| 检查条目顺序 | 检查内容 |
|---|---|
| 属于owner | 如果 owenr 权限满足要求的权限,则检查通过 |
| 属于user | 如果 user 的权限与 mask 的交集满足要求的权限,则检查通过 |
| 属于group owner、group | 所有 group 与 mask 的交集,或 group owner 与 mask 的交集,只要有一个交集满足要求的权限,则检查通过other 权限 |
| 属于other | 如果 other 权限满足要求的权限,则检查通过 |
NFS4 ACL 没有 Mask 的概念,无法像 POSIX ACL 一样配置 user 和 group、group owner 的允许最大权限范围。但引入了 OWNER@、 GROUP@、 EVERYONE@ 的 principle,它们与 POSIX principle 的对应关系如下:
| owner | user | group owner | group | other | |
|---|---|---|---|---|---|
| OWNER@ | √ | ||||
| GROUP@ | √ | ||||
| EVERYONE@ | √ | √ | √ | √ | √ |
Mode 与 ACL
linux 原生的权限检查中,先检查 POSIX ACL,如果检查通过,再检查 mode。mode 修改(chmod)不会影响 POSIX ACL,但修改 NFS4/POSIX ACL (nfs4_setfacl / setfacl)会影响 Mode。影响的范围如下:
| NFSv4 ACL Principal | POSIX ACL Principal | Mode |
|---|---|---|
| OWNER@ | owner | S_IRWXU (700) |
| GROUP@ | group owner | S_IRWXG (070) |
| EVERYONE@ | owner、group owner、other | S_IRWXU|S_IRWXG|S_IRWXO (777) |
| user | user | 无影响 |
| group | group | 无影响 |
NFSv4 ACL 使用方法
NFSv4 ACL 由多条 ACE 按顺序叠加组成,在linux 原生 nfs 服务端转为 POSIX ACL 生效,因此只支持NFSv4 ACL 的子集。
注:ACL 列表中第一条 ACE 条目的 index 是 1。下面的 -R 参考指递归配置目录下所有文件或目录。
1、查看 ACL 中 ACE 列表
nfs4_getfacl <path>
2、在 ACL 列表的某个位置添加 ACE 条目
nfs4_setfacl [-R] -a <ace> [ace_index] # 在第 index 条 ACE 前添加新的 ACE 条目,默认为1
3、删除 ACL 列表的某个位置的 ACE 条目
nfs4_setfacl [-R] -x <ace_index> # 删除第 index 条ACE
nfs4_setfacl [-R] -x <ace> # 要求 ACE 的内容与某一条 ACE 完全匹配
注:在linux 原生实现中 NFS4 ACL 在存储时,是先转为 POSIX ACL 再存入 inode 中的,查询时再转回 NFS4 ACL,顺序与最初添加的顺序可能不一致,但不影响语义。例如第一条 ACE deny 一个权限,第二条 ACE allow 一个权限,则最后只显示 deny 的 ACE 条目,即只显示生效的条目。
ACE 格式
type:flag:user_or_group:mask
ACE Type
| ACE Type | 含义 | 是否支持配置 | 行为 |
|---|---|---|---|
| A | 添加 allow ace条目 | 是 | 如果前面的 ace 条目没有 deny 此 ace 的权限,则此权限会被 allow |
| D | 添加deny ace 条目 | 是,但不建议用,建议用先删除原ace条目再添加新ace条目来代替 | 1、如果前面的 ace 条目没有 allow 此 ace 的权限,则此权限会被 deny 2、如果成功 deny 了一个权限,则可能导致“误伤”其它user 或 group的权限,这是为了满足 POSIX 模型的保守做法,因为 posix 是按检查条目顺序来检查的(owner->user->group_owner、group->other),deny后面条目的权限后,依然可能因为在匹配前面的检查条目,而导致权限被 allow。比如一个普通用户,它还可能也是 owner;一个用户属于一个普通 group,它还可能也是文件的 owner,也可能匹配 user 条目,也可能是某个组的 group onwer,也可能属于某个 group。在 NFS ACL 转 POSIX ACL 的阶段,无法知道转完后 POSIX ACL 的规则是怎样的,因而使用了这种比较保守的做法。 |
| U | 为访问行为添加审计日志 | 否 | 无影响 |
| L | 当产生允许或禁止的访问行为时触发报警 | 否 | 无影响 |
Deny 误伤矩阵
下面表格展示了当deny了某个 NFS Principle 的权限时,它可能会误伤哪些 NFS Principle 或 POSIX Principle 的权限。
| nfs principal\误伤 principle | OWNER@/owner | user | GROUP@/group owner | group | EVERYONE@ | other |
|---|---|---|---|---|---|---|
| OWNER@ | √ | |||||
| user | √ | √ | ||||
| GROUP@ | √ | √ | √ | √ | √ | |
| group | √ | √ | √ | √ | √ | |
| EVERYONE@ | √ | √ | √ | √ | √ | √ |
ACE Flag
| ACE Flags | 含义 | 是否支持 | 行为 |
|---|---|---|---|
| g | 为此目录或文件增加的是group 的 ace 而非user 的 ace | 是 | 增加的是 group 的 ace 而非 user 的 ace |
| d/f | 在此目录下新创建的目录/文件继承权限 | 是 | 1、在目录下创建文件与目录的权限归一:无论指定了d、f、df中的哪种flag,增加或删除权限的行为会同时应用于目录下新创建的目录和文件(相当于同时指定了 df) 2、只对目录生成,对文件应用 d/f 的 flag 的 ace 条目无效 |
| i | 是否影响原目录 | 是 | 1、指定 i 时,不影响当前目录的 acl 权限,只影响目录下新创建的文件或目录的 acl 权限。 2、只在指定 d/f flag时有效 |
ACE Mask
| ACE Mask | 含义 | 是否支持配置 | 权限 |
|---|---|---|---|
| r | 读文件或目录权限 | 是 | 1、读文件内容 2、列出目录下文件 |
| w/a | 修改文件或目录 | 是 | 1、追加写(a)或覆盖写(w)文件 2、在目录下创建文件或目录 3、无论指定了w、a、wa中的哪种,都相当于指定了 wa,即“修改”的权限 4、部分旧版本要求 ace 条目中对目录同时指定 waD 才有效 5、部分旧版本要求 ace 条目中对文件同时指定 wa 才有效 |
| x | 执行文件或进入目录 | 是 | 1、执行文件 2、进入目录 |
| d | 删除此文件或目录 | 否 | 无影响 |
| D | 删除此目录下的文件或目录 | 否 | 对目录有写属性时自动附带 D 权限 |
| t | 读文件或目录的 attr | 否 | EVERYONE@ 自动附带权限,即任何用户可读文件/目录的属性 |
| T | 写文件或目录的 attr | 否 | OWNER@ 自动附带权限,即只有 owner 可修改文件/目录的属性 |
| n | 读文件或目录的 named attr | 否 | 无影响 |
| N | 写文件或目录的 named attr | 否 | 无影响 |
| c | 读文件或目录的 acl | 否 | EVERYONE@ 自动附带权限,即任何用户可读文件/目录的 acl |
| C | 写文件或目录的 acl | 否 | OWNER@ 自动附带权限,即只有 owner 可修改文件/目录的 acl |
| o | 改变文件或目录的 owner | 否 | 无影响 |
| y | 允许nfs client 在提交写时确保文件内容落盘(sync IO) | 否 | EVERYONE@ 自动附带权限,即 nfs 服务端对于任务用户的写后 commit 请求,一定会等数据落盘才回复 nfs 客户端。 |
举例
例1
给 file 文件的 1002 用户添加读/写/执行权限,此条目加为 ACL 列表的第 4 条
nfs4_setfacl -a A::1003:warx 4 file
执行过程:
[root@localhost test]# touch file
[root@localhost test]#
[root@localhost test]# nfs4_getfacl file
# file: file
A::OWNER@:rwatTcCy
A::GROUP@:rtcy
A::EVERYONE@:rtcy
[root@localhost test]# nfs4_setfacl -a A::1002:warx file
[root@localhost test]# nfs4_getfacl file
# file: file
D::OWNER@:x
A::OWNER@:rwatTcCy
A::1002:rwaxtcy
A::GROUP@:rtcy
A::EVERYONE@:rtcy
[root@localhost test]# nfs4_setfacl -a D::1002:warx 4 file
[root@localhost test]# nfs4_getfacl file
# file: file
D::OWNER@:x
A::OWNER@:rwatTcCy
A::1002:rwaxtcy
A::GROUP@:rtcy
A::EVERYONE@:rtcy
从执行结果可知,在第4条位置添加 deny ace 不生效,因为第3条 ace 已经 allow 了写权限。
例2
给 dir 目录设置继承权限,使此目录下创建的文件或目录,对于 1003 用户拥有读/写/执行权限
nfs4_setfacl -a A:fdi:1003:wrx dir
执行过程:
[root@localhost test]# mkdir dir
[root@localhost test]# nfs4_getfacl dir
# file: dir
A::OWNER@:rwaDxtTcCy
A::GROUP@:rxtcy
A::EVERYONE@:rxtcy
[root@localhost test]# nfs4_setfacl -a A:fdi:1003:wrx dir
[root@localhost test]# nfs4_getfacl dir
# file: dir
A::OWNER@:rwaDxtTcCy
A::GROUP@:rxtcy
A::EVERYONE@:rxtcy
D:fdi:OWNER@:rx
A:fdi:OWNER@:tTcCy
A:fdi:1003:rxtcy
A:fdi:GROUP@:tcy
A:fdi:EVERYONE@:tcy
[root@localhost test]# touch dir/file
[root@localhost test]# nfs4_getfacl dir/file
# file: dir/file
D::OWNER@:r
A::OWNER@:tTcCy
A::1003:rtcy
A::GROUP@:tcy
A::EVERYONE@:tcy
可以发现由于指定了 flag i,dir 目录本身没有新增对 1003 用户的读/写/执行权限的 ACE。但目录下创建的 dir/file 文件新增对 1003 用户的读/写/执行权限的 ACE。
例3
给 dir 目录本身的 group owner 移除写权限,且此目录下创建的文件或目录的 group owner 均继承此权限
nfs4_setfacl -a D:f:GROUP@:w dir
执行过程
[root@localhost test]# mkdir dir
[root@localhost test]# nfs4_getfacl dir
# file: dir
A::OWNER@:rwaDxtTcCy
A::GROUP@:rxtcy
A::EVERYONE@:rxtcy
[root@localhost test]# nfs4_setfacl -a D:f:GROUP@:wa dir
[root@localhost test]# nfs4_getfacl dir
# file: dir
A::OWNER@:rxtTcCy
A::GROUP@:rxtcy
A::EVERYONE@:rxtcy
A:fdi:OWNER@:tTcCy
A:fdi:GROUP@:tcy
A:fdi:EVERYONE@:tcy
可以发现由于未指定 flag i,dir 目录除了新增对 group owner 的读/写/执行权限的 ACE外,目录本身的写权限也被deny了。且虽然只指定了f,但fd一起生效。除此之外产生了误伤,OWNER@与 EVERYONE@的写权限也被deny了。
FAQ
1、在目录下指定了 A:fdi:1001:raDwx,创建文件时为什么没有继承 x 属性?
实际上继承了,但 mask 把 x 属性掩盖了,通过 getfacl 可以看到其 mask 为 rw-,这是因为 touch 命令在调用 openat 时传入的 mode 就是默认的 666(见coreutils 包 touch.c)

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)