SELinux 安全¶
随着内核版本 2.6 的到来,引入了一个新的安全系统,以提供安全机制来支持访问控制安全策略。
这个系统被称为 SELinux (Security Enhanced Linux),由 NSA (National Security Agency) 创建,用于在 Linux 内核子系统中实施强大的 Mandatory Access Control (MAC) 体系结构。
如果你在职业生涯中一直禁用或忽略 SELinux,那么本文将是你了解该系统的良好入门。SELinux 的作用是限制权限或消除与破坏程序或守护进程相关的风险。
在开始之前,你应该知道 SELinux 主要适用于 RHEL 发行版,尽管也可以在其他发行版(如 Debian)上实施(但祝你好运!)。Debian 家族的发行版通常会集成 AppArmor 系统,该系统的工作方式与 SELinux 不同。
概论¶
SELinux (Security Enhanced Linux) 是一个强制访问控制系统。
在出现 MAC 系统之前,标准访问管理安全是基于 DAC (Discretionary Access Control) 系统。应用程序或守护进程使用 UID 或 SUID (Set Owner User Id) 权限,这使得根据该用户评估权限(针对文件、套接字和其他进程...)成为可能。这种操作不足以限制受损程序的权限,可能会允许它访问操作系统子系统。
MAC 系统加强了机密性和完整性信息的隔离,以实现一个包含系统。包含系统独立于传统权限系统,并且没有超级用户概念。
在每次系统调用时,内核都会查询 SELinux 以查看它是否允许执行该操作。
SELinux 为此使用一组规则(策略)。提供了一组两个标准规则集(目标和严格),每个应用程序通常都提供自己的规则。
SELinux 上下文¶
SELinux 的操作方式与传统的 Unix 权限完全不同。
SELinux 安全上下文由三元组 身份+角色+域定义。
用户的身份直接取决于其 Linux 帐户。一个身份被分配了一个或多个角色,但每个角色对应一个域,并且只有一个。
根据安全上下文的域(以及角色)来评估用户对资源的权限。
术语“域”和“类型”类似。通常,“域”指的是进程,而“类型”指的是对象。
命名约定为:user_u:role_r:type_t。
在用户连接时,根据其角色分配给用户安全上下文。文件的安全上下文由 chcon
(change context) 命令定义,我们将在本文后面看到。
考虑 SELinux 拼图中的以下部分
- 主体
- 客体
- 策略
- 模式
当主体(例如应用程序)尝试访问客体(例如文件)时,Linux 内核的 SELinux 部分会查询其策略数据库。根据操作模式,SELinux 在成功的情况下会授权访问客体,否则会在 /var/log/messages
文件中记录失败。
标准进程的 SELinux 上下文¶
进程的权限取决于其安全上下文。
默认情况下,进程的安全上下文由启动它的用户的上下文(身份 + 角色 + 域)定义。
域是指与进程关联的特定类型(在 SELinux 意义上),并从启动它的用户继承(通常)。它的权限用针对链接到对象的类型的授权或拒绝来表示
具有安全 **域 D** 上下文的进程可以访问 **类型 T** 的对象。
重要进程的 SELinux 上下文¶
大多数重要程序都被分配了一个专用域。
每个可执行文件都带有一个专用类型(这里为 **sshd_exec_t**),它会自动将关联的进程切换到 **sshd_t** 上下文(而不是 **user_t**)。
这种机制至关重要,因为它尽可能地限制了进程的权限。
管理¶
semanage
命令用于管理 SELinux 规则。
semanage [object_type] [options]
示例
semanage boolean -l
选项 | 观察 |
---|---|
-a | 添加一个对象 |
-d | 删除一个对象 |
-m | 修改一个对象 |
-l | 列出对象 |
在 Rocky Linux 下,semanage
命令可能不是默认安装的。
在不知道提供此命令的软件包的情况下,您应该使用以下命令搜索其名称:
dnf provides */semanage
然后安装它
sudo dnf install policycoreutils-python-utils
管理布尔对象¶
布尔值允许包含进程。
semanage boolean [options]
要列出可用的布尔值
semanage boolean –l
SELinux boolean State Default Description
…
httpd_can_sendmail (off , off) Allow httpd to send mail
…
注意
如您所见,存在一个 `默认` 状态(例如,在启动时)和一个运行状态。
setsebool
命令用于更改布尔对象的 state
setsebool [-PV] boolean on|off
示例
sudo setsebool -P httpd_can_sendmail on
选项 | 观察 |
---|---|
-P | 更改启动时的默认值(否则仅在重新启动之前有效) |
-V | 删除一个对象 |
警告
不要忘记 `-P` 选项,以在下次启动后保留状态。
管理端口对象¶
semanage
命令用于管理端口类型的对象
semanage port [options]
示例:允许 httpd 域进程使用端口 81
sudo semanage port -a -t http_port_t -p tcp 81
操作模式¶
SELinux 有三种操作模式
- 强制
Rocky Linux 的默认模式。访问将根据生效的规则进行限制。
- 宽容
规则将被轮询,访问错误将被记录,但访问不会被阻止。
- 已禁用
没有任何内容会被限制,没有任何内容会被记录。
默认情况下,大多数操作系统都将 SELinux 配置为强制模式。
getenforce
命令返回当前操作模式
getenforce
示例
$ getenforce
Enforcing
sestatus
命令返回有关 SELinux 的信息
sestatus
示例
$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
...
Max kernel policy version: 33
setenforce
命令更改当前操作模式
setenforce 0|1
将 SELinux 切换到宽容模式
sudo setenforce 0
/etc/sysconfig/selinux
文件¶
/etc/sysconfig/selinux
文件允许您更改 SELinux 的操作模式。
警告
禁用 SELinux 存在风险!最好学习 SELinux 的工作原理,而不是系统地禁用它!
编辑 /etc/sysconfig/selinux
文件
SELINUX=disabled
注意
/etc/sysconfig/selinux
是指向 /etc/selinux/config
的符号链接
重新启动系统
sudo reboot
警告
注意 SELinux 模式更改!
在禁用模式下,新创建的文件将不会有任何标签。
要重新激活 SELinux,您必须在整个系统上重新定位标签。
标记整个系统
sudo touch /.autorelabel
sudo reboot
策略类型¶
SELinux 提供两种标准类型的规则
- **有针对性**:仅保护网络守护程序(`dhcpd`、`httpd`、`named`、`nscd`、`ntpd`、`portmap`、`snmpd`、`squid` 和 `syslogd`)
- **严格**:保护所有守护程序
上下文¶
安全上下文的显示使用 `-Z` 选项完成。它与许多命令相关联
示例
id -Z # the user's context
ls -Z # those of the current files
ps -eZ # those of the processes
netstat –Z # for network connections
lsof -Z # for open files
matchpathcon
命令返回目录的上下文。
matchpathcon directory
示例
sudo matchpathcon /root
/root system_u:object_r:admin_home_t:s0
sudo matchpathcon /
/ system_u:object_r:root_t:s0
chcon
命令修改安全上下文
chcon [-vR] [-u USER] [–r ROLE] [-t TYPE] file
示例
sudo chcon -vR -t httpd_sys_content_t /data/websites/
选项 | 观察 |
---|---|
-v | 切换到详细模式 |
-R | 应用递归 |
-u ,-r ,-t | 应用于用户、角色或类型 |
restorecon
命令恢复默认安全上下文(由规则提供的上下文)
restorecon [-vR] directory
示例
sudo restorecon -vR /home/
选项 | 观察 |
---|---|
-v | 切换到详细模式 |
-R | 应用递归 |
要使上下文更改在 restorecon
后仍然有效,您必须使用 semanage fcontext
命令修改默认文件上下文
semanage fcontext -a options file
注意
如果您要对系统中非标准的文件夹进行上下文切换,那么创建规则然后应用上下文是一个很好的做法,如下例所示!
示例
sudo semanage fcontext -a -t httpd_sys_content_t "/data/websites(/.*)?"
sudo restorecon -vR /data/websites/
audit2why
命令¶
audit2why
命令指示 SELinux 拒绝的原因
audit2why [-vw]
示例:获取 SELinux 最后一次拒绝的原因
sudo cat /var/log/audit/audit.log | grep AVC | grep denied | tail -1 | audit2why
选项 | 观察 |
---|---|
-v | 切换到详细模式 |
-w | 翻译 SELinux 拒绝的原因,并提出解决方案来解决它(默认选项) |
深入了解 SELinux¶
audit2allow
命令根据 "audit" 文件中的行创建一个模块,以允许 SELinux 操作(当不存在模块时)
audit2allow [-mM]
示例
sudo cat /var/log/audit/audit.log | grep AVC | grep denied | tail -1 | audit2allow -M mylocalmodule
选项 | 观察 |
---|---|
-m | 只需创建模块(`*.te`) |
-M | 创建模块,编译并打包它(`*.pp`) |
配置示例¶
执行命令后,系统会将命令提示符返回给您,但预期结果不可见:屏幕上没有错误消息。
- **步骤 1**:读取日志文件,知道我们感兴趣的消息类型为 AVC(SELinux)、拒绝(拒绝)以及最新消息(因此是最后一条消息)。
sudo cat /var/log/audit/audit.log | grep AVC | grep denied | tail -1
消息已正确隔离,但对我们没有帮助。
- **步骤 2**:使用
audit2why
命令读取隔离的消息,以获取更明确的消息,其中可能包含解决我们问题的方案(通常是需要设置的布尔值)。
sudo cat /var/log/audit/audit.log | grep AVC | grep denied | tail -1 | audit2why
有两种情况:我们可以放置上下文或填充布尔值,或者我们必须转到步骤 3 来创建我们自己的上下文。
- **步骤 3**:创建您自己的模块。
$ sudo cat /var/log/audit/audit.log | grep AVC | grep denied | tail -1 | audit2allow -M mylocalmodule
Generating type enforcement: mylocalmodule.te
Compiling policy: checkmodule -M -m -o mylocalmodule.mod mylocalmodule.te
Building package: semodule_package -o mylocalmodule.pp -m mylocalmodule.mod
$ sudo semodule -i mylocalmodule.pp
作者:Antoine Le Morvan
贡献者:Steven Spencer、markooff、Ganna Zhyrnova