深度解析 JuiceFS 权限管理:Linux 多种安全机制全兼容
在多用户和高安全性要求的系统中,文件与目录权限控制是实现资源隔离与系统安全的基础机制。Linux 操作系统的文件权限模型提供了灵活强大的权限控制机制,通过对用户、组和其他用户的权限设置,确保系统资源的安全性和合规性。
作为一款支持 Linux 系统的分布式文件系统,JuiceFS 需要与 Linux 权限管理模型兼容,以实现一致的访问控制和数据安全。本文将深入探讨 JuiceFS 在实际应用中的权限管理实践,帮助用户更好地理解和应用。
01 访问控制模型:DAC 和 MAC
访问控制是系统安全的重要组成部分,旨在管理对资源(如文件、网络服务等)的访问。Linux上常见的访问控制模型有 DAC(Discretionary Access Control,自主访问控制)和 MAC(Mandatory Access Control,强制访问控制)。这两种模型有不同的授权机制和应用场景。
二者的区别如下:
特性 | DAC(分散式机制,用户自主访问控制) | MAC(中心化机制,管理员强制访问控制) |
---|---|---|
控制主体 | 资源所有者 | 系统级策略 |
权限分配 | 资源所有者自主分配 | 中央管理员统一管理 |
灵活性 | 高(用户自主控制) | 低(严格策略限制) |
安全等级 | 中等(依赖用户决策) | 高(适用于敏感环境) |
修改权限 | 资源所有者可随时修改 | 只能由管理员修改 |
常用的 Unix Permission 和 POSIX ACL 实现了自主访问控制 (DAC),允许资源所有者自由管理文件和目录的访问权限,而 SELinux 和 AppArmor 实现了强制访问控制(MAC),通过系统定义的安全策略来限制访问权限,从而提供更为严格的安全控制。
在下面的内容中,我们会展开介绍这些机制的细节和在 JuiceFS 的相关使用。
02 Unix Permission
Unix Permission 是从 Unix 系统中继承的一种权限管理机制,用于控制文件和目录的访问权限。 该机制简单总结如下:
主体(Subject)对客体(Object)的行为根据规则进行控制。
- 主体:操作者是用户或者说进程,划分为三类(ugo)
- u: 文件所有者(Owner)
- g: 文件所属组(Owner Group)
- o: 其他用户(Other)
- 客体:操作对象是文件或者目录
- 规则:三种权限(rwx),对于文件和目录有不同的含义
- r:读取权限
- 文件:读取文件内容,拓展属性,symlink等
- 目录: 列出目录内列表等
- w:写入权限
- 文件:修改文件内容,拓展属性等
- 目录:创建,删除,移动文件或目录
- x:执行权限
- 文件:执行文件
- 目录:切换目录,查看内部文件属性等
- r:读取权限
特殊权限位
简单的 ugo+rwx 权限模型,是大家比较熟悉的。在这基础上,还有一些拓展的特殊权限位:
- SUID: 当一个文件被赋予了 SUID 权限,其他用户在执行这个文件时,其权限会暂时提升到该文件所有者的权限。
- SGID: SGID 权限与 SUID 类似,但它影响的是文件的组权限而不是所有者权限。当一个文件被赋予了 SGID 权限,其他用户在执行这个文件时,其权限会暂时提升到该文件所属组的权限。
- SBIT: Sticky Bit 是一种特殊的目录权限。当一个目录被赋予了 Sticky Bit 权限,用户只能删除自己拥有的文件,即使他们对这个目录有写和执行权限。这个权限通常用在临时文件目录(如/tmp),以防止用户删除其他用户的文件。
JuiceFS 的权限校验
JuiceFS 是基于 FUSE 的用户态文件系统,默认情况下,JuiceFS 会开启 default_permissions 配置,即启用内核的权限检查。文件操作请求到达 JuiceFS 用户态前,内核会根据文件属性中的 mode 先进行 Unix Permission 的权限校验,通过后再交给 JuiceFS 处理。
此外,JuiceFS 本身在用户态也实现了兼容的权限校验逻辑,用于处理一些特殊的权限场景。
SDK 访问: 一个是 JuiceFS 提供了多种 SDK 访问方式,这些 SDK 请求不经过内核,所以 JuiceFS 需要自己实现权限校验;
Squash 功能:当启用 squash 功能时,JuiceFS 会将某些用户映射为指定的用户,在这种情况下,无法依赖内核权限校验,因此 JuiceFS 会启用用户态的权限校验。
下面简单介绍一下 squash 两种模式:
- root-squash (Root 降权映射)
root-squash 模式用于将本地 root 用户映射为其他用户,从而增强系统安全性。在该模式下,即使操作系统中的 root 用户,执行文件操作时也会受到权限控制,无法随意修改其他用户的文件。
# root in /tmp/jfs
$ ll /tmp/jfs/f1
-rw------- 1 user2 user2 0 2月 19 16:26 /tmp/jfs/f1
# 读取用户user2的文件,可以直接读取
$ cat /tmp/jfs/f1
hello
映射后
# root用户映射为普通用户user1(uid=1001,gid=1001)
./juicefs mount sqlite3://test.db /tmp/jfs -o allow_other -root-squash=1001:1001
# 读取user2的文件,权限不足
$ cat /tmp/jfs/f1
cat: /tmp/jfs/f1: Permission denied
- all-squash (所有用户映射为指定用户)
在 all-squash 模式下,系统将所有用户映射为指定的用户(例如 user1),此模式通常用于统一权限管理,所有操作都会以指定用户的身份进行。该功能将在 JuiceFS 社区 1.3 版本发布。
# 所有用户映射为user1(uid=1001,gid=1001)
$ ./juicefs mount sqlite3://test.db /tmp/jfs -o allow_other -all-squash=1001:1001
# user2 创建文件
$ whoami
user2
$ touch f1
# user3 创建文件
$ whoami
user3
$ touch f2
# 最后文件拥有者都是user1
$ ls -l .
total 0
-rw-rw-r-- 1 user1 user1 0 2月 19 14:10 f1
-rw-rw-r-- 1 user1 user1 0 2月 19 14:11 f2
03 POSIX ACL
Unix Permission 已经能够满足大部分的权限管理需求,但是在某些场景下,我们需要更加细粒度的权限控制。比如需要单独为某个用户开放文件权限的时候,这时候就可以用 ACL 做精细控制。 POSIX ACL(Access Control List)是一种扩展的权限控制机制,虽然没有统一的标准,但是草案《POSIX 1003.1e draft 17》是被广泛接受的。基于这个草案的实现,在 2002 年 11 月被添加到 Linux 内核的 2.5.46 版本中。
传统的 Unix Permission 只对主体做了三种分类(owner、group、other),而 POSIX ACL 在此基础上,对主体进行了更细致的分类,可以对任意的用户/组分配 rwx 权限。所有的用户权限定义在 ACL 中可以抽象成一条 entry 定义。每一条 entry,包含用户 id,以及他的权限定义,结构定义如下:
type Permission struct {
Owner Mode
Group Mode
Other Mode
}
type ACL struct {
Owner Mode
Group Mode
Other Mode
Mask Mode // 权限上界
NamedUsers Entry // 新增指定用户权限定义
NamedGroups Entry // 新增指定用户组权限定义
}
type Entry struct {
Uid uint32
Perm Mode
}
POSIX ACL 新增了指定用户(NamedUsers)和指定用户组(NamedGroup)的权限。从定义上看,我们可以把 POSIX ACL 新增的 entry(包括 Mask)划分到 group class,将 group class 的定义从原来所在组的权限,扩展到 group class 中所有 entry 的权限上界。
分组 | entry 项 | 文本格式 |
---|---|---|
owner class | owner | user::rwx |
group class | named user | user:name:rwx |
group class | owning group | group::rwx |
group class | named group | group:name:rwx |
group class | mask | mask::rwx |
other class | others | other::rwx |
当没有配置额外的 named user 和 named group 时,称之为 Minimal ACL, 与 Unix Permission 等价。
- Minimal ACL:等同于普通 unix permission
- Extended ACL:配置了任意 named user 或 named group 项
下面操作展示了 POSIX ACL 与 Unix Permission 之间的关联性。
# 查看权限
$ ls -l
drwxr-xr-x 2 root root 4.0K 4月 12 09:32 d1
# 通过setfacl设置d1目录的group1组权限
$ setfacl -m g:group1:rwx d1
# 再次查看权限
$ ls -l
drwxrwxr-x+ 2 root root 4.0K 4月 12 09:32 d1
设置了 ACL 之后,文件的 group class 也发生了变化, 增加了 “w” 权限。这是因为 ACL 拓展了 group class(请参考表格 1 中的分组)。
unix permission 中的 group class 仅代表了 owner group 的权限,但 POSIX ACL 中代表 group class 所有条目的权限上界。因此 group class 的权限位也会随条目变动而变化.
ACL 新增条目:Mask
上文提到 ACL 中新增的条目 “mask” ,该条目用于表示 group class 的动态权限变化。设置了 ACL 后,permission mode 的 group class 显示就是 mask。
通过 setfacl 设置 ACL, 默认会自动计算出 mask。比如上文所示, mask = owner group entry | group1 entry, 取并集"rwx"; 也可以独立设置 mask, 则 group class 中 entry 项的最终权限需要与 mask 取交集. 如下文:
- owner group 最终生效的权限为:"r-x" & "-wx" = "--x"
- group1 权限为:"rwx" & "-wx" = "-wx"
# 接上文操作, 设置mask为"-wx"
$ setfacl -m m::-wx d1
# 查看ACL
$ getfacl d1 --omit-header
user::rwx
group::r-x #effective:--x
group:group1:rwx #effective:-wx
mask::-wx
other::r-x
ACL 类别
ACL 分为两种类别,Access ACL 和 Default ACL。
- Access ACL: 用于权限定义和检查, 适用于文件和目录,定义如上面章节所述。
- Default ACL:结构与 Access ACL 相同,但仅应用于目录。子文件/子目录的 Access ACL将继承自父目录的 Default ACL。(继承后的权限,结合创建文件对象的系统调用的mode 参数生成最终的 Access ACL, 其中 owner/mask/other与mode 取交集)。
# 设置access acl
$ setfacl -m u:user1:rwx d1
# 设置default acl (with -d flag)
setfacl -d -m u:user1:rwx d1
# 查看acl
$ getfacl -c d1
# 前5项是access acl配置
user::rwx
user:user1:rwx
group::rwx
mask::rwx
other::r-x
# 后面5项是default acl配置
default:user::rwx
default:user:user1:rwx
default:group::rwx
default:mask::rwx
default:other::r-x
Access ACL 权限判断规则
进程请求访问文件对象,权限判断规则如下:
- 首先找到一条最匹配的 ACL entry
- entry按照以下顺序查找:
- owner
- named users
- owning or named groups
- others
- 一个进程可能属于多个组,有多条group class entry匹配(上面第3项),那么取拥有权限的那条entry。如果有匹配的group class entry,但都不满足权限要求,那么请求被拒绝。
- entry按照以下顺序查找:
- 检查这条 entry 的权限要求是否满足请求
如果对细节感兴趣,可以参考 JuiceFS 社区版 pkg/acl/acl.go
中的实现。
JuiceFS 的 ACL
JuiceFS 通过将 ACL 和扩展属性(xattr)解耦来优化 ACL 的存储。每个文件不再单独保存一份 ACL,而是将 ACL 存储在一个独立的元数据结构中,并通过全局唯一的 ACL ID 来引用相同的 ACL 配置。这种方法显著减少了重复数据存储需求,并提高了性能,特别是在使用 Default ACL 的目录下创建文件时,减少了存储 ACL 请求的频率。详情,请参考文章:ACL 功能全解析,更精细的权限控制;配置参考文档:POSIX ACL、JuiceFS POSIX ACL 权限管理上手指南。
04 Capability,细分权限能力,降低系统安全风险
传统的 unix 权限只区分了两种类别进程,特权 (root) 和非特权。 root 进程拥有系统的所有权限, 比如前面所述的 unix permission 和 acl 权限检查对其无效,可以任意访问/修改文件对象。
从 Linux 内核 2.2 版本之后,加入了 Capability 机制,将权限细分成不同能力。这样可以给非特权进程赋予部分特权,降低了系统的安全风险。
二进制文件的 capability 集合是记录在命名空间 security 下的拓展属性的。可以通过 getcap 和setcap 命令查看和设置 capability。
如果在 JuiceFS中(1.3版本)使用的话,需要同时开启拓展属性(挂载参数 --enable-xattr
)和capability (挂载参数 --enable-cap
) 支持。默认 capability 是关闭的,因为一般场景比较少使用到,开启后会增加许多对拓展属性的元数据请求,影响性能。
# 挂载, 需要启动xattr和cap
$ ./juicefs mount sqlite3://test.db /tmp/jfs --enable-cap --enable-xattr
# 设置capability:普通用户执行bin二进制,可以拥有修改文件owner的权限
$ sudo setcap 'cap_chown=+ep' bin
# 查看capability
$ getcap bin
bin cap_chown=ep
05 SELinux:增强 Linux 系统安全的内核模块
前面讲述 DAC 与 MAC 两种模型的原理与区别,DAC 比较灵活但不严格,有一定的安全隐患。在 DAC 的访问控制机制中,传统 Linux 由于 root 权限的“权力”过大而存在安全威胁。
MAC 模型则能解决这个问题,它是一种强制访问控制机制,由系统管理员配置策略,严格执行。SElinux 是实现 MAC 模型的一个安全增强的 Linux 内核模块,它控制了无限的 root 权限。
虽然 SELinux 和 AppArmor 都是 Linux 上的实现 MAC 的安全模块。但是使用和实现上有一些区别。不同 Linux 发行版默认使用不同,SELiunx 主要用于 RHEL/Fedora,AppArmor主要用于 Ubuntu 和 SUSE。这里主要介绍 SELinux。
在启用了 SELinux 的 Linux 操作系统中,系统权限管理要先通过 DAC 机制的检测, 再检测 SELinux 的安全策略。在 SELinux 中,每个对象(比如文件)都有一个 安全上下文(Security Context),通过文件拓展属性,记载着该对象具有的权限(SELinux 定义的权限)。
如果在 JuiceFS 中(1.3 版本)使用的话,需要同时开启拓展属性(挂载参数--enable-xattr
)和SELinux (挂载参数--enable-selinux
)支持。默认 ``--enable-selinux` 也是关闭的。
06 小结
本文全面梳理了 Linux 文件权限管理模型,并探讨了 JuiceFS 在此基础上的权限管理实现。作为一款基于 FUSE 的用户态分布式文件系统,JuiceFS 不仅兼容传统的 Unix 权限机制,还通过用户态权限校验、root-squash 和 all-squash 等特殊功能,提供了更加灵活的访问控制策略。这些功能使得 JuiceFS 能够在多种权限管理需求下稳定运行,特别适用于需要高安全性和复杂用户管理的环境。
通过灵活配置权限管理,JuiceFS 能有效提高数据的安全性、合规性,并确保在多用户环境中提供稳定和高效的数据存取服务,帮助企业应对更复杂的存储和安全挑战。
深度解析 JuiceFS 权限管理:Linux 多种安全机制全兼容的更多相关文章
- 【MySQL】MySQL解析用户权限管理
一.MySQL权限简介 关于mysql的权限简单的理解就是mysql允许你做你全力以内的事情,不可以越界.比如只允许你执行select操作,那么你就不能执行update操作.只允许你从某台机器上连接m ...
- 权限管理[Linux]
chown username file,... 改变文件的属主(只有管理员可以使用此命令) -R:修改目录及其内部文件的属主 -reference=somefile_path file,...把想要设 ...
- Linux(3)用户和权限管理
用户, 权限管理 Linux中root账号通常用于系统的维护和管理, 它对操作系统的所有部分具有不受限制的访问权限 在Unix/Linux安装过程中, 系统会自动创建许多用户账号, 而这些默认的用户就 ...
- Linux用户和权限管理看了你就会用啦
前言 只有光头才能变强 回顾前面: 看完这篇Linux基本的操作就会了 没想到上一篇能在知乎获得千赞呀,Linux也快期末考试了,也有半个月没有写文章了.这篇主要将Linux下的用户和权限知识点再整理 ...
- Linux命令-用户及权限管理
一.权限管理linux系统中对文件权限的描述机制: u g od r w x r w x r - x (r读,w写,x执行)文件 所有者 所属组 其他人可以表示为二进制: 111 111 101也可以 ...
- Linux权限管理、系统进程管理
权限管理 linux系统中分为四种角色 u=user 当前用户 g=group 同组用户 o=other 其他用户 a=all 代表所有用户 三种权限 r=read 可读 w=write ...
- Linux云计算-04_Linux用户及权限管理
Linux是一个多用户的操作系统,引入用户,可以更加方便管理Linux服务器,系统默认需要以一个用户的身份登录,而且在系统上启动进程也需要以一个用户身份器运行,用户可以限制某些进程对特定资源的权限控制 ...
- Linux的文件权限管理
Linux文件权限管理介绍 一:Ubuntu 简介 1 .什么是Ubuntu Ubuntu是基于Debian开发的一个开源的Linux操作系统,Ubuntu这个名字名称来⾃⾮洲南部某种语言的一个词语, ...
- linux ssh使用深度解析(key登录详解)
linux ssh使用深度解析(key登录详解) SSH全称Secure SHell,顾名思义就是非常安全的shell的意思,SSH协议是IETF(Internet Engineering Task ...
- 【linux相识相知】用户及权限管理
linux系统是多用户(Multi-users)和多任务(Multi-tasks)的,这样的目的是为了一台linux主机可以给很多用户提供服务同时运行多种服务,但是我们是怎么区分每个用户呢?作为一个管 ...
随机推荐
- k8s 报错: node(s) didn't match Pod's node affinity.
前言 k8s集群中,有pod出现了 Affinity ,使用 kubectl describe pod 命令,发现了报错 2 node(s) didn't match Pod's node affin ...
- 用状态模式开发一个基于WPF的截图功能
状态模式 状态模式是设计模式中的一种行为设计模式,对很多人来说,这个模式平时可能用不到.但是如果你做游戏开发的话,我相信你应该对这个模式有一个很深刻的理解.状态模式在游戏中开发中还是比较常见的.状态模 ...
- Spring定时任务的秘密
Spring定时任务的秘密 在 Spring 框架中,定时任务主要通过 @Scheduled 注解或 TaskScheduler 接口实现. 1.基本使用 在 Spring Boot 项目中,通过 @ ...
- linux 下给网卡添加ipv6、路由
route命令的使用举例如下: route // 显示路由信息. route add –host 192.168.1.110 dev eth0 // 给网卡eth0的路由表中加入新地址192 ...
- 【Python自动化测试环境管理】tox
1. tox基本介绍 1.1 tox是什么? tox 是一个用于管理 Python 项目的自动化测试和环境管理工具.它的主要功能是创建虚拟环境并运行项目的测试套件,tox能够让我们在同一个Host上自 ...
- BUUCTF---异性相吸(欠编码)
1.题目 ܟࠄቕ̐员䭜塊噓䑒̈́ɘ䘆呇Ֆ䝗䐒嵊ᐛ asadsasdasdasdasdasdasdasdasdasdqwesqf 2.知识 3.解题 很奇怪,不知道什么加密,借鉴网上参考,得知需将其转化为 ...
- llamacpp转换hf、vllm运行gguf
Linux通过huggingface安装大模型 huggingface官网 https://huggingface.co/ wget https://repo.anaconda.com/minicon ...
- 基于RK3568 + FPGA国产平台的多通道AD实时采集显示方案分享
在工业控制与数据采集领域,高精度的AD采集和实时显示至关重要.今天,我们就来基于瑞芯微RK3568J + FPGA国产平台深入探讨以下,它是如何实现该功能的.适用开发环境如下: Windows开发环境 ...
- js 小数取整
小数取整 var num = 123.456; // 常规方法 console.log(parseInt(num)); // 123 // 双重按位非 console.log(~~num); // 1 ...
- 技术博客:如何构建AI模拟面试系统(附完整GitHub代码)
引言:当董明珠.雷军.马斯克和特朗普成为你的面试官 在当今竞争激烈的求职市场中,模拟面试系统正成为开发者提升竞争力的秘密武器.但传统的模拟面试太过平淡,于是我开发了一个多风格AI面试官系统,让你可以体 ...