SELinux(Security-Enhanced Linux,强制访问控制增强的 Linux)是一个工作在传统 Linux 自主访问控制(DAC)之上的额外安全层。大多数 VPS 管理员会完全禁用 SELinux,因为他们不理解它的工作方式,但如果正确实施,SELinux 是一个强大的 Linux 级保护机制,可以显著降低未授权访问的风险。本指南教您如何在 CentOS Stream、Rocky Linux 或 AlmaLinux 上正确配置 SELinux,在发生拒绝错误时进行故障排查,并使用 audit2allow 创建针对性策略,而不是完全禁用 SELinux。
简而言之: SELinux 是一个工作在标准 Linux 权限之上的安全层。它有三种模式:Enforcing(主动阻止违规,最安全)、Permissive(仅记录日志)和 Disabled(完全关闭)。为了防止应用程序中断同时保持安全性,应检查审计日志并使用 audit2allow 创建策略,仅授予必要的权限。永远不要只是禁用 SELinux。
SELinux 是什么,与标准 Linux 权限有什么不同
传统的 Linux 使用自主访问控制(DAC),仅基于用户和组所有权来控制访问。例如,如果文件 /var/www/html/index.php 由 root 拥有,运行为 www-data 用户的 Apache 进程无法读取它。但是,如果 Apache 被攻击并被破坏,攻击者将获得 www-data 拥有的所有权限,包括访问 www-data 可以到达的任何文件。这就是传统权限模型的局限性所在。
SELinux 添加了一个第二层,称为强制访问控制(MAC),它独立于 DAC 权限运行。SELinux 不仅仅限制基于用户/组成员资格的访问,而是为每个进程和文件分配"角色"和"上下文"。例如,Apache 可能运行上下文"httpd_t",网络文件可能有上下文"httpd_sys_content_t"。SELinux 内核将只允许 httpd_t 读取标记为 httpd_sys_content_t 的文件,无论 www-data 拥有什么其他权限。即使 Apache 存在漏洞并被破坏,攻击者也无法访问 SELinux 策略禁止的文件。
小贴士: 将 SELinux 视为"服务器级防火墙"或附加检查点。标准 DAC 权限就像"身份验证"(证明你是谁),但 SELinux 是"授权层"(验证根据系统策略你应该被允许执行此操作)。
SELinux 的三种模式
SELinux 在三种不同的模式下运行。
- Enforcing: SELinux 主动强制执行策略。如果进程尝试执行策略禁止的操作,SELinux 会拒绝该操作并记录违规。这不是警告模式——操作实际上被阻止了。Enforcing 模式提供最大安全性,但如果策略没有授予足够的权限,可能会破坏应用程序。
- Permissive: SELinux 记录违规但不强制执行。任何违反策略的操作都被允许进行,但详情被记录在审计日志中。Permissive 模式对于测试和故障排查很有用,当你想看到进程在尝试做什么而又不用担心被阻止时。
- Disabled: SELinux 完全关闭,没有检查或日志记录。如果你设置此模式,必须重启 VPS 才能重新启用 SELinux(从禁用更改为启用需要重新标记所有文件,这需要大量时间)。
检查当前 SELinux 状态
在进行任何更改之前,使用 getenforce 检查 VPS 上的当前 SELinux 状态
getenforce
此命令返回单行:Enforcing、Permissive 或 Disabled。有关更详细的信息,请使用 sestatus
sestatus
输出显示当前模式、活动策略、文件上下文信息等。有关更多详情,请添加 -v 标志
sestatus -v
改变 SELinux 模式
要临时改变 SELinux 模式(直到下次重启),使用 setenforce
setenforce 0
以上命令将 SELinux 设置为 Permissive 模式(0 = Permissive,1 = Enforcing)。此更改仅是临时的。要使更改持久,需要以 root 身份编辑 /etc/selinux/config
sudo nano /etc/selinux/config
找到以 SELINUX= 开头的行并设置所需的值
SELINUX=enforcing
有效值为 enforcing、permissive 或 disabled。如果你从 disabled 改为 enforcing 或 permissive,必须重启,因为系统需要重新标记所有文件。
注意: 当从 disabled 改为 enforcing 或 permissive 时,系统必须重新标记每个文件(扫描所有文件以分配正确的上下文)。此过程可能需要数小时,具体取决于数据量。在 enforcing 模式下进行重新标记期间,某些服务可能被阻止或崩溃。请仔细规划此更改。
理解 SELinux 上下文
SELinux 上下文的格式为 user:role:type:level。对于正常操作,最重要的部分是类型(分类)。网络文件的典型上下文如下所示
httpd_sys_content_t
Apache 进程本身的上下文
httpd_t
要查看文件具有什么上下文,使用带 -Z 标志的 ls
ls -Z /var/www/html/index.php
要查看运行中进程的上下文
ps auxZ | grep httpd
输出显示分配给每个运行中进程的上下文。
常见 SELinux 命令
chcon - 改变文件上下文
要改变文件或目录的上下文,使用 chcon(change context)
chcon -t httpd_sys_rw_content_t /var/www/html/uploads/
-t 标志表示仅改变类型。上面的命令将 uploads 目录的类型改为 httpd_sys_rw_content_t,允许 Apache 读写其中的文件。
要递归地改变目录及其内部所有文件的上下文,添加 -R 标志
chcon -Rt httpd_sys_rw_content_t /var/www/html/uploads/
restorecon - 恢复默认上下文
如果你错误地改变了上下文或需要将文件恢复到其策略定义的默认值,使用 restorecon
restorecon -v /var/www/html/
此命令根据 SELinux 策略读取应该是什么上下文,然后调整文件以匹配。-v 标志显示详细输出(哪些文件被改变)。
要递归地更新目录及其所有内容的上下文
restorecon -Rv /var/www/html/
semanage - 管理策略和上下文
semanage 是管理 SELinux 策略的主要工具。常见用例是为目录永久定义上下文
semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/uploads(/.*)?"
这告诉 SELinux,/var/www/html/uploads 及其内部的所有文件和目录应该永久具有上下文 httpd_sys_rw_content_t。设置后,运行 restorecon 将其应用于现有文件
restorecon -Rv /var/www/html/uploads/
SELinux 布尔值
SELinux 包含称为布尔值的设置,用于控制策略行为的特定方面。一个重要示例是 httpd_can_network_connect,它允许 Apache 建立出站网络连接(对于连接到外部数据库、API 或服务的应用程序来说很必要)。
要查看所有可用的布尔值及其当前状态
getsebool -a
要启用特定的布尔值
setsebool -P httpd_can_network_connect on
-P 标志使更改在重启后保持不变。没有 -P,重启后设置会丢失。
真实场景:Apache 无法连接到数据库
假设你设置了一个新的 Rocky Linux VPS,安装了 Apache,并运行一个 PHP 网络应用程序,它连接到另一台服务器上的 MySQL。如果 SELinux 设置为 Enforcing,当应用程序尝试连接数据库时,你可能会收到"连接被拒绝"或超时错误,即使防火墙规则和 Linux 权限都正确。
要验证 SELinux 是否是原因,临时改为 Permissive 模式以记录违规而不阻止它们
sudo setenforce 0
然后再次访问网络应用程序并触发数据库操作。如果现在能正常工作并显示数据库中的数据,那么 SELinux 肯定是问题的原因。
使用审计日志查找问题
当 SELinux 拒绝一个操作时,它将详情记录到 /var/log/audit/audit.log。要查看最近的拒绝条目
tail -30 /var/log/audit/audit.log | grep denied
拒绝行看起来像这样
type=AVC msg=audit(1625126789.123:456): avc: denied { connect } for pid=1234 comm="apache" saddr=192.168.1.1 sport=12345 daddr=10.0.0.2 dport=3306
这显示 Apache(PID 1234)尝试创建到 10.0.0.2:3306(MySQL)的网络连接,但被 SELinux 阻止。为了更容易阅读,使用 ausearch
ausearch -m AVC -ts recent | head -30
-m AVC 标志搜索 AVC 消息类型,-ts recent 只查找最近的事件。
使用 audit2allow 创建策略
不要完全禁用 SELinux,而是使用 audit2allow 生成策略来授予必要的权限。首先,安装所需的软件包
sudo yum install -y audit policycoreutils-python-utils
然后通过读取审计日志拒绝生成策略模块
sudo audit2allow -a -M myapp
-a 标志表示处理审计日志中所有未处理的拒绝,-M 创建一个名为 myapp 的模块。这生成 myapp.pp(策略包)和 myapp.te(类型执行文件)。
在加载策略之前,查看 myapp.te 文件,看看 audit2allow 生成了什么权限
cat myapp.te
如果输出看起来合理且不过于宽泛,加载策略
sudo semodule -i myapp.pp
加载策略后,将 SELinux 切换回 Enforcing 模式
sudo setenforce 1
再次测试网络应用程序。现在应该可以正常工作,没有错误。如果出现其他拒绝,重复 audit2allow 流程。
小贴士: 如果 audit2allow 生成过度宽泛的策略(允许所有内容),不要加载它。删除生成的文件,让 SELinux 保持 Permissive 更长时间,然后再次尝试 audit2allow,使用更窄的条件或手动创建更具体的策略。
安全的 SELinux 配置方法
适当的 SELinux 配置不仅仅是禁用它,而是遵循系统的故障排查工作流
- 将 SELinux 临时设置为 Permissive 模式,以记录违规而不强制执行
- 运行应用程序并彻底测试所有功能——测试读取、写入、网络连接以及应用程序执行的任何其他操作
- 查看审计日志中与应用程序相关的 SELinux 拒绝
- 使用 audit2allow 生成仅允许必要操作的策略
- 查看生成的 .te 文件,以确保它仅允许所需的操作
- 使用 semodule -i 加载策略模块
- 将 SELinux 切换回 Enforcing 模式
- 再次彻底测试应用程序,以确保所有功能都可以正常工作
通过遵循此工作流,你创建了为特定应用程序需求量身定制的 SELinux 策略,同时提供真实的安全优势,避免了完全禁用系统的陷阱。
总结
SELinux 是一个强大的 Linux 级安全机制,但往往被误解。许多管理员会完全禁用它,而不是学习如何正确使用它。通过将其分解为可管理的步骤,理解模式、上下文、审计日志和 audit2allow 工作流,你可以自信地在 VPS 上配置 SELinux,并添加现代应用程序所需的真实防御层。
>>>常见问题 (FAQ)
SELinux 会显著降低服务器速度吗?
SELinux 开销通常很小——由于额外的上下文检查,通常只有 1-5% 的性能影响。如果 VPS 遭受严重的 CPU 性能问题,问题可能存在于其他地方。在大多数情况下,SELinux 的影响可以忽略不计。
我之前禁用了 SELinux 来修复问题。现在应该重新启用它吗?
如果 SELinux 已禁用,可以立即切换到 Permissive,无需重启。要使用 Enforcing 模式需要重启,因为系统必须重新标记所有文件,在大型系统上可能需要许多小时。如果设置新 VPS,从一开始就使用 Permissive 模式。
如果 audit2allow 创建允许所有内容的策略——这安全吗?
audit2allow 根据观察到的拒绝生成最小必需权限。如果你在 Permissive 模式下正确测试应用程序几天,audit2allow 将生成足够的策略。在加载前始终查看生成的 .te 文件,确保其作用域适当。
我可以删除或撤销我错误应用的 SELinux 策略吗?
可以,使用 semodule -l 列出已加载的模块,然后使用 semodule -r myapp 移除一个模块。如果需要重置文件上下文,使用 restorecon -R 将其恢复到策略默认值。更改立即生效,无需重启。
立即开始使用 AsiaGB VPS
AsiaGB VPS 全系列采用 SSD 存储,可选择泰国或新加坡数据中心,并提供完整的 Root 权限,Linux 系统每月低至 500 泰铢起,由泰语技术团队提供支持。
查看 VPS 套餐