Linux: Install and Configure Apache with SuPHP

If you install Apache  and PHP web server from your distribution repository, the system will auto-configure your web server to handle PHP script using Dynamic Shared Object (DSO) handler. The major effect of DSO is Apache process will be run under Apache user (it can be user nobody, www-data or wwwroot). If some PHP script is overloading the server, we will still see user ‘nobody’ as the executer, which is hard for us to determine which user’s script cause the problem.

To differentiate between available PHP handler, you can refer to this post. In this tutorial, we will install and configure suPHP to work with default installation of Apache. SuPHP is a tool for executing PHP scripts with the permissions of their owners. It consists of an Apache module (mod_suphp) and a setuid root binary (suphp) that is called by the Apache module to change the uid of the process executing the PHP interpreter.

Variables that I used:

Server: CentOS 6.0 64bit
Server IP:
User: ryan
Web directory: /home/ryan/public_html

1. Install Apache, PHP and required compiler via yum:

$ yum install -y httpd* php gcc-c++

2. Download mod_suphp RPM. The RPM version must be same with suPHP version that we are going to download on step 3:

$ cd /usr/local/src
$ wget
$ rpm -Uhv  mod_suphp-0.7.1-1.el6.rf.x86_64.rpm

3. Download and prepare suPHP from this website. At this moment, the latest version is suphp-0.7.1.tar.gz:

$ cd /usr/local/src
$ wget
$ tar -xzf suphp-0.7.1.tar.gz
$ cd suphp-*

4. Locate APR config binary and build suPHP:

$ which apr-1-config

Build suPHP:

$ ./configure --with-apr=/usr/bin/apr-1-config --with-setid-mode=owner
$ make
$ make install

5. Create the website and logs directory for user:

$ useradd -m ryan
$ mkdir /home/ryan/public_html
$ mkdir /home/ryan/logs
$ touch /home/ryan/logs/error_log
$ touch /home/ryan/logs/access_log

6. Create the configuration file in Apache to serve the website under user ryan. We will create a new virtual host in the Apache conf.d directory:

$ vi /etc/httpd/conf.d/vhost.conf

And add following line:

ServerAdmin [email protected]
DocumentRoot /home/ryan/public_html
ErrorLog /home/ryan/logs/error_log
CustomLog /home/ryan/logs/access_log combined
suPHP_Engine on
suPHP_UserGroup ryan ryan
AddHandler x-httpd-php .php .php3 .php4 .php5 .phtml
suPHP_AddHandler x-httpd-php

7. Change the PHP handler from mod_php to mod_suphp. We need to edit mod_suphp configuration file at /etc/httpd/conf.d/suphp.conf and uncomment following line:

LoadModule suphp_module modules/

And remove mod_php configuration file:

$ rm -Rf /etc/httpd/conf.d/php.conf

8. Make sure suPHP configuration file located at /etc/suphp.conf has value as below:

; Security options
;Check wheter script is within DOCUMENT_ROOT
;Send minor error messages to browser
;Handler for php-scripts
;Handler for CGI-scripts

9. SuPHP will throw some error because it will try to lookup suphp.conf under /usr/local/etc directory. So we need to create a symbolic link to the real /etc/suphp.conf:

$ ln -s /etc/suphp.conf /usr/local/etc/suphp.conf

10. We also need to fix the permission and ownership for user ryan:

$ chmod 755 /home/ryan
$ chown ryan.ryan /home/ryan/public_html -Rf
$ find /home/ryan -type d -exec chmod 755 {} \
$ find /home/ryan -type f -exec chmod 644 {} \

11. Now suPHP configuration is done. We need to restart Apache service as well as prepare the service to start on boot:

$ chkconfig httpd on
$ service httpd restart

Done! Now we can upload the website into the user web directory at /home/ryan/public_html. SuPHP will allowed you to run the file only owned by the respective user. So step #10 is quite important in order to fix the permission and ownership, or else the web server will throw an “Internal Server Error” in the browser.

All related files location for suPHP:

SuPHP log – /var/log/httpd/suphp_log
SuPHP config – /etc/suphp.conf
SuPHP module config – /etc/httpd/conf.d/suphp.conf
SuPHP module – /etc/httpd/modules/
Apache error log –  /etc/httpd/logs/error_log