跳转到内容

SELinux

来自 Arch Linux 中文维基

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

在 Linux 发行版下运行 SELinux 需要满足三个条件:开启了 SELinux 支持的内核、SELinux 用户空间工具与库,以及 SELinux 策略(通常基于参考策略(Reference Policy))。一些常见的 Linux 程序还需要应用补丁或在编译时开启 SELinux 特性。SELinux 使用文件系统拓展属性以维护 MAC 元数据,若需快速了解 SELinux 术语和技术概览,参见gentoo:SELinux/Quick introduction。

有关强制访问控制,参见强制访问控制。

在 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-selinuxAUR 与 pambase-selinuxAUR
包含pam_selinux.so的PAM软件包及其基础(base)软件包。它们分别替换pam包和pambase包软件包
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
为支持安全感知的应用程序提供的库。现已包含 semanage 和 setools 所需的 Python 绑定。
libsemanageAUR
用于策略管理的库。现已包含 semanage 和 setools 所需的 Python 绑定。
libsepolAUR
用于操作二进制策略的库。
policycoreutilsAUR
SELinux 核心工具,例如 newrole、setfiles 等。
restorecondAUR
用于维护部分文件标签的守护进程。
secilcAUR
针对以 CIL(通用中间语言)编写的 SELinux 策略的编译器。
selinux-dbus-configAUR
允许管理 SELinux 配置的 DBus 服务。
selinux-guiAUR
SELinux 图形界面工具(system-config-selinux)。
selinux-pythonAUR
SELinux Python 工具与库(包含 semanage、sepolgen、sepolicy 等)。
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-archAUR 或 selinux-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-archAUR或selinux-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

参见