这类问题我又碰上了一次。CentOS 7.9 上给上传目录用 chcon 打了 httpd_sys_rw_content_t,当天能用,第二天重启后 nginx 又写不进去,日志是 Permission denied,ls -Z 显示标签回到了 default_t。
第一反应是「上传目录由应用动态创建,新目录继承的是父目录的标签」,验证下来不成立。
这类报错背后常见的原因有几处,逐个排除就行。chcon 只改 inode 上的标签,不写进策略库,relabel 或重启就被覆盖;文件系统在开机时按 fcontext 规则重新打标,手工改动全部丢失;策略包里没有这个路径的规则,只能靠临时手段维持。
上来先看标签现在是什么
ls -Zd /data/upload && getenforce
注册持久的 fcontext 规则
semanage fcontext -a -t httpd_sys_rw_content_t '/data/upload(/.*)?'
然后按规则重新打标并保留上下文
restorecon -Rv /data/upload | tail -3
末了让新建的子目录自动继承
semanage fcontext -m -t httpd_sys_rw_content_t '/data/upload(/.*)?' && restorecon -R /data/upload
报错是间歇性的,我蹲守了半小时才抓到一次完整现场。
恢复的判定其实很直接。重启后 ls -Z 显示上传目录仍是 httpd_sys_rw_content_t,nginx 上传成功,error_log 里没有 Permission denied。
提醒一点。chcon 适合临时验证,长期一定要写 semanage fcontext;写规则时带上 (/.*)? 才能覆盖后面新建的子目录。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
