跳转至内容

SELinux

来自 ArchWiki

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

在Linux发行版上运行SELinux需要三样东西:一个支持SELinux的内核、SELinux用户空间工具和库,以及SELinux策略(主要基于Reference Policy)。一些常见的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策略 进行中,使用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 需要使用--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标志重新编译
uutils-coreutils 需要使用USE=selinux make标志重新编译以链接libselinux

所有其他与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:Mandatory access control

安装SELinux

软件包说明

所有与SELinux相关的软件包都属于AUR中的selinux组。在手动安装任何这些软件包之前,请阅读#安装部分,以了解全面安装的推荐选项。

支持SELinux的系统实用程序

coreutils-selinuxAUR
已启用SELinux支持的修改版coreutils软件包。它取代了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
已编译SELinux支持的OpenSSH软件包,用于设置用户会话的安全上下文。它取代了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
已编译SELinux支持的修改版sudo软件包,可正确设置安全上下文。它取代了sudo软件包。
systemd-selinuxAUR
已启用SELinux的systemd版本。它取代了systemd软件包。
util-linux-selinuxAUR
已启用SELinux支持的修改版util-linux软件包。它取代了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
Reference Policy源代码
selinux-refpolicy-gitAUR
Reference Policy git master(https://github.com/SELinuxProject/refpolicy),已针对Arch Linux进行配置编译
selinux-refpolicy-archAUR
预编译的模块化Reference Policy,包含头文件和文档,但不包含源代码。包含开发中的Arch Linux Refpolicy补丁,这些补丁修复了与路径标签和systemd支持相关的问题。这些补丁也已发送给Reference Policy维护者,并将它们包含在selinux-refpolicy-archAUR中,主要是为了在Refpolicy版本之间执行更新。

其他SELinux工具

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

安装

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

通过GitHub上的二进制包

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

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

通过GitHub上的构建脚本

此仓库还包含一个名为build_and_install_all.sh的脚本,该脚本按所需顺序构建和安装(或更新)所有软件包。以下是一个用户Shell中可以使用该脚本安装所有软件包的示例(下载用于验证软件包源代码的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是列表中第一个“主要”模块。[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中唯一的策略是Reference Policy。为了安装它,您应该使用源文件,这些文件可以从软件包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中删除一些不适宜处理参考策略的消息。这是一个丑陋的技巧,并且应该非常清楚地说明,这样安装的策略只是修补了参考策略,以隐藏不正确标记的影响。

在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. User:SELinux用户身份。这可以关联到一个或多个SELinux用户允许使用的角色。
  2. Role:SELinux角色。这可以关联到一个或多个SELinux用户允许访问的类型。
  3. Type:当一个类型与一个进程关联时,它定义了SELinux用户(主体)可以访问哪些进程(或域)。当一个类型与一个对象关联时,它定义了SELinux用户对该对象的访问权限。
  4. Level:如果策略支持MCS或MLS,则此可选字段也称为范围,并且仅在该策略支持时存在。

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

This is a great series of articles for someone seeking to understand how to work with 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
根据任何策略规则,恢复文件/目录的上下文(或递归使用-R
chcon
更改特定文件的上下文

报告问题

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

参见