Linux SELinux 的 restorecon vs chcon vs semanage 的正确使用顺序

7次阅读

restorecon 是还原 selinux 默认上下文的唯一正解,它依据 semanage fcontext 定义的策略自动修复文件上下文,而 chcon 仅临时覆盖且不持久,semanage fcontext 才是永久生效的起点。

Linux SELinux 的 restorecon vs chcon vs semanage 的正确使用顺序

restorecon 是“还原默认上下文”的唯一正解

当你发现某个文件或目录的 SELinux 上下文被改乱了(比如 httpd 突然无法读取 /var/www/html/custom.html),第一反应不应该是手动打补丁,而是先问:这个路径原本该是什么上下文?restorecon 就是干这个的——它查系统策略里为该路径预设的类型(比如 httpd_sys_content_t),然后把它“刷”回去。

  • 它不依赖你记类型名,只依赖当前已加载的策略(semanage fcontext -l 查到的规则)
  • -v 参数能看到实际变更:sudo restorecon -v /var/www/html/custom.html
  • -R递归修复整个目录,但要小心——如果目录里混着用户私有文件(如 ~/.ssh/config),强行 restorecon -R 可能把它改成错误类型,导致 SSH 失败
  • 它不会修改策略本身,只是“应用已有规则”,所以重启后依然有效

chcon 是临时覆盖,关机就丢,慎用

chcon 直接改文件元数据里的上下文字段,像给文件贴一张新标签。它快、直接,但代价是“不持久”且“不继承”——子文件/新建文件不会自动获得同样上下文,而且一旦执行 restorecon 或系统 relabel,就全没了。

  • 典型误用场景:看到 ls -Z 显示类型不对,随手 sudo chcon -t httpd_sys_content_t /path/to/file,结果第二天服务又挂了
  • 真正适合它的场景极少,比如调试时想快速验证某个类型是否真能解决问题,或临时绕过策略限制做测试
  • 永远别对整个 /home/etcchcon -R——用户家目录该是 user_home_t,硬改成 httpd_sys_content_t 会导致用户登录失败

semanage fcontext 才是“永久生效”的起点

想让某个自定义路径(比如 /srv/myapp/Static)长期拥有正确上下文,必须走 semanage fcontext + restorecon 这套组合。前者注册规则,后者落地执行。漏掉任一环,都不算真正解决。

  • 先加规则:sudo semanage fcontext -a -t httpd_sys_content_t '/srv/myapp/static(/.*)?'(注意正则末尾 (/.*)? 表示包含子目录)
  • 再执行:sudo restorecon -Rv /srv/myapp/static —— 这步不能跳,semanage 只写规则库,不改文件
  • 规则存在 /etc/selinux/targeted/contexts/files/file_contexts.local,所以重装系统或换策略后需重新导入(semanage import
  • 如果路径已存在且上下文错,restorecon 会按新规则修正;如果路径未来才创建,只要规则在,restorecon 或系统 relabel 都会自动处理

为什么不能只用 chcon + restorecon,跳过 semanage?

因为 restorecon 默认只认策略里“已知路径”的规则。你手动 chcon 改过的上下文,不在策略库里,下次 restorecon 一跑,就给你打回原形——它只认 semanage fcontext -l 输出里列出来的那些路径。

  • 常见翻车点:运维同学用 chcon 修好问题后没记录,一周后同事执行了 sudo restorecon -R /srv,服务立刻中断
  • 另一个坑:用 chcon -R 改了整个网站目录,但忘了 semanage 规则里没覆盖 .htaccess 或上传目录,结果上传功能因类型不匹配被拒,日志里只报“Permission denied”,看不出 SELinux 在作祟
  • 真实环境里,semanage fcontext 是配置管理(ansible/Chef)唯一该操作的命令,chcon 应该进黑名单

最常被忽略的一点:规则加完不 restorecon,等于写了合同没签字——策略存在,但文件还是老样子。

text=ZqhQzanResources