"failed to open stream: Read-only file system" when trying to create file outside webroot with php
I'm trying to setup nextcloud on a RaspberryPi 3 running arch linux (alarm) for a week now.
I've setup apache, php with php-fpm, postgresql and installed nextcloud-testing from the AUR (because nextcloud 17 does not support php 7.4).
apache's webroot is at /srv/http
but nextcloud installs to /usr/share/webapps/nextcloud
.
my VirtualHost:
<VirtualHost *:443>
DocumentRoot "/srv/http"
<Directory "/srv/http">
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
...
#ssl stuff
...
ScriptAlias /cgi-bin/ "/srv/http/cgi-bin/"
<Directory "/srv/http/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory>
Alias /nextcloud /usr/share/webapps/nextcloud/
<Directory /usr/share/webapps/nextcloud>
Options FollowSymlinks
AllowOverride all
Require all granted
</Directory>
</VirtualHost>
When accessing https://mydomain/nextcloud
in a browser the error message is that writing to the config directory is not possible. The php code to check this uses is_writable()
, so to debug this I tried (I will harden security again after this is working at all):
-
chown -R http:http /usr/share/webapps/nextcloud
-
chmod -R 777 /usr/share/webapps/nextcloud
- directories
/usr/share/webapps
,/usr/share
and/usr
have x permission for others -
sestatus
returnscommand not found
-
su -s /bin/bash http
, thenecho test > /usr/share/webapps/nextcloud/test.txt
works - setting
open_basedir = /
in/etc/php/php.ini
and restartingphp-fpm
didn't help
I've created /srv/http/test.php
:
<?php
echo "username: ", exec('whoami'), "<br/>";
echo "open_basedir: ", var_dump(ini_get('open_basedir')), "<br/>";
$myfile = "/usr/share/webapps/nextcloud";
#$myfile = "/srv/http";
// checking permissions of the file
$permissions = fileperms($myfile);
$perm_value = sprintf("%o", $permissions);
// Clearing the File Status Cache
clearstatcache();
// checking whether the file is writable or not
if(is_writable($myfile))
{
echo "$myfile file is writable and
it has the following file permissions : $perm_value", "<br/>";
}
else
{
echo "$myfile file is not writable and
it has the following file permissions : $perm_value", "<br/>";
}
// Clearing the File Status Cache
clearstatcache();
$fs = fopen($myfile . "/test.txt","w") or die("cannot fopen");
fwrite($fs,date(DATE_RSS));
fclose($fs);
?>
https://mydomain/test.php
shows
username: http
open_basedir: string(0) ""
/usr/share/webapps/nextcloud file is not writable and it has the following file permissions : 40777
Warning: fopen(/usr/share/webapps/nextcloud/test.txt): failed to open stream: Read-only file system in /srv/http/test.php on line 30
cannot fopen
When setting $myfile = "/srv/http";
the error message is as expectedWarning: fopen(/srv/http/test.txt): failed to open stream: Permission denied in /srv/http/test.php on line 30
as /srv/http
is owned by root
and has no write permission for others. When chmod o+w /srv/http
the script outputs file is writable
and writes the current date to /srv/http/test.txt
.
Because of the Read-only file system
-warning for /usr/share/webapps/nextcloud
I suspect a security setting or default behaviour of arch, apache, php, php-fpm or something else in place to restrict write access of php to /srv/http
, but I can't figure out which setting and how to include /usr/share/webapps/nextcloud
.
I guess I could move nextcloud to /srv/http/
, but I'd rather do this the right way to not break package updates and other things.
So the question is how can I allow php to create files in /usr/share/webapps/nextcloud
?
Edit:
Thanks Nover for the answer. This was indeed the reason for the denied access. Instead of moving the nextcloud-instance or removing the security restriction of ProtectSystem=full
completely by commenting it out, I created a drop-in file for php-fpm.service with systemctl edit php-fpm.service
with the following content:
[Service]
ReadWritePaths=/etc/webapps/nextcloud/config /usr/share/webapps/nextcloud/apps /usr/share/webapps/nextcloud/data
I found from the following link that the Systemd php-fpm
service may be configured to block any write action on certain folders and subfolders, and /usr
is impacted by this.
You may want to move you nextcloud instance as you mentionned, or you may also want to edit the systemd service (/usr/lib/systemd/system/php-fpm.service
) and comment the line ProtectSystem=full
. You will need to restart the service (sudo systemctl restart php-fpm
).
Please note that this line in the service was there for security purpose, so you may expose yourself to some attack.
https://github.com/getgrav/grav/issues/2756