apache2-mpm-itk (just mpm-itk for short) is an MPM (Multi-Processing Module) for the Apache web server. mpm-itk allows you to run each of your vhost under a separate uid and gid—in short, the scripts and configuration files for one vhost no longer have to be readable for all the other vhosts.
mpm-itk is based on the traditional prefork MPM, which means it's non-threaded; in short, this means you can run non-thread-aware code (like many PHP extensions) without problems. On the other hand, you lose out to any performance benefit you'd get with threads, of course; you'd have to decide for yourself if that's worth it or not. You will also take an additional performance hit over prefork, since there's an extra fork per request.
The latest version is 2.4.7-04 for Apache 2.4.7 and newer (older 2.4.x will not work), last updated 2016-02-14. You can download the archive here; it can be built as a regular module, so you no longer have to patch Apache.
The latest version for Apache 2.2.x is 2.2.17-01, updated 2011-03-21. Note that the mpm-itk 2.2.x series is less feature-rich than 2.4.x in several ways, although it still has security support. You can download the patch series (apply in order), or monolithic diff.
You should probably use a package from your distribution if you can. Several distributions now include mpm-itk as a choice alongside the other MPMs; in alphabetical order:
If you know of any I missed, or if you have included mpm-itk in your favorite distribution, please drop me a note (see below). I'd always be happy to expand this list :-)
If you cannot use a distribution package, you should strive to use
the 2.4.x series; it is much easier to install then the 2.2.x series.
Simply run ./configure && make && sudo make install
from the unpacked mpm-itk directory, which will build and install the module.
(If apxs
if not in your path, you'll need to give something like
--with-apxs=/usr/local/apache2/bin/apxs
to configure
.)
You can then write LoadModule mpm_itk_module modules/mpm_itk.so
in your httpd.conf. Remember that mpm-itk only works with non-threaded MPMs,
such as the prefork MPM.
The new configuration settings over the prefork MPM are:
AssignUserID
: Takes two parameters, uid and gid (or
really, user name and group name; use “#<uid>” if you want to
specify a raw uid); specifies what uid and gid the
vhost will run as (after parsing the request etc., of course).
Note that if you do not assign a user ID, the default one from
Apache will be used.AssignUserIDExpr
, AssignGroupIDExpr
(Apache 2.4 or newer only): Like AssignUserID, but takes in an
Apache expression
to dynamically choose user or group. See below.MaxClientsVHost
: A separate MaxClients for the vhost.
This can be useful if, say, half of your vhosts depend on some NFS
server; if the NFS server goes down, you do not
want the children waiting forever on NFS to take the non-NFS-dependent
hosts down. This can thus act as a safety measure, giving “server too
busy” on the NFS-dependent vhosts while keeping the other ones
happily running. (Of course, you could use it to simply keep one site
from eating way too much resources, but there are probably better
ways of doing that.)NiceValue
: Lets you nice some requests down, to give
them less CPU time.EnableCapabilities
(Apache 2.4 or newer only):
Drop most root capabilities in the parent process, and instead run as
the user given by the User/Group directives with some extra capabilities
(in particular setuid). Somewhat more secure (especially when coupled with
LimitUIDRange above), but can cause problems when serving from
filesystems that do not honor capabilities, such as NFS.LimitUIDRange
, LimitGIDRange
(Apache 2.4 or newer only):
Restrict setuid() and setgid() calls to a given range (e.g.
“LimitUIDRange 1000 2000" to allow only uids from 1000 to 2000, inclusive),
possibly increasing security somewhat. Note that this requires
seccomp v2 (Linux 3.5.0 or newer). Also, due to technical reasons,
setgroups() is not restricted, so a rogue process can still
get any group it might want. Still, performing a successful attack
will be somewhat trickier than otherwise.MaxClientsVHost
can only be set inside a VirtualHost
directive;
all others can be set wherever you'd like in the Apache
configuration, except in .htaccess.
AssignUserIDExpr
and AssignGroupIDExpr
(new in Apache 2.4) are quite
powerful, although how to use them is perhaps nonobvious. The easiest
way to use them is by combining with mod_rewrite,
for instance like this:
RewriteEngine on RewriteRule /~([a-z]+)/ - [E=ITKUID:$1] AssignUserIDExpr %{reqenv:ITKUID}
This will cause e.g. /~sesse/foo
to be run as the user
“sesse” (and /~root/foo
to be run as user “root”,
so beware!).
Since mpm-itk has to be able to setuid(), it runs as root (although restricted with POSIX capabilities and seccomp v2 where possible) until the request is parsed and the vhost determined. This means that any code execution hole before the request is parsed will be a potential root security hole. (The most likely place is probably in mod_ssl.) This is not likely to change in the near future, as socket passing, the most likely alternative solution, is very hard to get to work properly in a number of common use cases (e.g. SSL).
The lack of socket passing also leads to another minor quirk: If you connect to httpd, make a request and then make a request on the same connection that gets handled by a different uid, mpm-itk simply shuts down the connection. This is perfectly legal according to RFC 2616 section 8.1.4, and all major clients seem to handle it well; the web server simply simulates a timeout, and the client just opens a new connection and retries the request. However, there is a small performance hit, and thus you should avoid including content from multiple uids in the same page.
Note that mpm-itk is nowhere as tested as, say, prefork. That being said, it's being run in production at several sites in the world, both hobbyist and commercial, some as large as ~10 million hits a day.
mpm-itk is licensed under the Apache License, version 2.0, like the rest of Apache.
If mpm-itk does not suit your tastes, here are some alternatives:
mpm-itk is developed by Steinar H. Gunderson; email address is at my home page.
There is a user mailing list at mpm-itk [at] lists.err.no; please direct any support requests there. Visit the mailing list page to subscribe, or send a blank e-mail to mpm-itk-subscribe [at] lists.err.no.