Virtualhost does not work on Fedora with 403

JasonStack asked:

I have created a project under my home directory. Then, I created a virtual host in a new httpd conf file (I named it z-httpd.conf) I created under /etc/httpd/conf.d. The problem is that I cannot access the named virtual host that I created. When I browse to myservice.localhost, which I have also added to /etc/hosts, I get a 403 error. The z-httpd.conf file is as follows:

<Directory />
    AllowOverride none
    Require all denied
</Directory>


DocumentRoot "/var/www/html"

#
# Relax access to content within /var/www.
#
<Directory "/home/johndoe/src">
    AllowOverride None
    # Allow open access:
    Require all granted
</Directory>


# Further relax access to the default document root:
<Directory "/home/johndoe/src/webservice">
    #
    Options Indexes FollowSymLinks

    AllowOverride None

    #
    Require all granted
</Directory>


#Add a virtual host
NameVirtualHost *:80
<VirtualHost *:80>
    ServerName myservice.localhost
    DocumentRoot /home/johndoe/src/webservice/public
    ServerPath /home/johndoe/src/webservice/public
    SetEnv APPLICATION_ENV "development"
    <Directory /home/johndoe/src/webservice/public>
        DirectoryIndex index.php
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

I reassured that z-httpd.conf is included in the main Apache conf file and I also have an index.php file in my DocumentRoot. Also tried setenforce 0. Didn’t work either.
Output of ls -lZa on the DocumentRoot is as follows:

drwxr-xr-x. 6 johndoe johndoe unconfined_u:object_r:user_home_t:s0 4096 Apr 16 12:31 .
drwxr-xr-x. 7 johndoe johndoe unconfined_u:object_r:user_home_t:s0 4096 Apr 17 10:23 ..
drwxr-xr-x. 2 johndoe johndoe unconfined_u:object_r:user_home_t:s0 4096 Apr 16 12:31 css
drwxr-xr-x. 2 johndoe johndoe unconfined_u:object_r:user_home_t:s0 4096 Apr 16 12:31 fonts
-rwxr-xr-x. 1 johndoe johndoe unconfined_u:object_r:user_home_t:s0  748 Apr 16 12:31 .htaccess
drwxr-xr-x. 2 johndoe johndoe unconfined_u:object_r:user_home_t:s0 4096 Apr 16 12:31 img
-rwxr-xr-x. 1 johndoe johndoe unconfined_u:object_r:user_home_t:s0 1255 Apr 16 12:31 index.php
drwxr-xr-x. 2 johndoe johndoe unconfined_u:object_r:user_home_t:s0 4096 Apr 16 12:31 js
-rwxr-xr-x. 1 johndoe johndoe unconfined_u:object_r:user_home_t:s0 1032 Apr 16 12:31 web.config

In response to one of the comments, I’m adding httpd error_log output:

[Tue Apr 17 13:02:45.838159 2018] [core:error] [pid 9883:tid 140703779542784] (13)Permission denied: [client ::1:43674] AH00035: access to / denied (filesystem path '/home/johndoe/src') because search permissions are missing on a component of the path
[Tue Apr 17 13:06:11.389019 2018] [mpm_event:notice] [pid 9879:tid 140704428511232] AH00492: caught SIGWINCH, shutting down gracefully
[Tue Apr 17 13:06:12.498547 2018] [core:notice] [pid 10363:tid 140006580465664] SELinux policy enabled; httpd running as context system_u:system_r:httpd_t:s0
[Tue Apr 17 13:06:12.499134 2018] [suexec:notice] [pid 10363:tid 140006580465664] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain. Set the 'ServerName' directive globally to suppress this message
[Tue Apr 17 13:06:12.515517 2018] [lbmethod_heartbeat:notice] [pid 10363:tid 140006580465664] AH02282: No slotmem from mod_heartmonitor
[Tue Apr 17 13:06:12.519962 2018] [mpm_event:notice] [pid 10363:tid 140006580465664] AH00489: Apache/2.4.29 (Fedora) OpenSSL/1.1.0g-fips mod_perl/2.0.10 Perl/v5.26.1 configured -- resuming normal operations
[Tue Apr 17 13:06:12.519991 2018] [core:notice] [pid 10363:tid 140006580465664] AH00094: Command line: '/usr/sbin/httpd -D FOREGROUND'
[Tue Apr 17 13:29:23.288313 2018] [core:error] [pid 10368:tid 140005758412544] (13)Permission denied: [client ::1:44974] AH00035: access to / denied (filesystem path '/home/johndoe/src') because search permissions are missing on a component of the path
[Tue Apr 17 13:29:29.223311 2018] [core:error] [pid 10368:tid 140005783590656] (13)Permission denied: [client 127.0.0.1:44392] AH00035: access to / denied (filesystem path '/home/johndoe/src') because search permissions are missing on a component of the path

And .htaccess content (located in public):

RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [L]
# The following rewrites all other queries to index.php. The 
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting or installed the project in a subdirectory,
# the base path will be prepended to allow proper resolution of
# the index.php file; it will work in non-aliased environments
# as well, providing a safe, one-size fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L]

Additional info:
Server version: Apache/2.4.29 (Fedora)
kernel-release: 4.15.4-300.fc27.x86_64

My answer:


This error is about Unix permissions, and so that is what you need to check. It may also be caused by SELinux in some circumstances.

In particular it means that Apache could not search a directory somewhere above the requested file, so you need to check the permissions on the entire path.

Fortunately Linux has a tool to do this, called namei. Run namei -l /home/johndoe/src and you can then inspect and fix the permissions on whichever directory is the problem.

I bet it will look something like this:

[[email protected] src]$ namei -l /home/johndoe/src
f: /home/johndoe/src
dr-xr-xr-x root    root    /
drwxr-xr-x root    root    home
drwx------ johndoe johndoe johndoe
drwxr-xr-x johndoe johndoe src

Now the problem is obvious: The directory /home/johndoe doesn’t have search permissions for anyone but the owner. You obviously would fix that with chmod +x /home/johndoe.

You also need to check the SELinux boolean httpd_read_user_content. Without this boolean, a web server won’t be able to access anything in user home directories.

[[email protected] ~]$ semanage boolean -l | grep httpd_read_user_content
httpd_read_user_content        (off  ,  off)  Allow httpd to read user content

If it’s off, as in this example, turn it on.

[[email protected] ~]$ setsebool -P httpd_read_user_content on

View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.