SELinux 不是摆设:策略配置与常见排错
文章目录写在前面被关掉的往往是最后一道闸一、SELinux 到底在防什么1.1 DAC 不够的地方1.2 MAC 一句话1.3 三种模式二、核心概念上下文、域、类型2.1 看标签Label2.2 targeted 策略为何是主流2.3 布尔值Boolean策略的“开关旋钮”三、策略配置实战你会用的 80% 工具3.1 文件上下文semanage restorecon3.2 端口上下文3.3 常用服务布尔举例3.4 生成自定义策略模块进阶但实用四、常见排错总流程建议背下来4.1 读懂 AVC denied4.2 为什么“chmod 777 也没用”五、高频故障场景与处理配方场景 1Nginx/Httpd 无法读站点目录场景 2PHP 上传失败 / 无法写 cache场景 3服务要连非标端口数据库场景 4rsync/scp 到家目录后上下文不对场景 5容器与 SELinuxcontainer-selinux场景 6Samba/NFS 共享六、Permissive 域比全局 setenforce 0 更专业的排错七、企业落地让 SELinux 成为默认而不是例外7.1 黄金准则7.2 与 CI/CD 集成7.3 监控与告警7.4 与其它防线协同八、典型误区纠正九、一小时实验推荐 Rocky/Alma 虚拟机结语不是摆设是“被嫌麻烦的真货”附录 A命令速查写在前面被关掉的往往是最后一道闸Linux 主机被拿下之后攻击者最喜欢听到一句话“这机子 SELinux早就Disabled了不然服务起不来。”于是 DAC用户/组/rwx成了唯一门禁。文件权限配错、Web 目录可写、服务账号被盗用——攻击面瞬间变大。而本可以在进程即使被攻破也难任意读/etc/shadow、难随便绑端口、难随便改 systemd的那层约束被随手卸掉了。SELinuxSecurity-Enhanced Linux不是神话也不是“专门跟运维作对的开关”。它是一套强制访问控制MAC即使进程以某个用户运行也必须同时满足策略允许的类型/域规则。环境以RHEL / Rocky / Alma / CentOS Stream为主Ubuntu 默认是 AppArmor思路可类比工具不同。一、SELinux 到底在防什么1.1 DAC 不够的地方传统权限模型看的是谁拥有文件属主/属组/其他人的 rwx进程的 euid/egid。问题是一旦 Web 进程nginx/httpd/php-fpm被 RCE它拥有的写权限范围内都能动手很多站点又给了过宽目录权限。DAC 很难表达这种策略“httpd 可以读/var/www/html但绝对不能读/home/*/id_rsa也不能随便监听 22 端口。”SELinux 用**类型强制Type Enforcement**表达这类规则。1.2 MAC 一句话主体进程域对客体文件类型/端口类型等的每次访问都必须有策略允许。即便你是 root在 enforcing 模式下也可能被策略拦住——这正是“强制”的含义。root 不是万能豁免金牌当然策略本身可以被 root 改掉所以主机被完全沦陷后任何本地机制都有极限SELinux 防的是漏洞利用后的横向与越权扩大。1.3 三种模式模式含义适用Enforcing拒绝违规并审计生产应为此Permissive不拒绝只记录排错/磨合Disabled完全关闭尽量避免长期使用查看与临时切换getenforcesudosetenforce0# 临时 permissive重启可能恢复sudosetenforce1# 临时 enforcing永久配置/etc/selinux/configSELINUXenforcing SELINUXTYPEtargeted注意从disabled改回enforcing往往需要一次完整的文件系统重新标记fixfiles/touch /.autorelabel否则满屏拒绝。这也是很多人“一关再也不敢开”的历史原因——开关方式粗暴不是 SELinux 没用。二、核心概念上下文、域、类型2.1 看标签Labells-Z/var/www/htmlps-eZ|headid-Z常见文件上下文形态system_u:object_r:httpd_sys_content_t:s0粗读用户身份SELinux user不同于 Linux user角色 role类型 type排错最常看这个灵敏度 MCS/MLS 等级targeted 策略里常见s0。进程例如system_u:system_r:httpd_t:s0含义直觉跑在httpd_t域的进程只能按策略碰被允许的类型。2.2 targeted 策略为何是主流RHEL 系默认SELINUXTYPEtargeted重点约束网络服务等目标域而不是一上来全系统 MLS 军事级。对企业来说这是安全性与可运维性的折中也是“不是摆设但能上生产”的关键。2.3 布尔值Boolean策略的“开关旋钮”很多能力用布尔控制例如是否允许 httpd 访问 NFS、是否允许 httpd 发邮件等。getsebool-a|grephttpdsudosetsebool-Phttpd_can_network_connect1-P表示永久写入。运维排错时优先查布尔而不是直接关 SELinux。三、策略配置实战你会用的 80% 工具3.1 文件上下文semanage restorecon场景站点内容放到/data/www服务读不了。# 查询默认映射规则sudosemanage fcontext-l|grephttpd_sys_content# 为定制路径添加规则sudosemanage fcontext-a-thttpd_sys_content_t/data/www(/.*)?# 按规则重新标记sudorestorecon-Rv/data/wwwls-Z/data/www只跑chcon临时改标签也能“马上好”但重启或 restorecon 可能丢。企业正确姿势semanage fcontext 持久规则 restorecon。3.2 端口上下文场景sshd 改到 2222或 httpd 听 8081。sudosemanage port-l|grephttpsudosemanage port-a-thttp_port_t-ptcp8081不教端口类型服务可能起不来或被拒。3.3 常用服务布尔举例# Web 需要连数据库/外网 API 时按需sudosetsebool-Phttpd_can_network_connect1sudosetsebool-Phttpd_can_network_connect_db1# NFS 家目录等场景sudosetsebool-Puse_nfs_home_dirs1布尔不是越多越好每开一个就扩大该域能力。按最小需要打开。3.4 生成自定义策略模块进阶但实用当官方布尔/类型仍不够先 permissive 或保持 enforcing 收集拒绝用审计日志生成模块审查后安装。sudoausearch-mavc-tsrecentsudoausearch-mavc-tsrecent|audit2allow-Mmyapp# 会生成 myapp.te / myapp.ppsudosemodule-imyapp.pp危险点盲目audit2allow -M全盘允许等于把 SELinux 打成纸窗。必须人工看.te是否出现unconfined、是否允许写shadow_t、是否允许任意exec。四、常见排错总流程建议背下来当服务“权限看起来对但就失败”时1. getenforce 是否 enforcing 2. 看服务日志nginx/httpd/mysql具体失败点 3. 查审计ausearch / ausearch -m avc / journalctl 4. 用 ls -Z / ps -Z 对比“能工作的机器”与“不能工作的机器” 5. 判断文件类型端口类型布尔自定义路径 6. 用 semanage/setsebool/restorecon 修复 7. 验证后保持 enforcing不要留在 permissive4.1 读懂 AVC denied典型审计消息typeAVC msgaudit(...): avc: denied { write } for pid1234 commhttpd nameuploads devsda1 ino... scontextsystem_u:system_r:httpd_t:s0 tcontextsystem_u:object_r:var_t:s0 tclassdir翻译httpd进程httpd_t想对某目录做write但目标类型是var_t策略不允许 → 拒绝修复方向通常是把上传目录标成httpd_sys_rw_content_t示例而不是关 SELinux。sudosemanage fcontext-a-thttpd_sys_rw_content_t/var/www/html/uploads(/.*)?sudorestorecon-Rv/var/www/html/uploads4.2 为什么“chmod 777 也没用”因为拦你的不是 DAC是 MAC。777 只能让“Linux 用户权限”放行SELinux 类型不对照样 denied。这正是很多人误判“SELinux 坏了”的瞬间——其实它在正确工作。五、高频故障场景与处理配方场景 1Nginx/Httpd 无法读站点目录症状403、Permission deniedDAC 权限正常。检查ls-Z/var/www/html# 期望类似 httpd_sys_content_t处理semanage fcontextrestorecon。若站点在/home/user/site还要考虑httpd_enable_homedirs等布尔并评估是否改到标准路径更干净。场景 2PHP 上传失败 / 无法写 cache需要rw 内容类型不是只读httpd_sys_content_t。sudosemanage fcontext-a-thttpd_sys_rw_content_t/var/www/html/storage(/.*)?sudorestorecon-Rv/var/www/html/storage场景 3服务要连非标端口数据库例如 MySQL 听 3307sudosemanage port-a-tmysqld_port_t-ptcp3307Web 访问 DB 还可能需要httpd_can_network_connect_db。场景 4rsync/scp 到家目录后上下文不对拷贝可能带来错误标签。习惯同步后restorecon -Rv或使用保持上下文的拷贝选项视工具而定。场景 5容器与 SELinuxcontainer-selinux在启用 SELinux 的宿主机上跑 Podman/Docker常需:Z/:z挂载标签或正确的容器类型。排错时看宿主机 AVC不要只看容器内 chmod。场景 6Samba/NFS 共享需要对应布尔与文件类型如samba_share_t否则“Windows 能连上但写不了”。配方仍是审计 → 布尔/类型 → restorecon。六、Permissive 域比全局 setenforce 0 更专业的排错全局关 SELinux 影响整机。更好的做法是# 对某一类型域临时 permissive需 setroubleshoot/policycoreutils 等工具支持sudosemanage permissive-ahttpd_t# 排错完成后删除 permissivesudosemanage permissive-dhttpd_t这样只放宽目标服务域其它服务仍受保护。配合setroubleshoot的可读建议若已安装sudosealert-a/var/log/audit/audit.log会给出较友好的“可能的恢复命令”——仍需人工审查。七、企业落地让 SELinux 成为默认而不是例外7.1 黄金准则生产enforcing禁止在文档里写“标准解决方案Disabled”应用发布流水线包含restorecon / fcontext自定义路径必须入库Ansiblesefcontext自定义策略模块走评审不裸奔audit2allow。7.2 与 CI/CD 集成镜像或部署脚本中semanage fcontext-a-thttpd_sys_content_t/opt/app/share(/.*)?||truerestorecon-Rv/opt/app/share容器场景把 SELinux 选项写进编排文件避免人工漏挂载标签。7.3 监控与告警统计 AVC denied 速率新增semodule安装事件模式从 enforcing 变为 permissive/disabled 立即告警这是严重安全事件。检测配置被改grep^SELINUX/etc/selinux/config getenforce可纳入 CIS 基线核查必须为 enforcing。7.4 与其它防线协同机制作用层DAC 权限用户身份基础隔离SELinux进程能力强制约束能力 Capabilities细粒度特权seccomp系统调用过滤命名空间/容器资源视图隔离防火墙网络隔离SELinux 不是替代防火墙也不是替代补丁而是漏洞利用成功后的膨胀抑制器。八、典型误区纠正误区纠正SELinux 太难不如关难在路径非标与标签缺失可用标准路径semanage 解决777 能修 SELinux 问题不能类型不对照样拒chcon 一次就永久不一定要用 semanage fcontextpermissive 等于安全只审计不强制生产勿久留root 不受 SELinux 限制enforcing 下 root 进程同样受类型约束容器里不用管宿主机 SELinux挂载与标签常在宿主机策略里体现九、一小时实验推荐 Rocky/Alma 虚拟机确认getenforce为 Enforcing安装 httpd把页面放到/srv/www非默认路径观察 403/拒绝ausearch -m avc -ts recent找到原因用semanage fcontextrestorecon修复造一个可写目录上传场景设置httpd_sys_rw_content_t打开一个布尔再关闭观察行为差异用semanage permissive -a httpd_t体验定向排错再改回记录一份“本环境 Web 路径标签规范”。做完后你基本不会再对同事说“把 SELinux 关了吧”。结语不是摆设是“被嫌麻烦的真货”SELinux 的口碑差很大程度上来自早期资料少软件包默认路径外的“野路子部署”排错只会setenforce 0的文化。但在勒索、WebShell、供应链木马层出不穷的今天能卡住“进程不该碰的东西”的 MAC恰恰是主机安全稀缺的深度防御。请用这三句话结束下次排障先查 AVC再谈开关先修标签与布尔再谈自定义模块排错可以 permissive结束必须 enforcing。当团队把restorecon写进发布手册把getenforce写进巡检把“关 SELinux”写进禁止事项——它就不再是摆设而是沉默却可靠的那道闸。附录 A命令速查getenforce / setenforce sestatusls-Zps-eZid-Zsemanage fcontext-lsemanage fcontext-a-ttypepath_regexrestorecon-Rvpathsemanage port-a-ttype-ptcpportgetsebool-a|grepsvcsetsebool-Pbool0|1ausearch-mavc-tsrecent aureport-aaudit2allow-Mname# 务必审查semodule-l|grepnamesemanage permissive-adomain_t