Centos 7 / Apache / PHP - mkdir(): Permission denied Centos 7 / Apache / PHP - mkdir():权限被拒绝

20

在你们大喊“重复”,将我放逐到深渊之前,请听我说。 :)

我正在为我所在公司开发一个内部网站,最初我是直接从我的运行Windows 7 / IIS的工作站上进行开发的。随着我接近完成网站/应用程序的开发,我得到了一台Centos 7的机器,它运行着Apache,所以我已经开始将它迁移到那个系统上。我已经解决了大部分小问题,并使网站现在可以运行。然而,有一部分网站与我们的数据库交互,并根据登录的用户创建日志目录/文件。这部分使用了mkdir()函数,但我遇到了权限问题。

mkdir(): Permission denied

我已经做了以下工作:

  • 由于我使用的是Centos 7,所以Apache用户/组为apache:apache。 我使用chown并将/var/www/html/和Logs文件夹的所有者更改为apache用户/组。为了安全起见,我双重检查了httpd.conf并检查了运行中的进程,以确保我有正确的用户/组。
  • 我尝试过,只是为了测试目的,将所有这些文件夹的权限更改为chmod 777,但仍然出现相同的错误。
  • 从头到尾搜索StackOverflow,并且只得到了一些已经尝试过的答案,但都没有用。

因此,无论我使用chmod还是chown更改访问的文件夹的权限,我都会收到相同类型的错误。为了安全起见,我也检查了PHP用户,它也使用apache用户。

如果有人能够对为什么即使权限更改后也无法正常工作有额外见解,请告诉我。如果我错过了解释这种特殊情况的文章,则请指出并责备我。哈哈:)


编辑 好的,进一步测试后,我发现两个问题似乎导致了这个总体问题。

  1. 当脚本创建文件夹时,PHP尝试设置文件夹的权限,即使apache是所有者,似乎服务器也不喜欢这样做。删除代码的那部分后,权限错误消失了,我收到了一个“没有这样的文件或目录”的错误。
  2. 当通过sudo使用Apache用户测试创建目录时,它能够轻松地创建目录。但是,我的PHP脚本正在创建两个目录,然后在最后一个目录中创建日志文件。似乎您无法同时创建两个目录?例如,已经创建了一个Logs文件夹,而PHP正在尝试在其中创建两个目录,一个用于用户ID,然后在其中创建另一个文件夹以显示日期。因此,一旦PHP脚本运行,它应该创建类似于“Logs/5235/3-3-2015/”这样的东西

请注意,我尝试在PHP中将递归值设置为true,但那时我得到了最初记录的权限问题。当递归/模式被移除时,它不会出现权限问题,但无法创建嵌套目录。


编辑2

为了测试我的理论,我取消了嵌套并尝试让mkdir只创建1个目录,但它产生了与以前相同的错误。虽然它由Apache拥有,即使我将其设置为777,它仍然会返回权限问题。


3
你有检查所有日志吗?例如:SElinux 日志。尝试使用 tail -f /var/log/* 命令查看是否有其他内容。在测试时也请使用 sudo。例如:sudo -H -u apache bash -c 'mkdir /tmp/testapache'。 - risyasin
@Risyasin 我已经检查了所有日志,并且得到了相同类型的日志错误。我尝试通过sudo使用Apache创建目录,它可以完全无问题地创建目录。不过我可能已经发现了问题的根源,我将在原始帖子中更新新信息。 - Fata1Err0r
@Risyasin 我已经更新了原始帖子,加入了新的信息。基本上,当mkdir尝试设置递归和默认权限时,它会被拒绝。当我删除递归/模式时,它不会出现权限问题,但它也不会创建嵌套目录,因为默认情况下递归为false,所以它认为该位置不存在。正如我提到的,我已经将文件夹的所有权交给了Apache,甚至尝试将它们设置为777进行测试。 - Fata1Err0r
3个回答

55
可能是尽管你已经设置了755/777权限,但SELinux阻止httpd写入/创建目录。
尝试执行以下操作:
chcon -R -t httpd_sys_content_t /path/to/www
chcon -R -t httpd_sys_content_rw_t /path/to/www/dir/for/rw

进一步了解信息: http://wiki.centos.org/TipsAndTricks/SelinuxBooleans

我尝试了一下,但仍然出现相同的错误。我正在学习SELinux,并将继续深入研究它。我会告诉你我找到了什么。感谢您的回复,考虑得非常好。 - Fata1Err0r
这是我的错误,我把第一个命令放在了 /var/www/html 上,而将第二个命令放在了 /var/www/html/Logs 上。实际上,我应该在两个目录前面再多加一个文件夹。不管怎样,非常感谢! :D 这对我有帮助。SELinux 相当有趣,我将来会更加关注它。 - Fata1Err0r
7
正确的上下文是 httpd_sys_rw_content_t,而不是 httpd_sys_content_rw_t。 - CpnCrunch
2
它在我新安装的CentOs 7 + Apache + PHP(FastCGI)上也起作用了。 - AndrewShmig
"sudo chcon -R -t httpd_sys_content_t /var/www" 及 "sudo chcon -R -t httpd_sys_rw_content_t /var/www/html" 是两条有用的评论。 - FormerAtariUser

2

不确定,但您的Centos PHP二进制文件可能已经破坏了文件权限。有两种方法可以修复这个问题。

  • 从头开始编译PHP。我更喜欢这种方法,因为所有的控制权都在你手中。
  • 或者更改您的php脚本以使用PHP的Umask()函数。文档链接

感谢您的进一步协助。我将尝试并告诉您结果。 - Fata1Err0r
1
我没有机会测试这个,但感谢你今天给我的建议和建议。我从你那里学到了一些很棒的东西,我相信它将在未来派上用场。此外,如果没有你的帮助,我不会找到解决方案。最终问题出在SELinux如何处理我的HTTPD上。 - Fata1Err0r

-2
根据DRU响应,
这个问题是由SELINUX引起的。请使用以下命令:
chcon -R -t httpd_sys_content_rw_t /path/to/www/dir/for/rw

2
那与 @Dru 回应有何不同? - afxentios

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接