ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RH134 SELinux实战笔记:从安全上下文到AVC排错精讲

RH134 SELinux实战笔记:从安全上下文到AVC排错精讲 昨晚我照着文档在RHEL 9上部署一个内部Web服务firewall-cmd已经放行了端口目录权限也改成了755curl却一直返回403。折腾一个多小时最后用ausearch -m AVC翻审计日志才发现是SELinux把httpd进程的文件访问拦了下来。这种经历凡是学过RH134的朋友应该都不陌生。RH134作为Red Hat系统管理进阶课程SELinux单独成章篇幅不多但绝对值得反复咀嚼。它不要求你成为一名安全策略编写专家却要求你掌握一套完整的观察—分析—修复思路模式怎么切换、安全上下文是什么、布尔值在哪查、日志去哪看。这篇文章是我学习这一章的完整笔记从权限模型到实操命令再到两个真实排错链路适合正在备考RH134的学员也适合被SELinux导致服务异常坑过的运维同行。1. 从DAC到MAC为什么root说了不算SELinux刚接触时最颠覆认知的一点是root用户居然也会被拒绝。很多人在普通Linux环境里习惯了root万能于是遇到SELinux拦截时第一反应是系统出bug了接着就是关掉它。要真正理解SELinux得先搞明白它到底补上了传统权限模型的哪个漏洞。1.1 传统rwx权限管不住root传统Linux权限模型叫DAC自主访问控制每个文件都标着所有者、所属组、其他人三组rwx权限逻辑上完全由文件所有者来决定谁能访问这个文件。这套机制用了几十年问题在于如果进程是以root身份运行的DAC对它来说基本是透明的。试想一个场景Apache的httpd进程以root启动通过漏洞被攻击者拿到Shell攻击者直接读取/etc/shadow、把自己写进/root/.ssh/authorized_keysDAC完全拦不住因为root可以无视文件权限位直接读改。即便严格遵循最小权限原则给进程降权也做不到进程A能读文件X但不能读文件Y这种细粒度隔离。DAC的决策依据只有对象属于谁、进程属于谁没有进程本身的身份和行为是否可信。这还不够。传统权限还面临setuid程序、共享库注入等利用方式一旦进程权限提升攻击面直接扩散到整个文件系统。RH134课程里讲SELinux之前会花一定篇幅强调这份风险——不是为了否定DAC而是为了说明仅仅依赖文件权限的服务部署在安全上存在多大的盲区。1.2 SELinux引入的MAC策略优先于身份SELinux实现的是MAC强制访问控制。它的核心思想是文件系统上每个对象、系统里每个进程都被打上一个叫做安全上下文的标签系统管理员通过策略文件统一规定哪些标签的进程可以访问哪些标签的对象。注意这个判断发生在DAC判断之后即使DAC放行了MAC不匹配照样拒绝。可以这样类比DAC和MAC的区别DAC相当于办公室门口的签到本只要你是这个公司的人用户身份匹配就能进MAC相当于每间机房的独立门禁卡即便你有公司工牌门禁系统没有授予你进入机房A的权限你一样进不去。root在公司里相当于持有万能钥匙但在MAC的规则里万能钥匙只对应很少的区域其他区域看的是卡上的权限标签。SELinux里进程的安全上下文像一个domain域文件的安全上下文则是type类型。HTTP服务进程跑在httpd_t域普通网站文件标记为httpd_sys_content_t策略中定义了httpd_t可以对httpd_sys_content_t进行读取于是正常访问被放行。但如果你把网站目录改成/data/web这个目录的默认标签可能是usr_t策略中没有httpd_t读取usr_t的规则于是一切变得诡异权限、端口、防火墙都没问题服务就是不可达。1.3 RH134为何把SELinux设为独立章节RH134的定位是系统管理员进阶服务部署是重头戏——Apache、NFS、Samba、vsftpd一个接一个。这些服务哪个都绕不开SELinux策略改默认配置、换目录、调端口、跨网络共享每一样都有可能触发拦截。更关键的是RH134考试环境评分时会检查你有没有保留SELinux的强制模式直接把SELinux禁用后部署服务也许本机能跑但生产环境不会允许你这么做。所以这一章的教学目标非常明确不要求你写出复杂的.te策略文件但要求你熟练使用semanage、setsebool、restorecon、ausearch这套组合拳知道出了问题时去哪找线索而不是先想到关SELinux。这套能力恰恰是很多自学Linux的人最缺的。2. 三种模式切换背后的风险都藏在重启里SELinux有三种运行模式enforcing强制、permissive宽容、disabled禁用。很多人理解成开、半开、关这没错但实际操作中模式的切换远没有听起来那么简单尤其在disabled和enforcing之间来回切重启一次可能让整个系统起不来。2.1 三种模式的区别不是关不关这么简单用一张表快速看清差别模式策略是否生效是否记录日志典型适用场景enforcing是违反策略直接拒绝是写入audit.log生产环境、考试环境permissive否违反策略放行是写入audit.log调试策略、观测影响范围disabled否否长期不需要SELinux如部分容器镜像临时切换用setenforce 0切到permissive和setenforce 1切回enforcing这条命令只影响当前运行状态重启后失效想永久改变要修改/etc/selinux/config文件。一个常见误区是需要关闭SELinux时直接setenforce 0心想重启后还是关的。其实重启后系统还会按config文件里写的模式启动。想要彻底禁用得把SELINUXdisabled写进配置文件还要重启。反过来说如果你只是想让一个服务暂时通过验证用setenforce 0就够了别动不动改配置文件改完忘了改回来生产环境会出大事故。2.2 从disabled切回enforcing最容易翻车这是我在练习中踩过的最深一坑。某次实验环境因需求把SELinux设成了disabled跑了几天再改回enforcing重启发现系统启动卡在奇怪的地方登录后各种服务异常网络管理也报错。原因在于SELinux disabled状态下系统不会维护任何文件的安全上下文。期间新建、改动过的文件都没有正确标签甚至关键系统文件在重启时应该被赋予的类型也被跳过。当你重新开启enforcing时内核开始用活动策略检查所有对象发现大量文件的标签缺失或错误于是表现为系统突然什么都不正常。正确做法是在切换前让系统重建标签修改配置为SELINUXenforcing后在根目录创建自动relabel标记文件然后重启touch /.autorelabel reboot系统启动时检测到/.autorelabel会对整个文件系统重新打上符合当前策略的标签。完成后该文件自动消失。注意这个过程在文件较多时耗时很长务必预留停机时间千万别中途断电。2.3 日常运维的查看三板斧判断当前状态三个命令最常用getenforce # 输出 Enforcing / Permissive / Disabled sestatus # 显示模式、策略版本、加载的策略名 sestatus -v # 额外显示关键进程和文件的安全上下文我在排查服务问题时习惯把sestatus和ps -eZ、ls -Z配合使用先确认系统整体处于什么模式再看目标进程和文件分别是什么标签。如果进程的domain是unconfined_t说明它不受SELinux限制问题多半不在SELinux如果domain很明确比如httpd_t那就需要顺着AVC日志往下查了。3. 安全上下文拦你的那串奇怪的字符串在支持SELinux的目录里执行ls -Z你会看到每个文件额外多出一段类似system_u:object_r:httpd_sys_content_t:s0的内容。这串字符就是安全上下文SELinux一切判断都基于它。学这一节的关键是理解三段分别代表什么以及哪些字符串需要你关注。3.1 user、role、type各自管什么安全上下文格式是user:role:type在某些发行版还会带level如s0用于多级安全策略RH134一般只需要了解。user是SELinux用户跟系统登录用户不是一回事。它更像一个策略身份比如system_u代表系统进程和服务unconfined_u代表不受约束的用户。我们平时管理文件时基本不需要改它。role用于角色切换文件对象上基本都是object_r进程可能有system_r等。管理员日常也不需要动它。type也叫类型才是核心。文件上叫类型进程上叫domain两者都是策略判断的主要依据。RH134并不要求深入理解SELinux用户映射但要求你能读懂type并且知道某个服务的进程domain是什么、对应的文件type应该是什么。比如httpd进程的domain是httpd_t网页文件通常是httpd_sys_content_tSELinux的策略允许httpd_t访问这类文件。3.2 类型强制为什么换了目录就不行SELinux默认策略是目标策略targeted核心机制就是类型强制。可以这样理解每个服务像一个持卡的员工卡上写着他的权限等级domain每个文件桌上贴着权限标签type保安SELinux策略手里有一份对照表只有domain type在表上出现了才能放行。默认情况下/var/www/html目录里的文件被打上httpd_sys_content_t所以httpd读起来没问题。你换到/data/web新建文件通常被打成usr_t对照表里没有httpd_t读取usr_t的规则于是403。这不是文件权限问题而是SELinux认为这个进程不应该访问这些文件。这恰恰是SELinux的精髓让服务默认只能访问它该访问的东西。管理员需要做的不是关掉门禁而是正确告知系统这个目录现在是网站目录请按网站目录的类型处理。3.3 查看标签的三个命令ls -Z /var/www/html/index.html ps -eZ | grep httpd id -Zid -Z显示当前用户的SELinux身份ls -Z看文件类型ps -eZ看进程domain。图形文件管理器在RHEL上右键属性也能看到安全上下文但命令行更快。3.4 修改标签chcon、restorecon、semanage可以把类型改掉但方式决定持久性chcon -t httpd_sys_content_t /data/web/index.htmlchcon直接修改对象的安全上下文立刻生效适合临时验证。但它不改变策略规则一旦日后对该目录执行restorecon标签又会恢复到策略默认值。semanage fcontext -a -t httpd_sys_content_t /data/web(/.*)? restorecon -Rv /data/websemanage fcontext才是把规则写入策略库存的办法。它告诉SELinux以后这个路径下创建的文件默认使用指定类型。restorecon按照策略库里的映射关系把现有文件的标签修正过来。这组合才是生产环境的标准操作。为什么推荐semanage而不是chcon因为restorecon是一个会被反复使用的修复命令比如系统升级、管理员误操作后都需要用它恢复。如果当初只用了chcon没有写进策略库执行restorecon后标签就丢失了。用semanage注册规则等于给了系统一个长期记忆。3.5 一个典型的目录迁移案例把网站从/var/www/html迁到/opt/web常规操作是改httpd.conf的DocumentRoot然后复制文件、放开权限。但在enforcing模式下还需要两步semanage fcontext -a -t httpd_sys_content_t /opt/web(/.*)? restorecon -Rv /opt/web如果网站还要写入文件比如上传目录还需要加上可写类型semanage fcontext -a -t httpd_sys_content_rw_t /opt/web/upload(/.*)? restorecon -Rv /opt/web/upload一不注意就会少一步。我的习惯是迁移任何服务目录后第一件事就是semanage fcontext注册新路径而不是等到访问报错再排查。4. 排错链路从服务异常到策略修改SELinux排错最怕的是用错误的方式做对了的事。比如遇到httpd访问不了直接setenforce 0确实能临时解决但下次重启又复发而且问题可能不止一处。正确的链路是确认模式 → 复现问题 → 查AVC日志 → 分析被拒原因 → 修改布尔值/端口/文件上下文 → 验证。4.1 日志在哪里看AVC记录SELinux拒绝访问时会在审计日志中写入一条AVCAccess Vector Cache记录。主要查看入口ausearch -m AVC -ts recent ausearch -m AVC -p 12345 # 按PID过滤 grep denied /var/log/audit/audit.log sealert -l 完整日志消息ausearch会输出类似这样的内容typeAVC msgaudit(1690000000.123:456): avc: denied { read } for pid7890 commhttpd nameindex.html devdm-0 ino12345 scontextsystem_u:system_r:httpd_t:s0 tcontextsystem_u:object_r:usr_t:s0 tclassfile permissive0看两个关键字段scontext是进程的domaintcontext是目标文件的typetclass是对象类别。上面这条日志可以直接读出httpd_t域进程想读取类型为usr_t的文件被拒绝。需要说明的是RHEL默认配置下AVC日志会进入/var/log/audit/audit.log但如果不确定系统是否开了auditd也可以直接看/var/log/messages或执行dmesg | grep -i selinux信息可能少一些但同样有价值。4.2 案例一httpd访问不了NFS共享目录有次NFS挂载了一个共享目录/mnt/shareApache文档根目录指向其中浏览器始终403ls -l看权限没问题NFS挂载参数也正常。查AVC日志ausearch -m AVC -ts recent结果里出现了httpd_t对nfs_t类型目录的read被拒。原因很清楚SELinux默认不允许httpd去访问NFS文件系统类型。修复需要打开对应布尔值getsebool -a | grep httpd setsebool -P httpd_use_nfs onsetsebool就是SELinux的开关总闸。布尔值数量很多用grep过滤关键词是最高效的办法。-P参数代表持久化到磁盘不加的话重启失效。4.3 案例二修改SSH端口后连接被拒把sshd监听端口从22改到2222放行防火墙后客户端连接却被拒绝。这通常是SELinux对端口的强制sshd进程只能监听被标记为ssh_port_t的端口。可以用semanage port -l | grep ssh看到当前允许的端口列表修改命令semanage port -a -t ssh_port_t -p tcp 2222然后确认semanage port -l | grep ssh_port_t类似的问题还有NFS、DNS等自定义端口原则一模一样服务启动失败或端口连不上时先看AVC日志再查semanage port -l是否包含该端口。4.4 案例三Samba共享目录无法写入Samba目录默认标签是samba_share_t如果管理员把共享目录建在/home/share或者给已有目录打了错误的标签客户端只能读不能写甚至根本看不见。semanage fcontext -a -t samba_share_t /home/share(/.*)? restorecon -Rv /home/share同时注意Samba相关的布尔值比如samba_export_all_rw用来允许Samba导出所有可读写文件系统。这类问题在RH134实验里出现频率很高考试也喜欢用服务配置正确但功能异常来考察排错能力。4.5 布尔值调整的最佳实践SELinux布尔值的调整要遵循最小化原则只开需要的开关不要图省事全开getsebool -a | grep ftp setsebool -P ftpd_full_access on # 慎重这相当于放开整个FTP域限制练习环境下可以临时不开-P先用当前会话验证确认业务正常后再决定是否持久化。开启后一定要检查/var/log/audit/audit.log有没有继续输出新的AVC记录避免解决了A问题又触发B问题。5. 那些坑、考试要点和延伸思考学SELinux最大的障碍不是概念多难懂而是习惯性地用传统权限思维去猜问题。整理几个我在RH134学习和实际运维中反复踩过的坑以及这门课在考试和后续技术栈里的连接点。5.1 四个最容易踩的坑第一一遇到权限问题就setenforce 0。临时降级定位问题本身没问题但很多人定位完忘了切回来服务正常了就以为万事大吉下次重启策略恢复后问题复发又重复降级。生产环境如果只能在enforcing模式下运转通过降级来绕过问题的习惯迟早要出事。第二只改/etc/selinux/config不重启以为立即生效。这个文件只在启动阶段读取你想让它立刻生效又不想重启可以用setenforce 0/1临时切换或者干脆按计划窗口重启。很多人改了配置文件后对着getenforce看了半天觉得怎么没变原因就在这里。第三把chcon当成永久修改。前面已经说过chcon直接改标签一旦restorecon就会按策略库重写。正确做法是semanage fcontext注册规则然后用restorecon落地。第四只关注文件权限不关注目录权限和父目录上下文。SELinux对目录的type要求经常被漏掉比如httpd要访问/data/web/pic你只给pic打了httpd_sys_content_t但父目录/data/web还是usr_t进程在遍历路径时一样会被拦。用restorecon -Rv把整棵目录树都校正过才不容易漏。5.2 RH134考试里SELinux的考查方式RH134考试不会让你去写策略文件它的重点是通过一系列服务配置场景暗中检查你是否掌握了SELinux管理。比如把网站根目录换到一个新路径要求排错直到服务能正常访问或者把sshd端口修改后要求服务依然可用又或者Samba共享能在客户端读写。这些题目的共同点是如果直接关闭SELinux服务可能判定成功但考试环境会检查SELinux模式禁用了或者长期permissive都可能导致整题零分。备考时建议在enforcing模式下完成所有服务实验并且练熟下面的组合semanage fcontext -a -t 类型 路径(/.*)? restorecon -Rv 路径 semanage port -a -t 服务类型 -p tcp 端口 setsebool -P 布尔值 on ausearch -m AVC -ts recent练到看到服务异常第一反应是去查AVC日志而不是去看防火墙和权限基本就过关了。5.3 延伸SELinux不仅是红帽课程里的知识点SELinux并不只是RHEL的专属概念。Android内核也默认开启了SELinux强制模式把每个应用当成一个独立domain限制应用访问系统属性、传感器、其他应用的数据。近期有开发者反馈Android 16上某些原本可用的数据存储方案比如SharedPreferences的兼容实现因SELinux策略收紧而无法工作底层原因本质上就是目标对象的标签或domain的权限不再匹配。理解了RH134里的domain与type的概念再看这类移动端问题会通透很多这不是Flutter、Java代码能解决的问题而是安全策略层面的限制。学习RH134这一章真正的收获是建立系统安全状态需要被观测和管理的意识。它不是给你一套需要背的规则而是给你一套定位问题和修正状态的工具箱。把这套工具练熟无论以后管理服务器还是排查应用兼容性问题都会比别人多一个维度。
返回列表