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


Permission denied writing to one directory, but not the other -- both have same owner/group/755

这让我发疯了。 httpd 以用户 Apache 的身份运行。 我在/var/www/html 中有两个目录——上传和照片。 两者都有 group:Owner of 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 界面确认了权限。 为了确定,我又把所有东西都揣了一遍又一遍。 我已将上传目录重命名为其他名称,并将照片重命名为上传,以查看目录的名称是否是此处的关键,但事实并非如此。 它是目录本身。 重命名的上传仍然使用新名称,现在称为"上传"的照片目录则无法使用。

值得注意的是,在测试之前,文件夹中不存在_test.log,因此该文件的权限并不好。

有趣的是,如果我创建一个新目录,将其 chown 到 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() 在所有方面都是错误的。

mkdir('var/www/html/test');

警告: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/

我调用了 clearstatcache(); 我已经重新启动了服务器。 什么。。。上。。。地球?

既然你使用的是 CentOS,并且你已经尝试了其他所有方法,我的猜测应该是与 SELinux 有关的东西。 这个问题的答案之一可能会有所帮助 禁止 您无权访问此服务器。仙人 6/拉拉维尔 4

具体尝试这样做来分析 SELinux 权限 (ls -lZ) 并暂时禁用 SELinux:

如果你使用的是 CentOS,这可能是 selinux 的问题。检查 selinux 是否启用了"sestatus"。如果已启用,您可以使用"sudo setenforcement 0"检查这是否是问题(暂时)。如果 apache 可以为站点提供服务,那么你只需要使用 'sudo chcon -R -t httpd_sys_content_t' 递归地更改文件的上下文(您可以使用 'ls -Z' 检查现有上下文。

如果启用了 selinux(sestatus会告诉你),请先尝试sudo restorecon -Rv /var/www/。听起来很像 SELinux 妨碍了您,并且您以某种方式在那里有一个未正确标记的文件/目录。Restorecon 会将标签恢复为默认值,-v将显示哪些标签已更正(如果有)。

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