Apache says DocumentRoot doesn't exist when it does

I used Webmin to create the following Virtual Host:

<VirtualHost *:80>
        DocumentRoot "/var/www/whatever"
        ServerName whatever.ourdomain
        <Directory "/var/www/whatever">
                allow from all
                Options +Indexes
        </Directory>
</VirtualHost>

And when restarting Apache I get

Starting httpd: Warning: DocumentRoot [/var/www/whatever] does not exist

The thing is, the directory absolutely DOES exist. I'm staring right at it. pwd shows me that's my current directory, etc. It's not that hard to spell it right. I can't find any other errors or warnings in the httpd logs. apache:apache owns the directory and all subdirectories/files. There isn't any symlinks or anything involved here. What am I missing or what else should I look at to determine why this is?

OS is CentOS 6.0


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


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

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