跳转到内容

SELinux

来自 Arch Linux 中文维基

安全增强型 Linux (Security-Enhanced Linux, SELinux)(又称安全增强式 Linux)是一项 Linux 特性,通过在 Linux 内核中使用Linux 安全模块(Linux Security Modules, LSM)提供多种安全策略,其中包括美国国防部风格的强制访问控制(Mandatory Access Control, MAC)。SELinux 并不是一个 Linux 发行版,而是一套可以应用于Linux和BSD等类 Unix 操作系统的修改补丁集。

在 Linux 发行版下运行 SELinux 需要满足三个条件:开启了 SELinux 支持的内核、SELinux 用户空间工具与库,以及 SELinux 策略(通常基于参考策略(Reference Policy))。一些常见的 Linux 程序还需要应用补丁或在编译时开启 SELinux 特性。

有关强制访问控制,参见zhwp:强制访问控制

在 Arch Linux 中的状态

SELinux 并不是 Arch Linux 官方支持的功能(参见[1][2])。非官方支持的状态如下:

名称 状态 获取渠道
SELinux 启用的内核 适用于所有官方支持的内核 自 4.18.8 版本以来已在官方仓库中提供
SELinux 用户空间工具和库 已在 AUR 中提供:https://aur.archlinux.org/packages/?O=0&K=selinux 相关开发工作已在 https://github.com/archlinuxhardened/selinux 中完成
SELinux 策略 正在开发中,以 Reference Policy 作为基础 上游:https://github.com/SELinuxProject/refpolicy (自 20170805 版本以来,该策略已集成了对 systemd 和单一/usr/bin目录的支持)

与官方核心包相比,以下是 AUR 中的一些包的变更摘要:

名称 状态与说明
linux, linux-lts, linux-zen, linux-hardened 需要设置 lsm= 参数
coreutils 需要使用 --with-selinux 选项重新构建以链接 libselinux
cronie 需要使用 --with-selinux 选项重新构建
dbus 需要使用 --enable-libaudit--enable-selinux 选项重新构建
findutils 需要使用 libselinux 并重新构建以启用 SELinux 特定选项
iproute2 需要使用 --with-selinux 选项重新构建
logrotate 需要使用 --with-selinux 选项重新构建
openssh 需要使用 --with-selinux 选项重新构建
pam 对于 Linux-PAM,需要使用 --enable-selinux 编译选项重新构建;对于 pam_unix2 ,需要应用一个补丁,该补丁仅用于删除一个在近版本的 libselinux 中已实现的重复函数
pambase 修改配置,将 pam_selinux.so 添加到 /etc/pam.d/system-login
psmisc 需要使用 --with-selinux 选项重新构建
shadow 需要使用 --with-selinux 选项重新构建
sudo 需要使用 --with-selinux 选项重新构建
systemd 需要使用 --enable-audit--enable-selinux 选项重新构建
util-linux 需要使用 --with-selinux 选项重新构建

所有其他 SELinux 相关软件包均可直接引入,无需修改,且无安全风险。

安装 SELinux

软件包说明

所有 SELinux 相关软件包都属于AUR中的selinux包组手动安装这些包之前,请先阅读#安装章节

支持 SELinux 的系统工具

coreutils-selinuxAUR
经过修改的 coreutils 软件包,编译时已启用 SELinux 支持,它会替换coreutils软件包。
cronie-selinuxAUR
由 Fedora维护的 Vixie cron 派生版本,已启用 SELinux 支持。它会替换cronie软件包。
dbus-selinuxAUR
支持 SELinux 的 D-Bus 版本. 它会替换 dbus 软件包。
findutils-selinuxAUR
经过补丁修改并开启了 SELinux 支持的 findutils 软件包,使得按特定安全上下文搜索文件成为可能。它会替换 findutils 软件包。
iproute2-selinuxAUR
开启了 SELinux 支持的 iproute2 软件包;例如,它为ss命令增加了-Z选项。它会替换iproute2软件包
logrotate-selinuxAUR
开启了 SELinux 支持的 logrotate 软件包,它会替换logrotate软件包
openssh-selinuxAUR
开启了 SELinux 支持的OpenSSH软件包。它会替换openssh软件包
pam-selinuxAURpambase-selinuxAUR
包含pam_selinux.so的PAM软件包及其基础(base)软件包。它们分别替换pampambase软件包
psmisc-selinuxAUR
开启了 SELinux 支持的 psmisc 软件包;例如,它为killall增加了-Z选项。它会替换psmisc软件包
shadow-selinuxAUR
开启了 SELinux 支持的 shadow 软件包;包含修改后的 /etc/pam.d/login 文件,用于在用户登录后设置正确的安全上下文。它会替换 shadow 软件包。
sudo-selinuxAUR
经过修改且开启了 SELinux 支持的 sudo 软件包,可正确设置安全上下文。它会替换 sudo 软件包。
systemd-selinuxAUR
支持 SELinux 的 systemd 版本。它会替换 systemd 软件包。
util-linux-selinuxAUR
经过修改的 util-linux 软件包,编译时已启用 SELinux 支持。它会替换 util-linux 软件包。

SELinux 用户空间实用程序

checkpolicyAUR
用于构建 SELinux 策略的工具。
mcstransAUR
供 libselinux 使用,用于转换 MCS 标签的守护进程。
libselinuxAUR
为支持安全感知的应用程序提供的库。现已包含 semanagesetools 所需的 Python 绑定。
libsemanageAUR
用于策略管理的库。现已包含 semanagesetools 所需的 Python 绑定。
libsepolAUR
用于操作二进制策略的库。
policycoreutilsAUR
SELinux 核心工具,例如 newrolesetfiles 等。
restorecondAUR
用于维护部分文件标签的守护进程。
secilcAUR
针对以 CIL(通用中间语言)编写的 SELinux 策略的编译器。
selinux-dbus-configAUR
允许管理 SELinux 配置的 DBus 服务。
selinux-guiAUR
SELinux 图形界面工具(system-config-selinux)。
selinux-pythonAUR
SELinux Python 工具与库(包含 semanagesepolgensepolicy 等)。
selinux-sandboxAUR
SELinux 沙箱工具。
semodule-utilsAUR
在构建策略时用于处理 SELinux 模块的工具。

SELinux 策略相关软件包

selinux-refpolicy-srcAUR
参考策略(Reference Policy)的源码。
selinux-refpolicy-gitAUR
参考策略的 Git 主分支版本 (https://github.com/SELinuxProject/refpolicy) ,针对 Arch Linux的具体配置进行了构建,但是与 Arch Linux 软件包兼容并不完美。
selinux-refpolicy-archAUR
预编译的模块化参考策略,包含头文件和文档,但不含源码。该版本包含了正在开发中的 Arch Linux Refpolicy 补丁,用以修复路径标签和 systemd 支持的相关问题;在selinux-refpolicy-archAUR 中包含这些补丁,主要是为了在 Refpolicy 正式版发布间隙进行及时的滚动更新。

其他 SELinux工具

setoolsAUR
用于管理SELinux的命令行和图形界面工具。
selinux-alpm-hookAUR
pacman 钩子;在安装和更新软件包时,根据 SELinux 策略自动为文件标记标签

安装

安装所需的 SELinux 软件包共有三种方法:

通过 Github 上的二进制软件包

所有软件包均可通过selinux非官方仓库获取。在系统安装阶段的arch-bootstrap阶段,可以使用base-selinux替换base软件包。

警告:目前该仓库不提供软件包签名,这意味着 pacman 将无法验证下载的二进制文件。这存在风险;慎重执行。

通过 Github 上的构建脚本

该仓库还包含一个名为build_and_install_all.sh的脚本,它会按照所需顺序构建并安装(或更新)所有软件包。以下是在用户终端中使用该脚本安装所有软件包的实例(包含下载用于验证软件包源码的GPG密钥):

$ git clone https://github.com/archlinuxhardened/selinux.git
$ cd selinux
$ ./recv_gpg_keys.sh
$ ./build_and_install_all.sh

在运行脚本之前可以修改build_and_install_all.sh的内容;例如,若已经拥有支持 SELinux 的内核,则可以调整相关内容。

通过 AUR

完成上述所有步骤后,可以安装支持 SELinux 的内核(如linux)以及相关策略(如selinux-refpolicy-archAURselinux-refpolicy-gitAUR)。

启用 SELinux LSM

若要在每次启动时默认启用 SELinux 作为安全模型,需设置以下内核参数

lsm=landlock,lockdown,yama,integrity,selinux,bpf

注意:内核参数lsm=用于设置 Linux 安全模块的初始化顺序。可以通过zgrep CONFIG_LSM= /proc/config.gz查看内核配置的lsm=默认值,通过cat /sys/kernel/security/lsm查看当前运行时的值。
  • 确保selinux是列表中的第一个“主要(major)”模块。[1]有效值及其顺序的实例可以在security/Kconfig中找到。
  • capability应当从lsm=参数中省略,因为它总会自动隐式被包含。

自定义内核

编译内核时,必须至少设置以下选项:

CONFIG_SECURITY_SELINUX=y

CONFIG_AUDIT=y

若需默认启用 SELinux 安全模型,从而省去手动设置内核参数的麻烦,需额外设置CONFIG_LSM选项,并将selinux指定为列表中第一个“主要(major)”模块:

CONFIG_LSM="landlock,lockdown,yama,integrity,selinux,bpf"

检查 PAM 配置

正确配置PAM对于在登录状态后获得正确的安全上下文至关重要。检查/etc/pam.d/system-login文件中是否存在以下行:

# pam_selinux.so close 应当是会话(session)规则中的第一条
session         required        pam_selinux.so close
# pam_selinux.so open 之后应当只跟随需要在用户上下文中执行的会话(session)
session         required        pam_selinux.so open

安装策略

警告:SELinuxProject提供的参考策略 (Reference Policy) 对 Arch Linux 的支持并不理想。大多数提交补丁以改进策略的人使用的是其他发行版(如 Debian、Gentoo、RHEL等),因此该策略与 Arch Linux 软件包的兼容并不完美(例如,策略可能不支持程序的最前沿特性),建议使用selinux-refpolicy-archAUR

策略是 SELinux 的支柱,决定了系统的行为,目前 AUR 中唯一可用的策略是参考策略(Reference Policy)。为了安装它,应采用以下方法:

使用 AUR 软件包

这是最简单且快捷的方法。安装selinux-refpolicy-archAURselinux-refpolicy-gitAUR,该软件包会自动处理编译和基础配置。

手动安装

需对策略源码进行深度定制时使用,可以通过安装selinux-refpolicy-srcAUR软件包获取,也可以从这里下载最新发行版本

# make bare
# make conf
# make install

上述命令将按原样安装参考策略。了解如何编写 SELinux 策略的用户可以在运行命令前根据喜好自行调整。编译过程需要一段时间,且会占满系统的一个 CPU 核心,这属于正常现象,无需担心。等待命令运行完成即可。

运行以下命令加载参考策略:

# make load

然后创建内容如下的/etc/selinux/config文件(仅当使用上述默认设置时才有效;若更改了策略名称,则需要对文件进行相应调整):

/etc/selinux/config
# 此文件控制系统上 SELinux 的状态。
# SELINUX= 可以取以下三个值之一:
#       enforcing - 强制执行 SELinux 安全策略。
#                   若 SELinux 已按预期配置完毕并且系统已经准备好部署,请设置此值。
#       permissive - SELinux 仅打印警告而非强制阻断.
#                    在部署前使用此模式来自定义 SELinux 策略和布尔值。
#       disabled - 不加载 SELinux 策略。
#                  不推荐此设置,可能导致文件标签(Labeling)问题
SELINUX=permissive
# SELINUXTYPE= 指定要使用的 SELinux 策略名称。
# 当前选项为:
#       refpolicy(原生参考策略)
#       <自定义策略> - 将<自定义策略>替换为需加载的任何自定义策略名称
SELINUXTYPE=refpolicy

现在可以重启系统了,重启系统后运行以下命令:

# restorecon -r /

以为文件系统标记标签。

警告:以下步骤是为了解决 Refpolicy 在 Arch Linux 上的兼容性报错,若系统正常且没有相关审计错误,可以跳过此步骤

接着,创建一个名为requiredmod.te的文件,内容如下

requiredmod.te
module requiredmod 1.0;

require {
        type devpts_t;
        type kernel_t;
        type device_t;
        type var_run_t;
        type udev_t;
        type hugetlbfs_t;
        type udev_tbl_t;
        type tmpfs_t;
        class sock_file write;
        class unix_stream_socket { read write ioctl };
        class capability2 block_suspend;
        class dir { write add_name };
        class filesystem associate;
}

#============= devpts_t ==============
allow devpts_t device_t:filesystem associate;

#============= hugetlbfs_t ==============
allow hugetlbfs_t device_t:filesystem associate;

#============= kernel_t ==============
allow kernel_t self:capability2 block_suspend;

#============= tmpfs_t ==============
allow tmpfs_t device_t:filesystem associate;

#============= udev_t ==============
allow udev_t kernel_t:unix_stream_socket { read write ioctl };
allow udev_t udev_tbl_t:dir { write add_name };
allow udev_t var_run_t:sock_file write;

接着运行以下命令:

# checkmodule -m -o requiredmod.mod requiredmod.te
# semodule_package -o requiredmod.pp -m requiredmod.mod
# semodule -i requiredmod.pp

这样做是为了消除/var/log/audit/audit.log中一些在参考策略(Reference Policy)里处理起来非常麻烦的干扰信息。这是一个非常“丑陋”的临时方案(Ugly hack);必须明确指出,这样安装策略仅仅是为了修补参考策略,从而掩盖因标签(Labeling)错误产生的影响。

在 Vagrant 虚拟机中进行测试

可以使用Vagrant来配置一个预装并配置好 SELinux 的Arch Linux 虚拟机。这是一种在不修改当前系统的情况下,测试运行 SELinux 的 Arch Linux 系统的便捷方法。可通过以下命令实现:

$ git clone https://github.com/archlinuxhardened/selinux.git
$ cd selinux/_vagrant
$ vagrant up
$ vagrant ssh

安装后的后续步骤

可以使用sestatus命令来检查 SELinux 是否正在正常运行。应看到类似如下的输出:

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             refpolicy
Current mode:                   permissive
Mode from config file:          permissive
Policy MLS status:              disabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

为了保证正确的安全上下文,可以启用restorecond.service服务。

若要在不重启系统的情况下切换到强制(enforcing)模式,可以使用以下命令:

# echo 1 > /sys/fs/selinux/enforce

交换文件

若使用交换文件(swap file)而非交换分区(swap partition),需运行以下命令以设置正确的安全上下文:

# semanage fcontext -a -t swapfile_t "/path/to/swapfile"
# restorecon /path/to/swapfile

使用 SELinux

SELinux 定义安全性的机制与传统的 Unix 访问控制(DAC)不同。理解它的最佳方式是通过实例。例如,Apache 主页文件的 SELinux 安全上下文如下所示:

$ ls -lZ /var/www/html/index.html
-rw-r--r--  username username system_u:object_r:httpd_sys_content_t /var/www/html/index.html

任何(Arch) Linux 用户都应该熟悉前三个字段和最后一个字段。第四字段是新增内容,格式如下:

用户(user):角色(role):类型(type)[:级别(level)]

解释:

  1. 用户(User): SELinux 用户身份。可以关联到一个或多个该用户允许使用的角色。
  2. 角色(Role): SELinux 角色。可以关联到一个或多个该用户允许访问的类型。
  3. 类型(Type): 当类型与进程关联时,它定义了该进程(即域/Domain)可以访问哪些资源。当类型与对象(如文件)关联时,它定义了主体对该对象拥有的访问权限。
  4. 级别(Level): 此可选字段也称为“范围(range)”,仅在策略支持 MCS 或 MLS 时出现。

若想了解如何构建自定义策略,这些基础知识至关重要,因为它们是 SELinux 的基本构建基块。但在大多数情况下无需深入了解,因为参考策略(Reference Policy)已经足够成熟。但对于高级用户或有非常特定需求的用户,学习如何制定自定义 SELinux 策略将是理想选择。

这系列文章是寻求理解如何使用 SELinux 的绝佳资源。

故障排除

查找 SELinux 错误的主要地方是systemd/Journal。例如,若要查看与system_u:system_r:policykit_t:s0标签相关的 SELinux 消息,需运行:

# journalctl _SELINUX_CONTEXT=system_u:system_r:policykit_t:s0

实用工具

以下是一些能对使用 SELinux 提供极大帮助的工具和命令:

restorecon
根据参考策略(Reference Policy)规则恢复文件或目录的上下文(配合-R参数可进行递归处理)。
chcon
修改特定文件的上下文。

报告问题

请在Github上报告相关问题:https://github.com/archlinuxhardened/selinux/issues

参见