程序的DAC检查
在Linux中,程序的DAC(Discretionary Access Control,自主访问控制)检查是指操作系统对程序执行期间对文件和资源的访问权限进行的检查。
Linux使用一种基于权限的访问控制模型,其中每个文件和资源都与所有者、所属组和其他用户相关联,并且为每个类别分配了读取、写入和执行等权限。当程序尝试访问文件或资源时,操作系统会执行以下DAC检查:
- 访问权限检查:操作系统会检查程序是否具有足够的权限来读取、写入或执行目标文件。这些权限由文件的所有者、所属组和其他用户的权限位所决定。
- 文件所有权检查:操作系统会验证当前执行程序的用户是否是文件的所有者,因为文件的所有者可能具有特殊权限,例如修改文件权限或删除文件。
- 文件所属组检查:操作系统会检查当前执行程序的用户是否属于文件的所属组。如果是,那么用户将根据所属组的权限位来访问文件。
这些DAC检查确保了对文件和资源的访问是受到限制的,只有具有适当权限的程序可以进行读取、写入和执行操作。但请注意,DAC仅仅是Linux安全模型的一部分,还有其他访问控制机制如SELinux(Security-Enhanced Linux)可以提供更细粒度的访问控制。
LSM简介
几个关键点:
- LSM框架基于hook机制实现内核功能扩展
- 虽然名字里带Module,但LSM并不是传统意义上的内核模块
- Kernel中可以同时编译进多个不同的LSM
- LSM并不是运行时加载,而是编译时引入,在boot阶段通过命令行加载
LSM架构与实现原理:从下图中可以看出LSM在Linux安全体系中所处的位置,LSM hook被插入到访问kernel对象与DAC 检查之见,然后LSM调用系统中启用的访问控制模块,检查是否可以访问。若有多个访问控制模块,会根据初始化的优先顺序执行,都允许访问才能进一步访问 kernel 对象。使用LSM Hook框架进行内核安全审计和元数据捕获。安全开发人员只需要按照既定的调用规范编写LSM模块,并加载进Linux内核,而不需要对系统调用表进行任何修改。
LSM的设计思想是在最少改变内核代码的情况下,提供一个能够成功实现强制访问控制模块需要的结构或者接口。其中,LSM对内核代码的改动如下:
- 在特定的内核数据结构中加入安全域
- 在内核源代码中不同的关键点插入对安全钩子函数的调用
- 加入一个通用的安全系统调用
- 提供了函数允许内核模块注册为安全模块或者注销
- 将capabilities逻辑的大部分移植为一个可选的安全模块
LSM机制之所以简单实用,是因为它的设计者几乎罗列了任何可能出现安全问题的地方,然后在这些地方安插钩子,并且这些钩子的实现定义为回调函数,具体的安全引擎只需要自己实现这些钩子函数即可。
在LSM诞生之前,Linux Kernel安全加固的方案多种多样,随着LSM加入内核,从前的安全性内核补丁如今破坏了内核的完整性,使用LSM框架中的标准预置回调函数进行hook是当前最优雅的解决方案。而Kernel 5.4中加入的lockdown模块(前文提到的early_lsm阶段加载的模块)直接禁止了运行时对内核进行动态修改,使得LSM成为Linux安全模块开发的唯一途径。
对root用户的限制问题
Root 权限 “无法无天”,几乎可以做任意事情,一旦入侵者拿到root 权限,即已经完全掌控了系统。另外,每一个进程默认都拿到对应这个用户的所有权限,可以改动/删除这个用户的所有文件资源。很明显,这个难以防止恶意软件。
一方面限制Root 权限,即使你有root 权限,如果无法通过验证(对每个文件资源进行验证),那么一样的无法真正执行相关的操作.。另外对每一项权限进行了更加完整的细化,可限制用户对资源的访问行为。
即,需要对root用户进行限制,这样可以只需关注于文件本身的安全性,而LSM对root可以实现对root用户的限制。