Linux内核安全模块深入剖析【1.5】
第二部分 强制访问控制
LSM——Linux Security Module,字面意思为 Linux 安全模块,在内核中体现为一组安全相关的函数。这些安全函数在系统调用的执行路径中会被调用,所以 LSM 的目的是对用户态进程进行强制访问控制。至于这些安全函数要实施什么样的访问控制,这是由安全模块决定的。截止到 2014 年, Linux 内核主线上有 5 个安全模块: SELinux、 SMACK、 Tomoyo、 AppArmor 和 Yama。用户可以选择哪些安全模块被编译入内核。可以同时有多个安全模块存在于内核中,但是在运行时只能有一个安全模块处在工作状态㊀ 。
虽然还叫模块,但是自 2.6.x㊁ 之后, Linux 就强制 LSM 各个模块必须被编译在内核中,不能再以模块的形式存在了。这意味着在运行时,不能再随意加载一个所谓的安全模块作为访问控制机制了,也不能随意卸载一个安全模块了。 Tomoyo 自己还保留了一个没有进主线的发布,在那个发布里, Tomoyo 可以以模块形式存在。
在当前的 5 个安全模块中, SELinux 进入内核最早,事实上 LSM 机制是伴随着 SELinux而进入内核的。 SELinux 是 5 个安全模块中功能最全最复杂的一个。第二个进入内核主线的是SMACK, SMACK 标榜的是简单,它在安全功能上和安全机制上没有突破。第三个是 Tomoyo, Tomoyo 的长处是易用性,相关管理工具和文档都很完备。第四个是 AppArmor, AppArmor 开发得很早,但开发时断时续,结果很晚才进入内核主线。 AppArmor 也在易用性上下工夫,它的长处是很容易对单个应用进行安全加固并且不影响到系统其他部分。 最后一个是 Yama, Yama的有趣之处是它只针对某一个安全问题点(ptrace)做工作,其余不管。回顾历史可以看到, SELinux 之后的模块在系统性安全上没有突破,只在简单性和易用性上下功夫,而且有从系统性全功能安全防护向单个应用安全和单一功能防护上发展的趋势。
SELinux 的开发引入了 LSM。在 2001 年, Linus Torvalds 拒绝了 SELinux 直接进入内核主线。 Linus Torvalds 要求把 SELinux 做成一个相对独立的模块。于是 Linux 内核安全子领域的开发者实现了 LSM 机制。 LSM 机制带来了两个可能,一个是内核代码中多个安全模块并存,另一个是用户或管理员可以在内核编译和系统启动时选择安全模块。
到 2012 年时, Linux 主线上已经有 5 个安全模块了。但是除了 Yama,各个安全模块是运行时互斥的。如果系统中 SELinux 在工作, SMACK 就一定不能工作。这时就有人想,能不能让安全模块可以同时工作呢? SMACK 的负责人 Casey Schaufler 承担了这项工作。 两年过去了,虽然 Casey Schaufler 提交了多个 patch,但终因安全模块的差异性和系统的复杂性而没有成功。
以下不展开对 LSM 架构的分析,有兴趣的读者可以参阅附录。
㊀ Yama 特殊,它可以和别的安全模块共存,同时起作用。
㊁ 确切历史已经很难追溯,作者只能确定自 2.6.12 之后, LSM 模块就必须被编译进内核。至于之前何时发生的变化,作者无法确定。
第 7 章 SELinux
7.1 简介
7.1.1 历史
在 Linux 内核安全领域, SELinux 可谓鼎鼎大名。几乎所有接触过 Linux 安全和试图接触Linux 安全的人都或多或少了解过 SELinux。了解的结果是大部分人对 SELinux 望而却步,小部分人略知一二后对 SELinux 敬而远之。作者怀疑是否有人在了解 SELinux 之后还会对 SELinux推崇备至。
SELinux 的全称是 Security Enhanced Linux,中文直译为安全增强的 Linux。美国国家安全局(National Security Agency——NSA)主导了 SELinux 的开发工作。
SELinux 的历史可以追溯到 NSA 的三次开发安全操作系统的努力。第一次是在 1992 年到1993 年间, NSA 与安全计算公司(Secure Computing Corporation——SCC)合作开发了以 Mach操作系统为载体的 DTMach,那时的 DTMach 就已经实现了类型增强(Type Enforcement——TE),后来类型增强成为 SELinux 最主要的访问控制机制。第二次是 NSA 和 SCC 在 DTMach 基础上开发的 DTOS( Distributed Trusted Operating System)。第三次是 NSA、 SCC 和犹他大学合作的 Flux 项目,将 DTOS 安全架构移植到一个名为 Fluke 的科研操作系统上, Flux项目最大的成果是实现了一个能支持动态管理的安全策略架构——Flask( Flux Advanced Security Kernel) ㊀ 。随后 Flask 衍生出众多后代,包括 Linux 之上的 SELinux、 OpenSolaris上的 FMAC、 BSD 上的 TrustedBSD、 Darwin 上的 SEDarwin、 Xen 上的 XSM( Xen Security Modules),以及在用户态应用领域的 SEPostgreSQL、 SE-DBUS、 XACE( X Access Control Extension) ㊁ 。
在科研领域取得突破后, NSA 进而希望安全操作系统能够被广大用户接受并使用。因此以Linux 为载体的 SELinux 就诞生了。 SELinux 的第一个开放源代码版本以内核补丁的方式发布于 2000 年 12 月 22 日。随后, NSA 进行了近三年不懈的努力,终于在 2003 年 8 月 8 日使 SELinux 并入 Linux 2.6.0-test3 主线。
7.1.2 工作原理
也许是因为开发工作开始得比较早而让 SELinux 背负了历史包袱,也许是因为 SELinux 的设计者想要面面俱到, SELinux 的安全机制不止一种。 SELinux 的安全机制包含:基于角色的访问控制(Role Based Access Control, RBAC)、类型增强(Type Enforcement, TE)和多级安全(Multi Level Security, MLS)。
1.基于角色的访问控制
首先要明白什么是角色(Role)。举个例子,一个公司有研发人员、市场人员、保安、会计等,这些分工就是角色。不同的角色可以做不同的事情,接触不同的资源,比如研发人员可以接触研发文档,会计可以查看财务报表。所谓基于角色的访问控制就是将用户映射到角色,不同的角色有不同的操作许可。基于角色的访问控制的应用背景是一个大型组织,组织里有很多分工不同的人。在遥远的大型机时代,许多人登录到同一台计算机,每个人有自己的账号。或者在一个大型企业中,每个员工的计算机都联入企业内部网,访问企业内部不同的数据库,也是如此的场景。在上述两种场景下,基于角色的访问控制很容易实行。但是在单个个人电脑中,或者在智能手机中,基于角色的访问控制就有些勉强了。
其实除了基于角色的访问控制, SELinux 还有一个基于用户的访问控制( User Based Access Control——UBAC)。 SELinux 提供了一个 SELinux 用户的概念, SELinux 用户作为Linux 用户和 SELinux 角色的中介。用户登录系统, SELinux 先将 Linux 用户映射为 SELinux用户,然后再将 SELinux 用户映射为 SELinux 角色。 SELinux 用户是不是必须的呢?作者认为不是, SELinux 用户和 SELinux 角色可以合并在一起。
2.类型增强
上一节用人类社会的分工来类比 SELinux 中的角色。这一节用生物的物种来类比 SELinux中的类型。生物分属不同的物种,不同的物种有不同的特征。老虎的天性是吃山羊,不吃苜蓿;山羊的天性是吃苜蓿,躲避老虎。这是自然法则。但是,在生物的进化过程中,有些生物的天性也会发生变化,例如熊猫就从肉食动物变成了植食动物。
在 SELinux 的类型增强机制下,进程和文件都有一个类型。比如进程 A 是本地管理类型,进程 B 是网络服务类型;文件 a 是本地管理类型,文件 b 是网络服务类型。系统管理员制定策略规定本地管理类型的进程可以读网络服务类型的文件,而反过来不行。于是进程 A 可以读文件 a 和文件 b,进程 B 只能读文件 b。
3.多级安全
多级安全,英文是 Multi-level Security,简称 MLS。多级安全来源于 BLP( Bell-Lapadula)模型。 BLP 中的 B 指的是 Bell, LP 指的是 Lapadula㊀ 。 20 世纪 70 年代初, Bell 和 Lapadula两人受命参考美国军方的保密制度,在计算机上创建一个安全的信息处理系统。一番辛苦之后,二人创建了经典的 BLP 模型。 BLP 模型大致是这样的:进程和文件都有安全标签。标签有两项,一项是敏感度,另一项是组别。 BLP 模型下进程对文件的操作方式有两种:读和写。BLP 模型规定:
(1)低敏感度进程不能读高敏感度文件,高敏感度进程不能写低敏感度文件。
(2)当进程的组别包含或等于文件的组别时,进程可以操作文件。
BLP 模型的目的是防止信息泄漏。第一条规定可概括为“禁上读,禁下写”。“上读”是下级读了上级的文件,“下写”是上级写了下级的文件,有可能把秘密泄漏给下级。第二条规则是按组区分进程和文件,进程不能接触组外的文件。
SELinux 的 MLS 机制基于两个因素:敏感度(sensitivities)和组别(categories)。敏感度以一个整数表示,组别以一个整数的集合表示。敏感度之间的关系是小于、等于、大于。组别之间的关系是包含、被包含、相等、不相关。由这两种关系又推导出一种新关系,新关系有 4个值:支配(Dominate)、被支配(DominatedBy)、相等(equal)、不相关(incompatible),见表 7-1。
表 7-1 的含义是用进程的敏感度和组别与文件的敏感度和组别相比较㊀ ,导出新的关系。
第一行:当进程的组别包含文件的组别时,如果进程的敏感度大于或等于文件的敏感度,进程支配文件;如果进程的敏感度小于文件的敏感度,进程和文件不相关。
第二行:当进程的组别被文件的组别包含时,如果进程的敏感度小于或等于文件的敏感度,进程被文件支配;如果进程的敏感度大于文件的敏感度,进程和文件不相关。
第三行:当进程的组别和文件的组别相同时,如果进程的敏感度小于文件的敏感度,进程被文件支配;如果进程的敏感度等于文件的敏感度,进程和文件相等;如果进程的敏感度大于文件的敏感度,进程支配文件。
第四行:当进程的组别和文件的组别不相关时,无论进程的敏感度和文件的敏感度关系如何,进程和文件都不相关。
表 7-1 的逻辑是由 SELinux 代码实现的,是固定的,不能由用户配置的策略调整。用户可以通过配置策略在表 7-1 所导出的新关系的基础上定义操作许可,配置出安全模型。比如BLP 模型,见表 7-2。

进程可以读它所支配的文件,可以写支配它的文件,对于处于相等关系的文件可读可写。
下面看一个 BLP 模型的例子。 在某个应用场景下有两个敏感度: 普通和秘密, 有三个部门:研发、财务、销售。进程 A 的敏感度是普通,部门是研发;进程 B 的敏感度是秘密,部门是研发和财务;进程 C 的敏感度是秘密,部门是销售。文件 a 的敏感度是秘密,部门是研发和财务。先导出支配关系,进程 A 被文件 a 支配,进程 B 相等于文件 a,进程 C 与文件 a 不相关。再看BLP 模型,进程 A 可以写文件 a,进程 B 可以读写文件 a,进程 C 对文件 a 不可读也不可写。如图 7-1 所示。
㊀ 确切地说是主体和客体之间的比较,这里做了简化。
多级安全又衍生出多组安全——MCS(Multi-category Security)。当敏感度总是一个值时,起作用的就只有组别了,这时就是 MCS。实践中, MCS 用于隔离,配置策略阻断不同组之间的信息流动。比如用 SELinux 保护虚拟机实例是这样工作的,每次启动一个新的虚拟机,虚拟机控制器就从 1024 个组别中选择 2 个组别分配给新的虚拟机实例。配套的策略是只在多级安全的关系为相等的情况下, SELinux 才允许进程操作文件。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)