Options for securing PHP in a shared virtual hosting environment
The terms and options for implementing security measures can be quite confusing. This blog post is a survey of the options available, including some possible pros and cons and definitions of relevant terminology.
It is very typical to run multiple sites on a single server, since it would be overkill to run each small website and blog on its own VPS instance. The default Apache setup: mod_php and prefork-mpm does not offer any privilege separation or hardening for virtual hosts. Hence the need for additional security measures.
What are the general approaches taken to securing PHP?
The approaches taken in securing PHP can be divided into two broad categories:
- Hardening PHP. This approach aims to improve the security of PHP scripts by limiting dangerous functionality on a site-by-site basis and by preventing flaws from escalating through additional patches to the PHP core. The main examples are: a) tweaking PHP core settings such as open_basedir and b) running a version of PHP which includes additional options to limit functionality and prevent flaws such as buffer overflows (Suhosin).
- Privilege separation. This approach limits the extent to which other sites can be damaged if one of the websites on the shared server is compromised. There are several solutions, including mod_suPHP and suEXEC.
There are several ways in which PHP and other scripts can be invoked by Apache:
- CGI (Common Gateway Interface) is a standard protocol that defines how webserver software can delegate the generation of webpages to a console application. It operates on a "one new process per request" basis.
- FastCGI is a protocol introduced in the mid-1990s that improves upon the older CGI protocol. It allows a single persistent process pool to handle multiple requests over its lifetime, reducing overhead.
- In-process as an Apache module, such as the default mod_php.
Privilege separation can be done either:
- by using CGI scripts and suEXEC, a feature built in Apache
- by using Apache modules that make invoking CGI scripts easier
- Apache modules are bundles that can be loaded to add new functionality to Apache. They are integrated into the Apache server and add new functionality to instances of the server, such as the capability to interpret PHP scripts.
- Examples: mod_php, mod_suPHP, mod_fastcgi and mod_fcgid.
- by using Apache MPMs that support privilege separation
- Apache MPMs (Multi-Processing Modules) are responsible for binding to network ports on the machine, accepting requests, and dispatching children to handle the requests. There are several different MPMs - the Unix platform default is the prefork mpm.
- Examples: prefork, worker, perchild, mpm_itk, mpm_peruser
suEXEC
suEXEC is a feature built into Apache, but not included in the default Apache installation. It makes all CGI scripts execute with the user id and permissions of their owners. It can be used with PHP and with other CGI scripts.
It consists of a setuid "wrapper" binary that is called by the main Apache web server, and which executes CGI scripts with the correct used id.
Tried and tested
Can be used with other languages than PHP
Low performance without FastCGI (similar to suPHP)
Separate script files are a minor hassle
Module: mod_suPHP
mod_suPHP makes PHP scripts execute with the user id and permissions of their owners.
It consists of an Apache module (mod_suphp) and a setuid root binary (suphp), which calls PHP as a CGI process.
Easy to install, in RPMForge repo (http://wiki.centos.org/AdditionalResources/Repositories/RPMForge)
Quite commonly used
Low performance relative to others (similar to suEXEC)
PHP specific solution
= Recommended for low load sites which are not using their resources to their limits.
Module: FastCGI (mod_fastcgi or mod_fcgid)
mod_fastcgi and mod_fcgid implement process persistence between page views and communicate with PHP using FastCGI. They do not by themselves perform privilege separation, suEXEC is needed.
Decent performance when using suEXEC with FastCGI, similar or better performance than mod_php has been reported
Can be used with other languages than PHP
FastCGI may require more memory because there are more persistent processes (more suited for servers with a lot of memory)
Separate script files are a minor hassle
= Recommended for higher load sites.
MPM: mpm_itk and mpm_peruser
These are alternative MPMs for Apache that replace the default preform MPM and perform additional privilege separation.
mpm_itk works in a manner similar to regular CGI scripts in that it does not reuse processes after each request. However, unlike CGI scripts, it invokes each process with the user id and group specified for that virtual host.
Neat solution with decent performance, some systems have it in the repos
Must patch and compile separately in Centos
Not as commonly used as suEXEC or suPHP
= Recommended as a upcoming solution that is higher performance than mod_suPHP and easier to setup than suEXEC+FastCgi.
mpm_peruser creates one or more apache child processes for each unique user/group, each handling its own set of virtual hosts.
Faster than mpm_itk
Must patch and compile separately in most systems
Development and adoption seems to be more limited than mpm_itk
Comments
PhpCatalog: I do not recommend Shared Hosting for a serious business
Mikito Takada: "Shared hosting" here refers to sharing a single VPS among multiple websites. I do agree that keeping physically separate hosts is valuable - but it should not be the only form of security in use.
There are many cases in which a shared environment works better - like hosting a bunch of blogs and brochure websites and still be remain reasonably secure.
Matt Kukowski: Only problem with suPHP is that it does not allow you to use PHP opcode caching such as APC which greatly speeds up PHP and less disk thrashing.
But, there are other methods, but they are harder to set up.