I have few different sites in the /home
directory. It worked before the update, but now the Apache HTTP Server cannot access them. I get the error below:
Permission denied: [client 127.0.0.1:58170] AH00035: access to / denied (filesystem path '/home/xxx') because search permissions are missing on a component of the path
There is a warning on startup too:
AH00112: Warning: DocumentRoot [/home/xxx/websites/a_website] does not exist
The file exists int the file system though.
The /home
is a mount point for a whole partition. If I mount the same partition on /alt_home
, it works fine from there. I have to alter configuration though. Soft links do not work.
AH00037: Symbolic link not allowed or link target not accessible: /a/path/to/website
To my knowledge there is no SELinux or AppArmor. The Linux distribution is the Arch.
What makes this blockage and how to fix it?
1 Answer 1
Arch doesn't do SELinux, but it does have AppArmor. You might happen to have it installed, although it is ineffective in this case because it only ships a profile for /usr/bin/apache2 (Debian style) but not for /usr/bin/httpd. If that weren't the case, dmesg
or journalctl -b
would be the place to find AppArmor denials.
With systemctl cat httpd
you would see that the service has additional isolation options (not based on SELinux or AppArmor). Specifically:
[Service]
ProtectHome=on
which is based on container namespacing – i.e. the service sees different things than you, and the contents of /home literally do not exist in Apache's "view" of the filesystem (i.e. the warning is accurate). You can change this to off
using systemctl edit httpd
, then restart the service.
Note that you don't need to disable ProtectHome in general – you can use BindPaths=
or BindReadOnlyPaths=
to allow Apache to read just some specific directories.
[Service]
; To unveil individual paths, must use the 'tmpfs' mode
; so that systemd could create mountpoints.
ProtectHome=tmpfs
BindPaths=/home/foo/public_html
BindReadOnlyPaths=/home/bar/public_html
(Specifically BindPaths=
, not ReadWritePaths=
. The latter only works with ProtectHome=ro
, i.e. makes still-visible read-only paths writable again, whereas ProtectHome=on
makes the paths invisible (nonexistent) so they need to be bind-mounted into place again.)