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 的访问控制方式。

MAC

MAC 的全称是 Mandatory Access Control,翻译过来为 强制访问控制

DAC 和 MAC 的区别

2. Policy

在 RHEL(CentOS) 中,SELinux 有两种策略(Policy),分别是:

很显然,这篇文章的后面我都是介绍 Target 的,所以 SELinux 之所以烦人是因为它的 MLS Policy 异常复杂,导致大家望而却步。

3. SELinux 的基本元素

SELinux 基于两个基本元素,了解这两个基本元素将对理解和使用 SELinux 很有帮助,这两个元素就是

Labeling

什么是 Label,其实就是文件、设备、socket、端口和进程等的属性,下面使用一些命令来看一下所谓的 labeling:

  1. [root@liqiang.io]# ll -alZ
  2. drwxr-xr-x. liuliqiang liuliqiang unconfined_u:object_r:user_home_t:s0 .
  3. drwxr-xr-x. liuliqiang liuliqiang unconfined_u:object_r:user_home_t:s0 ..
  4. drwxrwxr-x. root root unconfined_u:object_r:user_home_t:s0 bin
  5. drwxr-xr-x. root root unconfined_u:object_r:user_home_t:s0 pkg
  6. 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 进行查看问题,它会给你提示,例如:

  1. [root@liqiang.io]# journalctl -B -0

这里我访问一个远程文件协议的时候出现了问题,于是 journalctl 告诉我问题是什么,然后可以怎么解决:

图 2:Journalctl 提示解决方法

这里只需要按照提示,执行一下这个命令就 OK 了。

解决软件问题

如果你安装了一个新的软件,它不是一条命令就可以搞定的怎么办?还是使用 journalctl,例如你安装了一个邮件服务器,它需要的不仅仅是一个访问文件的权限,还有监听端口,发送邮件等功能,那么要用 SELinux 更好的解决这个问题,有个功能叫做:Policy Module,它可以记录一个软件在运行过程中,需要的各项 SELinux 权限,但是不阻止这个权限,而是将他们记录下,然后你可以将他们作为这个软件的 Policy Module,具体的操作步骤为:

  1. [root@liqiang.io]# setenforce 0 # <----- 这个是主动暂停 SELinux
  2. [root@liqiang.io]# smtpserver # <------ 这里运行你的应用,并执行各项操作
  3. [root@liqiang.io]# journalctl -B -0 # <------ 查看 SELinux 的日志,它会提示你如何捕获权限
  4. [root@liqiang.io]# grep httpd /var/log/audit/audit.og | audit2allow -M mypol # <----- 这是 journalctl 提示的内容
  5. [root@liqiang.io]# semodule -i mypol.pp # <----- 这就将前面一步导出来的 Policy Module 添加到 SELinux 中
  6. [root@liqiang.io]# setenforce 1 # <---- 重新打开 SELinux

你现在已经可以正常运行这个软件了,因为你已经将这个软件运行过程中需要的各种规则都添加到 SELinux 中了。

5. Ref