Info: Version 1.8.x is available.

Japanese Page

Last modified: $Date: 2015-08-31 22:19:51 +0900 (Mon, 31 Aug 2015) $

The world of TOMOYO Linux
The tenth installment: "Let's split Apache's permissions."

Contents of this installment.

In this installment, I explain steps for splitting domains based on Apache's VirtualHost configuration. I use CentOS 5 for this installment.

Installing mod_ccs

mod_ccs is an Apache 2.x module. mod_ccs allows Apache to perform TOMOYO Linux's domain transitions based on Apache's virtual host's names and based on CGI (processed inside Apache's process using mod_perl etc.) program's pathnames, using "domain transition without program execution" which is available in TOMOYO Linux 1.7.2 and later. Note that mod_ccs does not work with Linux 2.4 kernels.

First, prepare for compiling Apache's modules. If you are using RedHat, install "httpd-devel" package. If you are using Debian, install "apache2-threaded-dev" package or "apache2-prefork-dev" package. Login as "root" user and run command listed in Fig. 1.

♦ Fig. 1  Installing packages for compiling Apache modules
# yum install httpd-devel

Next, download the source code. Do command listed in Fig. 2.

♦ Fig. 2  Downloading source code for mod_ccs
# wget -O mod_ccs.c 'http://osdn.jp/projects/tomoyo/svn/view/branches/mod_ccs.c?revision=3787&root=tomoyo'

Compile and install and activate the mod_ccs module. Run command listed in Fig. 3. If you are using RedHat, the command name is "apxs". If you are using Debian, the command name is "apxs2".

♦ Fig. 3  Compiling mod_ccs
# apxs -i -a -c mod_ccs.c

You will find a line like Fig. 4 in the Apache's configuration files if Fig.3 finished successfully.

♦ Fig. 4  Configuration for loading mod_ccs
LoadModule ccs_module /usr/lib/httpd/modules/mod_ccs.so

Configuring mod_ccs

mod_ccs by default performs domain transition based on ServerName. If you specify the mapping table of pathnames and domainnames using CCS_TransitionMap keyword in the Apache's configuration files like Fig. 5, mod_ccs performs domain transition based on requested file's pathname in addition to domain transition based on ServerName. Fig. 5 assumes that IP address for www.tomoyo00.com www.tomoyo01.com www.tomoyo02.com www.tomoyo03.com are specified in /etc/hosts .

♦ Fig. 5  An example of specifying CCS_TransitionMap keyword
<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>

Define mapping table of requested file on the filesystem and domainname to transit to in the file specified by CCS_TransitionMap keyword. (Fig. 6)

♦ Fig. 6  An example of pathnames and domainnames mapping
/var/www/cgi-bin/\*         cgi-programs
/usr/share/horde/\{\*\}/\*  horde
/var/www/html/\{\*\}/\*     static-files

From now on, you need to use TOMOYO Linux kernel.

TOMOYO Linux can be used with SELinux. But SELinux's default policy configuration does not allow Apache to write to /proc/ccs/.transition . If SELinux is enabled, modify SELinux's policy configuration to allow Apache to write to /proc/ccs/.transition . (Steps for modifying SELinux's policy configuration depend on distributions and versions. Fig. 7 should work for CentOS 5 but may not work for older versions.)

♦ Fig. 7  Allow Apache to write to /proc/ccs/.transition
# cd /etc/selinux/
# echo 'type=AVC msg=audit(1277948886.369:106): avc:  denied  { write } for pid=32078 comm="httpd" name=".transition" 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 by doing Fig. 8.

♦ Fig. 8  Restarting Apache
# service httpd restart

Errors like Fig. 9 (if you specified CCS_TransitionMap keyword) or Fig. 10 (if you didn't specify CCS_TransitionMap keyword) are reported if write access to /proc/ccs/.transition failed.

♦ Fig. 9  Apache's error message upon startup
mod_ccs: Unable to open /proc/ccs/.transition for writing. (errno = 13)
♦ Fig. 10  Apache's error log ( /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/.transition for writing.

If there is a problem in the file specified by CCS_TransitionMap keyword, errors are reported when doing Fig. 8.

To be able to confirm that domain transitions are performed, create a simple CGI program. (Fig. 11)

♦ Fig. 11  A CGI program for printing current domain
# 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/&/&amp;/g;
$domain =~ s/</&lt;/g;
$domain =~ s/>/&gt;/g;
close(IN);
print $domain;
print "\n";

print "</BODY>\n";
print "</HTML>\n";
EOF
# chmod 755 /var/www/cgi-bin/test.cgi

By default, /proc/ccs/self_domain can be accessed by only "root" user. Loosen permissions in order to allow program in Fig. 11 to access this file. (Fig. 12)

♦ Fig. 12  Allow CGI programs to read /proc/ccs/self_domain
# chmod 444 /proc/ccs/self_domain

To automatically loosen permissions upon boot, do like Fig. 13.

♦ Fig. 13  Change permissions upon boot
# cat > /etc/ccs/ccs-post-init << EOF
#! /bin/sh
chmod 444 /proc/ccs/self_domain
exit 0
EOF
# chmod 700 /etc/ccs/ccs-post-init

Run the CGI programs using curl command (or web browsers) and confirm that domain transitions are performed. (Fig. 14)

♦ Fig. 14  Verify that domain transitions are performed
[root@tomoyo ~]# curl http://www.tomoyo00.com/cgi-bin/test.cgi
<HTML>
<HEAD>
<TITLE>test</TITLE>
</HEAD>
<BODY>
&lt;kernel&gt; /usr/sbin/httpd //www.tomoyo00.com //default /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>
&lt;kernel&gt; /usr/sbin/httpd //www.tomoyo01.com //default /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>
&lt;kernel&gt; /usr/sbin/httpd //www.tomoyo02.com //default /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>
&lt;kernel&gt; /usr/sbin/httpd //www.tomoyo03.com //default /var/www/cgi-bin/test.cgi
</BODY>
</HTML>
[root@tomoyo ~]#

The rest steps are the same as creating policy configuration for Apache. Collect permissions using learning mode, check that all permissions are given and tune policy configuration using permissive mode, and protect using enforcing mode.

Go back to the ninth installment.


Return to index page.

sflogo.php