So I’m a bit of a purist when it comes to CentOS administration. CentOS is built on the idea of stability and sustainability. Without the addition of extra 3rd-party repositories, it provides the bare necessities to run a reliable and secure server. Don’t get me wrong though, there are plenty of great packages out of the box (from OpenSSL, Apache, PHP to OpenLDAP, PostgreSQL and then some), but sometimes you need some heavy-duty next-gen power tools like ffmpeg, nginx, OpenVPN or suPHP. Most of these packages are not available from the “CentOS Certified” base, extras and updates repositories; in fact, you can’t get them via yum without adding a third-party repo like RPMForge.
With that said, I need suPHP for a PHP staging environment. I’m not going to talk about what suPHP is, you can read about it on your own time. Going back to me being a purist, I don’t use RPMForge repos or anything similar. I like to stick to base and extras only and since there isn’t a suPHP RPM available – I’ll have to build it myself. The proper way to do this is to build it as an RPM (Red Hat Package Manager) and install via yum from the locally built RPM, but for whatever reason I can never get myself to do it this way.
Reminder, suPHP can only use PHP CGI, not PHP CLI (so look for a php-cgi binary, not just a php one)
Download & Building suPHP from Source
Before we start, make sure you have dev tools:
1 |
yum groupinstall "Development Tools" |
We’ll also need development packages for httpd (Apache 2.2), php53 (PHP 5.3), and apr (Apache Runtime Libraries and Utilities):
1 |
yum install apr apr-devel apr-util apr-util-devel httpd-devel php53-devel |
Now create a working directory, download the suPHP src, configure it and build (make). Note that you need to figure out where the apr config is located, mine is at /usr/bin/apr-1-config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
mkdir ~/mod_suphp cd ~/mod_suphp wget http://www.suphp.org/download/suphp-0.7.1.tar.gz tar -xzf suphp-0.7.1.tar.gz cd suphp-0.7.1 # RTFM less doc/INSTALL # quit less by typing "q" ./configure --with-apr=/usr/bin/apr-1-config make make install # notice that suphp is in /usr/local/sbin/suphp # also it should have auto-installed into the apache modules directory: ls -al /usr/lib64/httpd/modules/ | grep suphp -rwxr-xr-x 1 root root 60303 XXX XX XX:XX mod_suphp.so |
Configure Apache + PHP to use suPHP
I’ll admit, I relied heavily on the suPHP docs, but even then it was not 100% complete. That, and sites like this one didn’t provide any useful information – I’m mainly aggravated that they used RPMForge and did not use php53 packages. But, after some re-reading, reinterpreting and trial & error, I’m up and running… and this is how it went (starting to get tired of writing this post, this will be short and sweet):
Important Files
- /usr/local/etc/suphp.conf (this is the core suPHP configuration)
- /etc/httpd/conf.d/suphp.conf (this is the Apache mod_suphp configuration… needed to create this)
- /etc/httpd/conf.d/php.conf (this is the php configuration that I had to disable)
- /etc/httpd/conf/httpd.conf (for some of the primary virtual hosts… all my other vhosts are in separate files)
suPHP Core Configuration
/usr/local/etc/suphp.conf, I based it off of the suphp.conf-example file located in the source code’s doc directory. This is an ini-style configuration:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
[global] ;Path to logfile logfile=/var/log/suphp.log ;Loglevel loglevel=info ;User Apache is running as ;in centos this is apache ;if you dont know, look it up via: grep Apache /etc/passwd webserver_user=apache ;Path all scripts have to be in ;delimited by a colon (:) ;the default is docroot=/var/www:${HOME}/public_html ;but i added a few extras docroot=/var/www:${HOME}/public_html:/var/custom/dir:/usr/local/www ;Path to chroot() to before executing script ;chroot=/do/not/bother/setting/this ; Security options ; set group writeable perms to true to allow for session writing and tmp storage allow_file_group_writeable=true allow_file_others_writeable=false allow_directory_group_writeable=true allow_directory_others_writeable=false ;Check whether script is within DOCUMENT_ROOT ;just turn this off, dont feel like explaining check_vhost_docroot=false ;Send minor error messages to browser errors_to_browser=false ;PATH environment variable env_path=/bin:/usr/bin ;Umask to set, specify in octal notation umask=0077 ; Minimum UID ; allow for root and system-level groups min_uid=0 ; Minimum GID ; allow for root and system-level groups min_gid=0 [handlers] ;Handler for php-scripts ;NOTE that this should match with the handler type ;in the mod_suphp config (suphp.conf) application/x-httpd-php="php:/usr/bin/php-cgi" ;Handler for CGI-scripts x-suphp-cgi="execute:!self" |
mod_suphp Configuration
/etc/httpd/conf.d/suphp.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# load the core module that was installed previously LoadModule suphp_module modules/mod_suphp.so # register the x-httpd-php mime-type for the php extension # we'll have to remove this in php.conf # note that this mime-type aligns with the configuration in /usr/local/etc/suphp.conf AddType application/x-httpd-php .php # in case this isn't set anywhere else: DirectoryIndex index.php # turn suPHP on suPHP_Engine on # this is the path to the directory that contains php.ini suPHP_ConfigPath /etc # register the php mime-type with suPHP so it knows what to consider suPHP_AddHandler application/x-httpd-php # path to the PHP CGI executable # this should not be the PHP CLI executable (/usr/bin/php) suPHP_PHPPath /usr/bin/php-cgi # the default user and group to execute php under # this could be nobody:nobody, or apache:apache, or jack:jack # this will be overridden based on the virtual host directives suPHP_UserGroup apache apache |
PHP Configuration
/etc/httpd/conf.d/php.conf, just comment everything out, you don’t need it
Apache Virtual Host (vhost) Configuration
This can be set in each individual vhost if you want to override. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
NameVirtualHost *:80 # all my vhosts are stored here... Include conf.d/vhosts/* # system-level virtual hosts <VirtualHost *:80> ServerName stage.domain.tld DocumentRoot /var/www/html suPHP_UserGroup root root </VirtualHost> <VirtualHost *:80> ServerName util.domain.tld CustomLog logs/utilcommon_log common DocumentRoot /var/utilwww/www suPHP_UserGroup utilwww utilwww <Directory /var/util/www> Options FollowSymLinks Includes MultiViews AllowOverride All </Directory> </VirtualHost> |
Almost Done…
Now restart httpd:
1 |
service httpd restart |
Refresh a php page and check. If it didn’t work, re-read this post or email me (contact info in my resume) and I won’t help, but i’ll refine this post and provide more information.