The Apache Web server, like most if not all of the others in common use
today, lets you execute arbitrarily complex operations through the use of CGI
scripts. These can involve database lookups, system administration functions,
real-time control of machinery, online payments, or almost anything else you
can think of.
When you’re running an Apache Web server for yourself, you don’t think about the user that’s running the Apache server itself (typically nobody on Linux systems). But what if you’re an ISP with multiple companies being hosted on your system? Or an educational institution with faculty who want to be able to execute their own scripts?
Ordinarily, all of these things occur in the context of the user running
the Apache server itself (typically nobody
on Linux systems). This
is fine when you’re using a system that is owned and used by a single
entity…but what if you’re an ISP with multiple companies being hosted on your
system? Or an educational institution with faculty who want to be able to
execute their own scripts? Either everything has to be accessible to the Apache
nobody
user, or you have to run multiple instances of Apache on
multiple ports and IP addresses, one of each per user, with the
concomitant confusion of configuration files.
On the other hand, if the server is to be allowed to change its identity,
it needs to be done in a controlled manner, so that the chance of compromising
your system’s security is kept to a minimum. (Remember, Apache is usually
started as root
and only changes to nobody
later!)
The suexec
(pronounced ‘SUE-ex-Ek‘) tool helps
make this possible. It’s found in the src/support/
directory under
your Apache source tree.
Assumptions in This Article
For the rest of this article, I’m going to make the following assumptions:
-
your Apache source tree starts at
./apache-1.3/
-
your Apache ServerRoot is
/usr/local/web/apache
-
your Apache DocumentRoot is
/usr/local/web/htdocs
-
the username under which Apache runs (the value of the
User
directive in yourhttpd.conf
file) isnobody
All of the cd
and other shell commands in this article that
refer to directories use these locations.
How Does Suexec Work?
Since suexec
works by wrapping an operation up in a package
executed under a different username, it’s called a wrapper. In order to
execute a script under the auspices of the wrapper, the Apache server creates a
child process running the suexec
binary and passes the particulars
to it. The wrapper verifies that all the security requirements are met, edits
the list of environment variables so that only the ones on its ‘trusted’ list
are available, closes its logfile, and calls some flavour of
execv(2)
to load the script into the edited process environment,
replacing suexec
itself.
Requirements For suexec
Operation
Since suexec
is used to run applications on your system on behalf
of arbitrary people out on the Web, it’s very paranoid about doing anything
that might compromise your system’s security. Here is a list of the conditions
suexec
requires to be met before it will proceed; if any don’t
measure up, the wrapper will log an error and not execute the script.
-
suexec
must be invoked with the correct number of arguments.
If it isn’t, it assumes someone is trying to penetrate your system by running
it outside the Apache environment. -
The username/UID invoking
suexec
must be a valid user; that
is, it must be listed in the/etc/passwd
file. If it isn’t,
something’s not quite right–and when in doubt, punt. -
The username executing the wrapper must be the one that was compiled into
it when it was built. Again, a mismatch here is interpreted as someone trying
to usesuexec
in other than the prescribed way.