Running CGI as a different user under Apache 2

by

The following was written with RedHat Fedora Core 6 (FC6) in mind, but should not represent too much misguidance for most other Linux distributions.

The problem: We have some CGI which has to be executed as a particular user, which is not the same as the one running the web server.

The solution: Configure apache to have per-user cgi-bin’s and use suexec.

First lets install Apache and set it up to start at boot time. In RedHat apache is called httpd (as if there isn’t any other webservers out there), so the commands you are looking for are:

root@server$ yum install httpd httpd-manual httpd-devel
root@server$ /sbin/chkconfig httpd on
root@server$ /sbin/service httpd start

To get some info on the apache installation run the following command:

root@server$ /usr/sbin/apachectl -V

In particular, notice the SUEXEC_BIN option. If a suexec executable is found at this location all per-user CGI and SSI is run as the appropriate user. According to this (section 16.1) suexec on Fedora Core 6 is set up for a document root (DOCROOT) of /var/www. There might be a problem using different DOCROOT’s.

To make sure that the server actually started:

root@server$ ps auxwww | grep apache

As the default FC6 apache is configured to pre-fork you should see a lot of /usr/sbin/httpd processes.

Configure apache (/etc/httpd/conf/httpd.conf) to have per-user public_html dirs by modifying the ‘IfModule mod_userdir.c’ section to contain:

<IfModule mod_userdir.c>
#
# UserDir is disabled by default since it can confirm the presence
# of a username on the system (depending on home directory
# permissions).
#
# UserDir disable#
# To enable requests to /~user/ to serve the user's public_html
# directory, remove the "UserDir disable" line above, and uncomment
# the following line instead:
#
UserDir public_html

</IfModule>

Also add per-user cgi-bin's to the same file:

#
# Per-user cgi-bin
#
<Directory /home/*/public_html/cgi-bin/>
Options ExecCGI
SetHandler cgi-script
</Directory>

Make sure that the directories for the appropriate user exists:

user@server$ mkdir ~/public_html
user@server$ mkdir ~/public_html/cgi-bin

Restart apache to make changes take affect:

root@server$ /etc/init.d/httpd restart

Testing: Place the following in a file called /home/user/public_html/cgi-bin/whoami.cgi:

<pre>#!/usr/bin/python

import cgi
import os

# for form access
import cgitb; cgitb.enable()

form = cgi.FieldStorage()

# get username
execution = os.popen('whoami', 'r', 0)
whoami = "".join(execution.readlines())
execution.close()

# print header
print "Content-Type: text/html"     # HTML is following
print                               # blank line, end of headers

# print html
print "<html>"
print "  <head>"
print "    <title>Whoami</title>"
print "  </head>"
print "  <body>"
print "    <h1>Whoami</h1>"
print "    "+whoami
print "  </body>"
print "</html>"</pre>

Give it the right permissions:

user@server$ chmod a+x /home/user/public_html/cgi-bin/whoami.cgi

And direct your browser to:

http://server/~user/cgi-bin/whoami.cgi

Leave a comment