使用自定义临时目录时,上传文件为何被标记为httpd_tmp_t?
核心原因:SELinux上下文与文件移动的行为差异
默认
/tmp的SELinux特殊适配
系统默认/tmp目录的SELinux标签为tmp_t,但它属于系统预设的标准临时目录范畴,SELinux策略中专门做了适配:允许httpd进程处理该目录下的文件,且在跨目录移动时,会自动将文件上下文调整为目标目录的标签。这就是使用默认/tmp时不会出现问题的根本原因。自定义临时目录的SELinux策略缺失
你创建的/var/www/project/tmp标签为tmp_t,但不在系统预设的httpd允许的临时目录范围内。PHP在该目录创建的文件会被标记为httpd_tmp_t,使用move_uploaded_file移动时,SELinux会保留原文件的上下文,不会自动转换为目标目录的httpd_sys_rw_content_t——因为默认策略不允许非标准临时目录的文件直接继承目标目录的上下文。ACL丢失的关联因素
文件在自定义临时目录创建时,继承的是该目录的ACL(对应1777权限)。跨目录移动时,由于SELinux上下文不匹配,安全策略会干扰目标目录默认ACL的继承逻辑,最终导致文件丢失目标目录的ACL配置。
解决方法
1. 修改自定义临时目录的SELinux标签
将临时目录的标签改为httpd_sys_rw_content_t,这样PHP创建的文件会直接继承该标签,移动到uploads目录时上下文一致,也能正常继承ACL:
semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/project/tmp(/.*)?" restorecon -Rv /var/www/project/tmp
2. 放宽httpd的SELinux上下文限制
如果不想修改临时目录标签,可以开启httpd_unified布尔值,允许httpd在不同的相关上下文之间转换文件:
setsebool -P httpd_unified 1
3. 确保目标目录的默认ACL配置正确
检查并设置uploads目录的默认ACL,保证文件移动后能正确继承权限:
# 查看当前ACL配置 getfacl /var/www/project/uploads # 设置默认ACL(若未配置) setfacl -d -m u:apache:rwx /var/www/project/uploads setfacl -m u:apache:rwx /var/www/project/uploads
验证操作
修改配置后重新上传文件,通过以下命令检查结果:
# 检查SELinux上下文 ls -Z /var/www/project/uploads/[上传文件名] # 检查ACL配置 getfacl /var/www/project/uploads/[上传文件名]
内容的提问来源于stack exchange,提问作者jamieburchell

