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

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或/etc用chcon -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,等于写了合同没签字——策略存在,但文件还是老样子。










