Apache virtual hosts with different users – CentOS 6.2 and Apache 2.2

mpm-itk is a MPM (multi-processing module) for the Apache web server that allows you to run each virtualhost with it’s own user id and group id. This is basically used to make a shared hosting secured, since you don’t have to make all virtualhosts folders readeable by apache user.
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.


Download a newest or upgrade your version of EPEL from here: http://dl.fedoraproject.org/pub/epel/
For my example:

wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -i epel-release-6-8.noarch.rpm

Next ste is to install httpd-itk pacage:

yum install httpd-itk.x86_64

After that, if you are currently running httpd, stop it, as the switch is done in the httpd control scripts.

 /etc/init.d/httpd stop

Then uncomment and edit /etc/sysconfig/httpd:


Add users and groups for your vhosts and configure httpd’s vhosts to use them:

<VirtualHost *:80>
 ServerName example.com
 DocumentRoot /path/to/web/root
 AssignUserId vhost-user vhost-group

If using php with mod_php, don’t forget to add to /etc/httpd/conf.d/php.conf :

<IfModule itk.c>
 LoadModule php5_module modules/libphp5.so 

It is good to change website’s root to be owned by the user, the group set to the vhost’s group:

 chown vhost-user:vhost-group /path/to/webroot

And finally start Apache

/etc/init.d/httpd start

For a complete and secure setup, you’ll need 2 users and 1 group for each virtual host. First user is the “write” user, the one that you (or you customer…) use to upload files. The second user is the user that apache runs the vhost under, the group allows apache to access the files loaded by first user.


If mpm-itk does not suit your tastes, here are some alternatives:

  • If you only run CGI scripts, suexec will probably solve most of your problems with any MPM. Similarly, suPHP provides a PHP-only solution.
  • If you are on Solaris, mod_privileges, part of Apache since 2.4, provides functionality somewhat like mpm-itk.
  • There is an MPM similar to mpm-itk called peruser, but it seems it no longer has a web site. There is still a mailing list, though.

That’s all.

All configuration options

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.
  • LimitUIDRange, LimitGIDRange (Apache 2.4 or newer only, for now): 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!).

 Thanks to:

Matteo Brancaleoni


One Reply to “Apache virtual hosts with different users – CentOS 6.2 and Apache 2.2”

  1. Pingback: How to use different user and group for just one Virtual Host in Apache | Gerson Barreiros

Leave a Reply

Your email address will not be published. Required fields are marked *