使用 SELinux
防止用户和进程使用增强安全的 Linux (SELinux)与文件和设备执行未授权的交互
摘要
对红帽文档提供反馈
我们感谢您对我们文档的反馈。让我们了解如何改进它。
通过 Jira 提交反馈(需要帐户)
- 登录到 Jira 网站。
- 在顶部导航栏中点 Create
- 在 Summary 字段中输入描述性标题。
- 在 Description 字段中输入您的改进建议。包括文档相关部分的链接。
- 点对话框底部的 Create。
第 1 章 SELinux 入门
SELinux(Security Enhanced Linux)提供了一个额外的系统安全层。SELinux 从根本上解决以下问题:May <subject> do <action> to <object>?, 例如:Web 服务器是否可以访问用户主目录中的文件?
1.1. SELinux 简介
系统管理员一般无法通过基于用户、组群和其它权限(称为 Discretionary Access Control,DAC)的标准访问策略生成全面、精细的安全策略。例如,限制特定应用程序只能查看日志文件,而同时允许其他应用程序在日志文件中添加新数据。
Security Enhanced Linux(SELinux)实现强制访问控制(MAC)。每个进程和系统资源都有一个特殊的安全性标签,称为 SELinux 上下文(context)。SELinux 上下文有时被称为 SELinux 标签,它是一个提取系统级别细节并专注于实体的安全属性的标识符。这不仅提供了在 SELinux 策略中引用对象的一个一致方法,而且消除了在其他身份识别系统中可能存在的模糊性。例如,某个文件可以在使用绑定挂载的系统中有多个有效的路径名称。
SELinux 策略在一系列规则中使用这些上下文,它们定义进程如何相互交互以及与各种系统资源进行交互。默认情况下,策略不允许任何交互,除非规则明确授予了相应的权限。
请记住,对 SELinux 策略规则的检查是在 DAC 规则后进行的。如果 DAC 规则已拒绝了访问,则不会使用 SELinux 策略规则。这意味着,如果传统的 DAC 规则已阻止了访问,则不会在 SELinux 中记录拒绝信息。
SELinux 上下文包括以下字段: user(用户)、role(角色)、type(类型)和 security level(安全级别)。在 SELinux 策略中,SELinux 类型信息可能是最重要的。这是因为,最常用的、用于定义允许在进程和系统资源间进行的交互的策略规则会使用 SELinux 类型而不是 SELinux 的完整上下文。SELinux 类型以 _t
结尾。例如,Web 服务器的类型名称为 httpd_t
。通常位于 /var/www/html/
中的文件和目录的类型上下文是 httpd_sys_content_t
。通常位于 /tmp
and /var/tmp/
中的文件和目录的类型上下文是 tmp_t
。Web 服务器端口的类型上下文是 http_port_t
。
有一个策略规则允许 Apache(作为 httpd_t
运行的 Web 服务器进程)访问通常位于 /var/www/html/
和其他 Web 服务器目录中上下文的文件和目录(httpd_sys_content_t
)。策略中没有允许规则适用于通常位于 /tmp
和 /var/tmp/
中的文件,因此不允许访问。因此,当使用 SELinux 时,即使 Apache 被破坏,一个恶意的脚本可以访问它,也无法访问 /tmp
目录。
图 1.1. 通过 SELinux 以安全的方式运行 Apache 和 MariaDB 的示例。
如上图所示,SELinux 允许作为 httpd_t
运行 Apache 进程访问 /var/www/html/
目录,并且拒绝同一进程访问 /data/mysql/
目录,因为 httpd_t
和 mysqld_db_t
类型上下文没有允许规则。另一方面,作为 mysqld_t
运行的 MariaDB 进程可以访问 /data/mysql/
目录,SELinux 也会正确地拒绝使用 mysqld_t
类型的进程来访问标记为 httpd_sys_content_t
的 /var/www/html/
目录。
其他资源
-
selinux(8)
手册页和apropos selinux
命令列出的 man page。 -
在安装了
selinux-policy-doc
软件包后,man -k _selinux
命令会列出 man page。 - The SELinux Coloring Book 可帮助您更好地了解 SELinux 基本概念。。
- SELinux Wiki FAQ
1.2. 运行 SELinux 的好处
SELinux 提供以下优点:
- 所有进程和文件都被标记。SELinux 策略规则定义了进程如何与文件交互,以及进程如何相互交互。只有存在明确允许的 SELinux 策略规则时,才能允许访问。
- SELinux 提供精细的访问控制。传统的 UNIX 通过用户的授权、基于 Linux 的用户和组进行控制。而 SELinux 的访问控制基于所有可用信息,如 SELinux 用户、角色、类型以及可选的安全级别。
- SELinux 策略由系统管理员进行定义,并在系统范围内强制执行。
- SELinux 可以缓解权限升级攻击。进程在域中运行,因此是相互分离的。SELinux 策略规则定义了如何处理访问文件和其它进程。如果某个进程被破坏,攻击者只能访问该进程的正常功能,而且只能访问已被配置为可以被该进程访问的文件。例如:如果 Apache HTTP 服务器被破坏,攻击者无法使用该进程读取用户主目录中的文件,除非添加或者配置了特定的 SELinux 策略规则允许这类访问。
- SELinux 可以强制实施数据保密性和完整性,并可以防止进程不受不受信任的输入的影响。
SELinux 旨在增强现有的安全解决方案,而不是替换 antivirus 软件、安全密码、防火墙或其他安全系统。即使运行 SELinux,仍需要遵循好的安全实践,如保持软件更新、使用安全的密码、使用防火墙。
1.3. SELinux 示例
以下示例演示了 SELinux 如何提高安全性:
- 默认操作为 deny(拒绝)。如果 SELinux 策略规则不存在允许访问(如允许进程打开一个文件),则拒绝访问。
-
SELinux 可以限制 Linux 用户。SELinux 策略中包括很多受限制的 SELinux 用户。可将 Linux 用户映射到受限制的 SELinux 用户,以便利用其使用的安全规则和机制。例如,将 Linux 用户映射到 SELinux
user_u
用户,这会导致 Linux 用户无法运行,除非有其他配置的用户 ID(setuid)应用程序,如sudo
和su
。 - 增加进程和数据的分离。SELinux 域(domain)的概念允许定义哪些进程可以访问某些文件和目录。例如:在运行 SELinux 时,除非有其他配置,攻击者将无法侵入 Samba 服务器,然后使用 Samba 服务器作为攻击向量读取和写入其它进程使用的文件(如 MariaDB 数据库)。
-
SELinux 可帮助缓解配置错误带来的破坏。在区传输(zone transfer)过程中,不同的 DNS 服务器通常会在彼此间复制信息。攻击者可以利用区传输来更新 DNS 服务器使其包括错误的信息。当在 Red Hat Enterprise Linux 中使用 BIND(Berkeley Internet Name Domain)作为 DNS 服务器运行时,即使管理员没有限制哪些服务器可执行区传输,默认的 SELinux 策略也会阻止区文件 [1] 通过 BIND
named
守护进程本身或其它进程,使用区传输。 -
如果没有 SELinux,攻击者可以利用漏洞在 Apache Web 服务器上路径遍历,并使用特殊元素(如
../
)访问存储在文件系统中的文件和目录。如果攻击者尝试对使用了强制模式运行 SELinux 的服务器进行攻击,SELinux 会拒绝对httpd
进程不能访问的文件的访问。虽然 SELinux 无法完全阻止这型的攻击,但它可以有效地缓解它。 -
使用强制(enforcing)模式的 SELinux 可以成功防止利用 kernel NULL pointer dereference operators on non-SMAP platforms (CVE-2019-9213) 安全漏洞进行攻击。攻击者可以利用
mmap
功能中的一个漏洞(不检查 null 页面的映射)将任意代码放在本页中。 -
deny_ptrace
SELinux boolean 和使用 enforcing 模式的 SELinux 的系统可以防止利用 PTRACE_TRACEME 安全漏洞 (CVE-2019-13272) 进行的攻击。这种配置可以防止攻击者获得root
特权。 -
nfs_export_all_rw
和nfs_export_all_ro
SELinux 布尔值提供了一个易于使用的工具,以防止错误配置网络文件系统 (NFS),如意外地共享了/home
目录。
其他资源
- SELinux as a security pillar of an operating system - Real-world benefits and examples 知识库文章
- 使用 Ansible 的 SELinux 强化 知识库文章
- 使用 Ansible playbook 进行 SELinux 强化的 selinux-playbooks Github 存储库
1.4. SELinux 构架和软件包
SELinux 是一个内置在 Linux 内核中的 Linux 安全模块(LSM)。内核中的 SELinux 子系统由安全策略驱动,该策略由管理员控制并在引导时载入。系统中所有与安全性相关的、内核级别的访问操作都会被 SELinux 截取,并在加载的安全策略上下文中检查。如果载入的策略允许操作,它将继续进行。否则,操作会被阻断,进程会收到一个错误。
SELinux 决策(如允许或禁止访问)会被缓存。这个缓存被称为 Access Vector Cache(AVC)。通过使用这些缓存的决定,可以较少对 SELinux 策略规则的检查,这会提高性能。请记住,如果 DAC 规则已首先拒绝了访问,则 SELinux 策略规则无效。原始审计消息会记录到 /var/log/audit/audit.log
,它们以 type=AVC
字符串开头。
在 RHEL 9 中,系统服务由 systemd
守护进程控制; systemd
启动和停止所有服务,用户和进程使用 systemctl
实用程序与 systemd
通信。systemd
守护进程可以参考 SELinux 策略,检查调用进程标签以及调用者试图管理的单元文件标签,然后询问 SELinux 是否允许调用者的访问。这个方法可控制对关键系统功能的访问控制,其中包括启动和停止系统服务。
systemd
守护进程也可以作为 SELinux 访问管理器使用。它检索运行 systemctl
或向 systemd
发送 D-Bus
消息的进程标签。然后守护进程会查找进程要配置的单元文件标签。最后,如果 SELinux 策略允许进程标签和单元文件标签之间的特定访问,systemd
就可以从内核中检索信息。这意味着,需要与特定服务交互的 systemd
进行交互的应用程序现在可以受 SELinux 限制。策略作者也可以使用这些精细的控制来限制管理员。
如果进程向另一个进程发送 D-Bus
消息,如果 SELinux 策略不允许这两个进程的 D-Bus
通信,则系统会打印 USER_AVC
拒绝消息,以及 D-Bus 通信超时。请注意,两个进程间的 D-Bus 通信会双向运行。
为了避免不正确的 SELinux 标记以及后续问题,请确定使用 systemctl start
命令启动服务。
RHEL 9 提供以下用于 SELinux 的软件包:
-
策略:
selinux-policy-targeted
,selinux-policy-mls
-
工具:
policycoreutils
,policycoreutils-gui
,libselinux-utils
,policycoreutils-python-utils
,setools-console
,checkpolicy
1.5. SELinux 状态和模式
SELinux 可使用三种模式之一运行: enforcing(强制)、permissive(宽容)或 disabled(禁用)。
- Enforcing 模式是默认操作模式,在 enforcing 模式下 SELinux 可正常运行,并在整个系统中强制实施载入的安全策略。
- 在 permissive 模式中,系统会象 enforcing 模式一样加载安全策略,包括标记对象并在日志中记录访问拒绝条目,但它并不会拒绝任何操作。不建议在生产环境系统中使用 permissive 模式,但 permissive 模式对 SELinux 策略开发和调试很有帮助。
- 强烈建议不要使用禁用(disabled)模式。它不仅会使系统避免强制使用 SELinux 策略,还会避免为任何持久对象(如文件)添加标签,这使得在以后启用 SELinux 非常困难。
使用 setenforce
实用程序在 enforcing 模式和 permissive 模式之间切换。使用 setenforce
所做的更改在重新引导后不会保留。要更改为 enforcing 模式,请以 Linux root 用户身份输入 setenforce 1
命令。要更改为 permissive 模式,请输入 setenforce 0
命令。使用 getenforce
实用程序查看当前的 SELinux 模式:
# getenforce
Enforcing
# setenforce 0 # getenforce Permissive
# setenforce 1 # getenforce Enforcing
在 Red Hat Enterprise Linux 中,您可以在系统处于 enforcing 模式时,将独立的域设置为 permissive 模式。例如,使 httpd_t 域为 permissive 模式:
# semanage permissive -a httpd_t
请注意,permissive 域是一个强大的工具,它可能会破坏您系统的安全性。红帽建议谨慎使用 permissive 域,如仅在调试特定情境时使用。
第 2 章 更改 SELinux 状态和模式
启用后,SELinux 可使用两种模式之一运行: enforcing 或 permissive。以下小节介绍了如何永久更改这些模式。
2.1. SELinux 状态和模式的更改
如 SELinux 状态和模式 中所述,SELinux 可以被启用或禁用。启用后,SELinux 有两个模式: enforcing 和 permissive。
使用 getenforce
或 sestatus
命令检查 SELinux 的运行模式。getenforce
命令返回 Enforcing
、Permissive
或 Disabled
。
sestatus
命令返回 SELinux 状态以及正在使用的 SELinux 策略:
$ 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
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 31
当系统以 permissive 模式运行 SELinux 时,用户和进程可能会错误地标记各种文件系统对象。当禁用 SELinux 时创建的文件系统对象不会被标记。这会在将 SELinux 改为 enforcing 模式时导致问题,因为 SELinux 依赖于正确的文件系统对象标签。
为防止错误标记和未标记的文件造成问题,SELinux 在从 disabled 状态更改为 permissive 或 enforcing 模式时自动重新标记文件系统。以 root 用户身份使用 fixfiles -F onboot
命令创建包含 -F
选项的 /.autorelabel
文件,以确保在下次重启时重新标记文件。
在重新引导系统以进行重新标记之前,请确保系统将以 permissive 模式引导,例如使用 enforcing=0
内核选项。在启动 selinux-autorelabel
服务前,当系统包括 systemd
需要的未被标记的文件时,系统无法引导。如需更多信息,请参阅 RHBZ#2021835。
2.2. 将 SELinux 更改为 permissive 模式
当 SELinux 是以 permissive 模式运行时,不会强制 SELinux 策略。系统可保持正常操作,SELinux 不会拒绝任何操作,而只是记录 AVC 信息,它们可用于故障排除、调试和 SELinux 策略改进。每个 AVC 在这个示例中仅记录一次。
先决条件
-
selinux-policy-targeted
、libselinux-utils
和policycoreutils
软件包已安装在您的系统中。 -
未使用
selinux=0
或enforcing=0
内核参数。
步骤
在您选择的文本编辑器中打开
/etc/selinux/config
文件,例如:# vi /etc/selinux/config
配置
SELINUX=permissive
选项:# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=permissive # SELINUXTYPE= can take one of these two values: # targeted - Targeted processes are protected, # mls - Multi Level Security protection. SELINUXTYPE=targeted
重启系统:
# reboot
验证
系统重启后,确认
getenforce
命令返回Permissive
:$ getenforce Permissive
2.3. 将 SELinux 更改为 enforcing 模式
当 SELinux 处于 enforcing 模式时,它会强制 SELinux 策略并根据 SELinux 策略规则拒绝访问。在 RHEL 中,当系统最初使用 SELinux 安装时,默认启用 enforcing 模式。
先决条件
-
selinux-policy-targeted
、libselinux-utils
和policycoreutils
软件包已安装在您的系统中。 -
未使用
selinux=0
或enforcing=0
内核参数。
步骤
在您选择的文本编辑器中打开
/etc/selinux/config
文件,例如:# vi /etc/selinux/config
配置
SELINUX=enforcing
选项:# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing # SELINUXTYPE= can take one of these two values: # targeted - Targeted processes are protected, # mls - Multi Level Security protection. SELINUXTYPE=targeted
保存更改,重启系统:
# reboot
在下一次引导中,SELinux 会重新标记系统中的所有文件和目录,并为禁用 SELinux 时创建的文件和目录添加 SELinux 上下文。
验证
系统重启后,确认
getenforce
命令返回Enforcing
:$ getenforce Enforcing
故障排除
切换到 enforcing 模式后,SELinux 可能会因为不正确或缺少 SELinux 策略规则而拒绝某些操作。
要查看 SELinux 拒绝的操作,以 root 用户身份输入以下命令:
# ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts today
另外,如果安装了
setroubleshoot-server
软件包,请输入:# grep "SELinux is preventing" /var/log/messages
如果 SELinux 是活跃的,且 Audit 守护进程(
auditd
)没有在您的系统中运行,在dmesg
命令输出中搜索特定的 SELinux 信息:# dmesg | grep -i -e type=1300 -e type=1400
如需更多信息,请参阅 SELinux 故障排除。
2.4. 在之前禁用的系统中启用 SELinux
为了避免问题(如系统无法引导或进程失败),当在之前禁用的系统中启用 SELinux 时,首先在 permissive 模式中解析 Access Vector Cache (AVC)信息。
当系统以 permissive 模式运行 SELinux 时,用户和进程可能会错误地标记各种文件系统对象。当禁用 SELinux 时创建的文件系统对象不会被标记。这会在将 SELinux 改为 enforcing 模式时导致问题,因为 SELinux 依赖于正确的文件系统对象标签。
为防止错误标记和未标记的文件造成问题,SELinux 在从 disabled 状态更改为 permissive 或 enforcing 模式时自动重新标记文件系统。
在重新引导系统以进行重新标记之前,请确保系统将以 permissive 模式引导,例如使用 enforcing=0
内核选项。在启动 selinux-autorelabel
服务前,当系统包括 systemd
需要的未被标记的文件时,系统无法引导。如需更多信息,请参阅 RHBZ#2021835。
步骤
- 以 permissive 模式启用 SELinux。如需更多信息,请参阅切换到 permissive 模式。
重启您的系统:
# reboot
- 检查 SELinux 拒绝消息。如需更多信息,请参阅 识别 SELinux 拒绝。
确保在下次重启时重新标记文件:
# fixfiles -F onboot
这会创建包含
-F
选项的/.autorelabel
文件。警告进入
fixfiles -F onboot
命令前,始终切换到 permissive 模式。默认情况下,
autorelabel
使用并行多个线程,因为系统有可用的 CPU 内核。要在自动重新标记过程中只使用单个线程,请使用fixfiles -T 1 onboot
命令。- 如果没有拒绝的操作,切换到 enforcing 模式。如需更多信息,请参阅在引导时进入 SELinux 模式。
验证
系统重启后,确认
getenforce
命令返回Enforcing
:$ getenforce Enforcing
后续步骤
要在 enforcing 模式下使用 SELinux 运行自定义应用程序,请选择以下之一:
-
在
unconfined_service_t
域中运行您的应用程序。 - 为应用程序编写新策略。如需更多信息,请参阅 编写自定义 SELinux 策略 部分。
其他资源
- SELinux 状态和模式部分涵盖了模式中的临时更改。
2.5. 禁用 SELinux
当您禁用 SELinux 时,您的系统不会载入 SELinux 策略。因此,系统不会强制执行 SELinux 策略,且不会记录 Access Vector Cache (AVC)信息。因此,运行 SELinux 的好处中介绍的好处都将没有。
除非在特定情况下,否则不要禁用 SELinux,如对性能敏感的系统,当弱安全性不会带来重大风险时。
如果您的场景需要在生产环境中执行调试,请临时使用 permissive 模式,而不是永久禁用 SELinux。如需有关 permissive 模式的更多信息,请参阅切换为 permissive 模式。
先决条件
已安装
grubby
软件包:$ rpm -q grubby grubby-<version>
步骤
将您的引导装载程序配置为在内核命令行中添加
selinux=0
:$ sudo grubby --update-kernel ALL --args selinux=0
重启您的系统:
$ reboot
验证
重新引导后,确认
getenforce
命令返回Disabled
:$ getenforce Disabled
2.6. 在引导时更改 SELinux 模式
在引导时,您可以设置以下内核参数来更改 SELinux 的运行方式:
- enforcing=0
设置此参数可让系统以 permissive 模式启动,这在进行故障排除时非常有用。如果您的文件系统被破坏,使用 permissive 模式可能是唯一的选择。在 permissive 模式中,系统将继续正确创建标签。在这个模式中产生的 AVC 信息可能与 enforcing 模式不同。
在 permissive 模式中,只报告来自于同一拒绝的一系列操作的第一个拒绝信息。然而,在 enforcing 模式中,您可能会得到一个与读取目录相关的拒绝信息,应用程序将停止。在 permissive 模式中,您会得到相同的 AVC 信息,但应用程序将继续读取目录中的文件,并为因为每个拒绝额外获得一个 AVC。
- selinux=0
这个参数会导致内核不载入 SELinux 构架的任意部分。初始化脚本会注意到系统使用
selinux=0
参数引导,并涉及/.autorelabel
文件。这会导致系统在下次使用 SELinux enabled 模式引导时自动重新标记。重要不要在生产环境中使用
selinux=0
参数。要调试您的系统,请临时使用 permissive 模式而不是禁用 SELinux。- autorelabel=1
这个参数强制系统使用类似以下命令的重新标记:
# touch /.autorelabel # reboot
如果文件系统中包含大量错误标记的对象,以 permissive 模式启动系统,使 autorelabel 进程成功。
其他资源
有关 SELinux 的其他内核引导参数,如
checkreqprot
,请查看由kernel-doc
软件包安装的/usr/share/doc/kernel-doc- <KERNEL_VER>/Documentation/admin-guide/kernel-parameters.txt
文件。使用安装的内核的版本号替换 <KERNEL_VER> 字符串,例如:# dnf install kernel-doc $ less /usr/share/doc/kernel-doc-4.18.0/Documentation/admin-guide/kernel-parameters.txt
第 3 章 管理限制和未限制的用户
每个 Linux 用户都根据 SELinux 策略中的规则映射到一个 SELinux 用户。管理员可以使用 semanage login
工具或将 Linux 用户直接分配给特定的 SELinux 用户来修改这些规则。因此,Linux 用户对其分配给的 SELinux 用户有限制。当分配给 SELinux 用户的 Linux 用户启动进程时,此过程将继承 SELinux 用户的限制,除非其他规则指定了不同的角色或类型。
3.1. SELinux 中的限制和未限制的用户
默认情况下,Red Hat Enterprise Linux 中的所有 Linux 用户(包括管理权限的用户)都会映射到无限制的 SELinux 用户 unconfined_u
。您可以通过将用户分配给受 SELinux 限制的用户来提高系统安全性。
Linux 用户的安全上下文由 SELinux 用户、SELinux 角色和 SELinux 类型组成。例如:
user_u:user_r:user_t
其中:
user_u
- 是 SELinux 用户。
user_r
- 是 SELinux 角色。
user_t
- 是 SELinux 类型。
Linux 用户登录后,其 SELinux 用户不能改变。但是,其类型和角色可以改变,例如在转换过程中。
要在您的系统中查看 SELinux 用户映射,以 root 用户身份使用 semanage login -l
命令:
# semanage login -l
Login Name SELinux User MLS/MCS Range Service
__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
在 Red Hat Enterprise Linux 中,Linux 用户默认映射到 SELinux __default__
登录,后者映射到 SELinux unconfined_u
用户。下面一行定义了默认映射:
default unconfined_u s0-s0:c0.c1023 *
限制的用户受 SELinux 策略中明确定义的 SELinux 规则的限制。无限制的用户只能受到 SELinux 的最小限制。
受限制和不受限制的 Linux 用户会受到可执行和可写入的内存检查,也受到 MCS 或 MLS 的限制。
要列出可用的 SELinux 用户,请输入以下命令:
$ seinfo -u
Users: 8
guest_u
root
staff_u
sysadm_u
system_u
unconfined_u
user_u
xguest_u
请注意,seinfo
命令由 setools-console
软件包提供,该软件包默认不会安装。
如果一个未限制的 Linux 用户执行一个应用程序,这个应用程序被 SELinux 策略定义为可以从 unconfined_t
域转换到其自身限制域的应用程序,则未限制的 Linux 用户仍会受到那个受限制域的限制。这样做的安全优点是,即使 Linux 用户的运行没有限制,但应用程序仍受限制。因此,对应用程序中漏洞的利用会被策略限制。
同样,我们可以将这些检查应用到受限制的用户。每个受限制的用户都受到受限用户域的限制。SELinux 策略还可定义从受限制的用户域转换到自己受限制的目标域转换。在这种情况下,受限制的用户会受到那个目标限制的域的限制。重点是,根据用户的角色,把特定的权限与受限制的用户相关联。
3.2. SELinux 用户的角色和权限
SELinux 策略将每个 Linux 用户映射到 SELinux 用户。这允许 Linux 用户继承 SELinux 用户的限制。
您可以通过调整策略中的布尔值来自定义 SELinux 策略中受限用户的权限。您可以使用 semanage boolean -l
命令确定这些布尔值的当前状态。要列出所有 SELinux 用户、MLS 和 MCS 的级别和范围,请以 root
用户身份使用 semanage user -l
命令。
User | 默认角色 | 其他角色 |
---|---|---|
|
|
|
|
| |
|
| |
|
| |
|
|
|
| ||
| ||
|
| |
|
|
|
| ||
| ||
|
|
请注意,system_u
是系统进程和对象的特殊用户身份,system_r
是关联的角色。管理员不得将这个 system_u
用户和 system_r
角色关联到 Linux 用户。另外,unconfined_u
和 root
是没有限制的用户。因此,与这些 SELinux 用户关联的角色不会包含在下表 类型和 SELinux 角色的访问权限中。
每个 SELinux 角色都与 SELinux 类型对应,并提供特定的访问权限。
Role | Type | 使用 X Window 系统登录 | su 和 sudo | 在主目录和 /tmp 中执行(默认) | Networking |
---|---|---|---|---|---|
|
| 是 | 是 | 是 | 是 |
|
| 否 | 否 | 是 | 否 |
|
| 是 | 否 | 是 | 仅限 Web 浏览器(Mozilla Firefox、GNOME Web) |
|
| 是 | 否 | 是 | 是 |
|
| 是 |
仅 | 是 | 是 |
|
| 是 | 是 | 是 | |
|
| 是 | 是 | 是 | |
|
| 是 | 是 | 是 | |
|
| 是 | 是 | 是 | |
|
| 是 | 是 | 是 | |
|
|
仅在 | 是 | 是 | 是 |
有关非管理员用户角色的更详细描述,请参阅 SELinux 中被限制的非管理员用户角色。
有关管理员角色的更详细描述,请参阅 SELinux 中受限的管理员角色。
要列出所有可用角色,请输入 seinfo -r
命令:
$ seinfo -r
Roles: 14
auditadm_r
dbadm_r
guest_r
logadm_r
nx_server_r
object_r
secadm_r
staff_r
sysadm_r
system_r
unconfined_r
user_r
webadm_r
xguest_r
请注意,seinfo
命令由 setools-console
软件包提供,该软件包默认不会安装。
其他资源
-
selinux-policy-doc
软件包安装的seinfo (1)
,semanage-login (8)
和xguest_selinux (8)
手册页 - 如何使用布尔值修改 SELinux 设置
3.3. SELinux 中约束的非管理员角色
在 SELinux 中,约束的非管理员角色将执行特定任务的特权和权限的特定集合授予分配给它们的 Linux 用户。通过分配单独的约束的非管理员角色,您可以将特定的特权分配给单个用户。这在有多个有不同授权级别的用户时很有用。
您还可以通过更改系统上相关的 SELinux 布尔值来自定义 SELinux 角色的权限。要查看 SELinux 布尔值及其状态,请以 root 用户身份使用 semanage boolean -l
命令。如果安装了 selinux-policy-devel
软件包,您可以获得更详细的描述。
# semanage boolean -l
SELinux boolean State Default Description
…
xguest_connect_network (on , on) Allow xguest users to configure Network Manager and connect to apache ports
xguest_exec_content (on , on) Allow xguest to exec content
…
user_t
、guest_t
和 xguest_t
域中的 Linux 用户只能在 SELinux 策略允许的情况下运行设置用户 ID (setuid
)应用程序(例如 passwd
)。这些用户无法运行 setuid
应用程序 su
和 sudo
,因此无法使这些应用程序变为 root 用户。
默认情况下,staff_t
、user_t
、guest_t
和 xguest_t
域中的 Linux 用户可以在其主目录和 /tmp
中执行应用程序。应用程序继承执行它们的用户的权限。
要防止 guest_t
和 xguest_t
用户在其有写权限的目录中执行应用程序,请将 guest_exec_content
和 xguest_exec_content
布尔值设置为 off
。
SELinux 有以下约束的非管理员角色,每个角色都有特定的特权和限制:
guest_r
有非常有限的权限。分配给此角色的用户无法访问网络,但可以执行
/tmp
和/home
目录中的文件。相关的布尔值:
SELinux boolean State Default Description guest_exec_content (on , on) Allow guest to exec content
xguest_r
有有限的权限。分配给此角色的用户可以登录到 X 窗口,使用网络浏览器访问网页和访问介质。它们也可以执行
/tmp
和/home
目录中的文件。相关的布尔值:
SELinux boolean State Default Description xguest_connect_network (on , on) Allow xguest users to configure Network Manager and connect to apache ports xguest_exec_content (on , on) Allow xguest to exec content xguest_mount_media (on , on) Allow xguest users to mount removable media xguest_use_bluetooth (on , on) Allow xguest to use blue tooth devices
user_r
有具有完整用户权限的非特权访问权限。分配给此角色的用户可以执行大多数不需要管理特权的操作。
相关的布尔值:
SELinux boolean State Default Description unprivuser_use_svirt (off , off) Allow unprivileged user to create and transition to svirt domains.
staff_r
具有类似于
user_r
的权限和其他特权。特别是,分配给此角色的用户被允许运行sudo
来执行通常为root
用户保留的管理命令。这会更改角色和有效的用户 ID (EUID),但不更改 SELinux 用户。相关的布尔值:
SELinux boolean State Default Description staff_exec_content (on , on) Allow staff to exec content staff_use_svirt (on , on) allow staff user to create and transition to svirt domains.
其他资源
-
要将 Linux 用户映射到
staff_u
并配置sudo
,请参阅 使用 sudo 和 sysadm_r 角色配置管理员。 有关每个角色和相关类型的详情,请查看
selinux-policy-doc
软件包安装的相关手册页:guest_selinux (8)
,xguest_selinux (8)
,user_selinux (8)
, 和staff_selinux (8)
3.4. SELinux 中受限的管理员角色
在 SELinux 中,受限制的管理员角色将执行特定任务的特定的特权和权限集合授权给分配给它们的 Linux 用户。通过分配单独的受限制的管理员角色,您可以将不同系统管理域上的权限划分给单个用户。这在有多个管理员的情况下很有用,每个管理员都有单独的域。
您可以使用 semanage user
命令将这些角色分配给 SELinux 用户。
SELinux 有以下受限制的管理员角色:
auditadm_r
审计管理员角色允许管理与审计子系统相关的进程。
相关的布尔值:
SELinux boolean State Default Description auditadm_exec_content (on , on) Allow auditadm to exec content
dbadm_r
数据库管理员角色允许管理 MariaDB 和 PostgreSQL 数据库。
相关的布尔值:
SELinux boolean State Default Description dbadm_exec_content (on , on) Allow dbadm to exec content dbadm_manage_user_files (off , off) Determine whether dbadm can manage generic user files. dbadm_read_user_files (off , off) Determine whether dbadm can read generic user files.
logadm_r
日志管理员角色允许管理日志,特别是与 Rsyslog 日志记录服务和审计子系统相关的 SELinux 类型。
相关的布尔值:
SELinux boolean State Default Description logadm_exec_content (on , on) Allow logadm to exec content
webadm_r
Web 管理员允许管理 Apache HTTP 服务器。
相关的布尔值:
SELinux boolean State Default Description webadm_manage_user_files (off , off) Determine whether webadm can manage generic user files. webadm_read_user_files (off , off) Determine whether webadm can read generic user files.
secadm_r
安全管理员角色允许管理 SELinux 数据库。
相关的布尔值:
SELinux boolean State Default Description secadm_exec_content (on , on) Allow secadm to exec content
sysadm_r
系统管理员角色允许执行之前列出的角色的任何操作,并具有额外的特权。在非默认配置中,可以通过在 SELinux 策略中禁用
sysadm_secadm
模块来将安全管理与系统管理分开。具体步骤请参阅 MLS 中的从安全管理分离系统管理。sysadm_u
用户无法使用 SSH 直接登录。要为sysadm_u
启用 SSH 登录,请将ssh_sysadm_login
布尔值设置为on
:# setsebool -P ssh_sysadm_login on
相关的布尔值:
SELinux boolean State Default Description ssh_sysadm_login (on , on) Allow ssh logins as sysadm_r:sysadm_t sysadm_exec_content (on , on) Allow sysadm to exec content xdm_sysadm_login (on , on) Allow the graphical login program to login directly as sysadm_r:sysadm_t
其他资源
- 要将 Linux 用户分配给受限管理员角色,请参阅通过 映射到 sysadm_u 来限制管理员。
有关每个角色以及相关类型的详情,请查看
selinux-policy-doc
软件包安装的相关手册页:auditadm_selinux (8)
,dbadm_selinux (8)
,logadm_selinux (8)
,webadm_selinux (8)
,secadm_selinux (8)
, 和sysadm_selinux (8)
3.5. 添加一个新用户会自动映射到 SELinux unconfined_u 用户
下面的步骤演示了如何在系统中添加新 Linux 用户。用户会自动映射到 SELinux unconfined_u
用户。
先决条件
-
root
用户运行没有限制,这在 Red Hat Enterprise Linux 中默认运行。
步骤
输入以下命令创建一个名为
<example_user>
的新 Linux 用户:# useradd <example_user>
为 Linux
<example_user>
用户分配一个密码:# passwd <example_user> Changing password for user <example_user>. New password: Retype new password: passwd: all authentication tokens updated successfully.
- 退出当前会话。
-
以 Linux
<example_user>
用户身份登录。当您登录时,pam_selinux
PAM 模块会自动将 Linux 用户映射到 SELinux 用户(本例中为unconfined_u
),并设置生成的 SELinux 上下文。然后会使用这个上下文启动 Linux 用户的 shell。
验证
以
<example_user>
用户身份登录时,请检查 Linux 用户的上下文:$ id -Z unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
其他资源
-
系统中的
pam_selinux (8)
手册页
3.6. 以 SELinux 限制的用户身份添加新用户
使用以下步骤为该系统添加新的 SELinux 保护用户。这个示例步骤会在创建用户帐户后马上将用户映射到 SELinux staff_u
用户。
先决条件
-
root
用户运行没有限制,这在 Red Hat Enterprise Linux 中默认运行。
步骤
输入以下命令创建一个名为
<example_user>
的新 Linux 用户,并将其映射到 SELinuxstaff_u
用户:# useradd -Z staff_u <example_user>
为 Linux
<example_user>
用户分配一个密码:# passwd <example_user> Changing password for user <example_user>. New password: Retype new password: passwd: all authentication tokens updated successfully.
- 退出当前会话。
-
以 Linux
<example_user>
用户身份登录。用户的 shell 使用staff_u
上下文启动。
验证
以
<example_user>
用户身份登录时,请检查 Linux 用户的上下文:$ id -Z uid=1000(<example_user>) gid=1000(<example_user>) groups=1000(<example_user>) context=staff_u:staff_r:staff_t:s0-s0:c0.c1023
其他资源
-
系统中的
pam_selinux (8)
手册页
3.7. 在 SELinux 中限制常规用户
您可以通过将系统映射到 user_u
SELinux 用户来限制系统中的所有常规用户。
默认情况下,Red Hat Enterprise Linux 中的所有 Linux 用户(包括管理权限的用户)都会映射到无限制的 SELinux 用户 unconfined_u
。您可以通过将用户分配给受 SELinux 限制的用户来提高系统安全性。这对遵守 V-71971 安全技术实施指南非常有用。
步骤
显示 SELinux 登录记录列表。这个列表显示了 Linux 用户与 SELinux 用户的映射:
# semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * root unconfined_u s0-s0:c0.c1023 *
将
__default__
用户(表示没有显式映射的所有用户)映射到user_u
SELinux 用户:# semanage login -m -s user_u -r s0 __default__
验证
检查
__default__
用户是否已映射到user_u
SELinux 用户:# semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ user_u s0 * root unconfined_u s0-s0:c0.c1023 *
验证新用户的进程在
user_u:user_r:user_t:s0
SELinux 上下文中运行。创建一个新用户:
# adduser <example_user>
为
<example_user>
定义一个密码:# passwd <example_user>
-
注销
root
,然后以新用户身份登录。 显示用户 ID 的安全上下文:
[<example_user>@localhost ~]$ id -Z user_u:user_r:user_t:s0
显示用户当前进程的安全上下文:
[<example_user>@localhost ~]$ ps axZ LABEL PID TTY STAT TIME COMMAND - 1 ? Ss 0:05 /usr/lib/systemd/systemd --switched-root --system --deserialize 18 - 3729 ? S 0:00 (sd-pam) user_u:user_r:user_t:s0 3907 ? Ss 0:00 /usr/lib/systemd/systemd --user - 3911 ? S 0:00 (sd-pam) user_u:user_r:user_t:s0 3918 ? S 0:00 sshd: <example_user>@pts/0 user_u:user_r:user_t:s0 3922 pts/0 Ss 0:00 -bash user_u:user_r:user_dbusd_t:s0 3969 ? Ssl 0:00 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only user_u:user_r:user_t:s0 3971 pts/0 R+ 0:00 ps axZ
3.8. 通过映射到 sysadm_u
来限制管理员
您可以通过将用户直接映射到 sysadm_u
SELinux 用户来限制具有管理权限的用户。当用户登录时,会话会在 sysadm_u:sysadm_r:sysadm_t
SELinux 上下文中运行。
默认情况下,Red Hat Enterprise Linux 中的所有 Linux 用户(包括管理权限的用户)都会映射到无限制的 SELinux 用户 unconfined_u
。您可以通过将用户分配给受 SELinux 限制的用户来提高系统安全性。这对遵守 V-71971 安全技术实施指南非常有用。
先决条件
-
root
用户运行没有限制。这是 Red Hat Enterprise Linux 的默认设置。
步骤
可选:要允许
sysadm_u
用户使用 SSH 连接到系统:# setsebool -P ssh_sysadm_login on
将新用户映射到
sysadm_u
SELinux 用户:要映射新用户,请在
wheel
用户组中添加一个新用户,并将用户映射到sysadm_u
SELinux 用户:# adduser -G wheel -Z sysadm_u <example_user>
要映射现有用户,将用户添加到
wheel
用户组,并将用户映射到sysadm_u
SELinux 用户:# usermod -G wheel -Z sysadm_u <example_user>
恢复用户主目录的上下文:
# restorecon -R -F -v /home/<example_user>
验证
检查
<example_user>
是否被映射到sysadm_u
SELinux 用户:# semanage login -l | grep <example_user> <example_user> sysadm_u s0-s0:c0.c1023 *
以
<example_user>
身份登录,例如使用 SSH,并显示用户的安全上下文:[<example_user>@localhost ~]$ id -Z sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
切换到
root
用户:$ sudo -i [sudo] password for <example_user>:
验证安全性上下文是否保持不变:
# id -Z sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
尝试管理任务,例如重启
sshd
服务:# systemctl restart sshd
如果没有输出结果,则代表命令可以成功完成。
如果该命令没有成功完成,它会输出以下信息:
Failed to restart sshd.service: Access denied See system logs and 'systemctl status sshd.service' for details.
3.9. 使用 sudo 和 sysadm_r 角色约束管理员
您可以将具有管理权限的特定用户映射到 staff_u
SELinux 用户,并配置 sudo
,以便用户获取 sysadm_r
SELinux 管理员角色。这个角色允许用户在不拒绝 SELinux 的情况下执行管理任务。当用户登录时,会话运行在 staff_u:staff_r:staff_r:staff_t
SELinux 上下文中,但当用户使用 sudo
输入命令时,会话会更改为 staff_u:sysadm_r:sysadm_t
上下文。
默认情况下,Red Hat Enterprise Linux 中的所有 Linux 用户(包括管理权限的用户)都会映射到无限制的 SELinux 用户 unconfined_u
。您可以通过将用户分配给受 SELinux 限制的用户来提高系统安全性。这对遵守 V-71971 安全技术实施指南非常有用。
先决条件
-
root
用户运行没有限制。这是 Red Hat Enterprise Linux 的默认设置。
步骤
将新用户或现有用户映射到
staff_u
SELinux 用户:要映射新用户,请将新用户添到
wheel
用户组,并将用户映射到staff_u
SELinux 用户:# adduser -G wheel -Z staff_u <example_user>
要映射现有用户,请将用户添加到
wheel
用户组,并将用户映射到staff_u
SELinux 用户:# usermod -G wheel -Z staff_u <example_user>
恢复用户主目录的上下文:
# restorecon -R -F -v /home/<example_user>
要允许
<example_user>
获得 SELinux 管理员角色,请在/etc/sudoers.d/
目录中创建一个新文件,例如:# visudo -f /etc/sudoers.d/<example_user>
在新文件中添加以下行:
<example_user> ALL=(ALL) TYPE=sysadm_t ROLE=sysadm_r ALL
验证
检查
<example_user>
是否已映射到staff_u
SELinux 用户:# semanage login -l | grep <example_user> <example_user> staff_u s0-s0:c0.c1023 *
以
<example_user>
身份登录,例如使用 SSH,并切换到root
用户:[<example_user>@localhost ~]$ sudo -i [sudo] password for <example_user>:
显示
root
安全上下文:# id -Z staff_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
尝试管理任务,例如重启
sshd
服务:# systemctl restart sshd
如果没有输出结果,则代表命令可以成功完成。
如果该命令没有成功完成,它会输出以下信息:
Failed to restart sshd.service: Access denied See system logs and 'systemctl status sshd.service' for details.
3.10. 其他资源
-
selinux-policy-doc
软件包安装的unconfined_selinux (8)
,user_selinux (8)
,staff_selinux (8)
和sysadm_selinux (8)
手册页。 - 如何设置 SELinux 受限用户的系统
- 如何使用布尔值修改 SELinux 设置
第 4 章 为使用非标准配置的应用程序和服务配置 SELinux
当 SELinux 处于 enforcing 模式时,默认策略是目标(targeted)策略。以下小节提供了有关在更改配置默认值后为各种服务设置和配置 SELinux 策略的信息,如端口、数据库位置或进程的文件系统权限。
您将了解如何为非标准端口更改 SELinux 类型,识别并修复默认目录更改的不正确的标签,以及使用 SELinux 布尔值调整策略。
4.1. 在非标准配置中为 Apache HTTP 服务器自定义 SELinux 策略
您可以将 Apache HTTP 服务器配置为在不同端口中侦听,并在非默认目录中提供内容。要防止 SELinux 拒绝带来的后果,请按照以下步骤调整系统的 SELinux 策略。
先决条件
-
已安装
httpd
软件包,并将 Apache HTTP 服务器配置为侦听 TCP 端口 3131,并使用/var/test_www/
目录而不是默认的/var/www/
目录。 -
policycoreutils-python-utils
和setroubleshoot-server
软件包已安装在您的系统中。
步骤
启动
httpd
服务并检查状态:# systemctl start httpd # systemctl status httpd ... httpd[14523]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:3131 ... systemd[1]: Failed to start The Apache HTTP Server. ...
SELinux 策略假设
httpd
在端口 80 上运行:# semanage port -l | grep http http_cache_port_t tcp 8080, 8118, 8123, 10001-10010 http_cache_port_t udp 3130 http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000 pegasus_http_port_t tcp 5988 pegasus_https_port_t tcp 5989
更改 SELinux 类型端口 3131 使其与端口 80 匹配:
# semanage port -a -t http_port_t -p tcp 3131
再次启动
httpd
:# systemctl start httpd
但是,内容仍无法访问:
# wget localhost:3131/index.html ... HTTP request sent, awaiting response... 403 Forbidden ...
使用
sealert
工具查找原因:# sealert -l "*" ... SELinux is preventing httpd from getattr access on the file /var/test_www/html/index.html. ...
使用
matchpathcon
工具比较标准 SELinux 类型以及新路径:# matchpathcon /var/www/html /var/test_www/html /var/www/html system_u:object_r:httpd_sys_content_t:s0 /var/test_www/html system_u:object_r:var_t:s0
将新
/var/test_www/html/
内容目录的 SELinux 类型改为默认/var/www/html
目录的类型:# semanage fcontext -a -e /var/www /var/test_www
递归重新标记
/var
目录:# restorecon -Rv /var/ ... Relabeled /var/test_www/html from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0 Relabeled /var/test_www/html/index.html from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
验证
检查
httpd
服务是否正在运行:# systemctl status httpd ... Active: active (running) ... systemd[1]: Started The Apache HTTP Server. httpd[14888]: Server configured, listening on: port 3131 ...
验证 Apache HTTP 服务器提供的内容是否可以访问:
# wget localhost:3131/index.html ... HTTP request sent, awaiting response... 200 OK Length: 0 [text/html] Saving to: ‘index.html’ ...
其他资源
-
semanage (8)
,matchpathcon (8)
, 和sealert (8)
man pages.
4.2. 使用 SELinux 布尔值调整用于共享 NFS 和 CIFS 卷的策略
您可以使用布尔值在运行时更改 SELinux 策略部分,即使您不了解 SELinux 策略的编写方式。这启用了更改,比如允许服务访问 NFS 卷而无需重新载入或者重新编译 SELinux 策略。以下流程演示了列出 SELinux 布尔值并进行配置,以实现策略中所需的更改。
在客户端的 NFS 挂载使用 NFS 卷策略定义的默认上下文标记。在 RHEL 中,此默认上下文使用 nfs_t
类型。另外,挂载在客户端中的 Samba 共享使用策略定义的默认上下文标记。此默认上下文使用 cifs_t
类型。您可以启用或禁用布尔值来控制允许哪些服务访问 nfs_t
和 cifs_t
类型。
要允许 Apache HTTP 服务器服务(httpd
)访问和共享 NFS 和 CIFS 卷,请执行以下步骤:
先决条件
-
(可选)安装
selinux-policy-devel
软件包,以获取semanage boolean -l
命令的输出中 SELinux 布尔值的更清晰和详细描述。
步骤
识别与 NFS、CIFS 和 Apache 相关的 SELinux 布尔值:
# semanage boolean -l | grep 'nfs\|cifs' | grep httpd httpd_use_cifs (off , off) Allow httpd to access cifs file systems httpd_use_nfs (off , off) Allow httpd to access nfs file systems
列出布尔值的当前状态:
$ getsebool -a | grep 'nfs\|cifs' | grep httpd httpd_use_cifs --> off httpd_use_nfs --> off
启用指定的布尔值:
# setsebool httpd_use_nfs on # setsebool httpd_use_cifs on
注意使用
setsebool
和-P
选项,使更改在重新启动后仍然有效。setsebool -P
命令需要重建整个策略,且可能需要一些时间,具体取决于您的配置。
验证
检查布尔值为
on
:$ getsebool -a | grep 'nfs\|cifs' | grep httpd httpd_use_cifs --> on httpd_use_nfs --> on
其他资源
-
semanage-boolean (8)
,sepolicy-
,booleans (8)
getsebool (8)
,setsebool (8)
,booleans (5)
, 和 booleans (8) man pages
4.3. 查找用于管理对非标准目录的访问的正确 SELinux 类型
如果您需要设置默认 SELinux 策略没有涵盖的访问控制规则,请首先搜索与您的用例匹配的布尔值。如果您无法找到合适的布尔值,您可以使用匹配的 SELinux 类型甚至创建本地策略模块。
先决条件
-
selinux-policy-doc
和setools-console
软件包已安装在您的系统中。
步骤
列出所有与 SELinux 相关的主题,并将结果限制为您要配置的组件。例如:
# man -k selinux | grep samba samba_net_selinux (8) - Security Enhanced Linux Policy for the samba_net processes samba_selinux (8) - Security Enhanced Linux Policy for the smbd processes …
在与您的场景对应的 man page 中,找到相关的 SELinux 布尔值、端口类型和文件类型。
请注意,只有安装
selinux-policy-doc
软件包后,man -k selinux
或apropos selinux
命令才可用。可选:您可以使用
semanage fcontext -l
命令显示默认位置上进程的默认映射,例如:# semanage fcontext -l | grep samba … /var/cache/samba(/.*)? all files system_u:object_r:samba_var_t:s0 … /var/spool/samba(/.*)? all files system_u:object_r:samba_spool_t:s0 …
使用
sesearch
命令显示默认 SELinux 策略中的规则。您可以通过列出对应的规则来查找要使用的类型和布尔值,例如:$ sesearch -A | grep samba | grep httpd … allow httpd_t cifs_t:dir { getattr open search }; [ use_samba_home_dirs && httpd_enable_homedirs ]:True …
SELinux 布尔值可能是您的配置问题最直接的解决方案。您可以使用
getsebool -a
命令显示所有可用的布尔值及其值,例如:$ getsebool -a | grep homedirs git_cgi_enable_homedirs --> off git_system_enable_homedirs --> off httpd_enable_homedirs --> off mock_enable_homedirs --> off mpd_enable_homedirs --> off openvpn_enable_homedirs --> on ssh_chroot_rw_homedirs --> off
您可以使用
sesearch
命令验证所选布尔值是否准确执行所需的内容,例如:$ sesearch -A | grep httpd_enable_homedirs … allow httpd_suexec_t autofs_t:dir { getattr open search }; [ use_nfs_home_dirs && httpd_enable_homedirs ]:True allow httpd_suexec_t autofs_t:dir { getattr open search }; [ use_samba_home_dirs && httpd_enable_homedirs ]:True …
如果没有与您的场景匹配,则找到适合您问题单的 SELinux 类型。您可以使用
sesearch
从默认策略查询对应的规则来查找您的文件类型,例如:$ sesearch -A -s httpd_t -c file -p read … allow httpd_t httpd_t:file { append getattr ioctl lock open read write }; allow httpd_t httpd_tmp_t:file { append create getattr ioctl link lock map open read rename setattr unlink write }; …
- 如果前面的解决方案没有满足您的场景,您可以在 SELinux 策略中添加自定义规则。如需更多信息 ,请参阅创建本地 SELinux 策略模块 部分。
其他资源
-
man -k selinux
命令提供的与 SELinux 相关的 man page -
sesearch (1)
,semanage-fcontext (8)
,semanage-boolean (8)
, 和getsebool (8)
手册页
第 6 章 使用多级别安全(MLS)
多级别安全(Multi-Level Security,简称 MLS)策略使用许可级别的概念,这个概念首先由美国国防人员设计。MLS 满足一组非常严格的安全要求,这基于在严格控制的环境中管理的信息(如军事)。
使用 MLS 非常复杂,不适合于一般用例场景。
6.1. 多级别安全(MLS)
多级别安全(MLS)技术使用信息安全级别将数据分为分级分类,例如:
- [Low] 非保密
- [low] 保密
- [high] 机密
- [Highest] 顶端机密
默认情况下,MLS SELinux 策略使用 16 敏感度级别:
-
s0
是最敏感的。 -
s15
是最敏感的。
MLS 使用特定的术语来代表敏感度级别:
- 用户和进程称为 主题(subjects),其敏感度级别被称为 安全权限(clearance)。
- 系统文件、设备和其他被动组件称为 对象(objects),其敏感度级别被称为安全级别(classification)。
为了实施 MLS,SELinux 使用 Bell-La Padula Model (BLP)模型。这个模型根据附加到每个主体和对象的标签指定系统中如何进行信息流。
BLP 的基本原则是"不能从上面读取,不能向下面写入”。这意味着用户只能读取自己的敏感度级别及更低级别的文件,数据只能从较低级别流入到更高级别,且不会从高级别流向低级别。
MLS SELinux 策略(RHEL 中的 MLS 实现)应用一个名为 Bell-La Padula with write equality 的经过修改的原则。这意味着,用户可以在自己的敏感度级别和更低级别中读取文件,但只能在自己的级别上写入。例如,这可以防止不明确的用户将内容写入 top-secret 文件中。
例如,默认情况下,具有安全许可级别 s2
的用户:
-
可以读取敏感度级别为
s0
、s1
和s2
的文件。 -
无法读取敏感度级别为
s3
及更高等级的文件。 -
可以修改敏感级别为
s2
的文件。 -
无法修改敏感级别不是
s2
的文件。
安全管理员可以通过修改系统的 SELinux 策略来调整此行为。例如,可以允许用户修改更低级别的文件,这需要将文件的敏感级别增加到用户的安全许可级别。
实际上,用户通常会被分配为具有一系列的安全许可级别,如 s1-s2
。用户可以读取级别低于用户的最大级别的文件,并可以写入该范围内的任何文件。
例如,默认情况下,用户有一个安全许可级别范围 s1-s2
:
-
可以读取具有敏感度级别
s0
和s1
的文件。 -
不能读取级别
s2
及更高等级的文件。 -
可以修改具有敏感度级别
s1
的文件。 -
无法修改敏感级别不是
s1
的文件。 -
可以将自己的安全许可级别更改为
s2
。
MLS 环境中非特权用户的安全上下文是:
user_u:user_r:user_t:s1
其中:
user_u
- 是 SELinux 用户。
user_r
- 是 SELinux 角色。
user_t
- 是 SELinux 类型。
s1
- 是 MLS 敏感级别的范围。
系统始终将 MLS 访问规则与传统的文件访问权限合并。例如,如果具有安全级别 "Secret" 的用户使用 Discretionary Access Control(DAC)来阻止其他用户对文件的访问,即使"Top Secret"用户无法访问该文件。较高的安全许可不会自动允许用户浏览整个文件系统。
拥有顶级别的用户不会自动获得多级系统的管理权限。虽然他们可以访问有关系统的所有敏感信息,但这与具有管理权限不同。
此外,管理权限不提供对敏感信息的访问权限。例如,即使某人以 root
身份登录,它们仍然无法读取 top-secret 信息。
您可以使用类别进一步调整 MLS 系统中的访问。使用多类别安全性(MCS),您可以定义项目或部门等类别,用户只能访问为其分配的类别中的文件。如需更多信息,请参阅 使用多类别 Security(MCS)获取数据保密性。
6.2. MLS 中的 SELinux 角色
SELinux 策略将每个 Linux 用户映射到 SELinux 用户。这允许 Linux 用户继承 SELinux 用户的限制。
MLS 策略不包含 unconfined
模块,包括无限制的用户、类型和角色。因此,用户将不受限制(包括 root
)的用户无法访问每个对象,并执行他们在目标策略中可以进行的每个操作。
您可以通过调整策略中的布尔值来自定义 SELinux 策略中受限用户的权限。您可以使用 semanage boolean -l
命令确定这些布尔值的当前状态。要列出所有 SELinux 用户、其 SELinux 角色和 MLS/MCS 级别和范围,以 root
用户身份使用 semanage user -l
命令。
User | 默认角色 | 其他角色 |
---|---|---|
|
| |
|
| |
|
| |
|
|
|
| ||
| ||
| ||
|
| |
|
|
|
| ||
| ||
| ||
|
|
请注意,system_u
是系统进程和对象的特殊用户身份,system_r
是关联的角色。管理员不得将这个 system_u
用户和 system_r
角色关联到 Linux 用户。另外,unconfined_u
和 root
是没有限制的用户。因此,与这些 SELinux 用户关联的角色不会包含在下表中 type 和 SELinux 角色的访问中。
每个 SELinux 角色都与 SELinux 类型对应,并提供特定的访问权限。
Role | Type | 使用 X 窗口系统登录 | su 和 sudo | 在主目录和 /tmp 中执行(默认) | Networking |
---|---|---|---|---|---|
|
| 否 | 否 | 是 | 否 |
|
| 是 | 否 | 是 | 仅限 Web 浏览器(Firefox、GNOME Web) |
|
| 是 | 否 | 是 | 是 |
|
| 是 |
仅 | 是 | 是 |
|
| 是 | 是 | 是 | |
|
| 是 | 是 | 是 | |
|
|
仅在 | 是 | 是 | 是 |
-
默认情况下,
sysadm_r
角色具有secadm_r
角色的权限,这意味着具有sysadm_r
角色的用户可以管理安全策略。如果这没有与您的用例对应,您可以通过在策略中禁用sysadm_secadm
模块来分离这两个角色。如需更多信息,请参阅 MLS 中的从安全管理分离系统管理。 -
非登录角色
dbadm_r
、logadm_r
和webadm_r
可用于管理任务的子集。默认情况下,这些角色不与任何 SELinux 用户关联。
6.3. 将 SELinux 策略切换到 MLS
使用以下步骤将 SELinux 策略从 targeted 切换到多级别安全(MLS)。
不要在运行 X 窗口系统的系统中使用 MLS 策略。另外,当您使用 MLS 标签重新标记文件系统时,系统可能会阻止受限制的域访问,这会阻止您的系统正确启动。因此请确定您在重新标记文件前将 SELinux 切换到 permissive 模式。在大多数系统中,您会看到在切换到 MLS 后出现了很多 SELinux 拒绝信息,且其中很多都不容易修复。
步骤
安装
selinux-policy-mls
软件包:# dnf install selinux-policy-mls
在您选择的文本编辑器中打开
/etc/selinux/config
文件,例如:# vi /etc/selinux/config
将 SELinux 模式从 enforcing 改为 permissive,并从 targeted 策略切换到 MLS:
SELINUX=permissive SELINUXTYPE=mls
保存更改,退出编辑器。
在启用 MLS 策略前,您必须使用 MLS 标签重新标记文件系统中的每个文件:
# fixfiles -F onboot System will relabel on next boot
重启系统:
# reboot
检查 SELinux 拒绝信息:
# ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent -i
因为前面的命令没有涵盖所有情况,请参阅 SELinux 故障排除中有关识别、分析以及修复 SELinux 拒绝的指导。
在确定您的系统中没有与 SELinux 相关的问题后,通过更改
/etc/selinux/config
中的对应选项将 SELinux 切换回 enforcing 模式:SELINUX=enforcing
重启系统:
# reboot
如果您的系统没有启动,或者您无法在切换到 MLS 后登录,请将 enforcing=0
参数添加到内核命令行。如需更多信息,请参阅在引导时更改 SELinux 模式。
另请注意,在 MLS 中,以 root
用户身份通过 SSH 登录映射到 sysadm_r
SELinux 角色,它与作为 staff_r
中的 root
登录不同。在 MLS 中首次启动系统前,请考虑通过将 ssh_sysadm_login
SELinux 布尔值设置为 1
来允许以 sysadm_r
身份登录 SSH 登录。要稍后才启用 ssh_sysadm_login
(已在 MLS 中),您需要在 staff_r
中以 root
身份登陆,使用 newrole -r sysadm_r
命令切换到 sysadm_r
中的 root
,然后将布尔值设置为 1
。
验证
验证 SELinux 是否在 enforcing 模式下运行:
# getenforce Enforcing
检查 SELinux 的状态是否返回
mls
值:# sestatus | grep mls Loaded policy name: mls
其他资源
-
fixfiles (8)
,setsebool (8)
, 和ssh_selinux (8)
man page
6.4. 在 MLS 中建立用户明确
将 SELinux 策略切换到 MLS 后,必须通过将 SELinux 策略映射到受限的 SELinux 用户来为用户分配安全清晰级别。默认情况下,具有给定安全许可的用户:
- 不能读取具有更高敏感度级别的对象。
- 无法写入具有不同敏感度级别的对象。
先决条件
-
SELinux 策略被设置为
mls
。 -
SELinux 模式设置为
enforcing
。 -
已安装
policycoreutils-python-utils
软件包。 分配给 SELinux 受限用户的用户:
-
对于非授权用户,分配给
user_u
(以下流程中的example_user )。 -
对于特权用户,分配给
staff_u
(以下流程中的 staff )。
-
对于非授权用户,分配给
确保 MLS 策略处于活动状态时已创建该用户。MLS 中无法使用在其他 SELinux 策略中创建的用户。
步骤
可选:要防止向 SELinux 策略添加错误,切换到
permissive
SELinux 模式,这有助于进行故障排除:# setenforce 0
请注意,在 permissive 模式中,SELinux 不强制执行活跃策略,而是只记录 Access Vector Cache (AVC)信息,然后可用于故障排除和调试。
为
staff_u
SELinux 用户定义清晰的范围。例如,这个命令会将安全权限范围设置为s1
到s15
,s1
是默认的安全权限级别:# semanage user -m -L s1 -r s1-s15 staff_u
为用户主目录生成 SELinux 文件上下文配置条目:
# genhomedircon
将文件安全上下文恢复到默认值:
# restorecon -R -F -v /home/ Relabeled /home/staff from staff_u:object_r:user_home_dir_t:s0 to staff_u:object_r:user_home_dir_t:s1 Relabeled /home/staff/.bash_logout from staff_u:object_r:user_home_t:s0 to staff_u:object_r:user_home_t:s1 Relabeled /home/staff/.bash_profile from staff_u:object_r:user_home_t:s0 to staff_u:object_r:user_home_t:s1 Relabeled /home/staff/.bashrc from staff_u:object_r:user_home_t:s0 to staff_u:object_r:user_home_t:s1
为用户分配安全权限级别:
# semanage login -m -r s1 example_user
其中
s1
是分配给用户的安全权限级别。将用户的主目录重新标记到用户的明确级别:
# chcon -R -l s1 /home/example_user
可选:如果您之前切换到
permissive
SELinux 模式,并在验证所有内容可以正常工作后,切换回enforcing
SELinux 模式:# setenforce 1
验证
验证用户是否已映射到正确的 SELinux 用户,并分配了正确的级别:
# semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ user_u s0-s0 * example_user user_u s1 * …
- 以 MLS 内的用户身份登录。
验证用户的安全级别是否正常工作:
警告如果配置不正确,您用于验证的文件不应包含任何敏感信息,并且用户实际上可以访问未经授权的文件。
- 验证用户无法读取具有更高级别敏感性的文件。
- 验证用户可以写入具有相同敏感级别的文件。
- 验证用户可以读取具有较低级别的敏感性的文件。
6.5. 在 MLS 中定义的安全范围内更改用户安全许可的级别
作为 MLS 中的用户,您可以在管理员分配给您的范围内更改当前的安全许可级别。您永远不会超过范围的上限,或将您的级别降到范围的下限以下。例如,您可以修改敏感级别低的文件,而不需要提高其敏感级别。
例如,用户的范围为 s1-s3
:
-
您可以将级别切换到
s1
、s2
和s3
。 -
您可以将范围切换到
s1-s2
和s2-s3
。 -
您不能将范围切换到
s0-s3
或s1-s4
。
切换到其他级别会打开一个新的、具有不同安全许可级别的 shell。这意味着,您无法按照降级的相同方式将您的级别恢复到原始的安全许可级别。但是,输入 exit
可以返回到之前的 shell。
先决条件
-
SELinux 策略被设置为
mls
。 -
SELinux 模式设置为
enforcing(强制)
模式。 - 您可以作为分配了一个 MLS 安全许可级别范围的用户身份登录。
流程
以用户身份从一个安全终端进行登录。
安全终端在
/etc/selinux/mls/contexts/securetty_types
文件中定义。默认情况下,控制台是一个安全终端,但 SSH 不是。检查当前用户的安全上下文:
$ id -Z user_u:user_r:user_t:s0-s2
在本例中,该用户被分配给
user_u
SELinux 用户、user_r
角色、user_t
类型,以及 MLS 安全范围s0-s2
。检查当前用户的安全上下文:
$ id -Z user_u:user_r:user_t:s1-s2
切换到用户安全许可范围内的不同安全许可范围:
$ newrole -l s1
您可以切换到任何范围,只要其最大级别低于或等于您被分配的范围的任何范围。输入单级别范围会更改所分配范围的较低限制。例如,输入
newrole -l s1
作为具有s0-s2
范围的用户,相当于输入newrole -l s1-s2
。
验证
显示当前用户的安全上下文:
$ id -Z user_u:user_r:user_t:s1-s2
通过终止当前 shell,返回到之前带有原始范围的 shell:
$ exit
其他资源
- 在 MLS 中建立用户明确
-
您系统上的
newrole (1)
和securetty_types (5)
手册页
6.6. 在 MLS 中增大文件敏感级别
默认情况下,MLS 用户无法增加文件敏感度级别。但是,安全管理员 (secadm_r
) 可以更改此默认行为,通过向系统 SELinux 策略添加本地模块 mlsfilewrite
来增加文件的敏感度。然后,分配至策略模块中定义的 SELinux 类型的用户可以通过修改文件来增加文件类别级别。每当用户修改文件时,文件的敏感度级别都会提高用户当前安全范围的值。
安全管理员以分配给 secadm_r
角色的用户身份登录时,可以使用 chcon -l s0 /path/to/file
命令更改文件的安全级别。如需更多信息,请参阅 MLS 中的更改文件敏感度。
先决条件
-
SELinux 策略被设置为
mls
。 -
SELinux 模式设置为
enforcing(强制)
模式。 -
已安装
policycoreutils-python-utils
软件包。 -
mlsfilewrite
local 模块安装在 SELinux MLS 策略中。 您以 MLS 中的用户登录,如下:
-
分配给定义的安全范围。本例演示了一个安全性范围为
s0-s2
的用户。 -
分配给
mlsfilewrite
模块中定义的同一 SELinux 类型。这个示例需要(typeattributeset mlsfilewrite (user_t))
模块。
-
分配给定义的安全范围。本例演示了一个安全性范围为
流程
可选:显示当前用户的安全上下文:
$ id -Z user_u:user_r:user_t:s0-s2
将用户的 MLS 安全许可范围的较低级别改为您要分配给该文件的级别:
$ newrole -l s1-s2
可选:显示当前用户的安全上下文:
$ id -Z user_u:user_r:user_t:s1-s2
可选:显示文件的安全上下文:
$ ls -Z /path/to/file user_u:object_r:user_home_t:s0 /path/to/file
通过修改该文件,将文件的敏感度级别改为用户安全许可的较低级别:
$ touch /path/to/file
重要如果系统上使用了
restorecon
命令,则分类级别恢复为默认值。可选:退出 shell 以返回到用户的前一个安全范围:
$ exit
验证
显示文件的安全上下文:
$ ls -Z /path/to/file user_u:object_r:user_home_t:s1 /path/to/file
其他资源
6.7. 在 MLS 中更改文件敏感度
在 MLS SELinux 策略中,用户只能修改自己的敏感度级别的文件。这是为了防止以较低明确的级别向用户公开任何高度敏感信息,同时防止不明确的用户创建高敏感文件。不过,管理员可以手动增加文件的分类,例如要在更高级别处理该文件。
先决条件
-
SELinux 策略设置为
mls
。 - SELinux 模式被设置为 enforcing。
您有安全管理权限,这意味着您要分配给其中之一:
-
secadm_r
角色。 -
如果启用了
sysadm_secadm
模块,进入sysadm_r
角色。sysadm_secadm
模块默认启用。
-
-
已安装
policycoreutils-python-utils
软件包。 分配给任何安全权限级别的用户。如需更多信息,请参阅 MLS 中建立用户清除级别。
在本例中,
User1
已有s1
级别的权限。分配了安全级别的、您有全访问的文件。
在本例中,
/path/to/file
具有级别s1
权限。
步骤
检查该文件的安全级别:
# ls -lZ /path/to/file -rw-r-----. 1 User1 User1 user_u:object_r:user_home_t:s1 0 12. Feb 10:43 /path/to/file
更改文件的默认安全级别:
# semanage fcontext -a -r s2 /path/to/file
强制重新标记文件的 SELinux 上下文:
# restorecon -F -v /path/to/file Relabeled /path/to/file from user_u:object_r:user_home_t:s1 to user_u:object_r:user_home_t:s2
验证
检查该文件的安全级别:
# ls -lZ /path/to/file -rw-r-----. 1 User1 User1 user_u:object_r:user_home_t:s2 0 12. Feb 10:53 /path/to/file
可选:验证具有较低级别权限的用户是否无法读取该文件:
$ cat /path/to/file cat: file: Permission denied
其他资源
6.8. 在 MLS 中将系统管理与安全管理分离
默认情况下,sysadm_r
角色具有 secadm_r
角色的权限,这意味着具有 sysadm_r
角色的用户可以管理安全策略。如果需要对安全授权进行更多控制,您可以通过将 Linux 用户分配给 secadm_r
角色并在 SELinux 策略中禁用 sysadm_secadm
模块将系统管理与安全管理分开。
先决条件
-
SELinux 策略被设置为
mls
。 -
SELinux 模式设置为
enforcing
。 -
已安装
policycoreutils-python-utils
软件包。 分配给
secadm_r
角色的 Linux 用户:-
该用户被分配给
staff_u
SELinux 用户 - 定义了此用户的密码。
警告确保您可以以用户 身份登录,这将分配给
secadm
角色。如果不能,您可以防止以后修改系统的 SELinux 策略。-
该用户被分配给
步骤
为用户在
/etc/sudoers.d
目录中创建一个新的sudoers
文件:# visudo -f /etc/sudoers.d/<sec_adm_user>
为保持
sudoers
文件的组织,请<sec_adm_user>
替换为将分配给secadm
角色的 Linux 用户。在
/etc/sudoers.d/<sec_adm_user>
文件中添加以下内容:<sec_adm_user> ALL=(ALL) TYPE=secadm_t ROLE=secadm_r ALL
此行授权所有主机上的
<secadmuser>
用户执行所有命令,并默认将用户映射到secadm
SELinux 类型和角色。以 < sec_adm_user> 用户身份登录。
为确保 SELinux 上下文(由 SELinux 用户、角色和类型组成),请使用
ssh
、控制台或xdm
进行登录。su
和sudo
等其他方法无法更改整个 SELinux 上下文。验证用户的安全上下文:
$ id uid=1000(<sec_adm_user>) gid=1000(<sec_adm_user>) groups=1000(<sec_adm_user>) context=staff_u:staff_r:staff_t:s0-s15:c0.c1023
为 root 用户运行交互式 shell:
$ sudo -i [sudo] password for <sec_adm_user>:
验证当前用户的安全上下文:
# id uid=0(root) gid=0(root) groups=0(root) context=staff_u:secadm_r:secadm_t:s0-s15:c0.c1023
从策略中禁用
sysadm_secadm
模块:# semodule -d sysadm_secadm
重要使用
semodule -d
命令,而不是使用semodule -r
命令删除系统策略模块。semodule -r
命令从您的系统存储中删除模块,这意味着无法重新安装selinux-policy-mls
软件包。
验证
作为分配给
secadm
角色的用户,并在 root 用户的交互式 shell 中验证您可以访问安全策略数据:# seinfo -xt secadm_t Types: 1 type secadm_t, can_relabelto_shadow_passwords, (…) userdomain;
从 root shell 注销:
# logout
登出
<sec_adm_user>
用户:$ logout Connection to localhost closed.
显示当前安全上下文:
# id uid=0(root) gid=0(root) groups=0(root) context=root:sysadm_r:sysadm_t:s0-s15:c0.c1023
尝试启用
sysadm_secadm
模块。该命令应该失败:# semodule -e sysadm_secadm SELinux: Could not load policy file /etc/selinux/mls/policy/policy.31: Permission denied /sbin/load_policy: Can't load policy: Permission denied libsemanage.semanage_reload_policy: load_policy returned error code 2. (No such file or directory). SELinux: Could not load policy file /etc/selinux/mls/policy/policy.31: Permission denied /sbin/load_policy: Can't load policy: Permission denied libsemanage.semanage_reload_policy: load_policy returned error code 2. (No such file or directory). semodule: Failed!
尝试显示有关
sysadm_t
SELinux 类型的详情。该命令应该失败:# seinfo -xt sysadm_t [Errno 13] Permission denied: '/sys/fs/selinux/policy'
6.9. 在 MLS 中定义安全终端
SELinux 策略会检查用户从中连接的终端类型,并允许运行某些 SELinux 应用程序,例如 newrole
,只从安全终端检查。从非安全终端尝试此操作会产生错误:Error: you are not allowed to change levels on a non secure terminal;
。
/etc/selinux/mls/contexts/securetty_types
文件定义了 MLS 策略的安全终端。
该文件的默认内容:
console_device_t sysadm_tty_device_t user_tty_device_t staff_tty_device_t auditadm_tty_device_t secureadm_tty_device_t
将终端类型添加到安全终端列表中,可使您的系统暴露于安全风险。
先决条件
-
SELinux 策略设置为
mls
。 - 您从安全的终端进行连接,或者 SELinux 处于 permissive 模式。
您有安全管理权限,这意味着您要分配给其中之一:
-
secadm_r
角色。 -
如果启用了
sysadm_secadm
模块,进入sysadm_r
角色。sysadm_secadm
模块默认启用。
-
-
已安装
policycoreutils-python-utils
软件包。
流程
确定当前的终端类型:
# ls -Z `tty` root:object_r:user_devpts_t:s0 /dev/pts/0
在本例中,
user_devpts_t
是当前的终端类型。-
在
/etc/selinux/mls/contexts/securetty_types
文件中的新行中添加相关的 SELinux 类型。 可选:将 SELinux 切换到 enforcing 模式:
# setenforce 1
验证
-
从之前不安全的终端中登录到
/etc/selinux/mls/contexts/securetty_types
文件。
其他资源
-
您系统上的
securetty_types (5)
手册页
6.10. 允许 MLS 用户在较低级别上编辑文件
默认情况下,MLS 用户无法写入在明确范围内低值下具有敏感等级的文件。如果您的场景需要允许用户在较低级别上编辑文件,可以通过创建本地 SELinux 模块来实现。但是,写入文件会使用户当前范围内的低值提高其敏感度级别。
先决条件
-
SELinux 策略被设置为
mls
。 -
SELinux 模式设置为
enforcing
。 -
已安装
policycoreutils-python-utils
软件包。 -
setools-console
和audit
软件包进行验证。
流程
可选:切换到 permissive 模式以方便故障排除。
# setenforce 0
使用文本编辑器打开新的
.cil
文件,如~/local_mlsfilewrite.cil
,并插入以下自定义规则:(typeattributeset mlsfilewrite (_staff_t_))
您可以将
staff_t
替换为不同的 SELinux 类型。通过在此处指定 SELinux 类型,您可以控制哪些 SELinux 角色可以编辑低级别文件。要让您的本地模块更好地组织,请在本地 SELinux 策略模块的名称中使用
local_
前缀。安装策略模块:
# semodule -i ~/local_mlsfilewrite.cil
注意要删除本地策略模块,请使用
semodule -r ~/local_mlsfilewrite
。请注意,您必须引用不带.cil
后缀的模块名称。可选:如果您之前切换到 permissive 模式,返回到 enforcing 模式:
# setenforce 1
验证
在安装的 SELinux 模块列表中找到本地模块:
# semodule -lfull | grep "local_mls" 400 local_mlsfilewrite cil
由于本地模块具有优先级
400
,所以您也可以使用semodule -lfull | grep -v ^100
命令列出它们。-
以分配给自定义规则中定义的类型的用户身份登录,例如
staff_t
。 尝试写入到具有较低敏感度级别的文件。这会将文件的分类级别增加到用户的安全许可级别。
重要如果配置不正确,您用于验证的文件不应包含任何敏感信息,并且用户实际上可以访问未经授权的文件。
第 7 章 使用多类别安全(MCS)进行数据保密性
您可以使用 MCS 通过分类数据来增强系统数据的机密性,然后授予某些进程和用户对特定类别的访问权限
7.1. 多类别安全性(MCS)
多类别 Security(MCS)是一个访问控制机制,它使用分配给进程和文件的类别。然后,文件只能由分配到相同类别的进程访问。MCS 的目的是维护您系统上的数据保密性。
MCS 类别由 c0
到 c1023
的值定义,但您也可以为每个类别或类别组合定义一个文本标签,如"Personnel"、"ProjectX"或"ProjectX.Personnel"。MCS 转换服务(mcstrans
)随后将 category 值替换为系统输入和输出中的相应标签,以便用户可以使用这些标签而不是 category 值。
当用户分配给类别时,他们可以为他们分配的任何类别标记其任何文件。
MCS 适用于一个简单的原则:要访问文件,必须将用户分配给分配给该文件的所有类别。MCS 检查在常规 Linux Discretionary Access Control(DAC)和 SELinux Type Enforcement(TE)规则后应用,因此它只能进一步限制现有的安全配置。
多级别安全中的 MCS
您可以将自己上的 MCS 用作非层次系统,也可以将其与多级别安全(MLS)结合使用,作为分层系统中的非层次结构层。
一个 MLS 中的 MCS 示例是,保密性科研组织,其中文件被分类如下:
安全级别 | 类别 | |||
未指定 | 项目 X | 项目 Y | 项目 Z | |
未分类 |
|
|
|
|
机密 |
|
|
|
|
Secret |
|
|
|
|
Top secret |
|
|
|
|
拥有范围 s0:c0.1023
的用户可以访问分配给 s0
级别的所有类别的所有文件,除非访问被其他安全机制禁止,如 DAC 或类型执行策略规则。
文件或进程生成的安全上下文是以下组合:
- SELinux 用户
- SELinux 角色
- SELinux 类型
- MLS 敏感度级别
- MCS 类别
例如,在 MLS/MCS 环境中具有访问级别 1 和类别 2 的非授权用户可能具有以下 SELinux 上下文:
user_u:user_r:user_t:s1:c2
其他资源
7.2. 为数据机密配置多类别安全性
默认情况下,Multi-Category Security (MCS)在 targeted
和 mls
SELinux 策略中处于活跃状态,但不会为用户配置。在 targeted
策略中,仅针对以下内容配置 MCS:
- OpenShift
- virt
- sandbox
- 网络标记
-
containers (
container-selinux
)
您可以通过创建本地 SELinux 模块并将 user_t
SELinux 类型限制在类型强制的情况下,将 MCS 规则配置为分类用户的 MCS 规则。
更改某些文件的类别可能会导致某些服务无法正常运行。如果您并不是相关系统的专家,请联系红帽销售代表并请求咨询服务。
先决条件
-
SELinux 模式设置为
enforcing(强制)
模式。 -
SELinux 策略被设置为
targeted
或mls
。 -
已安装
policycoreutils-python-utils
和setools-console
软件包。
步骤
创建一个新文件,例如名为
local_mcs_user.cil
:# vim local_mcs_user.cil
插入以下规则:
(typeattributeset mcs_constrained_type (user_t))
安装策略模块:
# semodule -i local_mcs_user.cil
验证
对于每个用户域,显示所有组件的更多详情:
# seinfo -xt user_t Types: 1 type user_t, application_domain_type, nsswitch_domain, corenet_unlabeled_type, domain, kernel_system_state_reader, mcs_constrained_type, netlabel_peer_type, privfd, process_user_target, scsi_generic_read, scsi_generic_write, syslog_client_type, pcmcia_typeattr_1, user_usertype, login_userdomain, userdomain, unpriv_userdomain, userdom_home_reader_type, userdom_filetrans_type, xdmhomewriter, x_userdomain, x_domain, dridomain, xdrawable_type, xcolormap_type;
其他资源
- 创建本地 SELinux 策略模块
- 有关容器上下文中的 MCS 的更多信息,请参阅博客文章 如何使用多级安全性实现 SELinux 独立的容器,并 为什么您应该为您的 Linux 容器使用多类别安全性。
7.3. 在 MCS 中定义类别标签
您可以通过编辑 setrans.conf
文件来管理和维护 MCS 类别标签,或使用 MLS 级别的 MCS 类别组合。在这个文件中,SELinux 在内部敏感度和类别级别及其人类可读标签之间保持映射。
类别标签只让用户更易于使用类别。无论您定义标签或是否定义标签,MCS 的效果都相同。
先决条件
-
SELinux 模式设置为
enforcing
。 -
SELinux 策略被设置为
targeted
或mls
。 -
已安装
policycoreutils-python-utils
和mcstrans
软件包。
步骤
通过编辑文本编辑器中的
/etc/selinux/<selinuxpolicy>/setrans.conf
文件来修改现有类别或创建新类别。根据您使用的 SELinux 策略,将 <selinuxpolicy> 替换为targeted
或mls
。例如:# vi /etc/selinux/targeted/setrans.conf
在策略的
setrans.conf
文件中,使用语法s_<security level>_:c_<category number>_=<category.name>
来定义您的场景所需的类别组合,例如:s0:c0=Marketing s0:c1=Finance s0:c2=Payroll s0:c3=Personnel
-
您可以使用
c0
到c1023
中的类别号。 -
在
targeted
策略中,使用s0
安全级别。 -
在
mls
策略中,您可以标记各个敏感度级别和类别的组合。
-
您可以使用
-
可选:在
setrans.conf
文件中,您还可以标记 MLS 敏感度级别。 - 保存并退出 文件。
要使更改有效,重启 MCS 翻译服务:
# systemctl restart mcstrans
验证
显示当前类别:
# chcat -L
上面的示例会产生以下输出:
s0:c0 Marketing s0:c1 Finance s0:c2 Payroll s0:c3 Personnel s0 s0-s0:c0.c1023 SystemLow-SystemHigh s0:c0.c1023 SystemHigh
其他资源
-
您系统上的
setrans.conf (5)
手册页
7.4. 为 MCS 中的用户分配类别
您可以通过为 Linux 用户分配类别来定义用户授权。分配了类别的用户可以访问和修改用户类别子集的文件。用户也可以为他们自己分配到的类别分配文件。
无法将 Linux 用户分配给在为相关 SELinux 用户定义的安全范围之外的类别。
类别访问权限在登录期间分配。因此,在用户再次登录前,用户无法访问新分配的类别。同样,如果您撤销了对类别的访问权限,这仅在用户再次登录后有效。
先决条件
-
SELinux 模式设置为
enforcing
。 -
SELinux 策略被设置为
targeted
或mls
。 -
已安装
policycoreutils-python-utils
软件包。 Linux 用户被分配给 SELinux 受限用户:
-
非特权用户将分配给
user_u
. -
特权用户被分配给
staff_u
。
-
非特权用户将分配给
步骤
定义 SELinux 用户的安全范围。
# semanage user -m -rs0:c0,c1-s0:c0.c9 <user_u>
使用
setrans.conf
文件中的类别号c0
到c1023
或 category 标签。如需更多信息,请参阅 MCS 中的定义类别标签。为 Linux 用户分配 MCS 类别。您只能指定相关 SELinux 用户定义的范围内的范围:
# semanage login -m -rs0:c1 <Linux.user1>
注意您可以使用
chcat
命令从 Linux 用户添加或删除类别。以下示例添加<category1>
并从<Linux.user1>
和<Linux.user2>
中删除<category2>
:# chcat -l -- +<category1>,-<category2> <Linux.user1>,<Linux.user2>
在使用
-<category>
语法前,您必须在命令行上指定--
。否则,chcat
命令会错误地将类别删除作为命令选项进行解译。
验证
列出分配给 Linux 用户的类别:
# chcat -L -l <Linux.user1>,<Linux.user2> <Linux.user1>: <category1>,<category2> <Linux.user2>: <category1>,<category2>
其他资源
-
系统中
chcat (8)
手册页
7.5. 为 MCS 中的文件分配类别
您需要具有管理特权才能为用户分配类别。然后用户可以为文件分配类别。要修改文件的类别,用户必须拥有该文件的访问权限。用户只能为为其分配的类别分配一个文件。
系统将类别访问规则与传统的文件访问权限合并。例如,如果具有 bigfoot
类别的用户使用 Discretionary Access Control(DAC)来阻止其他用户对文件的访问,则其他 bigfoot
用户可以访问该文件。分配给所有可用类别的用户仍无法访问整个文件系统。
先决条件
-
SELinux 模式设置为
enforcing
。 -
SELinux 策略被设置为
targeted
或mls
。 -
已安装
policycoreutils-python-utils
软件包。 对 Linux 用户的访问权限和权限:
- 分配给 SELinux 用户。
- 分配给要为其分配该文件的类别。如需更多信息,请参阅 MCS 中的用户分配类别。
- 访问您要添加到该类别中的文件的访问权限和权限。
- 为进行验证:对尚未分配给此类别的 Linux 用户访问和权限
步骤
为文件添加类别:
$ chcat -- +<category1>,+<category2> <path/to/file1>
使用
setrans.conf
文件中的类别号c0
到c1023
或 category 标签。如需更多信息,请参阅 MCS 中的定义类别标签。您可以使用相同的语法从文件中删除类别:
$ chcat -- -<category1>,-<category2> <path/to/file1>
注意删除类别时,必须在使用
-<category>
语法前在命令行中指定--
。否则,chcat
命令会错误地将类别删除作为命令选项进行解译。
验证
显示文件的安全上下文,以验证它具有正确的类别:
$ ls -lZ <path/to/file> -rw-r--r-- <LinuxUser1> <Group1> root:object_r:user_home_t:_<sensitivity>_:_<category>_ <path/to/file>
文件的特定安全上下文可能有所不同。
可选:当作为未分配给与该文件相同的类别的 Linux 用户登录时,尝试访问该文件:
$ cat <path/to/file> cat: <path/to/file>: Permission Denied
其他资源
-
系统中
semanage (8)
和chcat (8)
手册页
第 8 章 编写自定义 SELinux 策略
要运行受 SELinux 限制的应用程序,您必须编写和使用自定义策略。
8.2. 为自定义应用程序创建并强制 SELinux 策略
您可以通过 SELinux 限制应用程序,来提高主机系统和用户数据的安全性。因为每个应用程序都有特定的要求,因此根据您的用例,为创建限制一个简单守护进程的 SELinux 策略修改这个流程示例。
先决条件
-
selinux-policy-devel
软件包及其依赖项已安装在您的系统上。
步骤
在本例中,准备一个简单的守护进程,它将打开
/var/log/messages
文件进行写入:创建一个新文件,然后在您选择的文本编辑器中打开:
$ vi mydaemon.c
插入以下代码:
#include <unistd.h> #include <stdio.h> FILE *f; int main(void) { while(1) { f = fopen("/var/log/messages","w"); sleep(5); fclose(f); } }
编译文件:
$ gcc -o mydaemon mydaemon.c
为您的守护进程创建一个
systemd
单元文件:$ vi mydaemon.service [Unit] Description=Simple testing daemon [Service] Type=simple ExecStart=/usr/local/bin/mydaemon [Install] WantedBy=multi-user.target
安装并启动守护进程:
# cp mydaemon /usr/local/bin/ # cp mydaemon.service /usr/lib/systemd/system # systemctl start mydaemon # systemctl status mydaemon ● mydaemon.service - Simple testing daemon Loaded: loaded (/usr/lib/systemd/system/mydaemon.service; disabled; vendor preset: disabled) Active: active (running) since Sat 2020-05-23 16:56:01 CEST; 19s ago Main PID: 4117 (mydaemon) Tasks: 1 Memory: 148.0K CGroup: /system.slice/mydaemon.service └─4117 /usr/local/bin/mydaemon May 23 16:56:01 localhost.localdomain systemd[1]: Started Simple testing daemon.
检查新守护进程是否没有被 SELinux 限制:
$ ps -efZ | grep mydaemon system_u:system_r:unconfined_service_t:s0 root 4117 1 0 16:56 ? 00:00:00 /usr/local/bin/mydaemon
为守护进程生成自定义策略:
$ sepolicy generate --init /usr/local/bin/mydaemon Created the following files: /home/example.user/mysepol/mydaemon.te # Type Enforcement file /home/example.user/mysepol/mydaemon.if # Interface file /home/example.user/mysepol/mydaemon.fc # File Contexts file /home/example.user/mysepol/mydaemon_selinux.spec # Spec file /home/example.user/mysepol/mydaemon.sh # Setup Script
使用上一命令创建的设置脚本使用新策略模块重建系统策略:
# ./mydaemon.sh Building and Loading Policy + make -f /usr/share/selinux/devel/Makefile mydaemon.pp Compiling targeted mydaemon module Creating targeted mydaemon.pp policy package rm tmp/mydaemon.mod.fc tmp/mydaemon.mod + /usr/sbin/semodule -i mydaemon.pp ...
请注意,设置脚本使用
restorecon
命令重新标记文件系统的对应部分:restorecon -v /usr/local/bin/mydaemon /usr/lib/systemd/system
重启守护进程,检查它现在被 SELinux 限制:
# systemctl restart mydaemon $ ps -efZ | grep mydaemon system_u:system_r:mydaemon_t:s0 root 8150 1 0 17:18 ? 00:00:00 /usr/local/bin/mydaemon
由于守护进程现在受 SELinux 限制,SELinux 也阻止它访问
/var/log/messages
。显示对应的拒绝信息:# ausearch -m AVC -ts recent ... type=AVC msg=audit(1590247112.719:5935): avc: denied { open } for pid=8150 comm="mydaemon" path="/var/log/messages" dev="dm-0" ino=2430831 scontext=system_u:system_r:mydaemon_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1 ...
您还可以使用
sealert
工具获取更多信息:$ sealert -l "*" SELinux is preventing mydaemon from open access on the file /var/log/messages. ***** Plugin catchall (100. confidence) suggests ************************** If you believe that mydaemon should be allowed open access on the messages file by default. Then you should report this as a bug. You can generate a local policy module to allow this access. Do allow this access for now by executing: # ausearch -c 'mydaemon' --raw | audit2allow -M my-mydaemon # semodule -X 300 -i my-mydaemon.pp Additional Information: Source Context system_u:system_r:mydaemon_t:s0 Target Context unconfined_u:object_r:var_log_t:s0 Target Objects /var/log/messages [ file ] Source mydaemon …
使用
audit2allow
工具推荐更改:$ ausearch -m AVC -ts recent | audit2allow -R require { type mydaemon_t; } #============= mydaemon_t ============== logging_write_generic_logs(mydaemon_t)
因为
audit2allow
建议的规则在某些情况下可能不正确,所以只使用其输出的一部分来查找对应的策略接口。使用macro-expander
工具检查logging_write_generic_logs(mydaemon_t)
宏,以查看宏提供的所有允许规则:$ macro-expander "logging_write_generic_logs(mydaemon_t)" allow mydaemon_t var_t:dir { getattr search open }; allow mydaemon_t var_log_t:dir { getattr search open read lock ioctl }; allow mydaemon_t var_log_t:dir { getattr search open }; allow mydaemon_t var_log_t:file { open { getattr write append lock ioctl } }; allow mydaemon_t var_log_t:dir { getattr search open }; allow mydaemon_t var_log_t:lnk_file { getattr read };
在这种情况下,您可以使用推荐的接口,因为它只提供对日志文件及其父目录的读写访问。在您的类型强制文件中添加对应的规则:
$ echo "logging_write_generic_logs(mydaemon_t)" >> mydaemon.te
另外,您可以添加这个规则而不是使用接口:
$ echo "allow mydaemon_t var_log_t:file { open write getattr };" >> mydaemon.te
重新安装策略:
# ./mydaemon.sh Building and Loading Policy + make -f /usr/share/selinux/devel/Makefile mydaemon.pp Compiling targeted mydaemon module Creating targeted mydaemon.pp policy package rm tmp/mydaemon.mod.fc tmp/mydaemon.mod + /usr/sbin/semodule -i mydaemon.pp ...
验证
检查您的应用程序是否受 SELinux 限制,例如:
$ ps -efZ | grep mydaemon system_u:system_r:mydaemon_t:s0 root 8150 1 0 17:18 ? 00:00:00 /usr/local/bin/mydaemon
验证您的自定义应用程序不会导致任何 SELinux 拒绝:
# ausearch -m AVC -ts recent <no matches>
其他资源
-
sepolgen (8)
,ausearch (8)
,audit2allow (1)
,audit2why (1)
,sealert (8)
, 和restorecon (8)
man page - 快速编写自定义 SELinux 策略 知识库文章
8.3. 其他资源
第 9 章 为容器创建 SELinux 策略
Red Hat Enterprise Linux 9 使用 udica
软件包提供为容器生成 SELinux 策略的工具。通过 udica
,您可以创建一个定制的安全策略来更好地控制容器如何访问主机系统资源,如存储、设备和网络。这可让强化容器部署以避免出现安全问题,并简化了规范合规性的实现和维护。
9.1. udica SELinux 策略生成器介绍
为了简化为自定义容器创建新 SELinux 策略,RHEL 9 提供了 udica
工具。您可以使用此工具基于容器的 JavaScript Object Notation(JSON)文件创建策略,该文件包含 Linux 功能、挂载点和端口定义。因此,该工具将使用检查结果生成的规则与从指定 SELinux 通用中间语言(CIL)块继承的规则合并。
使用 udica
为容器生成 SELinux 策略的过程有三个主要部分:
- 以 JSON 格式解析容器规格文件
- 根据第一部分的结果查找合适的允许规则
- 生成最终 SELinux 策略
在解析阶段,udica
会查找 Linux 功能、网络端口和挂载点。
根据结果,udica
检测到容器需要哪些 Linux 功能,并创建一个允许所有这些功能的 SELinux 规则。如果容器绑定到一个特定端口,udica
使用 SELinux 用户空间库来获取通过检查容器使用的端口的正确 SELinux 标签。
之后,udica
检测到哪些目录被挂载到主机中的容器文件系统名称空间中。
CIL 的块继承功能允许 udica
创建 SELinux 模板,允许规则专注于特定操作,例如:
- 允许访问主目录
- 允许访问日志文件
- 允许访问与 Xserver 的通讯。
这些模板称为块,最终 SELinux 策略通过合并这些块来创建。
9.2. 为自定义容器创建和使用 SELinux 策略
要为自定义容器生成 SELinux 安全策略,请按照以下步骤执行。
先决条件
-
已安装用于管理容器的
podman
工具。如果没有,使用dnf install podman
命令。 - 一个自定义 Linux 容器 - 本例中是 ubi8。
步骤
安装
udica
软件包:# dnf install -y udica
或者,安装
container-tools
模块,它提供一组容器软件包,包括udica
:# dnf module install -y container-tools
启动 ubi8 容器,它使用只读权限挂载
/home
目录,以及具有读取和写入的权限的/var/spool
目录。容器会公开端口 21。# podman run --env container=podman -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it ubi8 bash
请注意,现在容器使用
container_t
SELinux 类型运行。这个类型是 SELinux 策略中所有容器的通用域。针对于您的具体情况,这可能太严格或太宽松。打开一个新终端,并输入
podman ps
命令以获取容器的 ID:# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 37a3635afb8f registry.access.redhat.com/ubi8:latest bash 15 minutes ago Up 15 minutes ago heuristic_lewin
创建容器 JSON 文件,并使用
udica
根据 JSON 文件中的信息创建策略模块:# podman inspect 37a3635afb8f > container.json # udica -j container.json my_container Policy my_container with container id 37a3635afb8f created! […]
或者:
# podman inspect 37a3635afb8f | udica my_container Policy my_container with container id 37a3635afb8f created! Please load these modules using: # semodule -i my_container.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil} Restart the container with: "--security-opt label=type:my_container.process" parameter
如上一步中的
udica
输出所建议,加载策略模块:# semodule -i my_container.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil}
停止容器并使用
--security-opt label=type:my_container.process
选项再次启动它:# podman stop 37a3635afb8f # podman run --security-opt label=type:my_container.process -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it ubi8 bash
验证
检查容器使用
my_container.process
类型运行:# ps -efZ | grep my_container.process unconfined_u:system_r:container_runtime_t:s0-s0:c0.c1023 root 2275 434 1 13:49 pts/1 00:00:00 podman run --security-opt label=type:my_container.process -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it ubi8 bash system_u:system_r:my_container.process:s0:c270,c963 root 2317 2305 0 13:49 pts/0 00:00:00 bash
验证 SELinux 现在允许访问
/home
和/var/spool
挂载点:[root@37a3635afb8f /]# cd /home [root@37a3635afb8f home]# ls username [root@37a3635afb8f ~]# cd /var/spool/ [root@37a3635afb8f spool]# touch test [root@37a3635afb8f spool]#
检查 SELinux 是否只允许绑定到端口 21:
[root@37a3635afb8f /]# dnf install nmap-ncat [root@37a3635afb8f /]# nc -lvp 21 … Ncat: Listening on :::21 Ncat: Listening on 0.0.0.0:21 ^C [root@37a3635afb8f /]# nc -lvp 80 … Ncat: bind to :::80: Permission denied. QUITTING.
其他资源
-
系统中的
udica (8)
和podman (1)
手册页 - udica - 为容器生成 SELinux 策略
- 构建、运行和管理容器
第 10 章 在多个系统中部署相同的 SELinux 配置
您可以使用以下方法之一在多个系统上部署验证的 SELinux 配置:
- 使用 RHEL 系统角色和 Ansible
- 使用 RHEL web 控制台
-
在脚本中使用
semanage
导出和导入命令
10.1. selinux
RHEL 系统角色简介
RHEL 系统角色是 Ansible 角色和模块的集合,为远程管理多个 RHEL 系统提供一致的配置接口。您可以使用 selinux
RHEL 系统角色执行以下操作:
- 清理与 SELinux 布尔值、文件上下文、端口和登录相关的本地策略修改。
- 设置 SELinux 策略布尔值、文件上下文、端口和登录。
- 在指定文件或目录中恢复文件上下文。
- 管理 SELinux 模块。
rhel-system-roles
软件包安装的 /usr/share/doc/rhel-system-roles/selinux/example-selinux-playbook.yml
示例 playbook 演示了如何在 enforcing 模式下设置目标策略。playbook 还应用多个本地策略修改,并在 /tmp/test_dir/
目录中恢复文件上下文。
其他资源
-
/usr/share/ansible/roles/rhel-system-roles.selinux/README.md
file -
/usr/share/doc/rhel-system-roles/selinux/
directory
10.2. 使用 selinux
RHEL 系统角色在多个系统中应用 SELinux 设置
使用 selinux
RHEL 系统角色,您可以使用验证的 SELinux 设置准备并应用 Ansible playbook。
先决条件
- 您已准备好控制节点和受管节点
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
用于连接到受管节点的帐户具有
sudo
权限。
流程
准备您的 playbook。您可以从头开始,或修改作为
rhel-system-roles
软件包的一部分安装的示例 playbook:# cp /usr/share/doc/rhel-system-roles/selinux/example-selinux-playbook.yml <my-selinux-playbook.yml> # vi <my-selinux-playbook.yml>
更改 playbook 的内容,使其适合您的场景。例如,以下部分确保系统安装并启用
selinux-local-1.pp
SELinux 模块:selinux_modules: - { path: "selinux-local-1.pp", priority: "400" }
- 保存更改,然后退出文本编辑器。
验证 playbook 语法:
$ ansible-playbook <my-selinux-playbook.yml> --syntax-check
请注意,这个命令只验证语法,不会防止错误但有效的配置。
运行您的 playbook:
$ ansible-playbook <my-selinux-playbook.yml>
其他资源
-
/usr/share/ansible/roles/rhel-system-roles.selinux/README.md
file -
/usr/share/doc/rhel-system-roles/selinux/
directory - 使用 Ansible 的 SELinux 强化 知识库文章
10.3. 使用 selinux
RHEL 系统角色管理端口
您可以使用 selinux
RHEL 系统角色在多个系统中自动管理 SELinux 中的端口访问。例如,在将 Apache HTTP 服务器配置为侦听不同端口时,这可能很有用。您可以使用 selinux
RHEL 系统角色创建一个 playbook,将 http_port_t
SELinux 类型分配给特定的端口号。在受管节点上运行 playbook 后,SELinux 策略中定义的特定服务可以访问此端口。
您可以使用 seport
模块在 SELinux 中自动管理端口访问,这比使用整个角色更快,或者使用 selinux
RHEL 系统角色,在对 SELinux 配置进行其他更改时,这更为有用。这个方法等同于 selinux
RHEL 系统角色在配置端口时使用 seport
模块。每个方法都与在受管节点上输入 semanage port -a -t http_port_t -p tcp < port_number>
命令的影响相同。
先决条件
- 您已准备好控制节点和受管节点
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
用于连接到受管节点的帐户具有
sudo
权限。 -
可选:要使用
semanage
命令验证端口状态,必须安装policycoreutils-python-utils
软件包。
流程
要在不进行其他更改的情况下只配置端口号,请使用
seport
模块:- name: Allow Apache to listen on tcp port <port_number> community.general.seport: ports: <port_number> proto: tcp setype: http_port_t state: present
将
<port_number
> 替换为您要为其分配http_port_t
类型的端口号。对于涉及其他 SELinux 自定义的受管节点的更复杂的配置,请使用
selinux
RHEL 系统角色。创建一个 playbook 文件,如~/playbook.yml
,并添加以下内容:--- - name: Modify SELinux port mapping example hosts: all vars: # Map tcp port <port_number> to the 'http_port_t' SELinux port type selinux_ports: - ports: <port_number> proto: tcp setype: http_port_t state: present tasks: - name: Include selinux role ansible.builtin.include_role: name: rhel-system-roles.selinux
将
<port_number
> 替换为您要为其分配http_port_t
类型的端口号。
验证
验证端口是否已分配给
http_port_t
类型:# semanage port --list | grep http_port_t http_port_t tcp <port_number>, 80, 81, 443, 488, 8008, 8009, 8443, 9000
其他资源
-
/usr/share/ansible/roles/rhel-system-roles.selinux/README.md
file -
/usr/share/doc/rhel-system-roles/selinux/
directory
10.4. 在 web 控制台中创建一个 SELinux 配置 Ansible playbook
在 Web 控制台中,您可以生成一个 shell 脚本或一个 SELinux 配置的 Ansible playbook。如果是 Ansible playbook,您可以在多个系统上方便地应用配置。
先决条件
已安装 RHEL 9 web 控制台。
具体步骤请参阅安装并启用 Web 控制台。
步骤
登录到 RHEL 9 web 控制台。
详情请参阅 登录到 web 控制台。
- 点 SELinux。
点
。此时会打开一个带有生成的脚本的窗口。您可以在 shell 脚本页和 Ansible playbook 生成选项页之间转换。
- 点 按钮选择脚本或 playbook 并应用它。
因此,您有一个可应用到更多机器的自动脚本。
其他资源
- 故障排除与 SELinux 相关的问题
- 在多个系统中部署相同的 SELinux 配置
-
系统上的
ansible-playbook (1)
手册页
10.5. 使用 semanage 将 SELinux 设置传送到另一个系统中
使用以下步骤在基于 RHEL 9 的系统间传输自定义和验证的 SELinux 设置。
先决条件
-
policycoreutils-python-utils
软件包安装在您的系统中。
步骤
导出验证的 SELinux 设置:
# semanage export -f ./my-selinux-settings.mod
使用设置将该文件复制到新系统:
# scp ./my-selinux-settings.mod new-system-hostname:
登录新系统:
$ ssh root@new-system-hostname
在新系统中导入设置:
new-system-hostname# semanage import -f ./my-selinux-settings.mod
其他资源
-
系统中
semanage-export (8)
和semanage-import (8)
手册页
第 11 章 配置 polyinstantiated 目录
默认情况下,所有程序、服务和用户使用 /tmp
、/var/tmp
以及主目录进行临时存储。这使得这些目录容易受到基于文件名的竞争条件攻击和信息泄漏的影响。您可以使 /tmp/
、
和主目录实例化,使它们不再在所有用户之间共享,并且每个用户的 /var/tmp
//tmp-inst
和 /var/tmp/tmp-inst
单独挂载到 /tmp
和 /var/tmp 目录。
步骤
在 SELinux 中启用 polyinstantiation:
# setsebool -P allow_polyinstantiation 1
您可以通过输入
getsebool allow_polyinstantiation
命令来验证在 SELinux 中是否启用了 polyinstantiation。使用所需权限在重启后为数据持久性创建目录结构:
# mkdir /tmp-inst /var/tmp/tmp-inst --mode 000
恢复整个安全上下文,包括 SELinux 用户部分:
# restorecon -Fv /tmp-inst /var/tmp/tmp-inst Relabeled /tmp-inst from unconfined_u:object_r:default_t:s0 to system_u:object_r:tmp_t:s0 Relabeled /var/tmp/tmp-inst from unconfined_u:object_r:tmp_t:s0 to system_u:object_r:tmp_t:s0
如果您的系统使用
fapolicyd
应用程序控制框架,在/etc/
配置文件中启用fapolicyd
/fapolicyd.confallow_filesystem_mark
选项,允许 fapolicyd 监控底层文件系统上的文件访问事件。allow_filesystem_mark = 1
启用实例化
/tmp
、/var/tmp/
和用户主目录:重要使用
/etc/security/namespace.conf
而不是单独的文件在/etc/security/namespace.d/
目录中,因为pam_namespace_helper
程序不会读取/etc/security/namespace.d
中的附加文件。在具有多级别安全性(MLS)的系统上,取消注释
/etc/security/namespace.conf
文件中的最后三行:/tmp /tmp-inst/ level root,adm /var/tmp /var/tmp/tmp-inst/ level root,adm $HOME $HOME/$USER.inst/ level
在没有多级别安全(MLS)的系统上,在
/etc/security/namespace.conf
文件中添加以下行:/tmp /tmp-inst/ user root,adm /var/tmp /var/tmp/tmp-inst/ user root,adm $HOME $HOME/$USER.inst/ user
验证
pam_namespace.so
模块是否已为会话配置:$ grep namespace /etc/pam.d/login session required pam_namespace.so
可选:启用云用户使用 SSH 密钥访问系统:
-
安装
openssh-keycat
软件包。 在
/etc/ssh/sshd_config.d/
目录中创建一个包含以下内容的文件:AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat AuthorizedKeysCommandRunAs root
通过检查
sshd_config
中的PubkeyAuthentication
变量设为yes
,验证是否启用了公钥身份验证。默认情况下,Pub
keyAuthentication 设置为 yes,即使sshd_config
中的行被注释掉也是如此。$ grep -r PubkeyAuthentication /etc/ssh/ /etc/ssh/sshd_config:#PubkeyAuthentication yes
-
安装
在
会话包含 system-auth
行后,将所需的 pam_namespace.so unmnt_remnt/etc/pam.d/su
、/etc/pam.d/sudo
、/etc/pam.d/ssh
中,以及/etc/pam.d/sshd
:[...] session include system-auth session required pam_namespace.so unmnt_remnt [...]
验证
- 以非 root 用户身份登录。在配置了 polyinstantiation 之前登录的用户必须注销并登录,然后才能使它们生效。
检查
/tmp/
目录是否已挂载到/tmp-inst/
下:$ findmnt --mountpoint /tmp/ TARGET SOURCE FSTYPE OPTIONS /tmp /dev/vda1[/tmp-inst/<user>] xfs rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
SOURCE
输出会根据您的环境的不同而有所不同。在 virutal 系统上,它会显示/dev/vda_<number>_
。在裸机系统中,它会显示/dev/sda_<number>_
或/dev/nvme*
其他资源
-
/usr/share/doc/pam-docs/txts/README.pam_namespace
readme 文件随pam-docs
软件包安装。