我正在将几个 Wordpress 博客迁移到 AWS,并遇到了文件权限问题,这个问题在过去的几个小时里一直困扰着我。
最简单的 fopen 调用总是会失败,并显示“无法打开流:权限被拒绝”:
<?php $handle = fopen('test.txt', 'w') or die('Can\'t open file'); ?>
我已经尝试/检查了以下内容
- 我正在写入的目录具有正确的文件权限 (755) 和正确的所有权。 直到 /home 路径都是如此。
- 我正在写入正确的目录,并确认获取cwd()
- 测试 PHP 脚本对与我尝试写入的路径相同的所有权进行哈希处理并纠正权限(644)。
- 我正在运行 mod_suexec,以确保脚本以与我写入的路径相同的用户和组执行。函数获取我的 ID()和获取我的GID()返回正确的用户和组 ID(编辑:这是错误的,见下文)。
- PHP 安全模式在 php.ini 中被禁用。
- fopen 不是不允许的 PHP 函数。
- 指某东西的用途open_basedir被禁用。
我是否遗漏了什么可能导致了这种情况?我怀疑我已经盯着这个问题很久了,以至于忽略了一些明显的东西。
更新:申请后womble 的建议我开始认为这个问题比糟糕的权限或 PHP 配置错误更严重。我确实设法让上述代码写出一个文件,但是即使使用正确的用户和组执行 PHP 脚本,生成的文件所有权和组也设置为 apache。如果我从命令行执行相同的测试脚本,则发出的文件具有正确的权限。这让我相信这是我使用 mod_suexec 时出现的问题。
编辑:我的使用获取我的 ID()和获取我的GID()是错误的,因为它们只返回脚本文件的用户和组,而不是运行时的权限。更正确的方法是使用 comething,如下所示:
<?php echo exec('ps -up '.getmypid()); ?>
答案1
好问题——说明你已经做好了准备。
我想不出任何您未能检查的“明显”的事情,所以我只能给您一些更高级的调试建议。
- 启动
strace
PHP 进程,并准确了解其内部运行的情况。 - 编写一些代码来执行
fopen(..., 'r')
三重检查,以确保目录树权限确实正确。 su
发送给相关用户,并尝试在命令行上执行一些操作。如果成功,那么你知道您的脚本没有以您认为的权限运行。- 检查文件、目录或前导路径组件上是否没有扩展 ACL(
getfacl
可以使用的工具)。这种情况并不常见,但偶尔它们会突然出现并撕破你的脸。如果你确实有 ACL,请setfacl -x
在确认它们没有必要后将其删除。
答案2
检查 apache 的主文件夹是什么(通常是/var/www
),并将文件放在此文件夹下,最后授予必要的权限。将 php 临时上传文件夹更改为此。这对我来说很有效。
答案3
尝试/usr/sbin/apachectl -t -D DUMP_MODULES
检查所有模块是否已启用
如果你得到
Warning: SuexecUserGroup directive requires SUEXEC wrapper.
解决
此类警告通常是由于 suexec wrapper 上的权限无效引起的,应该是:
# ls -la /usr/sbin/suexec
-rwsr-xr-x 1 root root 12064 2008-04-17 01:15 /usr/sbin/suexec
如果权限或所有权与上面的示例不同,请使用以下命令进行更正:
# chown root:root /usr/sbin/suexec
# chmod 4755 /usr/sbin/suexec
修复之后一切正常。
答案4
2 件事。
- 您需要在 die 语句中转义撇号。
- 5 是 rx,6 是 rw-。我会将您的权限设置为 0766,即 -rwxrw-rw-