SELinux

来自 ArchWiki

Security-Enhanced Linux (SELinux) 是一个 Linux 功能,它提供了各种安全策略,包括美国国防部风格的强制访问控制 (MAC),通过使用 Linux 内核中的 Linux 安全模块 (LSM)。它不是一个 Linux 发行版,而是一组可以应用于类 Unix 操作系统(如 Linux 和 BSD)的修改。

在 Linux 发行版下运行 SELinux 需要三件事:启用 SELinux 的内核、SELinux 用户空间工具和库,以及 SELinux 策略(主要基于参考策略)。一些常见的 Linux 程序也需要使用 SELinux 功能进行修补/编译。

Arch Linux 中的当前状态

SELinux 未获得官方支持(参见[1][2])。非官方支持的状态是

名称 状态 可用位置
启用 SELinux 的内核 已为所有官方支持的内核实现 4.18.8起在官方仓库中可用。
SELinux 用户空间工具和库 在 AUR 中实现:https://aur.archlinux.org/packages/?O=0&K=selinux 工作在 https://github.com/archlinuxhardened/selinux 完成
SELinux 策略 正在进行中,使用 参考策略 作为上游 上游:https://github.com/SELinuxProject/refpolicy (自 20170805 版本以来,该策略已集成对 systemd 和 single-/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 需要使用 --enable-selinux 标志为 Linux-PAM 重新构建;需要 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)。与 SELinux 相比,传统的用户/组/rwx 权限是一种自主访问控制 (DAC)形式。MAC 与 DAC 的不同之处在于安全策略及其执行完全分离。

一个例子是使用 sudo 命令。当强制执行 DAC 时,sudo 允许临时特权提升到 root,从而使生成的进程具有不受限制的全系统访问权限。但是,当使用 MAC 时,如果安全管理员认为该进程只能访问一组特定的文件,那么无论使用何种特权提升方式,除非安全策略本身发生更改,否则该进程仍将仅限于该组文件。因此,如果在运行 SELinux 的机器上尝试 sudo 以便进程获得对其策略不允许访问的文件的访问权限,则将会失败。

另一组例子是赋予文件的传统 (-rwxr-xr-x) 类型权限。在 DAC 下,这些是用户可修改的。但是,在 MAC 下,安全管理员可以选择冻结某个文件的权限,这样任何用户都无法更改这些权限,直到更改有关该文件的策略。

您可以想象,这对于可能被入侵的进程(即 Web 服务器等)特别有用。如果使用 DAC,那么被入侵的程序很可能在获得特权提升权限后造成严重破坏。

有关更多信息,请访问 Wikipedia:强制访问控制

安装 SELinux

软件包描述

所有 SELinux 相关软件包都属于 AUR 中的 selinux 组。在手动安装其中任何一个之前,请阅读#安装以查看全面安装的推荐选项。

SELinux 感知的系统实用程序

coreutils-selinuxAUR
修改后的 coreutils 软件包,编译时启用了 SELinux 支持。它取代了 coreutils 软件包
cronie-selinuxAUR
启用 SELinux 的 Vixie cron 的 Fedora 分支。它取代了 cronie 软件包。
dbus-selinuxAUR
SELinux 感知版本的 D-Bus。它取代了 dbus 软件包。
findutils-selinuxAUR
修补后的 findutils 软件包,编译时启用了 SELinux 支持,以使搜索具有指定安全上下文的文件成为可能。它取代了 findutils 软件包。
iproute2-selinuxAUR
编译时启用 SELinux 支持的 iproute2 软件包;例如,它向 ss 添加了 -Z 选项。它取代了 iproute2 软件包。
logrotate-selinuxAUR
编译时启用 SELinux 支持的 Logrotate 软件包。它取代了 logrotate 软件包。
openssh-selinuxAUR
OpenSSH 软件包,编译时启用了 SELinux 支持,以设置用户会话的安全上下文。它取代了 openssh 软件包。
pam-selinuxAURpambase-selinuxAUR
带有 pam_selinux.so 的 PAM 软件包和底层基础软件包。它们分别取代了 pampambase 软件包。
psmisc-selinuxAUR
编译时启用 SELinux 支持的 Psmisc 软件包;例如,它向 killall 添加了 -Z 选项。它取代了 psmisc 软件包。
shadow-selinuxAUR
编译时启用 SELinux 支持的 Shadow 软件包;包含修改后的 /etc/pam.d/login 文件,以便在用户登录后设置正确的安全上下文。它取代了 shadow 软件包。
sudo-selinuxAUR
修改后的 sudo 软件包,编译时启用了 SELinux 支持,可以正确设置安全上下文。它取代了 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 核心实用程序,如 newrole、setfiles 等。
restorecondAUR
维护某些文件标签的守护程序
secilcAUR
以 CIL(通用中间语言)编写的 SELinux 策略编译器
selinux-dbus-configAUR
允许管理 SELinux 配置的 DBus 服务
selinux-guiAUR
SELinux GUI 工具 (system-config-selinux)
selinux-pythonAUR
SELinux python 工具和库 (semanage, sepolgen, sepolicy 等)
selinux-sandboxAUR
用于 SELinux 的沙盒工具
semodule-utilsAUR
在构建策略时处理 SELinux 模块的工具

SELinux 策略包

本文或章节需要扩充。

原因: 不清楚哪些软件包是替代品(在Talk:SELinux#Refpolicy instructions are unclear / out-of-date中讨论)
selinux-refpolicy-srcAUR
参考策略源
selinux-refpolicy-gitAUR
参考策略 git master (https://github.com/SELinuxProject/refpolicy) 使用特定于 Arch Linux 的配置构建
selinux-refpolicy-archAUR
预编译的模块化参考策略,带有标头和文档,但没有源代码。包含开发 Arch Linux Refpolicy 补丁,修复了与路径标记和 systemd 支持相关的问题。这些补丁也已发送给参考策略维护者,并且将它们包含在 selinux-refpolicy-archAUR 中主要是为了在参考策略版本之间执行更新。

其他 SELinux 工具

setoolsAUR
用于管理 SELinux 的 CLI 和 GUI 工具
selinux-alpm-hookAUR
pacman 钩子,用于在安装和更新软件包时根据 SELinux 策略标记文件

安装

有三种方法可以安装所需的 SELinux 软件包。

通过 GitHub 上的二进制包

所有软件包都可从 selinux 非官方仓库获得。base 软件包可以在系统安装的 arch-bootstrap 阶段替换为 base-selinux

警告: 目前此仓库不提供签名软件包,这意味着 pacman 不会验证其下载的二进制文件。这存在安全风险;请谨慎操作

通过 GitHub 的构建脚本

此仓库还包含一个名为 build_and_install_all.sh 的脚本,该脚本以所需的顺序构建和安装(或更新)所有软件包。以下是在用户 shell 中使用此脚本安装所有软件包的方法示例(带有下载用于验证软件包源 tarball 的 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 安全模块的初始化顺序。内核配置的 lsm= 值可以使用 zgrep CONFIG_LSM= /proc/config.gz 找到,当前值可以使用 cat /sys/kernel/security/lsm 找到。
  • 确保 selinux 是列表中第一个“主要”模块。[3] 有效值及其顺序的示例可以在 security/Kconfig 中找到。
  • capability 应从 lsm= 中省略,因为它将始终自动包含在内。

自定义内核

编译内核时,至少需要设置以下选项

CONFIG_SECURITY_SELINUX=y
CONFIG_AUDIT=y

要默认启用 SELinux Linux 安全模型并省略设置内核参数的需要,请另外设置 CONFIG_LSM 选项,并将 selinux 指定为列表中的第一个“主要”模块

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

检查 PAM

正确设置的PAM对于在登录后获得正确的安全上下文非常重要。检查 /etc/pam.d/system-login 中是否存在以下行

# pam_selinux.so close should be the first session rule
session         required        pam_selinux.so close
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session         required        pam_selinux.so open

安装策略

警告: SELinuxProject 给出的参考策略对于 Arch Linux 来说不是很好。大多数提交补丁以改进策略的人都使用其他发行版(Debian、Gentoo、RHEL 等),因此与 Arch Linux 软件包的兼容性并不完美(例如,该策略可能不支持程序的最新功能)。

策略是 SELinux 的支柱。它们是控制其行为的东西。目前 AUR 中唯一可用的策略是参考策略。为了安装它,您应该使用源文件,这些源文件可以从软件包 selinux-refpolicy-srcAUR 或通过在 https://github.com/SELinuxProject/refpolicy/wiki/DownloadRelease#current-release 上下载最新版本获得。当使用 AUR 软件包时,导航到 /etc/selinux/refpolicy/src/policy 并运行以下命令

# make bare
# make conf
# make install

要按原样安装参考策略。 那些了解如何编写 SELinux 策略的人员可以在运行上述命令之前根据自己的意愿进行调整。 该命令需要一段时间才能完成其工作,并完全占用系统的一个核心,因此请不要担心。 只需耐心等待命令运行完成即可。

要加载参考策略,请运行

# make load

然后,创建文件 /etc/selinux/config 并包含以下内容(仅当您使用上述默认设置时才有效。 如果您决定更改策略的名称,则需要调整该文件)

/etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#       enforcing - SELinux security policy is enforced.
#                   Set this value once you know for sure that SELinux is configured the way you like it and that your system is ready for deployment
#       permissive - SELinux prints warnings instead of enforcing.
#                    Use this to customise your SELinux policies and booleans prior to deployment. Recommended during policy development.
#       disabled - No SELinux policy is loaded.
#                  This is not a recommended setting, for it may cause problems with file labelling
SELINUX=permissive
# SELINUXTYPE= takes the name of SELinux policy to
# be used. Current options are:
#       refpolicy (vanilla reference policy)
#       <custompolicy> - Substitute <custompolicy> with the name of any custom policy you choose to load
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;

并运行以下命令

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

这是必需的,以从 /var/log/audit/audit.log 中删除一些消息,这些消息在参考策略中处理起来很麻烦。 这是一个糟糕的 hack,应该非常清楚地表明,如此安装的策略只是修补了参考策略,以隐藏不正确标记的效果。

在 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

要在不重新启动的情况下切换到强制模式,您可以使用

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

交换文件

如果您有交换文件而不是交换分区,请发出以下命令以设置适当的安全上下文

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

使用 SELinux

SELinux 使用与传统 Unix 访问控制不同的机制定义安全性。 理解它的最佳方式是通过示例。 例如,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. 用户: SELinux 用户身份。 这可以与 SELinux 用户被允许使用的一个或多个角色相关联。
  2. 角色: SELinux 角色。 这可以与 SELinux 用户被允许访问的一个或多个类型相关联。
  3. 类型: 当类型与进程关联时,它定义了 SELinux 用户(主体)可以访问哪些进程(或域)。 当类型与对象关联时,它定义了 SELinux 用户对该对象拥有的访问权限。
  4. 级别: 这个可选字段也可以称为范围,并且仅当策略支持 MCS 或 MLS 时才存在。

如果您希望了解如何构建自己的策略,这一点非常重要,因为这些是 SELinux 的基本构建块。 但是,对于大多数目的而言,没有必要这样做,因为参考策略已经足够成熟。 但是,如果您是高级用户或有非常特定需求的人,那么学习如何制作自己的 SELinux 策略可能是理想的选择。

这篇文章系列对于那些寻求理解如何使用 SELinux 的人来说非常有帮助。

故障排除

查找 SELinux 错误的地方是 systemd 日志。 为了查看与标签 system_u:system_r:policykit_t:s0(例如)相关的 SELinux 消息,您需要运行

# journalctl _SELINUX_CONTEXT=system_u:system_r:policykit_t:s0

有用的工具

有一些工具/命令可以极大地帮助使用 SELinux。

restorecon
根据任何策略规则恢复文件/目录(或使用 -R 递归恢复)的上下文
chcon
更改特定文件上的上下文

报告问题

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

另请参阅