Apache says DocumentRoot doesn't exist when it does

Solution 1:

Here's a tutorial approach to the SELinux case:

Find out if SELinux is active:

 $ sestatus
 SELinux status:                 enabled
 SELinuxfs mount:                /selinux
 Current mode:                   enforcing
 Mode from config file:          enforcing
 Policy version:                 24
 Policy from config file:        targeted

If so, some comparative checking might help. For instance, a server has a default DocumentRoot at /var/www/html, but we want it somewhere else like /path/to/document/root.

If SELinux is not actively messing with the resource, ls -dZ on the directory will show something like:

$ ls -dZ /path/to/document/root
? /path/to/document/root/

On the other hand, if SELinux contexts are applied, ls -dZ looks more like:

$ ls -dZ /path/to/document/root
drwxrws--x+ cfgadm cfgadmin system_u:object_r:file_t:s0 /path/to/document/root

If we compare to a working DocumentRoot, it would look something like:

$ ls -dZ /var/www/html
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html

The _r and _t relate to -r (--role and -t (--type) arguments to chcon. Here is a cut-down man page:

NAME
   chcon - change file security context

SYNOPSIS
   chcon [OPTION]... CONTEXT FILE...
   chcon [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...
   chcon [OPTION]... --reference=RFILE FILE...

DESCRIPTION
   Change the security context of each FILE to CONTEXT.  With --reference,
   change the security context of each FILE to that of RFILE.

   --reference=RFILE
          use RFILE's security context rather than  specifying a CONTEXT value

   -R, --recursive
          operate on files and directories recursively

At first guess, the following might seem to work, but might not.

$ sudo chcon -R -t httpd_sys_content_t /path/to/document/root

If the web server still cannot see the DocumentRoot, note that the context matters all the way back to root:

$ sudo chcon -R -t httpd_sys_content_t /path/to/document
$ sudo chcon -R -t httpd_sys_content_t /path/to
$ sudo chcon -R -t httpd_sys_content_t /path

At this point, the web server can see the directory.

Yes, I learned the hard way tonight.

NOTE: The use of chcon conceptually has a downside per RedHat documentation (5.6.1. Temporary Changes: chcon) that states:

The chcon command changes the SELinux context for files. However, changes
made with the chcon command do not survive a file system relabel, or the
execution of the restorecon command.

Use semanage and restorecon to make more permanent changes. A brief example:

 $ sudo semanage fcontext --add -t httpd_sys_content_t -s system_u \
     "/path/to/document/root(/.*)?"
 $ sudo restorecon -FR /path/to/document/root

With regards to restorecon, note that -F is required to affect the whole context (i.e. user and type). Also, -R means to make changes recursively. Arguments -v or -p can show progress in either a verbose or terse fashion. Use -FRnv to see what would happen without actually making any changes.

Once semanage is used in this way, it is possible to view local security changes with a command like:

$ sudo semanage export

The output of semanage export may be saved and used by semanage import to make it easier to apply a set of changes to various systems.

NOTE: This answer provides a most basic type context for a site. Security can be much more granular. For example, see a list of types that can apply to web server pages with a command like:

$ seinfo -t | grep http

NOTE: Utilities like semanage and seinfo may not be installed by default. At least on some distributions, required packages may be named something like this:

policycoreutils-python
setools-console

Solution 2:

The first thing that popped into my mind is does Apache have permission to access that directory?

Also, this: https://stackoverflow.com/questions/3948038/apache-says-my-documentroot-directory-doesnt-exist


Solution 3:

It sounds like SELinux.I would suggest you work with it. Look in the /var/log/audit directory to confirm.

Worse case, you can always turn off selinux, as noted earlier, but I suggest you work with it instead. For instance, if I were to create a directory for use with Apache, it will not have the right context, as noted here.

[root@amp23140 www]# ls -Z
drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 error
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 icons
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 whatever

So if that happens, I just apply the context from another directory, which in this case, is html:

[root@amp23140 www]# chcon whatever --reference=html
[root@amp23140 www]# ls -lZ
drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 error
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 icons
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 whatever