php-fpm在已有系统权限的情况下仍然提示无写入权限/Read-only file system的解决办法

杯杯杯杯具 2020-07-21 PM 97℃ 0条

重装系统后,重新配置了一遍开发环境,出现了一个神奇的PHP权限问题,记录如下。

/var/www/xxx/ —— 项目根目录,所有者tongyifan:tongyifan
/var/www/xxx/yyy/ —— 需要写入文件的目录,所有者tongyifan:tongyifan
nginx和php-fpm使用http:http运行

首先,尝试了一下如下代码

<?php
var_dump(is_writable("/var/www/xxx/yyy/"))

不出所料,返回了 bool(false)

第一反应是这个文件夹的权限没给够,遂直接运行了

sudo chown -R http:http /var/www/xxx/yyy
sudo chmod -R 777 /var/www/xxx/yyy

再运行了一下上面的代码,并没有什么变化,这就比较让人迷惑了。

去网上一番查找,有说是SELinux的问题,然而Manjaro并没有SELinux这种没有用的东西,再试了一下使用http用户直接在这个文件夹创建文件,可以直接创建,因此排除了系统权限的问题,把目标直接指向PHP。

sudo runuser -uhttp touch /var/www/xxx/yyy/test

继续查下去,还有说是 php.ini 中的 open_basedir 配置项的问题,这个配置项会限制php脚本仅可以访问指定的目录,具体见PHP文档,然而打开 php.ini 看了一下,这个配置项并没有被配置。

按照stackoverflow的一个问题「Why can't PHP create a file, even with 777 permissions?」中的代码尝试了一下 fopen ,发现了一个神奇的报错。

<?php
fopen("/var/www/xxx/yyy/test", "c");
// Warning: fopen(/var/www/xxx/yyy/test): failed to open stream: Read-only file system in /usr/share/nginx/html/xxx/test.php on line 17

最终,在serverfault的一个问题「“failed to open stream: Read-only file system” when trying to create file outside webroot with php」中找到了答案,我们打开 /usr/lib/systemd/system/php-fpm.service 可以看到一个配置项:

# Mounts the /usr, /boot, and /etc directories read-only for processes invoked by this unit.
ProtectSystem=full

查了查发现这个配置项在2018年底被引入到php-fpm.service中以保护系统安全,见[email protected],然而却卡了我这么久= =注释掉后问题解决。

标签: PHP

非特殊说明,本博所有文章均为博主原创。

评论啦~