尚未完工。但鉴于总是要查 SELinux 的笔记,所以决定先行放出。
访问控制
Linux 操作系统上有两种访问控制:自主访问控制(Discretionary Access Control,DAC)和强制访问控制(Mandatory Access Control,MAC)。讨论两者的异同之前,需要明确几个概念:
- 用户(user):人(碳基高等灵长类生物)
- 主体(subject):OS 中以某用户身份执行的进程
- 客体(object):OS 中的各种资源(如文件、sockets、设备等)
DAC 的策略是由资源的所有者来决定他人对该资源的访问权限。标准 Linux 安全是一种 DAC:文件的所有者可以对文件的读、写、执行权限进行设定;其他用户或进程要操作该文件,则需要基于所有者的设定进行鉴权。总的来说,DAC 将对资源的访问控制依托于资源所有者用户自身的审慎和理性上。
DAC 的这套权限控制有两个缺陷。首先,人自身也会犯错,也是有局限性的。其次,系统中实际运行的是程序,而“相信用户”和“相信该用户的程序”还是有区别的。例如,用户 A 给了用户 B 一个自己信任的程序 P,由于 B 信任 A,于是 B 就信任 P,然而有可能 A 和 B 都不知道 P 是有问题的。这还是出于 A 仅有过失而无恶意的情况。还有一种涉及恶意的场景:假设用户 U 可读写一个机密的客体 O,而用户 U’ 本身无权访问 O 却想要去访问,那么用户 U’ 可以先制作如下程序:
11. 创建客体 O'
22. 赋予 U 写 O' 的权限
33. 赋予 U' 读 O' 的权限
44. 将 O 的内容拷贝至 O'
随后,将该程序包装成用户 U 乐见的模样(如游戏、音乐、图片等),诱使用户 U 去执行。这样一来,用户 U’ 就(通过客体 O’)访问到了客体 O 的内容。这样的程序也被称为特洛伊木马(Trojan Horse)。
而基于 MAC 的理念——信息和资源属于一个组织而非创造者个体,资源的访问权限就应该是由该组织集中制定的一整套完整的策略来定义,组织内外的所有人对资源的访问都要遵从这套策略。MAC 有多种方案,常见的有类型增强(Type Enforcement, TE)和多级安全(Multi-Level Security, MLS)。这两者在 SELinux 上都有实现。
SELinux 为 MAC 的一种实现,Linux Kernel 上的其他实现还包括 AppArmor ,Smack ,TOMOYO 等。不过据作者所知,名气最大,使用最广泛的还要数 SELinux。
SELinux 架构
SELinux 的 LSM 架构:
位于用户空间的客体管理器:
来自《SELinux by Example: Using Security Enhanced Linux》 的 Section 3.1 和 3.2。
更详细的架构图,见《SELinux Notebook》 的 Figure 2.2。
安全上下文(Security Context)
所有操作系统的访问控制都是以与客体和主体相关联的某种访问控制属性为基础的。在 SELinux 中,访问控制属性被称为安全上下文。所有客体(文件、进程间通讯通道、套接字、网络主机等)和主体(进程)都有与其关联的安全上下文。一个安全上下文由四部分组成:用户、角色、类型和等级,格式如下:
1User:Role:Type:Sensitivity[:Category][ - Sensitivity [:Category]]
2---------------▼--------------------▼-------▼---------------------▼
3 | level | - | level |
4 | range |
安全上下文中的用户和角色标识符除了对强制有一点约束之外对类型强制访问控制策略没什么影响。
- 对于进程,用户和角色标识符显得更有意义,因为它们是用于控制类型和用户标识符的联合体,这样就会与 Linux 用户账号关联起来;
- 对于客体,用户和角色标识符几乎很少使用。为了规范管理,客体的角色常常是 object_r,客体的用户往往是创建客体的进程的用户标识符,它们在访问控制上没什么作用。
标准 Linux 安全中的用户 ID 和安全上下文中的用户标识符之间的区别: 就技术而论,它们是正交标识符,分别用于标准的和安全增强的访问控制机制,这两者之间的任一相互关联都是通过登陆进程按照规范严格规定的,而不是通过 SELinux 策略直接强制实施的。
类型强制(Type Enforcement,TE)访问控制
在 SELinux 中,所有访问都必须明确授权。不管进程的用户/组 ID 是什么,SELinux 默认不允许任何访问。因此在 SELinux 中,没有默认的超级用户(如标准 Linux 中的 root 用户),要通过使用 allow 规则授予某个主体类型(或称域)对某个客体类型的访问权限:
1allow user_t bin_t : file {read execute getattr};
多级/多类安全(Multi-Level/Multi-Category Security, MLS/MCS)
MLS/MCS 特性是可选的,在类型强制(TE)的基础上增加额外的安全校验,会使用到安全上下文中的 LEVEL 字段,其中包含 Sensitivity 和 Category 信息。从相关资料来看,目前已经比较少提 MCS 了,基本上用 MLS 同时指代两者。
可参考:
- NB MLS , SELinux Project Wiki
- Gentoo Wiki 中关于 SELinux Multi-Level Security 的 Tutorial 介绍到了两种操作符;
- RHEL 7 的 SELinux User’s and Administrator’s Guide 的 4.13 节 展示了使能 MLS 并切换策略的具体方法。
参考资料
- Access Control , CS513: System Security (2007 fall), Cornell University
- DAC and MAC , Slides of CS5322: Database Security, National University of Singapore
- https://blog.csdn.net/MyArrow/article/details/9856095
- https://blog.csdn.net/huangyabin001/article/details/47404555
各类 SELinux 策略文件及相互关系
(上图出自 Sven Vermeulen 的博客 Where does CIL play in the SELinux system? ,其中图片链接已断,图片文件是用网页时光机 找回来的。特此说明。)
一套 SELinux 策略会涉及到多种类型的文件。这些文件会被分模块编译,最终汇聚形成一个二进制的策略文件。模块们和其构成的策略文件会共同组织成一个 Policy Store。这个说法在 Gentoo
和 Fedora
的 Wiki 以及 The SELinux Notebook
中有被提到,可以理解为一套套制作好的策略集。一个系统中可以存在多份 Policy Store,由 /etc/selinux/config
中的 SELINUXTYPE
指定,方便管理员在不同策略套之间进行切换。如今比较常见的有 targeted
、mls
等。
当前系统正在使用的某个策略模块文件位于 /var/lib/selinux/targeted/active/modules/100/<module_name>/hll
1,将 hll
通过 bzip2 解压缩后便可获得 .pp 文件。
不同策略文件之间具体的转换方法:
-
生成 .te 文件
1grep postdrop /var/log/audit/audit.log | audit2allow -M postfixlocal
-
.te to mod
1checkmodule -M -m -o postfixlocal.mod postfixlocal.te
-
mod to .pp
1semodule_package -o postfixlocal.pp -m postfixlocal.mod
-
.pp to cil
1/usr/libexec/selinux/hll/pp XXX.pp XXX.cil
反其道而行,各策略文件的解码方法:
-
extract cil file
1semodule -c -E acct
-
extract pp file
1semodule -H -E acct
-
pp to mod
1semodule_unpackage postgreylocal.pp postgreylocal.mod
-
disassemble pp/mod to human-readable
1sedismod postgreylocal.pp 2sedismod postgreylocal.mod
是否加载进内核?
.fc 文件
.fc 文件不会被加载进内核,而是会由 semanage
转换为 file_contexts{,.homedirs}
文件,保存在 /etc/selinux/targeted/contexts/files/
目录下。restorecon
和 matchpathcon
为了确定某个路径上的文件的标签,会按以下顺序查询这些文件中的相关记录:
file_contexts.local
(由系统管理员在运行时通过semanage
生成)file_contexts.homedirs
file_contexts
Check 4.7.3. How File Context is Determined of SELinux User’s and Administrator’s Guide to get more relevant information.
te and other policy files
However, .te files will be compiled (eventually) into the binary policy.31
or policy.32
bulk, which is loaded into the kernel through /load
under selinuxfs’s mount point when running load_policy
. Use strace load_policy
to see the detailed process.
Reference
https://serverfault.com/a/321422
https://plautrba.fedorapeople.org/how-to-compare-two-selinux-modules.html
https://fedoraproject.org/wiki/Changes/SELinuxPolicyStoreMigration
https://selinuxproject.org/page/ConfigurationFiles
Out-of-date, or imcompatible with us:
https://wiki.gentoo.org/wiki/SELinux/Tutorials/How_is_the_policy_provided_and_loaded
Policy Loading During Boot
49.7.3. THE ROLE OF POLICY IN THE BOOT PROCESS , Deployment Guide of RHEL 5.
Chapter 49. Security and SELinux , Deployment Guide of RHEL 5.
- After kernel is initialized, policies are loaded by
init
process. init
checks/proc/filesystems
to see if kernel supports selinuxfs.init
needs to re-execute itself (remember the code of Android’s init? the second round/function?)
userland tools
audit related
1# ausearch
2ausearch -m AVC,USER_AVC,SELINUX_ERR -ts today # 10:09, recent, ...
3
4# setroubleshoot related
5journalctl -t setroubleshoot --since=[time]
6
7# sealert
8sealert -l [message_ID]
policy related
https://access.redhat.com/articles/2191331
1sesearch --all -s test_cap_userns_t | less
https://pagure.io/freeipa/issue/8513
1semanage module -l
https://serverfault.com/a/521082
1semodule -v -i test_policy/test_policy.pp test_mlsconstrain.cil test_overlay_defaultrange.cil test_userfaultfd.cil
Reference
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/chap-security-enhanced_linux-working_with_selinux
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/security-enhanced_linux-prioritizing_selinux_modules
- https://www.imperialviolet.org/2009/07/14/selinux.html
实现细节
https://www.imperialviolet.org/2009/07/14/selinux.html
(建议从 4.1 版本入手,代码相对简单,没太多复杂的数据结构。sidtab 基本能看懂。)
-
这里的 HLL 是指 High Level Language,即便 .pp 文件与高级语言毫不相干。根据 Sven Vermeulen 的博客 ,如此命名的原因是原本期待未来会出现多种安全框架,这些框架会带有各自的用于制定安全策略的高级语言,并且还有将这些高级语言转换成 CIL 文件的编译器/引擎。 ↩︎