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: 210.84.17.110
User: ryan
Web directory: /home/ryan/public_html
Website: http://www.misterryan.com/

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 ftp://rpmfind.net/linux/dag/redhat/el6/en/x86_64/dag/RPMS/mod_suphp-0.7.1-1.el6.rf.x86_64.rpm
$ 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 http://www.suphp.org/download/suphp-0.7.1.tar.gz
$ tar -xzf suphp-0.7.1.tar.gz
$ cd suphp-*

4. Locate APR config binary and build suPHP:

$ which apr-1-config
/usr/bin/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:

NameVirtualHost 210.84.17.110:80
 
<VirtualHost 210.84.17.110:80>
ServerName misterryan.com
ServerAlias www.misterryan.com
 
ServerAdmin webmaster@misterryan.com
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
</VirtualHost>

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/mod_suphp.so

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:

[global]
logfile=/var/log/httpd/suphp_log
loglevel=info
webserver_user=apache
docroot=/var/www/html:${HOME}/public_html
env_path=/bin:/usr/bin
umask=0077
min_uid=500
min_gid=500
 
; Security options
allow_file_group_writeable=false
allow_file_others_writeable=false
allow_directory_group_writeable=false
allow_directory_others_writeable=false
 
;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=true
 
;Send minor error messages to browser
errors_to_browser=false
 
[handlers]
;Handler for php-scripts
x-httpd-php="php:/usr/bin/php-cgi"
 
;Handler for CGI-scripts
x-suphp-cgi=execute:!self

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/mod_suphp.so
Apache error log –  /etc/httpd/logs/error_log