Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Httpd Wiki" for change 
notification.

The following page has been changed by slive:
http://wiki.apache.org/httpd/Recipes/Privilege_Separation

The comment on the change is:
Discussion of another common topic

New page:
Apache httpd is often used in a setup where the same server has content from 
multiple independent groups. For example, it may be used for a shared 
virtual-hosting service where many independent virtual hosts are run under the 
same instance of httpd.

In some cases, it may be necessary to have some level of privilege separation 
for the different groups sharing a server. For example, you may need to prevent 
the content authors on one virtual host from having access to the data files 
used by CGI scripts on another virtual host.

== Why not just switch userids to serve each request? ==

''Feel free to skip this section if the technical details are not important to 
you.''

Unfortunately, you cannot simply configure Apache httpd to adopt different 
privileges depending on what virtual host is being accessed. This is due to the 
basic nature of the unix permission model. 

In particular, httpd processes are long-lived, since starting new processes 
takes substantial resources. Further, any httpd process must be able to serve a 
request for any URL available from the server, since the URL is not known until 
after httpd processes the request headers. Then to serve each request from a 
different userid, httpd would need to process request headers as root, and then 
switch to the appropriate userid after determining the requested URL. There are 
two major problems with this:

 1. Request header processing is one of the most dangerous tasks of a web 
server. Doing this as root would open up the server to many potential security 
problems. Instead, Apache httpd is designed to do all request processing as a 
less-privileged user.

 2. Once the server switches to a less-privileged userid, there is no way to go 
back to root in order to process further requests. (If there was a way to get 
back to root, an attacker could obviously use this to subvert any restrictions 
on the less-privileged userid.) That means a new process would need to be 
created for each connection, substantially increasing resource usage.

== Privilege separation with CGI scripts ==

If privilege separation is required only for CGI scripts, there are two 
standard tools available: [http://httpd.apache.org/docs/trunk/suexec.html 
suexec] (included in the Apache HTTP Server distribution) and 
[http://cgiwrap.sourceforge.net/ cgiwrap] (a third-party tool).

These suid launchers allow CGI scripts to be run under different userids 
depending on the URL of the request. Each imposes different restrictions and 
has different capabilities.

Even in cases where you would ordinarily use an Apache httpd module like php or 
mod_perl, the simplest, safest, and most performant way to get privilege 
separation will often be to instead use php or perl as a CGI script under 
suexec or cgiwrap. 

In cases where the performance hit from using CGI scripts is not acceptable, 
the best alternative is often to use [http://www.fastcgi.com/ fastcgi] to run 
long-lived cgi processes outside the httpd process. The most up-to-date fastcgi 
module for Apache httpd is [http://fastcgi.coremail.cn/ mod_fcgi]. Work is 
currently underway to incorporate fastcgi management into the Apache HTTP 
Server distribution for a future version.

== Using Unix permissions for privilege separation ==

If privilege separation is needed simply to keep administrators of one site 
from reading files deployed on another site, proper configuration of unix 
permissions will often suffice.

In particular, instead of making all files to be served by Apache httpd 
world-readable, setup a group such as {{{web-content}}} and run httpd under 
this group (using the Group directive in httpd.conf). Then site administrators 
simply place any content needed by the server in the {{{web-content}}} group 
with  {{{chmod 640}}} (or similar) permissions.

On some operating systems, much-more granular and flexible permissions 
management is also possible. For example, SELinux allows very precise 
assignment of permissions beyond what would be possible with the standard Unix 
permissions model.

== Complete privilege separation using a reverse proxy ==

If complete isolation of virtual hosts (or even particular URLs) is necessary, 
then the only real solution is to run a separate instance of Apache httpd for 
each host. When using IP-based virtual hosting, you can simply have each 
instance listen on a separate IP address. For name-based virtual hosting (or to 
isolate particular URLs with a virtual host), you can setup a reverse proxy 
server that dispatches requests to independent httpd instances on different 
ports. Full details are provided in 
[wiki:Recipes/Different_UserIDs_Using_Reverse_Proxy another recipe].

This solution is flexible, powerful, and very efficient (although the reverse 
proxy must double-process the http requests). It can, however, be complicated 
to configure for a large number of hosts.

== MPMs that do privilege separation ==

Several different multi-processing modules (MPMs) have been written to address 
this problem.  These include perchild (now defunct),  Metux mpm, 
[http://www.telana.com/peruser.php Peruser MPM], and [http://mpm-itk.sesse.net/ 
MPM-ITK]. The first three keep a pool of threads or processes available under 
each userid and dispatches each request to the appropriate thread pool. 
Essentially, they are a more efficient version of the reverse proxy solution 
discussed above. None of these modules are apparently production-ready.

MPM-ITK, on the other hand, processes request headers under root, switches to 
the target userid, and then kills the httpd process when finished serving the 
connection. As discussed above, this has serious security and performance 
implications.

At the present time, you should only attempt to use one of these MPMs if you 
fully understand the security and performance trade-offs involved.

== A caveat on the effectiveness of privilege separation ==

It is important to remember that, no matter how hard you try to isolate 
different sites, denial of service attacks will always be possible.

Reply via email to