PHP handlers for Apache


In this article, I'll explain about the PHP Handlers on Apache Web server which are widely discussed in the context of Hosting Industry. There are two ways to configure Apache to use PHP :

(1) Configure Apache to load the PHP interpreter as an Apache module (DSO)
(2) Configure Apache to run the PHP interpreter as a CGI binary (CGI)


PHP Handlers

A handler is a piece of code built into Apache that performs certain actions when a file with a particular MIME or handler type is called. PHP handlers are the programs that interpret the PHP code in your web application and process it to be sent as HTML (or another static format which the web browser understands) by your web server. None of the major web servers available today can handle PHP by themselves which is why they need another program to do it for them. This program, known as a PHP handler takes all the PHP code and generates the output which is then sent to the web server which forwards it on to the user upon request. Currently there are Four major PHP handlers available on Apache. They are CGI, DSO, suPHP, & FastCGI. Each handler delivers the libraries through different files and implementations. Each file and implementation affects Apache’s performance, because it determines how Apache serves PHP. I will be explaining these handlers one by one from here.



(a) PHP as DSO (aka mod_php)

When PHP runs as an Apache module (DSO), it is compiled into the Apache code itself. This means, when an Apache process starts, PHP starts along with it. PHP depends on Apache to operate. It means when Apache spawns a child process, each process already contains a binary image of PHP. The benefit of this is that Apache tends to run very efficiently, and PHP is part of each Apache process.This makes it more of a security risk, particularly on shared hosting accounts. DSO based PHP does not change its user ID so you would be running all PHP scripts as the user your Apache web server is running as which is almost always 'nobody' and sometimes more rarely 'apache'. This means when PHP interacts with files on the file system, they are accessible by the 'nobody' user. This creates permissions issues, for instance a normal cPanel based user will not have access to RW (read/write) files that are owned by the 'nobody' user without assigning the proper permissions. Most PHP web apps or scripts need write access to files and directories. If those scripts are owned by the cPanel user, it will cause issues and most probably the scripts would be broken unles they have 777 permissions to files/directories. When running this PHP method you will have to manually manage the permissions on a per user basis to ensure that your PHP apps/scripts can read and write to the files and directories of which it needs to function. The undesired part is that this is insecure, when having 777 permissions on files and directories. It can allow exploits to spread across many user accounts on the server since its been executed by a common user.

Pros and Cons

Pros : Making PHP the Apache module is slightly faster than the CGI (as well as more stable under load). Using a DSO will also allow for most common PHP .htaccess (php_flag not to be confused with php_value) directives to be used ie .htaccess file can be used to change your php parameters.

Cons : All files created by a PHP script will have the ownership of ‘nobody’. If a hacker finds an exploit in your PHP script, they could implement a file that has the same privileges as important system files that are also owned by ‘nobody’. This will give them the ability to modify files outside of that user’s account. The other downside of PHP as a module is also that it is part of Apache. If PHP goes down, Apache would follow !

(b) PHP as CGI

CGI stands for Common Gateway Interface. The CGI handler provides the selected version of PHP through mod_cgi or mod_cgid. PHP as a CGI script means that PHP operates as an independent binary with its own processes. It is separate from Apache and can, therefore, run as another user, rather than Apache’s generic user. This increases security and adds a bit of stability, at the expense of speed.This means you can put your database passwords in a file readable only by you and your php scripts can still access it! CGI is the fallback in most servers when mod_php is not available. Instead of running the PHP code within Apache it is now run as it’s own CGI process, that is, in a program outside of your Apache server.Unlike mod_php, CGI spawns separate processes to execute the PHP scripts. Please note that the CGI handler will run PHP as a CGI module as opposed to an Apache module. CGI still runs PHP processes as the Apache ‘nobody’ user1.  However, if you have suEXEC enabled2, it will allow you to see the user that made the request. We will explain suEXEC later. According to cPanel’s own documentation, this method is only intended as a fallback for when DSO or suPHP is not available. Serving PHP as CGI is not especially fast or secure, even if suEXEC is enabled.

1 By default CGI will be called by the Apache server meaning that it will run as the Apache user with all the problems of doing so that mod_php encountered. Unlike mod_php however CGI has the ability to see the PHP as another user (presumably the user that owns the files) using another Apache module known as suexec. In more detail running php as cgi provides PHP through mod_cgi or mod_cgid. Using this option, you can enable suEXEC so that PHP scripts will be executed as the user who owns the VirtualHost that is serving the request. If suEXEC is disabled, the system user “nobody” will execute PHP scripts. UserDir requests will not function properly with the setup provided by cPanel.

2 When suEXEC is not enabled in CGI, it runs PHP processes as the Apache 'nobody' user.

(c) PHP as suPHP

suPHP stands for Single user PHP. suPHP also runs PHP as a CGI module instead of an Apache module. It differs from CGI in that PHP scripts that are called from the web will run under the user that owns them, as opposed to ‘nobody’. suPHP is typically the default handler and is recommended by cPanel for serving PHP because you will be able to see which user owns the account that is running the PHP script. Consider an example, as we said previously when php run as DSO processes are handled by the user that is running httpd. In most cases, this user is the 'nobody'.So in order to write a file to a location the permissions of the folder have to allow write access for that user (nobody). Suppose you want to write to the folder /home/user1/public_html folder then its permissions should be set to 777, inorder to perform the write operation for the user nobody (world-writable permissions). Alternatively, all the existing files permissions would need to have 777 permissions. suPHP provides an additional layer of protection on servers. It causes PHP scripts to run under the account username instead of the user ‘nobody’ . So in the previous example if you want to run a file at /home/user1/public_html/index.php then the file would be executed by user1. This allows us to better monitor the resource usage of accounts, as well as track down runaway script files with greater ease. The downside of using suPHP is that it causes a lot of additional CPU usage. Because each PHP process/script which is executed, a separate CGI process is started (under your user) which actually executes the script. By using suPHP you can avoid dangorous file permissions (777). The permission setting for an suPHP enabled server is 755 for directory and 644 files. In addition, because your PHP is being run as a different user any vulnerability in your site can be restricted to only the files of your website thereby providing substantial security benefits particularly on servers that run multiple websites.

(d) PHP as FastCGI (mod_fcgid)

FastCGI is alo a cgi module. It has the security/ownership benefits of suPHP ie., PHP scripts will run as the actual cPanel user as opposed to ‘nobody’. Unlike suPHP however it keeps open a session for the file when the processing is done resulting in significant memory use but also allowing for the use of OPCode caching such as APC or memcached. However FastCGI drastically save on CPU performance and give speeds close to that of DSO.

More about FastCGI and SuPHP (FastCGI vs SuPHP)

SuPHP spawns separate processes to execute the PHP scripts and end as soon it executes the script. Hence it conusmes less memory. It is slow in terms of speed since it need be launched anew PHP process with each invocation, a limitation that leads to two problems. First, the hardware and operating system have to deal with the overhead of creating a process for every request. CGI scripts can't handle persistent variables or data structures; they must be rebuilt with each invocation. This is where FastCGI comes to play.FastCGI can drastically save on CPU performance and give speeds close to that of DSO. FastCGI processes are persistent-they are reused to handle multiple requests ie they wait for a new request instead of exiting. This solves the CGI/SuPHP performance problem of creating new processes for each request hece reduces the CPU usage.The drawback is FastCGI has a high memory usage. This is because rather than creating the PHP process each time it is called, like suPHP, it keeps a persistent session open in the background. This is what lets it work with an opcode caching software.So FCGI is a good choice for saving ram. FastCGI does not understand Apache directives. If you wish to use Apache directives for PHP, FastCGI is not the handler for you. Also, it has a high memory footprint. If your server does not have much extra RAM hanging around, FastCGI is probably not the best choice.

Following is an image which will provide a brief comparison of PHP Handlers discussed so far :



Common Disadvantages of CGI

.htaccess

When PHP runs as an Apache module you are able to manipulate PHP using .htaccess - since .htaccess is an Apache feature. When PHP runs as a CGI, you can no longer do this because Apache no longer understand the PHP flags and values. Instead, when PHP runs as a CGI, you will need to create your own PHP initialization file, this file is called php.ini -- php.ini works almost the same as .htaccess -- it is simply a text file with directives that will be used instead of the servers default directives.

To give you a better understanding about how both work in regards to PHP, I have have listed a .htaccess file and a php.ini file below.

The .htaccess file

php_value magic_quotes_gpc on

The php.ini file

magic_quotes_gpc = on

What is suExec

1 comment:

Unknown said...

Nice one!!! Well explained