跳转到内容

SELinux

来自 Arch Linux 中文维基

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

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

在 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 之前,了解它的功能很有必要。简单直接的来说,SELinux在Linux上执行强制访问控制(MAC)。与之相对,传统的用户/组/rwx权限属于自主访问控制(DAC)。MAC与DAC的不同之处在于:安全策略和执行是完全分离的

sudo命令为例:在执行DAC时,sudo允许临时提权至root,从而赋予所产生的进程无限制的全系统访问权限。然而,在使用MAC时,如果安全管理员规定该进程只能访问某个文件集合,那么无论使用何种提权手段,除非更改安全策略本身,否则该进程仍将被限制在该文件范围内。因此,如果在运行SELinux的机器上尝试使用sudo让进程访问未授权的文件,该操作将会失败。

另一个例子是传统的(-rwxr-xr-x)类型权限。在DAC机制下,这些权限是用户可修改的。但在MAC下,安全管理员可以选择“冻结”特定文件的权限,除非更改相关策略,否则任何用户都无法修改这些权限。

正如你所想象的那样,这对于可能被攻破的进程(如Web服务器等)非常有用。如果使用DAC,一旦具备提权能力的程序被攻破,极有可能会对系统造成严重破坏。

欲了解更多信息,请访问维基百科: 强制访问控制

安装 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的具体配置进行了构建。适合尝鲜/开发场景。
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 的支柱,决定了系统的行为,目前 AUR 中唯一可用的策略是参考策略(Reference Policy)。为了安装它,你应该采用以下方法:

使用 AUR 软件包

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

手动安装

当你需要对策略源码进行深度定制时使用,可以通过安装selinux-refpolicy-srcAUR软件包获取,也可以从 https://github.com/SELinuxProject/refpolicy/wiki/DownloadRelease#current-release 下载最新发行版本

# 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 /

以为你的文件系统标记标签。

接着,创建一个名为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;
警告:以下代码是为了解决Refpolicy在 Arch Linux 上的兼容性报错,如果你发现系统正常且没有相关审计错误,可以跳过此步骤

接着运行以下命令:

# 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

参见