RHEL8环境Apache下PHP无法创建文件/文件夹Permission denied报错
RHEL 8 系统默认启用SELinux强制访问控制机制,你之前修改文件属主、给777权限都属于传统DAC权限调整,SELinux的强制规则会默认拦截Apache(httpd)进程对web目录的写入操作,这是你改完普通权限依然报错的核心原因。
1. 先确认SELinux运行状态
执行以下命令查看SELinux当前模式:
sestatus
如果输出中Current mode字段为enforcing,说明SELinux正处于强制拦截模式,大概率是拦截来源。
可以用临时命令切到宽容模式验证问题(服务器重启后自动恢复强制模式,仅用于验证):
sudo setenforce 0
刷新PHP测试页面,如果文件可以正常创建,就100%确认是SELinux规则拦截。验证完成后记得切回强制模式,避免安全风险:
sudo setenforce 1
2. 重置安全的文件权限(先删掉你之前配置的高危777权限)
777权限会给所有系统用户开放目录的完全控制权,存在严重安全隐患,先把权限重置为合规配置:
# 递归修正web目录属主为Apache运行用户 sudo chown -R apache:apache /var/www # 目录设置755权限(所有者可读写执行,其他用户只读执行) sudo find /var/www -type d -exec chmod 755 {} \; # 文件设置644权限(所有者可读写,其他用户只读) sudo find /var/www -type f -exec chmod 644 {} \;
注意:你之前执行chown时用的是相对路径www,如果执行命令时当前工作目录不是/var,这个命令根本不会修改/var/www的属主,后续操作请一律用绝对路径。
3. 配置SELinux规则允许Apache写入web目录
如果执行semanage命令提示不存在,先安装依赖工具包:sudo dnf install policycoreutils-python-utils -y
默认情况下/var/www/html的SELinux上下文标签是httpd_sys_content_t,仅允许httpd进程读取内容,要支持写入需要给需要写的路径打上可写标签:
- 如果是开发环境,需要给整个web目录开放写入权限,执行以下命令永久添加SELinux文件上下文规则:
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html(/.*)?"
- 如果是生产环境,只需要给你需要写入的特定目录(比如缓存目录、上传目录)加规则即可,比如只给
/var/www/html/runtime开权限:
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/runtime(/.*)?"
规则添加完成后,执行以下命令让上下文规则立即生效:
sudo restorecon -Rv /var/www/html
4. 开发环境可选配置(解决PHP调用exec等系统函数的权限问题)
你的测试代码里用到了exec()函数,开发环境可以开启SELinux的httpd统一权限布尔值,避免其他不必要的拦截(永久生效):
sudo setsebool -P httpd_unified 1
如果之后再遇到类似权限问题,可以直接查SELinux的拦截日志定位问题:
sudo ausearch -m avc -ts recent
命令会输出最近10分钟内所有SELinux拦截的操作记录,可以直接看到具体是哪条规则拦截了进程操作。
内容的提问来源于stack exchange,提问作者Ugur Demir

