Chapter 13: Securing Apache with the mod_tomoyo module
13.1. The mod_tomoyo module
mod_tomoyo 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.
13.2. Installing the module
13.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
13.2.2. Downloading the module
Download the source code for the mod_tomoyo:
# wget -O mod_tomoyo.c 'https://sourceforge.net/p/tomoyo/svn/5673/tree/branches/mod_tomoyo.c?format=raw'
Compile, install and activate mod_tomoyo:
13.2.3. Installing the module
RedHat distributions
# apxs -i -a -c mod_tomoyo.c
Debian distributions
# apxs2 -i -a -c mod_tomoyo.c
If installation completed successfully, the following should be present in the Apache configuration files:
LoadModule tomoyo_module /usr/lib/httpd/modules/mod_tomoyo.so
13.3. Configuration
The mod_tomoyo module performs domain transition based on the pathname of a requested file by specifying the mapping table of pathnames and domain names using the TOMOYO_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 TOMOYO_TransitionMap /etc/tomoyo/httpd-tomoyo00.conf </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/html-01 ServerName www.tomoyo01.com TOMOYO_TransitionMap /etc/tomoyo/httpd-tomoyo01.conf </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/html-02 ServerName www.tomoyo02.com TOMOYO_TransitionMap /etc/tomoyo/httpd-tomoyo02.conf </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/html-03 ServerName www.tomoyo03.com TOMOYO_TransitionMap /etc/tomoyo/httpd-tomoyo03.conf </VirtualHost>
In the file specified by the TOMOYO_TransitionMap directive, the pathname of a requested file needs to be mapped to a domain name. For example, in "/etc/tomoyo/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
Restart Apache. If the following error occurs on startup, then writing to the /sys/kernel/security/tomoyo/self_domain interface failed:
mod_tomoyo: Unable to open /sys/kernel/security/tomoyo/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_tomoyo: Unable to open /sys/kernel/security/tomoyo/self_domain for writing.
Other error messages may appear if there are problems in the mapping file specified by the TOMOYO_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, "/sys/kernel/security/tomoyo/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.