Apache suEXEC on FreeBSD

Scott Wiersdorf
Created: Wed Apr  7 23:48:26 MDT 2004
$Id: suexec.html,v 1.5 2004/04/08 06:31:29 scott Exp $
CGI programs under Apache's suEXEC execute with the permissions of the virtual host that invoked it.

Each virtual host (or the main Apache server) run under a user on the system. By default, this user is 'nobody' or 'www', but it is not necessarily so.

Often, virtual hosts are configured to run under the userid of the hierarchy they are rooted in. For example, if I have a user 'scott' on my system and he has a website 'somewebsite.dom' rooted in his home directory (/home/scott/www/somewebsite.dom), I would configure the VirtualHost entry like this:

<VirtualHost ip.add.re.ss:80>
  User  scott
  Group scottgroup
  ServerName somewebsite.dom
  DocumentRoot /home/scott/www/somewebsite.dom
  ...
</VirtualHost>
All CGI programs executed from this virtual host will be run under the 'scott' userid and 'scottgroup' groupid. We can demonstrate this with a simple cgi script in our server's cgi-bin directory:
#!/bin/sh
echo Content-type: text/plain
echo
touch "/tmp/foo.$$"
echo `ls -l /tmp/foo.$$`
This program creates a zero length file in /tmp. When this is run from somewebsite.dom (running under userid 'scott' and groupid 'scottgroup'), we have this output:
  rw-r--r-- 1 scott wheel 0 Apr 7 23:31 /tmp/foo.36108
Notice the file is owned by 'scott'. Were we to run it under another virtual host on the system, owned, say joeswebsite.dom which is run under userid 'joe', we'd have this instead:
  rw-r--r-- 1 joe wheel 0 Apr 7 23:31 /tmp/foo.36114
(Note: the group ownership of the file is determined by the group owner of the directory the file is written to, in this case the /tmp directory is owned by 'wheel' and so all new files written to this directory will be owned by group 'wheel'. This is the default behavior for FreeBSD servers and many other BSD-based servers).

If you have a program that needs to write data to a particular location, that location must be writable by the user or group of the virtual host (as specified by the Apache User and Group directives). If no User or Group directives are specified for a virtual host entry, the virtual host will inherit the main Apache server's User and Group (e.g., 'www' and 'www' are a likely default, or 'nobody' and 'nogroup' is common, etc.)

In our example, the User is 'scott' and the Group is 'scottgroup'. In order for a cgi program executed under somewebsite.dom to write to a file, that file must be writable by either the 'scott' userid or the 'scottgroup' groupid.

Troubleshooting

If you have a cgi program that needs to write to a location that you can't "chown" to the virtual host's userid (for security reasons, or others need to write there also), you might consider creating a new group for that virtual host:
<VirtualHost ip.add.re.ss:80>
  User  scott
  Group special
  ...
</VirtualHost>
'special' must be a real group on your system with a gid greater than (normally) 1000 (this is configured at compile time and may vary on your system) Add the group to your /etc/group file or pick from an existing group if you must. Now you can change the group ownership of the file that needs to be written to from this:
  rw-r--r-- 1 root wheel 120 Apr 7 23:31 /usr/local/etc/foo.conf
using this command: 'chgrp special /usr/local/etc/foo.conf', which will give you this:
  rw-r--r-- 1 root special 120 Apr 7 23:31 /usr/local/etc/foo.conf
Now, this file is group-owned by 'special', but the 'special' group can't write to it yet. We have to chmod it, like this:
  chmod g+w /usr/local/etc/foo.conf
which gives us finally:
  rw-rw-r-- 1 root special 120 Apr 7 23:31 /usr/local/etc/foo.conf
Now we have a file that is writable by anyone in the 'special' group or who is running with the 'special' group's permissions (like our virtual host is now).

Further Help

See the official Apache suEXEC documentation at:
http://httpd.apache.org/docs/suexec.html

Apache tutorials

Send comments to the author