0. 概述
之前在 2018 年我写过一篇关于 SELinux 的文章:SELinux 了解与使用,今天我回过头来自己看了一下,觉得写得是一陀垃圾,所以,就重新再了解了一遍 SELinux,然后再写了一篇关于 SELinux 入门的文章,我想,这次我应该可以让你懂了。
1. DAC 和 MAC
首先,之所以 Linux 会引入 SELinux 是因为旧的权限管理模型(UGO)并不好,很容易就误伤了自己:
图 1:Shoot self foot |
于是乎,就引入了新的权限管理模型,SELinux。
这两种模型在 RHEL 中,被抽象为 DAC 和 MAC。
DAC
DAC 的全称是 Discretionary Access Control,翻译过来为自主访问控制,它是传统的 Linux 的访问控制方式。
- DAC 可以对文件、文件夹、共享资源等进行访问控制;
- DAC 模型中,文件的所有者以及管理源都可以管理访问控制
- DAC 使用 ACL(Access Control List,访问控制列表)提供不同的权限,其中 root 用户有超级控制权
MAC
MAC 的全称是 Mandatory Access Control,翻译过来为 强制访问控制
- SELinux 在内核中使用 MAC 检查操作是否合法;
- MAC 模型中,系统管理员负责访问控制,用户不能直接改变强制访问控制属性;
- MAC 可以定义所有的进程对系统的其他部分(文件、设备、socket、端口和其它进程等)允许进行操作的权限和许可;
DAC 和 MAC 的区别
- DAC 的主体是真实有效的用户和组 ID,而 MAC 的主体是安全上下文,两者的 UID 是各自独立的。
- DAC 的访问控制模式是 URO,MAC 的访问控制模式是 user:role:type
2. Policy
在 RHEL(CentOS) 中,SELinux 有两种策略(Policy),分别是:
- Target:默认的策略,只有指定的进程才会被 SELinux 保护
- MLS:这个特别复杂,直接忽略
很显然,这篇文章的后面我都是介绍 Target 的,所以 SELinux 之所以烦人是因为它的 MLS Policy 异常复杂,导致大家望而却步。
3. SELinux 的基本元素
SELinux 基于两个基本元素,了解这两个基本元素将对理解和使用 SELinux 很有帮助,这两个元素就是
- Labeling(标签)
- Type Enforcement(类型增强)
Labeling
什么是 Label,其实就是文件、设备、socket、端口和进程等的属性,下面使用一些命令来看一下所谓的 labeling:
[root@liqiang.io]# ll -alZ
drwxr-xr-x. liuliqiang liuliqiang unconfined_u:object_r:user_home_t:s0 .
drwxr-xr-x. liuliqiang liuliqiang unconfined_u:object_r:user_home_t:s0 ..
drwxrwxr-x. root root unconfined_u:object_r:user_home_t:s0 bin
drwxr-xr-x. root root unconfined_u:object_r:user_home_t:s0 pkg
drwxr-xr-x. liuliqiang liuliqiang unconfined_u:object_r:user_home_t:s0 src
可以看到这里有 unconfined_u:object_r:user_home_t:s0 的属性,这就是所谓的 SELinux 的 Labeling,他们被分为 4 段,对于 Target Policy,我们只需要管理第三段:user_homee_t 即可。
这个 Type 如果出现在文件中,那么就称为 label,如果出现在进程中,那么就叫做 Context。如果要确定一个 Context 是否可以访问一个 Label,那么就需要考虑 Type Enforcement。
类型增强
所谓的类型增强其实就是一个映射关系,平白一点说就是“允许 Context A 访问 Label B” 这样的规则。当设置了一些这样的规则之后,那么也就让 SELinux 生效了,达到了控制权限的目的。
4. 实际操作解答
解决单个问题
如果你开启了 SELinux,并且遇到了访问权限问题,不妨使用 journalctl 进行查看问题,它会给你提示,例如:
[root@liqiang.io]# journalctl -B -0
这里我访问一个远程文件协议的时候出现了问题,于是 journalctl 告诉我问题是什么,然后可以怎么解决:
图 2:Journalctl 提示解决方法 |
这里只需要按照提示,执行一下这个命令就 OK 了。
解决软件问题
如果你安装了一个新的软件,它不是一条命令就可以搞定的怎么办?还是使用 journalctl,例如你安装了一个邮件服务器,它需要的不仅仅是一个访问文件的权限,还有监听端口,发送邮件等功能,那么要用 SELinux 更好的解决这个问题,有个功能叫做:Policy Module,它可以记录一个软件在运行过程中,需要的各项 SELinux 权限,但是不阻止这个权限,而是将他们记录下,然后你可以将他们作为这个软件的 Policy Module,具体的操作步骤为:
[root@liqiang.io]# setenforce 0 # <----- 这个是主动暂停 SELinux
[root@liqiang.io]# smtpserver # <------ 这里运行你的应用,并执行各项操作
[root@liqiang.io]# journalctl -B -0 # <------ 查看 SELinux 的日志,它会提示你如何捕获权限
[root@liqiang.io]# grep httpd /var/log/audit/audit.og | audit2allow -M mypol # <----- 这是 journalctl 提示的内容
[root@liqiang.io]# semodule -i mypol.pp # <----- 这就将前面一步导出来的 Policy Module 添加到 SELinux 中
[root@liqiang.io]# setenforce 1 # <---- 重新打开 SELinux
你现在已经可以正常运行这个软件了,因为你已经将这个软件运行过程中需要的各种规则都添加到 SELinux 中了。