Chapter 14: Securing Apache with the mod_ccs module
14.1. The mod_ccs module
mod_ccs is an Apache 2.x module that allows more precise control over Apache. This module allows domain transition based on virtual host names and CGI pathnames without requiring program execution. This way, each virtual host or CGI script can be isolated from each other and given different permissions in policy.
14.2. Installing the module
14.2.1. Install dependencies
This module is available for Linux 2.6 kernels only, and will not work with Linux 2.4 kernels.
These packages are required for compiling the module:
RedHat distributions
# yum -y install httpd-devel
Debian distributions
# apt-get -y install apache2-threaded-dev apache2-prefork-dev
14.2.2. Downloading the module
Download the source code for the mod_ccs:
# wget -O mod_ccs.c 'https://sourceforge.net/p/tomoyo/svn/5673/tree/branches/mod_ccs.c?format=raw'
Compile, install and activate mod_ccs:
14.2.3. Installing the module
RedHat distributions
# apxs -i -a -c mod_ccs.c
Debian distributions
# apxs2 -i -a -c mod_ccs.c
If installation completed successfully, the following should be present in the Apache configuration files:
LoadModule ccs_module /usr/lib/httpd/modules/mod_ccs.so
14.3. Configuration
The mod_ccs module performs domain transition based on the pathname of a requested file by specifying the mapping table of pathnames and domain names using the CCS_TransitionMap directive. This can be placed in the Apache configuration files like this (assuming that IP addresses for www.tomoyo00.com etc. are specified in "/etc/hosts"):
<VirtualHost *:80> DocumentRoot /var/www/html-00 ServerName www.tomoyo00.com CCS_TransitionMap /etc/ccs/httpd-tomoyo00.conf </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/html-01 ServerName www.tomoyo01.com CCS_TransitionMap /etc/ccs/httpd-tomoyo01.conf </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/html-02 ServerName www.tomoyo02.com CCS_TransitionMap /etc/ccs/httpd-tomoyo02.conf </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/html-03 ServerName www.tomoyo03.com CCS_TransitionMap /etc/ccs/httpd-tomoyo03.conf </VirtualHost>
In the file specified by the CCS_TransitionMap directive, the pathname of a requested file needs to be mapped to a domain name. For example, in "/etc/ccs/httpd-tomoyo00.com" the following might be specified:
/var/www/cgi-bin/\* <kernel> //apache /www.tomoyo00.com /cgi-programs /usr/share/horde/\{\*\}/\* <kernel> //apache /www.tomoyo00.com /horde /var/www/html/\{\*\}/\* <kernel> //apache /www.tomoyo00.com /static-files /\{\*\}/\* <kernel> //apache /www.tomoyo00.com /default
In domain policy, the domain transitions must be specified beforehand (otherwise Apache will fail with an Internal Server Error):
<kernel> /usr/sbin/httpd task manual_domain_transition <kernel> //apache /www.tomoyo00.com /cgi-programs task manual_domain_transition <kernel> //apache /www.tomoyo00.com /horde task manual_domain_transition <kernel> //apache /www.tomoyo00.com /static-files task manual_domain_transition <kernel> //apache /www.tomoyo00.com /default
If SELinux is enabled, policy must be configured to allow Apache to write to the /proc/ccs/self_domain interface. On CentOS 5.9, this may be done with the following commands, though this depends on policy configuration, distribution and package versions:
# cd /etc/selinux/ # echo 'type=AVC msg=audit(1277948886.369:106): avc: denied { write } for pid=32078 comm="httpd" name="self_domain" dev=proc ino=-268435010 scontext=root:system_r:httpd_t:s0 tcontext=system_u:object_r:proc_t:s0 tclass=file' | audit2allow -M ccsecurity # semodule -i ccsecurity.pp
Restart Apache. If the following error occurs on startup, then writing to the /proc/ccs/self_domain interface failed:
mod_ccs: Unable to open /proc/ccs/self_domain for writing. (errno = 13)
This may appear in the error logs for Apache (e.g. "/var/log/httpd/error_log"):
[Thu Jul 01 16:31:10 2010] [error] [client 127.0.0.1] (13)Permission denied: mod_ccs: Unable to open /proc/ccs/self_domain for writing.
Other error messages may appear if there are problems in the mapping file specified by the CCS_TransitionMap directive.
To confirm that domain transitions are performed, create a simple CGI program:
# cat > /var/www/cgi-bin/test.cgi << "EOF" #!/usr/bin/perl print "Content-type:text/html\r\n\r\n"; print "<HTML>\n"; print "<HEAD>\n"; print "<TITLE>test</TITLE>\n"; print "</HEAD>\n"; print "<BODY>\n"; open(IN, "/proc/ccs/self_domain") || print "error"; $domain = <IN>; $domain =~ s/&/&/g; $domain =~ s/</</g; $domain =~ s/>/>/g; close(IN); print $domain; print "\n"; print "</BODY>\n"; print "</HTML>\n"; EOF # chmod 755 /var/www/cgi-bin/test.cgi
Run the CGI programs using the curl command (or web browsers) and confirm that domain transitions are performed:
# curl http://www.tomoyo00.com/cgi-bin/test.cgi
<HTML> <HEAD> <TITLE>test</TITLE> </HEAD> <BODY> <kernel> //apache /www.tomoyo00.com /cgi-programs /var/www/cgi-bin/test.cgi </BODY> </HTML> [root@tomoyo ~]# curl http://www.tomoyo01.com/cgi-bin/test.cgi <HTML> <HEAD> <TITLE>test</TITLE> </HEAD> <BODY> <kernel> //apache /www.tomoyo01.com /cgi-programs /var/www/cgi-bin/test.cgi </BODY> </HTML> [root@tomoyo ~]# curl http://www.tomoyo02.com/cgi-bin/test.cgi <HTML> <HEAD> <TITLE>test</TITLE> </HEAD> <BODY> <kernel> //apache /www.tomoyo02.com /cgi-programs /var/www/cgi-bin/test.cgi </BODY> </HTML> [root@tomoyo ~]# curl http://www.tomoyo03.com/cgi-bin/test.cgi <HTML> <HEAD> <TITLE>test</TITLE> </HEAD> <BODY> <kernel> //apache /www.tomoyo03.com /cgi-programs /var/www/cgi-bin/test.cgi </BODY> </HTML>
Policy can now be developed for these domains as described in the core topics.