In order to increase security on a webserver, especially on a shared host, using suExec and FastCGI to execute a PHP script as a normal user will add a level of security. For example, we have a vhost configured already:
<VirtualHost *:80> ServerAdmin webmaster@dummy-host.example.com DocumentRoot /var/www/html/example ServerName example.com ServerAlias www.example.com ErrorLog logs/example.com-error_log CustomLog logs/example.com-access_log common <Directory /var/www/html/example> DirectoryIndex index.php AllowOverride All Allow from all Order allow,deny </Directory> </VirtualHost>
The first step is to make sure that the suExec and FastCGI module are enabled, in the httpd.conf or apache.conf (depending on which distribution you're using) for suExec and for FastCGI, look for a file called fcgid.conf located in the conf directory.
LoadModule suexec_module modules/mod_suexec.so
Now we need to go back to the vhost directive. Add the following lines that are in bold:
<VirtualHost *:80> ServerAdmin webmaster@dummy-host.example.com DocumentRoot /var/www/html/example ServerName example.com ServerAlias www.example.com ErrorLog logs/example.com-error_log CustomLog logs/example.com-access_log common SuexecUserGroup user group <Directory /var/www/html/example> DirectoryIndex index.php Options +ExecCGI AddHandler fcgid-script .php FCGIWrapper /var/www/conf/php-fcgi .php AllowOverride All Allow from all Order allow,deny </Directory> </VirtualHost>
Where you place your document root is up to you and where you place your php-fcgi (or what you decide to name it) is also up to you. The next step is to make all php files executeable.
For the php-fcgi script, which is located in /var/www/conf/ should contain the following:
#!/bin/bash PHP_CGI=/usr/bin/php-cgi PHP_FCGI_CHILDREN=4 PHP_FCGI_MAX_REQUESTS=1000 ### no editing below ### export PHP_FCGI_CHILDREN export PHP_FCGI_MAX_REQUESTS exec $PHP_CGI
the file should be 755
$ find . -type f -iname '*.php' -exec chmod u+x '{}' \;
suExec only handles binaries or shell scripts that are executable which is why we made all the php files executable in the above command. In order for a script to be executable, the script needs to have a #!interpreter before any code. One way to solve this problem is to add a #!/usr/bin/php-cli to the beginning of each php file or run the following command which is the equivalent of telling windows to 'always use this program when opening this kind of file.'
$ echo ':PHP:E::php::/usr/bin/php-cgi:' > /proc/sys/fs/binfmt_misc/register
PHP (1st position) - is used as the name.
E (2nd position) - is saying that this is going to be an executable file. The other option for this position is M, or magic, which assocates a binary file (eg: exe) with a program.
php (4th position) - The type of file we're associating.
/usr/bin/php-cgi (6th position) - What is to be run when this type of file is encountered.
If this still isn't working, and you may need to add the following line to the php.ini file:
cgi.force_redirect=0
Finally you can restart apache:
# service httpd restart
You can test this by creating a php file in the directory you specified in your VirtualHost directive.
<?php echo system('id'); ?>