Not an easy question, also there's a lot of discussion about this on the web. I will just summarize what I found on the web, give my personal evaluation of it, and name some sources.
The selection criteria here are esp. security and ease of use, within boundaries of performance and memory usage (here, of a medium-sized VPS host for shared webhosting).
The different alternatives
php-fpm sounds like the best overall solution both for speed and memory usage (except on systems with very limited RAM). It is a FastCGI implementation with improvements over the older mod_fastcgi and mod_fcgi ones that lets it better adapt to servers with limited RAM (by using its "dynamic mode", for example). See the php-fpm website. For installation, there are installation instructions for Apache (more of these) on Debian, also explaining how the Froxlor server admin panel accesses php-fpm (as it generates the VirtualHost configs just like that). But there are also slightly more advanced installation instructions for Apache and lighthttpd.
php-fpm will not allow php_admin_value open_basedir
directives in the per-site VirtualHost configs (Froxlor will not generate these directives in VirtualHost sections when having PHP-FPM enabled, and when using them manually there Apache will not start.). However, it allows open_basedir directives in its own per-site configuration files, with globally valid user additions. The instructions for using this feature are in teh article about PHP-FPM with Froxlor.
mod_suphp seems to be the best alternative for a shared webhost with very limited RAM (1 GiB) and many but rather low-traffic sites. Its disadvantage is having the slow speed of CGIs (because a separate process has to be started and for every PHP request), but that only becomes a problem when CPU resources for the overhead of process starting are no longer sufficient. On the plus side, it is memory efficient. See the installation instructions. If it does not work out well (too slow / too high CPU load), you can try php-fpm or mod_fcgi instead, with memory limiting tweaks by reducing idle process runtime.
However, the problem with mod_suphp is that it does not allow php_admin_value
directives per VirtualHost section. This can be worked around by using per-host php.ini files instead [source], except when using a server admin panel that does not support them. Like Froxlor, independent of the webserver you use with it (this feature is only provided by a bleeding edge patch for Froxlor 0.9.28-svn5, which even generates these per-site php.ini files and the proper open_basedir
settings [source]. Which is not a good idea to use, as the future development of Froxlor is unsure at best as of 2013-02, meaning one might get permanently stuck in using an untested development version of ones server panel (!)).
So the only option is to configure open_basedir
globally in the corresponding php.ini config file. But then, all website paths (or their common root path) would be listed there, which nearly completely anihilates the benefit of open_basedir
for shared hosting, namely, the protection against cross-infection with worms, between sites of different customers. Which means that currently, Froxlor prohibits a meaningful use of php-fpm, mod_suphp and mod_fcgi, except you want to put in own development efforts of course. Because: using one of these handlers alone, without open_basedir
, provides no proper protection as users will use mode 0666 for their files by mistake or lack of experience [source]. Then, open_basedir
alone is an even better protection alone than one of the uid-changing handlers alone. Which means currently, with Froxlor 0.9.27, security wise we're prohibited from using mod_suphp. Use php-fpm instead, or switch to mod_ruid2 or mpm-itk after hardening the kernel with grsec.
An added problem specific to mod_suphp and Froxlor is that, as Froxlor does not support mod_suphp natively, it will still assume that mod_php5 is in use and allow users to enable their open_basedir
sections (unlike when enabling php-fpm in Froxlor for example). Which will then cause Apache to fail on the next restart because of the generated php_admin_value
directives out of proper ifmod
sections … quite a nightmare scenario.
mod_fcgi and mod_fastcgi (implementing FastCGI) on the other hand also has the "execute with user ID of script owner" mechanism but needs a lot of RAM when having more than a few websites (50 MiB permanently for a single process, which can handle only one request in parallel for one website).
mod_php with mod_ruid2 is nice (security of mod_suphp plus speed of mod_php) but, in case that somebody finds certain apache2 vulnerabilities, is a security problem itself as it would allow people to suid to root with apache2 and scripts running inside of it (like with mod_php5). So it is only recommended when having a hardened kernel with grsecurity or similar [source, even recommended in the official project documentation], so nothing for simple and quick setups.
mpm-itk. This provides the same "execute as the file's user" security as the above alternatives (except mod_php alone of course). But it's not a module, instead part of the Apache binary. It also does not use the CGI model like mod_suphp, making it much faster than that. And also faster than FastCGI [benchmarks]. Indeed, it should be nearly as fast as mod_php alone. Also, it's very simple to configure with just three directives, and in contrast to mod_suphp it allows the php_admin_value
directives. See some installation instructions. However, the big caveat is the same as with mod_ruid2: Apache2 runs as root until after header processing, when it can switch user IDs, so a potential exploit happening before might give root access to the system immediately [source, at "Quirks and Warnings"]. For that reason, only use it with a hardened kernel, just as with mod_ruid2 (see there).
mod_php alone (resp. mod_php5 now) provides insufficient isolation of customer sites against each other, as all files are readable (and upload directories even writable) by the webserver user, which means world-readable and world-writable because of the way Froxlor does its user account management.
More alternatives. There is a nice Apache wiki article on Privilege Separation with some nice ideas and background infos. However, it provided no additional practical solution in this context.
Results (esp. together with Froxlor)
For a secure but also simple to do and simple to maintain setup on a shared webhost with not too many medium traffic sites, I would use php-fpm. The same if there's just one or a few high-traffic sites. If there are instead a really lot of low traffic sites, I would use mod_suphp instead.
If the solution has to be deployed together with the server management panel Froxlor (version 0.9.27 currently), php-fpm is also a good solution (instructions). mod_suphp however is not (see the discussion about open_basedir problems in the mod_suphp section above).
Sources
In addition to the individual sources already linked to, the following documents (mostly forum discussions) were consulted when writing this article:
- http://bit51.com/fastcgi-vs-suphp-vs-cgi-vs-mod_php-dso/
- http://forum.lxcenter.org/index.php?t=msg&th=16222
- http://forum.directadmin.com/showthread.php?t=43542
- https://github.com/frenkel/mod_ruid2
- http://serverfault.com/questions/460839/mod-ruid2-vs-suphp
- http://serverfault.com/questions/402188/mod-ruid2-over-mod-fcgid
- https://forum.mediatemple.net/topic/6353-a/#entry34847
- https://forums.cpanel.net/f189/a-275962.html
Leave a Reply