Using Apache2 ITK Multi-Processing Module on Linux

Those familiar with configuring Apache and PHP to run together, have
been introduced to the idea of Apache’s Multi-Processing Modules (MPM).
Basically Apache2 allows you to use different methodologies in how it
manages the various connections coming in. One of the more efficient
methods uses threads; however, when running PHP you’ve been restricted
to using the prefork MPM module since some extensions are not written in
a way that will enable work in thread safe mode.

The problem that has existed however, is that if you are running
multiple Virtual Hosts (vhosts) under Apache, they all need to run as
the same User ID (UID) and Group ID (GID) which, in some cases, is
hardly desirable, for instance, in a shared hosting environment.

The Apache2 MPM ITK enables running each Apache vhost under a separate
UID and GID. That way scripts and configuration files for one vhost no
longer have to be readable for other vhosts.
Apache2 MPM ITK is based on the traditional prefork MPM and hence is non
threaded. This way you can run PHP without worrying about the thread
issues.

There are some alternative solutions that under some conditions, will
accomplish the same goal:

  • suPHP which changes the UID of the process executing the PHP
    interpreter to the owner of the PHP script. However, while the
    ITK solution is generic, suPHP only applies to PHP scripts.
  • suEXEC which provides Apache users the ability to run programs
    under UIDs different from that of the calling web server

Both solutions make use of PHP CGI and thus, will not help in the event
you wish to use the PHP Apache module. For example, you may rely on the
php_value/php_admin_value directives provided by Apache’s PHP module
[mod_php] to parse configuration options for certain virtual hosts or
directories, if so, MPM ITK is a good option.

Keep in mind that it takes an additional performance hit over MPM
prefork due to an extra fork per request. Still, if you want to run PHP
as an Apache module and gain the flexibility of a different user and
group for each vhost, you may find MPM ITK suitable for your needs.

Installing Apache2 MPM ITK:

The installation options depend greatly on the Linux/UNIX distribution you’re working with, many Linux distributions have the Apache2 MPM ITK package available in their repositories, including:
Debian GNU/Linux, Ubuntu, FreeBSD [the package is available in the ports repositories], Gentoo Linux, Arch Linux and Mandriva.

If you are using one of the above listed distributions the most convenient method of installation [in this author’s humble opinion, of course] would be to simply use your package manager, for example, under Debian/Ubuntu run:

Users of other distributions can compile Apache2 MPM ITK themselves by applying a patch on the original Apache sources, to do so:

  1. Download the latest Apache source from: http://apache.org/dyn/closer.cgi and extract the sources.
  2. Download the ITK patch from: http://mpm-itk.sesse.net/apache2.2-mpm-itk-20090414-00.patch and place the file in the root directory of the extracted Apache source.
  3. Apply the patch by running: $ patch -p1 < apache2.2-mpm-itk-20090414-00.patch
  4. Run the configure script with your desired configuration flags and, in addition pass –with-mpm=itk.
  5. Run: $ make
  6. And then, as super user: # make install

Note to ZendServer users under RHEL, FC and CentOS:

Since these Linux distributions do not include the Apache2 MPM ITK package and ZendServer packages rely on the existence of the httpd package, users who wish to work with Apache2 MPM ITK and ZendServer will need to obtain the src.rpm package from here: https://sourceforge.net/projects/jessrpms/

RPM build instructions are beyond the scope of this article but interested readers are welcome to mail me at: MaxClients for the vhost.
This can be useful if, for instance, some vhosts depend on an NFS server; when the NFS server goes down, you do not want the children waiting forever on NFS in order to take the non-NFS-dependent vhosts 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.

NiceValue:
Set the nice value for the vhost. (A setting of how aggressive these processes should be towards the CPU of the system)

The lines below define a vhost, the entry to note, of course, is the one for AssignUserID:

A simple test:

This PHP snippet creates a file on the disk, calls stat() for the file and, finally, prints the UID and GID elements of the array returned by stat():

On my test machine:

And so, the output is:

Important notes:

These notes were taken from the project’s home page, I found them important enough to repeat here:

  1. Since mpm-itk has to be able to setuid(), it runs as root (although restricted with POSIX capabilities where possible) until the request is parsed and the vhost is determined. This means that any security hole exploitable before the request is parsed will be a root security hole (the most likely place being mod_ssl). This is not going to change in the near future, as the most likely alternative solution (socket passing and its variants) is very hard to get to work properly in a number of common use cases, like SSL.
  2. Apache MPM ITK is experimental software and, although a fair amount of stress testing was done, it’s nowhere as tested as 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.

Additional resources:

Special thanks:

My thanks go to Steinar H. Gunderson the developer and maintainer of Apache MPM ITK patch and home page.