我在全新的 centos7 上安装了 httpd 和 php,并将一些文件放入 /var/www/html,包括我编写的安装脚本。此脚本需要写入 /var/www/html 目录中的配置文件。我创建了一个空的配置文件,并将其所有者更改为 apache:apache。但是,尝试使用写权限打开此文件总是会出现错误:
fopen(/var/www/html/config-local.php): failed to open stream: Permission denied
在做研究时,我读到了这样一句话:“为了访问某个文件,所有父目录都必须是可读的。”所以我检查了一下,发现确实如此。/、/var、/var/www 和 /var/www/html 都是所有人都可读的。
那么这里发生了什么?看来 apache 用户是某种受到特殊限制的用户,因为使用标准用户测试相同的场景可以正常工作。
答案1
这可能是 SELinux 权限问题。/var/log/audit/audit.log
应该能够确认。
SELinux 上下文可能是system_u:object_r:httpd_sys_content_t:s0
,但应该是system_u:object_r:httpd_sys_rw_content_t:s0
。可以使用 进行更改chcon
。
我也不太相信DocumentRoot
您的网络服务器中有一个配置文件。我可能弄错了,因为您没有提供足够的细节,但如果您没有更改默认设置,情况就会如此。
答案2
花了很多时间寻找这个答案,但都是零零碎碎的,没有人发布解决方案(大多数时候),所以这是我的解决方案,它也用于各种网络控制面板。
安装并使用 MOD_RUID2
使用 CLI 安装 PHP(这是新版本的标准)
在虚拟主机中的 HTTPD.CONF 文件中,您将添加以下内容,将用户名替换为用户的登录名,将用户组替换为用户的组(这些通常是相同的)
<IfModule !mod_ruid2.c>
SuexecUserGroup username usergroup
</IfModule>
<IfModule mod_ruid2.c>
RMode config
RUidGid username usergroup
RGroups @none
</IfModule>
虚拟主机配置的一个示例是:
<VirtualHost *:443>
DocumentRoot "/home/imtheuser/public_html"
ServerName imtheuser.com
<IfModule !mod_ruid2.c>
SuexecUserGroup imtheuser imtheuser
</IfModule>
<IfModule mod_ruid2.c>
RMode config
RUidGid imtheuser imtheuser
RGroups @none
</IfModule>
<Directory "/home/imtheuser/public_html">
allow from all
Options None
Require all granted
</Directory>
</VirtualHost>
这将允许 apache/php 写入用户拥有的目录。这比将 chmod 设置为 0777 更安全。