Php 权限被拒绝写入一个目录,但不写入另一个目录--两者都具有相同的所有者/组/755

Php 权限被拒绝写入一个目录,但不写入另一个目录--两者都具有相同的所有者/组/755,php,apache,centos,Php,Apache,Centos,这快把我逼疯了。httpd以用户apache的身份运行。我在/var/www/html中有两个目录-上传和照片。两者都有一个组:apache:apache的所有者。两者都是755。上传是可从php写入的,而照片则不是 一些测试代码: var_dump(touch('/var/www/html/photos/_test.log')); var_dump(touch('/var/www/html/uploads/_test.log')); var_dump(touch('/var/www/html/

这快把我逼疯了。httpd以用户apache的身份运行。我在/var/www/html中有两个目录-上传和照片。两者都有一个组:apache:apache的所有者。两者都是755。上传是可从php写入的,而照片则不是

一些测试代码:

var_dump(touch('/var/www/html/photos/_test.log'));
var_dump(touch('/var/www/html/uploads/_test.log'));
var_dump(touch('/var/www/html/uploadsasdf/_test.log'));
结果:

Warning: touch(): Unable to create file /var/www/html/photos/_test.log because Permission denied in /var/www/html/test.php on line 2
bool(false) 
bool(true) 
Warning: touch(): Unable to create file /var/www/html/uploadsasdf/_test.log because Permission denied in /var/www/html/test.php on line 4
bool(false)
我已经通过shell和GUI界面确认了权限。我把所有东西都吃了又做了,只是为了确定。我已将uploads目录重命名为其他名称,并将photos重命名为uploads,以查看目录名是否是此处的键,但不是。这是目录本身。重命名后的uploads仍然可以使用新名称,而现在称为uploads的photos目录则不能使用

需要注意的是,_test.log在测试之前不存在于文件夹中,因此该文件并没有错误的权限或任何东西

有趣的是,如果我创建了一个新的目录,把它改成apache:apache,chmod改成777,我就不能写入它,所以这里可能有更大的错误;但问题依然存在:为什么上传目录可以工作

以前有人见过这种行为吗?我错过了什么明显的东西吗

提前感谢您的帮助

编辑以添加更多信息:

exec('whoami') 
阿帕奇

var_dump(posix_getpwuid(fileowner('/var/www/html/')));
var_dump(posix_getpwuid(fileowner('/var/www/html/uploads/')));
var_dump(posix_getpwuid(fileowner('/var/www/html/photos/')));
所有阿帕奇

所有文件都具有相同的fileperms值。但是,除了上传,is_writable在所有情况下都为false

警告:mkdir:权限被拒绝

ls-alF

drwxr-xr-x.  2 apache apache 286720 Nov 22 15:17 photos/
drwxr-xr-x.  2 apache apache  81920 Nov 22 12:06 uploads/
drwxr-xr-x.  2 apache apache      6 Nov 22 10:31 uploadsasdf/

我已经打电话给他了;我已重新启动服务器。什么在…上地球?

既然您使用的是CentOS,而且您已经尝试了其他一切,我猜可能与SELinux有关。这个问题的其中一个答案可能会有所帮助

具体来说,请尝试分析SELinux权限ls-lZ并暂时禁用SELinux:

如果您使用的是CentOS,则可能是selinux的问题。检查selinux是否使用“sestatus”启用。如果已启用,您可以使用“sudo set0”临时检查这是否是问题所在。如果apache可以为站点提供服务,那么您只需要使用“sudo chcon-R-t httpd_sys_content_t”递归地更改文件的上下文。您可以使用“ls-Z”检查现有上下文


由于您使用的是CentOS,并且您已经尝试了其他所有方法,因此我猜可能与SELinux有关。这个问题的其中一个答案可能会有所帮助

具体来说,请尝试分析SELinux权限ls-lZ并暂时禁用SELinux:

如果您使用的是CentOS,则可能是selinux的问题。检查selinux是否使用“sestatus”启用。如果已启用,您可以使用“sudo set0”临时检查这是否是问题所在。如果apache可以为站点提供服务,那么您只需要使用“sudo chcon-R-t httpd_sys_content_t”递归地更改文件的上下文。您可以使用“ls-Z”检查现有上下文

如果启用了selinux,sestatus会告诉您,请尝试sudo restorecon-Rv/var/www/first。听起来很像是SELinux在碍事,你不知怎的得到了一个没有正确标记的文件/目录。Restorecon将把标签恢复为默认值,-v将显示哪些标签已被更正(如果有的话)

如果做不到这一点,就会想到扩展属性。执行lsattr,如果输出看起来像--i---,则设置不可变标志。使用chattr-i更改它,您就可以开始了。

如果启用了selinux,sestatus会告诉您,请尝试sudo restorecon-Rv/var/www/first。听起来很像是SELinux在碍事,你不知怎的得到了一个没有正确标记的文件/目录。Restorecon将把标签恢复为默认值,-v将显示哪些标签已被更正(如果有的话)


如果做不到这一点,就会想到扩展属性。执行lsattr,如果输出看起来像--i---,则设置不可变标志。用chattr-i进行更改,您就可以开始了。

谢谢!我把这个作为答案,因为它是第一个,引导我走上正确的道路。该问题确实与selinux相关,但由于某些原因,chcon无法工作,并且此服务器上未安装semanage。因此,我安装了semanage,然后运行以下两个命令来添加新的上下文,然后应用它:semanage fcontext-a-t httpd_sys\u rw_content\u t/var/www/html/photos。。。restorecon-Rv/var/www/html/谢谢!我把这个作为答案,因为它是第一个,引导我走上正确的道路。该问题确实与selinux相关,但由于某些原因,chcon无法工作,并且此服务器上未安装semanage。因此,我安装了semanage,然后运行以下两个命令来添加新的上下文,然后应用它:semanage fcontext-a-t httpd_sys\u rw_content\u t/var/www/html/photos。。。restorecon-Rv/var/www/html/感谢您的帮助!restorecon本身不起作用,但这个答案帮助我找到了一个解决方案。照片和上传是通过相同的过程同时创建的
s、 所以我不明白为什么一个需要一个特殊的上下文规则,而另一个不需要,但它现在起作用了。@Sarthaz很高兴你修复了它。如果不进行认真的挖掘,就很难诊断上下文标签为什么会弄乱。一个常见的原因是移动文件,可能同时暂时禁用SELinux。我会给你一个投票,让你真正解决问题并在这里分享,而不仅仅是关掉SELinux,大多数人都会很遗憾地推荐它!:谢谢你的帮助!restorecon本身不起作用,但这个答案帮助我找到了一个解决方案。照片和上传是通过相同的过程同时创建的,所以我不明白为什么一个需要特殊的上下文规则,而另一个不需要,但它现在可以工作了。@Sarthaz很高兴你修复了它。如果不进行认真的挖掘,就很难诊断上下文标签为什么会弄乱。一个常见的原因是移动文件,可能同时暂时禁用SELinux。我会给你一个投票,让你真正解决问题并在这里分享,而不仅仅是关掉SELinux,大多数人都会很遗憾地推荐它!:
ls-alF

drwxr-xr-x.  2 apache apache 286720 Nov 22 15:17 photos/
drwxr-xr-x.  2 apache apache  81920 Nov 22 12:06 uploads/
drwxr-xr-x.  2 apache apache      6 Nov 22 10:31 uploadsasdf/