Assume you have a very simple, single website with .html files in /var/www/html, no CGI scripts, virtual hosting, or multiple Web administrators. Those advanced topics are covered in Section 6, “Virtual Hosting, CGI scripts and suEXEC”.
The security goal is to make sure that Apache HTTP is only reading the static Web content, and not doing anything else such as writing to the content, connecting to database sockets, reading user home directories, etc.
By default, the Fedora SELinux policy allows Apache HTTP to run CGI scripts and directly read home directory content. To disable these options for this section, run system-config-securitylevel, click the SELinux tab, and under , uncheck Allow httpd CGI support and Allow httpd to read home directories. Alternatively, you may run these commands from a terminal:
setsebool httpd_enable_cgi false setsebool httpd_enable_homedirs false
SELinux and booleans are discussed in Section 8.1, “Simple Customization”.
In Section 2, “Getting Started”, it was mentioned that the Apache HTTP process was labeled httpd_t and therefore had SELinux restrictions applied. In SELinux, every object on the system, such as regular files, network ports, processes, file descriptors, etc., has a security context associated with it. Here are the contexts of the files in the simple website:
ls -aZ /var/www/
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t .
drwxr-xr-x root root system_u:object_r:var_t ..
drwxr-xr-x root root system_u:object_r:httpd_sys_script_exec_t cgi-bin
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t error
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t html
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t icons
ls -aZ /var/www/error
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t .
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t ..
[...]
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t include
-rw-r--r-- root root system_u:object_r:httpd_sys_content_t noindex.php
-rw-r--r-- root root system_u:object_r:httpd_sys_content_t README
Again, the important part is the third component of the context, the httpd_sys_content_t type. The security policy allows httpd_t (Apache HTTP) to read files and directories with this type, along with other crucial types such as etc_t.
At this point, verify that you can point your Web browser at http://localhost, and see the expected default Fedora Core or Red Hat Enterprise Linux page. Next, try creating a new file such as hello.html in /var/www/html, and verify that you can see it from your Web browser:
$ echo "Hello world" > /var/www/html/hello.html $ ls -aZ /var/www/html/hello.html -rw-r--r-- root root system_u:object_r:httpd_sys_content_t hello.html
Notice that when you created a new file in /var/www/html, by default it inherited the httpd_sys_content_t type from the parent directory. This way Apache HTTP (running as httpd_t) can read the new file.
When you used system-config-securitylevel to set an SELinux Boolean that turned off Apache HTTP's ability to read home directories, this ensured that the httpd_t domain does not have permission to read the user_home_dir_t. This is the type assigned to a user's home directory. Since Apache HTTP cannot access the toplevel directory, it therefore cannot access any files contained within it either, even if it includes Web content.
ls -aZ /home/walters
drwx------ walters walters root:object_r:user_home_dir_t .
drwxr-xr-x root root system_u:object_r:home_root_t ..
-rw-r--r-- walters walters user_u:object_r:user_home_t anaconda-ks.cfg
-rwxr-xr-x walters walters user_u:object_r:user_home_t anaconda.log
...
One problem you may run into is the difference between the mv and cp commands. Suppose that you have some new content (about.html) to add to your website. After creating it in your home directory, you later do something such as: sudo mv /home/walters/about.html /var/www/html. The problem here is that mv by default preserves the context associated with the file, whereas cp, since it creates a new file, inherits the parent directory's context. For example, this is the result of the mv mentioned above:
ls -aZ /var/www/html/ drwxr-xr-x root root system_u:object_r:httpd_sys_content_t . drwxr-xr-x root root system_u:object_r:httpd_sys_content_t .. -rw-r--r-- root root system_u:object_r:httpd_sys_content_t index.php -rw-r--r-- walters walters system_u:object_r:user_home_t about.html
If you run Apache HTTP and try to open about.html in a Web browser, you will get a "Forbidden" error. If you then view /var/log/messages, you should see a message similar to this:
Oct 19 17:54:59 hostname kernel: audit(1098222899.827:0): avc: \
denied { getattr } for pid=19029 exe=/usr/sbin/httpd \
path=/var/www/html/about.html dev=dm-0 ino=373900 \
scontext=root:system_r:httpd_t tcontext=user_u:object_r:user_home_t \
tclass=file
This message is telling you that httpd_t couldn't access a file with type user_home_t. The user_home_t is, as seen in the listing of /home/walters/, used for a lot of files inside the home directory. The default security policy never allows httpd_t any access to the user_home_t type.
To relabel the file and allow Apache HTTP to read it, you can use the chcon utility: chcon -t httpd_sys_content_t /var/www/html/about.html. Verify the context on the file is correct:
ls -aZ /var/www/html/ drwxr-xr-x root root system_u:object_r:httpd_sys_content_t . drwxr-xr-x root root system_u:object_r:httpd_sys_content_t .. -rw-r--r-- root root system_u:object_r:httpd_sys_content_t index.php -rw-r--r-- walters walters system_u:object_r:httpd_sys_content_t about.html
The chcon utility is similar in style to the UNIX command chmod. For example, if you wanted to recursively change the types of a directory and all the files it contains, you could use this command: chcon -R -h -t httpd_sys_content_t /path/to/directory. The -R switch means to operate recursively, and the -h option means to not follow symlinks (which is almost always what you want).
![]() | chcon vs. restorecon |
|---|---|
There is another command available for changing file labels, called restorecon. This command is useful if you want to revert back to the default labels on files. For example, you can run restorecon -v -R /var/www/ to reset all the file labels in the /var/www/ directory. Internally, restorecon reads the /etc/selinux/targeted/contexts/files/file_contexts file, which has a set of regular expressions mapping file paths to security contexts. | |