Preface
We had seen the details of setting up PHP as an apache module. An Apache module is compiled into the Apache binary, so the PHP interpreter runs in the Apache process, meaning that when Apache spawns a child, each process already contains a binary image of PHP. The obvious advantage of using PHP as a module is speed. But it also gives much room for security concerns. Since php executes as the webserver user and it can be exploited for malicious operations like root escalation etc. Hence it is recommended to use further options such as PHP CGI for better security
CGI
The CGI (Common Gateway Interface) defines a way for a web server to interact with external content-generating programs, which are often referred to as CGI programs or CGI scripts. This means that the webserver, upon receiving a request, will forward the data to a specific program (php-cgi), setting some environment variables and marshalling the parameters via standard input and standard output so the program can know where and what to look for. In order to get your CGI programs to work properly, you’ll need to have Apache configured to permit CGI execution and is enabled through the Apache module mod_cgi
or mod_cgid
.
PHP can be run as CGI . The CGI handler will run PHP as a CGI module as opposed to an Apache module. As CGI, a new process is spawned on each request. CGI still runs PHP processes as the Apache ‘nobody’ user. However, if you have suEXEC enabled, you will be able to see which user, through the virtual host, has made the PHP request (The owner of a virtual host will be the same as the account name.).
Configuration
Running PHP as a CGI is different in various aspects. Since the PHP binary isn’t compiled within Apache or loaded as an apache module, it runs as any other process. In other words it runs under a separate process and user. Let us have glance over the process involved during the process
Please note that the paths used here are derviced from my custom installation of PHP with installation directory /usr/local/php and should be replaced with your values
1. Install PHP as CGI binary ( using the configure option –enable-cgi )
2. Once the installation is complete, you can get the installation location of various PHP Binary version paths from the output. Below is one one such output
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/
Installing PHP CLI binary: /usr/local/php/bin/
Installing PHP CGI binary: /usr/local/php/bin/
As you can see, the CGI version of the PHP binary is placed in the folder /usr/local/php54/bin/
# ls -l /usr/local/php/bin/php*
-rwxr-xr-x 1 root root 11654422 Nov 20 00:37 /usr/local/php/bin/php*
-rwxr-xr-x 1 root root 11632642 Nov 20 00:37 /usr/local/php/bin/php-cgi*
The first one /usr/local/php5/bin/php is the CLI and /usr/local/php/bin/php-cgi is the CGI version.
3. Once the installation is completed, confirm the version by using the command
#/usr/local/php/bin/php -v
PHP 5.4.14 (cli) (built: May 3 2013 12:21:56)
Copyright (c) 1997-2013 The PHP Group
4. Configuring Apache to use the PHP CGI
The integration Apache with php-cgi to interpret .php files is bit complicated than that of DSO. To get Apache to use the PHP CGI for files with the .php extension, we need to specify the php-cgi executable path in the Apache configuration. As we had seen earlier it is installed in /usr/local/php/bin/php-cgi.
Add the following to an appropriate place in your httpd.conf file
ScriptAlias /local-bin /usr/local/php/bin
AddHandler application/x-httpd-php php
Action application/x-httpd-php /local-bin/php-cgi
The ScriptAlias directive tells Apache that the /usr/local/php/bin directory can be used to execute scripts.
AddHandler specifically is meant to communicate within the server. It assigns or “maps” a handler or MIME type to the file extension you specify. Here the AddHandler directive tells Apache that whenever it encounters a file with a .php extension, it should mark it as having a MIME type of application/x-httpd-php.
The ‘Action’ directive runs the specified ‘cgi-script’ when a given request for a URL contains the specified ‘content-type’ (or handler name). In this case, the ‘Action’ line instructs Apache that that whenever it encounters a file of type application/x-httpd-php it should pass it to the script /usr/local/php/bin/php-cgi and generate the output.
5. Restart apache
/usr/local/apache/bin/apachectl start
6. Check the php handler by accessing a PHP info page and you should see
Server API as CGI
DSO Vs CGI
Running PHP as a CGI means that you basically tell your web server the location of the PHP executable file and execute it according to the invoked file/script. That means each time you load a page, PHP needs to set various parameters according to php.ini and load the extensions. Once this is done the script is parsed. This needs to be repeated for each request.
When you run PHP as a module, PHP literally sits inside your web server – it starts only once, loads its settings and extensions only once, and can also store information across sessions. But this requires webserver to be restarted whenever a modification is performed to the php.ini file.
Since CGI version reads the php.ini file every time a new process is to be spawned , there iss no need for restart of webserver.
PHP CGI is more secure because the server manages and controls access to the binaries. PHP can now run as your own user rather than the generic Apache user. This means you can put your database passwords in a file readable only by you, and your php scripts can still access it. This enables you to make more restrictive permissions for “Group” and “Others” which in turn makes the server more secure.
Further Reading :
https://www.supportsages.com/2010/06/php-basics/