suPHP on CentOS 6 from Source Code

So you’ve decided that you must run php as suPHP on your CentOS 6 based LAMP stack. This is a great idea for security on a multi-site or multi-user environment. Of course management panels like cPanel make running suPHP very easy, but what about the rest of us? Many of us do not use cPanel, perhaps because of the cost or because it’s resource intensive. Personally I like cPanel as a product, but I choose to forgo cPanel on servers requiring a high degree of security in an effort to minimize the amount of services that must be secured and updated. However I still want things like suPHP.

Without cPanel your choices for suPHP on CentOS are either using RPMForge or building it from source. I personally don’t like having the standard repos, plus EPEL, plus RPMForge, so I typically will keep EPEL and opt for installing the other stuff from source in an effort to keep updates from conflicting. So let’s do it from source.

I’m assuming you already have apache running, perhaps with mod_php. If not go ahead and install it from yum and configure it to your liking. Set? Let’s go!

First let’s grab a copy of the latest suPHP and unpack it: suPHP.org

cd /root/
wget http://www.suphp.org/download/suphp-0.7.1.tar.gz
tar xvzpf suphp-0.7.1.tar.gz

You will want to make sure you have all the compilers and developer tools needed to build stuff from source. We are assuming you have httpd installed and do NOT have php built from source, so we will make sure php is installed as well as httpd development tools:

yum groupinstall "Development Tools"
yum install php php-devel php-mysql apr-devel httpd-devel

Now let’s build this sucker and throw it into /opt/suphp:

cd /root/suphp-0.7.1
./configure '--prefix=/opt/suphp' '--sysconfdir=/opt/suphp/etc' '--with-apr=/usr/bin/apr-1-config' '--with-apxs=/usr/sbin/apxs' '--with-apache-user=apache' '--with-setid-mode=owner' '--with-php=/usr/bin/php-cgi' '--with-logfile=/var/log/httpd/suphp_log' '--enable-SUPHP_USE_USERGROUP=yes'
make
make install

If there were no errors through that entire process, you’re almost there. You will now find that mod_suphp.so has been installed in /usr/lib64/httpd/modules/mod_suphp.so (assuming you’re on x86_64.)

We must now modify the file /etc/httpd/conf.d/php.conf, clear it out and make it looks like so:

#
# PHP is an HTML-embedded scripting language which attempts to make it
# easy for developers to write dynamically generated webpages.
#

LoadModule suphp_module modules/mod_suphp.so

suPHP_Engine on
AddType application/x-httpd-suphp .php5 .php .php3 .php2 .phtml
<Directory />
    suPHP_AddHandler application/x-httpd-suphp
</Directory>


DirectoryIndex index.php

So for a final step let’s make a new directory and write a suphp.conf file:

mkdir /opt/suphp/etc
nano -w /opt/suphp/etc/suphp.conf

Setup the suphp.conf file as follows:

[global]
logfile=/var/log/httpd/suphp.log
loglevel=info
webserver_user=apache
docroot=/
allow_file_group_writeable=true
allow_file_others_writeable=false
allow_directory_group_writeable=true
allow_directory_others_writeable=false
check_vhost_docroot=true
errors_to_browser=false
env_path=/bin:/usr/bin
umask=0077
min_uid=100
min_gid=100

[handlers]
application/x-httpd-suphp="php:/usr/bin/php-cgi"
x-suphp-cgi="execute:!self"

Now you can restart Apache with the changes you made:

service httpd restart

If there were no errors displayed, you did well.

If you wish to test within your vhost that suphp is indeed working, try setting up a php script with the following content, place it in the webroot (i.e. public_html) and own it to the proper user (ie. ‘mywebuser’):

<?php
	exec("touch /home/mywebuser/public_html/omg.txt");
	echo exec("ls -al /home/mywebuser/public_html/omg.txt");
?>

When you visit that page it should create a file called omg.txt and show you that it’s owned by the ‘mywebuser’. This means that PHP ran as the proper user. You can also debug and see which user stuff runs as via the /var/log/httpd/suphp.log

Have fun!