系统管理入门笔记(第二十二期)——SELinux 安全加固——上下文、布尔值与故障排查)
LinuxCentOS系统管理入门笔记第二十二期——SELinux 安全加固——上下文、布尔值与故障排查Linux系统管理入门系列更多文章欢迎访问Linux入门——系统管理1、Linux入门——系统管理2我的主页AOwhisky这里有更多运维系统性知识整理和其他有趣内容欢迎与我一起探讨学习~引言Linux 安全的“第二道锁”——当文件权限不够用的时候我们学习了文件权限rwx、用户管理UID/GID和防火墙firewalld。这些都是 Linux 安全体系的重要组成部分。但有一个问题始终存在文件权限只能控制“谁能访问”无法控制“怎么访问”。想象一下你有一栋大楼每间办公室都有门锁文件权限——只有特定的人用户/组才能进入。但如果某个员工被黑客控制了黑客假扮成这个员工进入大楼他就能自由访问这个员工有权进入的所有房间。这就是 Linux 文件权限模型的本质缺陷——权限绑定的是“身份”而不是“行为”。Web 服务器进程以apache用户运行可以访问/var/www/html——这是正常的但如果黑客攻破了 Web 服务器同样的apache进程还可能访问/tmp、/var/tmp甚至通过漏洞读取/etc/passwd——这是灾难SELinuxSecurity-Enhanced Linux安全增强 Linux解决了这个问题。它为每个进程、文件、目录、端口都打上了一个“安全标签”SELinux 上下文并定义了一套严格的访问规则——即使你是 root如果 SELinux 策略不允许你也无法执行某个操作。传统 DAC自主访问控制 SELinux MAC强制访问控制 “你是谁决定了你能干什么” “你的标签是什么决定了你能干什么” ↓ ↓ 用户身份UID 安全上下文上下文SELinux 不是替代文件权限而是在其之上构建的第二道防线。它以最小权限原则为核心——默认拒绝所有操作只有明确允许的才能执行。本期将系统学习 SELinux 的核心概念与实战管理SELinux 概述DAC vs MAC、SELinux 的目标SELinux 模式Enforcing / Permissive / Disabled安全上下文管理文件、进程、端口的标签SELinux 布尔值开关式策略调整故障排查setroubleshoot 与 sealert 诊断工具读完这一期你将掌握 Linux 安全体系中最深层的防御机制——从“能访问”到“能安全访问”的跃升。— Compiled and Authored by Whisky — Augest 2 nd, 2026目录SELinux 概述文件权限之外的“行为管控”1.1 DAC vs MAC1.2 SELinux 的目标SELinux 工作模式2.1 三种模式详解2.2 查看与设置模式2.3 模式切换注意事项SELinux 安全上下文3.1 上下文的结构与 -Z 选项3.2 新文件的默认上下文3.3 chcon临时修改上下文3.4 restorecon恢复默认上下文3.5 semanage fcontext永久定义默认上下文3.6 实战配置自定义 Web 目录SELinux 端口管理4.1 端口标签的概念4.2 查看与添加端口标签4.3 实战Web 服务使用自定义端口SELinux 布尔值5.1 什么是布尔值5.2 查看与设置布尔值5.3 实战允许 httpd 访问用户家目录SELinux 故障排查6.1 setroubleshoot-server自动诊断6.2 sealert详细排查工具6.3 SELinux 问题处理思路总结与速查手册1. SELinux 概述文件权限之外的“行为管控”1.1 DAC vs MAC访问控制模型全称控制依据代表DACDiscretionary Access Control自主访问控制用户身份UID/GIDLinux 文件权限rwxMACMandatory Access Control强制访问控制安全标签/上下文SELinux、AppArmorDAC 的本质由文件所有者自主决定谁可以访问chmod/chown。root 用户可以访问任何文件——这对安全来说是巨大的风险。MAC 的本质由系统策略强制规定——即使你是 root如果没有匹配的安全标签操作也会被拒绝。# 即使 root 用户SELinux 策略也可以阻止操作[rootcentos7 ~]# echo test /var/www/html/index.html-bash: /var/www/html/index.html: Permission denied# 明明是 root却被拒绝了——这就是 SELinux 在起作用1.2 SELinux 的目标主要目标防止已遭泄露的系统服务访问用户数据。场景黑客攻破了 Web 服务器apache 进程获得了apache用户的权限。在传统的 DAC 模型下apache用户可能能访问/tmp、/var/tmp甚至读取/etc/passwd。在 SELinux 的保护下apache进程的标签是httpd_t/var/www/html文件的标签是httpd_sys_content_t/tmp目录的标签是tmp_tSELinux 策略规定httpd_t只允许访问httpd_sys_content_t标签的文件即使apache用户有权限访问/tmpSELinux 策略也会阻止——因为标签不匹配白话理解文件权限是“门禁卡”谁有卡能进门SELinux 是“保安”即使有卡保安不批准也不能进也不能去不该去的地方。2. SELinux 工作模式2.1 三种模式详解模式访问控制违规记录推荐场景Enforcing强制✅ 强制执行✅ 记录生产环境Permissive允许❌ 不强制仅警告✅ 记录调试/测试Disabled禁用❌ 完全关闭❌ 不记录❌ 不推荐# 查看当前模式[rootcentos7 ~]# getenforceEnforcing2.2 查看与设置模式# 查看当前模式[rootcentos7 ~]# getenforce# 临时切换模式立即生效无需重启[rootcentos7 ~]# setenforce 0 # 切换到 Permissive[rootcentos7 ~]# setenforce 1 # 切换到 Enforcing# 或使用名称[rootcentos7 ~]# setenforce Permissive[rootcentos7 ~]# setenforce Enforcing# 永久设置修改配置文件需重启[rootcentos7 ~]# vim /etc/selinux/configSELINUXenforcing# 可选enforcing / permissive / disabledSELINUXTYPEtargeted# 策略类型targeted 是默认模式切换注意事项切换方向是否需要重启Enforcing ↔ Permissive❌ 不需要Enforcing → Disabled✅需要重启Disabled → Enforcing/Permissive✅需要重启2.3 内核参数启动时设置 SELinux 模式在 GRUB2 启动菜单中可通过内核参数控制 SELinux 模式常用于故障修复内核参数效果enforcing0启动时进入 Permissive 模式enforcing1启动时进入 Enforcing 模式默认selinux0完全禁用 SELinux3. SELinux 安全上下文3.1 上下文的结构与 -Z 选项SELinux 安全上下文格式用户:角色:类型:敏感度部分含义示例用户userSELinux 用户身份与 Linux 用户不同unconfined_u、system_u角色role进程角色进程是_r文件是_robject_r类型type核心部分以_t结尾策略基于类型匹配httpd_t、httpd_sys_content_t敏感度levelMLS/MCS 安全级别多级安全s0、s0-s0:c0.c1023使用-Z查看安全上下文# 查看进程的安全上下文[rootcentos7 ~]# ps -ZLABEL PID TTY TIME CMD system_u:system_r:sshd_t:s0-s0:c0.c1023951? 00:00:00 sshd unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c10231276pts/0 00:00:00bash# 查看文件的安全上下文[rootcentos7 ~]# ls -Z /etc/hostssystem_u:object_r:net_conf_t:s0 /etc/hosts# 查看目录的安全上下文[rootcentos7 ~]# ls -Zd /var/www/htmlsystem_u:object_r:httpd_sys_content_t:s0 /var/www/html⚠️关键理解SELinux 基于类型type做访问控制而不是用户或角色。httpd_t能访问httpd_sys_content_t但不能访问tmp_t。3.2 新文件的默认上下文新文件通常从父目录继承SELinux 上下文。# 在 /tmp 中创建文件继承 tmp_t[rootcentos7 ~]# touch /tmp/testfile[rootcentos7 ~]# ls -Z /tmp/testfileunconfined_u:object_r:user_tmp_t:s0 /tmp/testfile# 复制到 /root继承 admin_home_t[rootcentos7 ~]# cp /tmp/testfile /root/[rootcentos7 ~]# ls -Z /root/testfileunconfined_u:object_r:admin_home_t:s0 /root/testfile两种情况上下文保持不变操作SELinux 上下文变化cp -a保留属性❌ 不变mv移动❌ 不变# 移动文件上下文不变仍是 user_tmp_t但位置在 /root[rootcentos7 ~]# mv /tmp/testfile /root/testfile-mv[rootcentos7 ~]# ls -Z /root/testfile-mvunconfined_u:object_r:user_tmp_t:s0 /root/testfile-mv# 这可能导致 SELinux 问题——文件在 root 家目录但标签是 tmp_t3.3 chcon临时修改上下文chcon用于直接修改文件的 SELinux 上下文适用于测试和调试。# 创建目录并查看上下文[rootcentos7 ~]# mkdir /www[rootcentos7 ~]# ls -Zd /wwwunconfined_u:object_r:default_t:s0 /www# 修改上下文改为 httpd_sys_content_t[rootcentos7 ~]# chcon -t httpd_sys_content_t /www[rootcentos7 ~]# ls -Zd /wwwunconfined_u:object_r:httpd_sys_content_t:s0 /www# 使用 -R 递归修改[rootcentos7 ~]# chcon -R -t httpd_sys_content_t /www⚠️重要chcon的修改不会保存到 SELinux 策略数据库。当系统执行restorecon或完整 relabel 时修改会被重置。3.4 restorecon恢复默认上下文restorecon根据 SELinux 策略数据库中的规则恢复文件的默认上下文。# 恢复单个文件的上下文[rootcentos7 ~]# restorecon -v /wwwRelabeled /www from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0# -v显示恢复过程# 递归恢复目录下所有文件[rootcentos7 ~]# restorecon -Rv /www/3.5 semanage fcontext永久定义默认上下文semanage fcontext在 SELinux 策略数据库中添加/删除/修改上下文规则restorecon将依据这些规则恢复上下文。# 安装 semanage 工具[rootcentos7 ~]# yum install -y policycoreutils-python-utils# 为 /www 目录定义默认上下文使用正则表达式匹配所有子文件[rootcentos7 ~]# semanage fcontext -a -t httpd_sys_content_t /www(/.*)?# 查看自定义规则[rootcentos7 ~]# semanage fcontext -lCSELinux fcontexttypeContext /www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0# 恢复上下文[rootcentos7 ~]# restorecon -Rv /www/Relabeled /www from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0# 删除自定义规则[rootcentos7 ~]# semanage fcontext -d -t httpd_sys_content_t /www(/.*)?# 验证删除[rootcentos7 ~]# semanage fcontext -lC# 无输出3.6 实战配置自定义 Web 目录场景将 Web 服务的主目录从/var/www/html改为/www。# 1. 创建自定义 Web 目录[rootcentos7 ~]# mkdir /www[rootcentos7 ~]# echo h1Hello SELinux/h1 /www/index.html# 2. 配置 httpd 主目录[rootcentos7 ~]# vim /etc/httpd/conf/httpd.confDocumentRoot/wwwDirectory/wwwAllowOverride None Require all granted/Directory# 3. 尝试启动失败SELinux 阻止[rootcentos7 ~]# systemctl start httpdJobforhttpd.service failed because the control process exited with error code.[rootcentos7 ~]# tail /var/log/messages... SELinux is preventing httpd from getattr access on the directory /www...# 4. 永久修改 SELinux 上下文[rootcentos7 ~]# semanage fcontext -a -t httpd_sys_content_t /www(/.*)?[rootcentos7 ~]# restorecon -Rv /www/# 5. 启动成功[rootcentos7 ~]# systemctl start httpd[rootcentos7 ~]# curl http://localhost/h1Hello SELinux/h14. SELinux 端口管理4.1 端口标签的概念SELinux 不仅给文件打标签还给网络端口打标签。当服务进程尝试绑定到某个端口时SELinux 检查进程的域如httpd_t是否被允许绑定到该端口标签如http_port_t# 查看端口标签[rootcentos7 ~]# semanage port -l | grep http_port_thttp_port_t tcp80,81,443,488,8008,8009,8443,9000# 注意httpd 服务可以绑定到这些端口4.2 查看与添加端口标签# 查看所有端口标签仅查看自定义的用 -lC[rootcentos7 ~]# semanage port -l# 添加端口标签将 18020 端口标记为 http_port_t[rootcentos7 ~]# semanage port -a -t http_port_t -p tcp 18020# 修改端口标签将 18020 改为 ssh_port_t[rootcentos7 ~]# semanage port -m -t ssh_port_t -p tcp 18020# 删除端口标签[rootcentos7 ~]# semanage port -d -t ssh_port_t -p tcp 18020# 查看自定义的端口标签[rootcentos7 ~]# semanage port -lCSELinux Port Type Proto Port Number http_port_t tcp180204.3 实战Web 服务使用自定义端口场景让 httpd 监听在 18020 端口。# 1. 修改 httpd 配置文件[rootcentos7 ~]# vim /etc/httpd/conf/httpd.confListen18020# 2. 尝试启动失败——SELinux 阻止绑定非标准端口[rootcentos7 ~]# systemctl restart httpdJobforhttpd.service failed...[rootcentos7 ~]# tail /var/log/messages... AH00072: make_sock: could notbindto address0.0.0.0:18020# 3. 将端口添加到 http_port_t 标签[rootcentos7 ~]# semanage port -a -t http_port_t -p tcp 18020# 4. 再次启动成功[rootcentos7 ~]# systemctl restart httpd[rootcentos7 ~]# curl http://localhost:18020/h1Hello SELinux/h15. SELinux 布尔值5.1 什么是布尔值SELinux 布尔值是可以在运行时动态开启/关闭的策略开关用于调整特定功能的行为而无需修改复杂的策略规则。布尔值就像是 SELinux 策略的“开关面板” - 每个开关控制一个特定的功能 - 可以随时打开或关闭 - 无需重启系统5.2 查看与设置布尔值# 查看所有布尔值[rootcentos7 ~]# getsebool -ahttpd_enable_homedirs --off httpd_unified --off...# 查看特定布尔值[rootcentos7 ~]# getsebool httpd_enable_homedirshttpd_enable_homedirs --off# 临时设置布尔值运行时生效重启后恢复[rootcentos7 ~]# setsebool httpd_enable_homedirs1# 或使用 on/off/true/false[rootcentos7 ~]# setsebool httpd_enable_homedirs on# 永久设置写入策略数据库重启后仍生效-P[rootcentos7 ~]# setsebool -P httpd_enable_homedirs1# 使用 semanage 管理布尔值[rootcentos7 ~]# semanage boolean -l # 查看所有[rootcentos7 ~]# semanage boolean -lC # 只查看自定义的[rootcentos7 ~]# semanage boolean -m --on httpd_enable_homedirs # 启用[rootcentos7 ~]# semanage boolean -m --off httpd_enable_homedirs # 禁用5.3 实战允许 httpd 访问用户家目录场景允许用户通过~usernameURL 访问自己的public_html目录。# 1. 配置 httpd 启用 UserDir[rootcentos7 ~]# vim /etc/httpd/conf.d/userdir.confUserDir enabled UserDir public_html# 2. 用户创建 public_html 目录并写入文件[whiskycentos7 ~]$mkdir~/public_html[whiskycentos7 ~]$echoWelcome to whiskys home~/public_html/index.html# 3. 确保用户家目录有执行权限其他人可进入[whiskycentos7 ~]$chmod711~# 4. 尝试访问SELinux 阻止[rootcentos7 ~]# curl http://localhost/~whisky/!DOCTYPE HTML PUBLIC-//IETF//DTD HTML 2.0//ENhtmlheadtitle403Forbidden/title/headbody...# 5. 启用 httpd_enable_homedirs 布尔值[rootcentos7 ~]# setsebool -P httpd_enable_homedirs1# 6. 再次访问[rootcentos7 ~]# curl http://localhost/~whisky/Welcome to whiskys home6. SELinux 故障排查6.1 setroubleshoot-server自动诊断setroubleshoot-server服务会自动监控 SELinux 拒绝事件AVC 消息并将诊断摘要发送到/var/log/messages。# 安装[rootcentos7 ~]# yum install -y setroubleshoot-server# 服务已集成无需额外启动# 触发一个 SELinux 错误后查看日志[rootcentos7 ~]# tail -f /var/log/messagesNov3010:39:34 server setroubleshoot[4035]: SELinux is preventing /usr/sbin/httpd from getattr access on thefile/home/whisky/public_html/index.html. For complete SELinux messages run: sealert-lbb10b03c-bed2-4853-85cb-92c1824fd75d6.2 sealert详细排查工具根据/var/log/messages中的提示使用sealert获取完整诊断信息[rootcentos7 ~]# sealert -l bb10b03c-bed2-4853-85cb-92c1824fd75dSELinux is preventing /usr/sbin/httpd from getattr access on thefile/home/whisky/public_html/index.html. ***** Plugin public_content(32.5confidence)suggests ******************** If you want to treat index.html as public content Then you need to change the label on index.html to public_content_t or public_content_rw_t. Do# semanage fcontext -a -t public_content_t /home/whisky/public_html/index.html# restorecon -v /home/whisky/public_html/index.html***** Plugin catchall_boolean(32.5confidence)suggests ****************** If you want to allow httpd toenablehomedirs Then you must tell SELinux about this by enabling thehttpd_enable_homedirsboolean. Do setsebool-Phttpd_enable_homedirs1...sealert给出了具体的解决方案通常有多个选项解决方案适用场景修改文件上下文semanage fcontextrestorecon文件标签不正确调整布尔值setsebool -P功能开关未启用修改端口标签semanage port服务使用非标准端口6.3 SELinux 问题处理思路1. 确认是否 SELinux 引起的 └─ tail -f /var/log/messages 或 audit2why /var/log/audit/audit.log 2. 判断这个拒绝是正常的还是误报 └─ 如果是正常的阻止如 httpd 访问 /home说明 SELinux 在正确工作 └─ 如果是误报需要被允许继续↓ 3. 最常见的 SELinux 问题文件上下文不正确 └─ 文件从其他地方移动过来上下文不匹配 └─ 解决方法restorecon -Rv /path 4. 布尔值设置不当 └─ 如 httpd_enable_homedirs、ftpd_anon_write 等 └─ 解决方法setsebool -P 布尔值1 5. 端口上下文不匹配 └─ 服务绑定到非标准端口 └─ 解决方法semanage port -a -t 标签 -p 协议 端口 6. SELinux 策略 Bug极少见 └─ 使用 audit2allow 生成自定义策略模块7. 总结与速查手册7.1 核心知识点一览主题关键点SELinux 目标防止已遭泄露的系统服务访问用户数据三种模式Enforcing强制、Permissive允许、Disabled禁用安全上下文用户:角色:类型:敏感度基于类型type做访问控制chcon临时修改上下文不持久化restorecon根据策略数据库恢复默认上下文semanage fcontext永久定义默认上下文规则semanage port管理端口标签布尔值开关式调整 SELinux 策略行为setroubleshoot自动诊断 SELinux 问题7.2 命令速查表命令作用getenforce查看当前模式setenforce 01/etc/selinux/config永久配置ls -Z/ps -Z查看安全上下文chcon -t 类型 文件临时修改上下文restorecon -Rv 目录恢复默认上下文semanage fcontext -a -t 类型 正则添加默认上下文规则semanage fcontext -lC查看自定义上下文规则semanage port -a -t 类型 -p 协议 端口添加端口标签semanage port -lC查看自定义端口标签getsebool -a查看所有布尔值setsebool -P 布尔值1永久启用布尔值sealert -l UUID查看 SELinux 问题详情7.3 常用 SELinux 类型速查类型用途httpd_thttpd 进程域httpd_sys_content_tWeb 服务器的文档内容httpd_sys_script_exec_tCGI 脚本http_port_thttpd 绑定的端口ssh_port_tSSH 端口tmp_t/tmp 目录中的文件user_home_dir_t用户家目录public_content_t公共内容如匿名 FTP7.4 SELinux 工作模式速查模式是否强制执行是否记录违规重启要求Enforcing✅✅设为默认需重启Permissive❌✅设为默认需重启Disabled❌❌必须重启7.5 常见错误排查问题原因解决方案服务启动失败日志有Permission deniedSELinux 阻止查看/var/log/messages用sealert诊断文件访问被拒上下文不匹配restorecon -Rv /path服务无法绑定端口端口标签未添加semanage port -a -t 标签 -p tcp 端口功能需要特殊权限布尔值未启用getsebool查找setsebool -P启用禁用 SELinux 后想重新启用config 中设为 disabled将 SELINUXdisabled 改为 enforcing重启系统会重新标记7.6 思考与拓展原课后作业转化SELinux 的 Enforcing 和 Permissive 模式有什么区别→ EnforcingSELinux 策略被强制执行违规操作被拒绝Permissive策略被加载但不强制执行仅记录违规日志。Permissive 用于测试和调试。为什么chcon修改上下文后restorecon会将其恢复→chcon只修改文件本身的标签不修改策略数据库。restorecon从策略数据库中读取默认规则将文件恢复到规则定义的标签。SELinux 布尔值的作用是什么→ 布尔值提供了开关式调整 SELinux 策略的能力无需编写复杂策略。例如httpd_enable_homedirs控制 httpd 是否能访问用户家目录。什么时候应该禁用 SELinux→极少情况下才建议禁用。如果确实需要应先设置为 Permissive 模式运行一段时间收集所有违规记录然后根据日志调整策略最终再启用 Enforcing。如何判断一个问题是 SELinux 引起的还是文件权限引起的→ 查看/var/log/messages是否有SELinux is preventing或AVC字样或使用sealert诊断。如果日志无 SELinux 相关记录可能是文件权限问题。7.7 生产环境最佳实践场景建议生产环境保持SELINUXenforcing不要禁用应用部署遵循标准的目录和上下文规范必要时使用semanage fcontext定义自定义规则故障排查先切换到Permissive模式确认是 SELinux 问题修复后切回Enforcing新服务部署使用sealert获取正确的修复建议而非盲目禁用 SELinux软件升级升级后检查 SELinux 策略更新必要时执行restorecon -Rv /监控监控/var/log/messages中的 SELinux 告警及时处理系列结语至此LinuxCentOS系统管理入门笔记系列全部 22 期内容已完整呈现。我们从 Linux 的历史哲学出发走过了命令行基础、文件系统管理、用户权限体系、存储管理分区/RAID/LVM/Swap、启动原理与故障恢复、防火墙和 SELinux 安全加固——覆盖了 Linux 系统管理员从入门到实战所需的完整知识体系。这个系列的特点是理论与实践并重每个概念都有可执行的命令和清晰的输出解读循序渐进从零到一从“会敲命令”到“懂系统原理”生产导向每期结尾都有生产环境最佳实践和常见问题排查记住真正的 Linux 管理员不是“记住所有命令的人”而是“知道去哪里查、怎么组合工具、如何排查问题”的人。愿你在 Linux 的世界里越走越远越走越深。下个系列预告至此你已经掌握了 Linux 系统管理的完整技能——从命令行基础、文件系统、用户权限到进程管理、存储管理、系统启动、防火墙与 SELinux 安全加固。这是一名合格系统管理员的核心能力。但系统管理的终点正是网络服务架设的起点。管理系统是为了运行服务——DHCP 动态分配地址、DNS 解析域名、NFS/SMB 共享文件、Apache/Nginx 提供 Web 服务、MariaDB/MySQL 存储数据、TLS 加密通信……下一个系列我们将进入Linux 网络服务架设学习笔记的世界从DHCP 服务器开始——学习如何为网络中的设备自动分配 IP 地址、配置网关和 DNS以及如何部署 DHCP 中继实现跨网段分配。敬请期待愿你在 Linux 的世界里越走越远越走越深。— LinuxCentOS系统管理入门笔记 全系列完 —— Compiled and Authored by Whisky — Augest 2 nd, 2026