(dv) 4.0 - Making It Better :: Using mod suphp with Plesk
- This page was last modified on December 16, 2011, at 01:09.
From (mt) Community Wiki
The Apache module mod_suphp is one of the many ways that has been developed for the web server to handle PHP code so that it is executed as a user other than apache. In many cases, this is considered a more secure option. Also, in many cases, this avoids permissions issues that PHP-based applications will encounter, such as
- "this directory/htaccess file is not write-able"
- errors when trying to upload
- having to resort to 777 permissions on directories or files
The end-result of this guide is to have mod_suphp installed and configured so that automatically ties in to Plesk to work with both existing domains and those added in the future.
It is very important to note that Plesk 10 already has its own PHP handler that runs PHP as the domain user using FCGI. The guide for that can be found at (dv) 4.0:Enable FastCGI
This guide is an alternative to the method already provided by Plesk and will entirely replace it. Running PHP as FCGI will often have more potential in terms of optimization. It provides the ability to separate PHP processes from Apache itself and allows for opcaching such as APC. However, it is much more difficult to create something that takes advantage of this potential and is still somewhat one-size-fits-all for those that would prefer to avoid too much server administration.
To goal here is to create a compromise that will help the average (dv) Dedicated-Virtual user - high-end users and server administrators may get more mileage out of a more customized FCGI setup. The footprint for mod_suphp is normally very manageable and it will address many of the common issues PHP applications run into.
This guide will make significant changes to file permissions and general server configuration. It it highly advisable that you make a backup of meta data (file permissions, ownerships, and timestamps) that you will want to revert to if this does not work for your specific set up.
Before you continue, you may have a few additional questions. Hopefully this FAQ can address them.
Will this guide allow my Wordpress, Drupal, Joomla, etc CMS to work without any additional changes?
- Yes. The only thing suPHP requires is that PHP files are owned by your domain user. So if you upload your files as your subscription's FTP user, you're already good to go. No checkboxes or SSH commands required from here on out.
What if I want to change a specific PHP value for one of my domains - can I still use php_value in an .htaccess file?
- No, suPHP will not allow setting PHP values in a .htaccess file. However, it does allow custom php.ini files. To that end, this guide sets up every domain with their own php.ini file that can be accessed via FTP. Hopefully, this makes things easier on users with minimal SSH experience. If you connect over FTP with your subscription's user, you can find these at the following locations:
- primary domain: etc/php.ini
- absolute path: /var/www/vhosts/<parent_domain>/etc/php.ini
- additional domains: other_domains_etc/<other_domain>/php.ini
- absolute path: /var/www/vhosts/<parent_domain>/other_domains_etc/<other_domain>/php.ini
- this is a symlink to /var/www/vhosts/<other_domain>/etc/php.ini
- primary domain: etc/php.ini
Wait, does this mean I have to make a php.ini for every domain?
- Not at all. Any values not specified in those custom files will just be inherited by the main configuration in /etc/php.ini. This simply allows you to over-ride those settings on a domain-by-domain basis if the need arises.
-
Since we need to ensure that this will cooperate with Plesk, we'll be compiling mod_suphp from source. A prerequisite for this is a compiler, which is included in yum's development tools. We will also need to install http-devel:
yum -y groupinstall "development tools"
yum -y install httpd-devel
-
You will need to download mod_suphp to your server. For organizational purposes, it is good practice to use /usr/local/src. That way, you always know where to find the temperamental data/source code you use for new installations. So we can step into that directory:
cd /usr/local/src
And download and unpack mod_suphp:
wget http://www.suphp.org/download/suphp-0.7.1.tar.gz
tar xzf suphp-0.7.1.tar.gz
rm -f suphp-0.7.1.tar.gz
cd suphp-0.7.1
-
Next, everything is put together and installed, specified with settings that will cooperate with Plesk:
./configure --prefix=/usr --sysconfdir=/etc --with-apr=/usr/bin/apr-1-config --with-apache-user=apache --with-setid-mode=paranoid --with-php=/usr/bin/php-cgi --with-apxs=/usr/sbin/apxs
make
make install
-
The first thing mod_suphp will require in order to run are a few configuration files. Each can be created with a single command.
- Basic config file:
cat <<EOF > /etc/suphp.conf [global] logfile=/var/log/httpd/suphp.log loglevel=error webserver_user=apache docroot=/var/www allow_file_group_writeable=true allow_file_others_writeable=true allow_directory_group_writeable=true allow_directory_others_writeable=true check_vhost_docroot=false errors_to_browser=false umask=0022 min_uid=30 min_gid=30 [handlers] php5-script="php:/usr/bin/php-cgi" EOF
- Apache configuration:
cat <<EOF > /etc/httpd/conf.d/mod_suphp.conf LoadModule suphp_module modules/mod_suphp.so suPHP_AddHandler php5-script EOF
You may notice that the suPHP engine is not being turned on yet. The reason for this is so that it will not interfere with root-owned web files such as webmail. Instead, it will be turned on later for each domain individually as part of their VirtualHost entry.
-
Hooks now need tied into the Plesk system so that when domains are added or updated, the suPHP settings come along for the ride. This requires creating a number of scripts that will be run as event handlers.
-
Script to handle changes to existing hosting settings:
- create the script
cat <<EOF > /usr/local/psa/admin/sbin/suphp_settings_change.sh #!/bin/bash oldUser=\$1 newUser=\$2 ls -ld /var/www/vhosts/*/etc /var/www/vhosts/*/subdomains/*/etc |\ perl -ne '\$_ =~ /^([^\s]+\s+){2}'"\$oldUser"'.*?([^\s]+)$/ and print "\$2\n"'|\ while read x; do chown \$newUser \$x chown \$newUser \$x/php.ini perl -0 -p -i -e 's/(^\#\#\#mt-opt[^\n]*(\n|[^\n])+?)'"\$oldUser"'/\1'"\$newUser"'/' \$x/../conf/vhost.conf done /usr/local/psa/admin/sbin/httpdmng --reconfigure-all /etc/init.d/httpd stop /etc/init.d/httpd start EOF- chmod the script
chmod 755 /usr/local/psa/admin/sbin/suphp_settings_change.sh
- insert the script as an event handler in Plesk
mysql -u'admin' -p$(cat /etc/psa/.psa.shadow) psa -e"insert into event_handlers values(default,(select id from actions where descr='Update Physical Hosting'),0,'root','/usr/local/psa/admin/sbin/suphp_settings_change.sh <old_system_user> <new_system_user>');"
-
Script to handle adding new domains:
- create the script
cat <<EOF > /usr/local/psa/admin/sbin/suphp_domain_add.sh #!/bin/bash newDom=/var/www/vhosts/\$1 domUser=\$2 if [ -d \$newDom/etc ]; then mkdir \$newDom/other_domains_etc else mkdir \$newDom/etc ln -s \$newDom/etc `mysql -u'admin' -p\$(cat /etc/psa/.psa.shadow) -Ns psa \ -e"select home from sys_users where login='\$domUser';"`/other_domains_etc/\$1; fi chown \$domUser:psacln \$newDom/etc touch \$newDom/etc/php.ini chown \$domUser:psacln \$newDom/etc/php.ini cat <<EndOF > \$newDom/conf/vhost.conf ###mt-opt - comment the following lines to disable mod_suphp for this domain suPHP_Engine On suPHP_UserGroup \$domUser psacln suPHP_ConfigPath \$newDom/etc ###mt-opt EndOF /usr/local/psa/admin/sbin/httpdmng --reconfigure-all /etc/init.d/httpd stop /etc/init.d/httpd start EOF
- chmod the script
chmod 755 /usr/local/psa/admin/sbin/suphp_domain_add.sh
- insert the script as an event handler in Plesk
mysql -u'admin' -p$(cat /etc/psa/.psa.shadow) psa -e"insert into event_handlers values(default,(select id from actions where descr='Create Physical Hosting'),0,'root','/usr/local/psa/admin/sbin/suphp_domain_add.sh <new_domain_name> <new_system_user>');"
-
Script to handle adding new subdomains:
- create the script
cat <<EOF > /usr/local/psa/admin/sbin/suphp_subdomain_add.sh #!/bin/bash newDom=/var/www/vhosts/\$1/subdomains/\$2 domUser=\$3 mkdir \$newDom/etc chown \$domUser:psacln \$newDom/etc touch \$newDom/etc/php.ini chown \$domUser:psacln \$newDom/etc/php.ini cat <<EndOF > \$newDom/conf/vhost.conf ###mt-opt - comment the following lines to disable mod_suphp for this domain suPHP_Engine On suPHP_UserGroup \$domUser psacln suPHP_ConfigPath \$newDom/etc ###mt-opt EndOF /usr/local/psa/admin/sbin/httpdmng --reconfigure-all /etc/init.d/httpd stop /etc/init.d/httpd start EOF
- chmod the script
chmod 755 /usr/local/psa/admin/sbin/suphp_subdomain_add.sh
- insert the script as an event handler in Plesk
mysql -u'admin' -p`cat /etc/psa/.psa.shadow` psa -e"insert into event_handlers values(default,(select id from actions where descr='Create Subdomain'),0,'root','/usr/local/psa/admin/sbin/suphp_subdomain_add.sh <new_domain_name> <new_subdomain_name> <new_system_user>');"
-
Script to handle adding changing subdomains:
- create the script
cat <<EOF > /usr/local/psa/admin/sbin/suphp_subdomain_change.sh #!/bin/bash newDom=/var/www/vhosts/\$1/subdomains/\$2 domUser=\$3 mkdir \$newDom/etc chown \$domUser:psacln \$newDom/etc touch \$newDom/etc/php.ini chown \$domUser:psacln \$newDom/etc/php.ini cat <<EndOF > \$newDom/conf/vhost.conf ###mt-opt - comment the following lines to disable mod_suphp for this domain suPHP_Engine On suPHP_UserGroup \$domUser psacln suPHP_ConfigPath \$newDom/etc ###mt-opt EndOF /usr/local/psa/admin/sbin/httpdmng --reconfigure-all /etc/init.d/httpd stop /etc/init.d/httpd start EOF
- chmod the script
chmod 755 /usr/local/psa/admin/sbin/suphp_subdomain_change.sh
- insert the script as an event handler in Plesk
mysql -u'admin' -p`cat /etc/psa/.psa.shadow` psa -e"insert into event_handlers values(default,(select id from actions where descr='Update Subdomain'),0,'root','/usr/local/psa/admin/sbin/suphp_subdomain_change.sh <new_domain_name> <new_subdomain_name> <new_system_user>');"
-
Script to handle changes to existing hosting settings:
-
Since PHP scripts will now be running as the domain user rather than apache, the permissions on the sessions folder need updated to allow for this:
chmod 1777 /var/lib/php/session
-
Now that the server is ready to handle any new content that will be added, existing domains and subdomains need updated to include correct permissions and suPHP directives. These commands are very lengthy and are designed to set everything in one run.
- Configure existing domains for suPHP
mysql -u'admin' -p$(cat /etc/psa/.psa.shadow) -Ns psa -e"select name,www_root,login,home from domains join \ hosting on domains.id=hosting.dom_id join sys_users on sys_users.id=hosting.sys_user_id;" | \ while read x; do domName=`echo $x | awk '{print $1}'` wwwRoot=`echo $x | awk '{print $2}'` domUser=`echo $x | awk '{print $3}'` userRoot=`echo $x | awk '{print $4}'` domPath="/var/www/vhosts/$domName" chown -R $domUser:psacln $wwwRoot chgrp psaserv $wwwRoot [ -d $domPath/etc ] || mkdir $domPath/etc chown $domUser:psacln $domPath/etc touch $domPath/etc/php.ini chown $domUser:psacln $domPath/etc/php.ini if ! echo $wwwRoot | grep -q "^/var/www/vhosts/$domName/"; then [ -d $userRoot/other_domains_etc ] || mkdir $userRoot/other_domains_etc [ -h $userRoot/other_domains_etc/$domName ] && rm -f $userRoot/other_domains_etc/$domName ln -s $domPath/etc $userRoot/other_domains_etc/$domName; fi touch $domPath/conf/vhost.conf perl -0 -p -i -e 's/^\#\#\#mt-opt(\n|[^\n])+?\#\#\#mt-opt\n?//g' $domPath/conf/vhost.conf cat <<EndOF >> $domPath/conf/vhost.conf ###mt-opt - comment the following lines to disable mod_suphp for this domain suPHP_Engine On suPHP_UserGroup $domUser psacln suPHP_ConfigPath $domPath/etc ###mt-opt EndOF done- Configure existing subdomains
mysql -u'admin' -p$(cat /etc/psa/.psa.shadow) -Ns psa -e"select domains.name,subdomains.name,login,subdomains.www_root from domains join \ subdomains on domains.id=subdomains.dom_id join sys_users on sys_users.id=subdomains.sys_user_id;" | \ while read x; do domName=`echo $x | awk '{print $1}'` subName=`echo $x | awk '{print $2}'` domUser=`echo $x | awk '{print $3}'` wwwRoot=`echo $x | awk '{print $4}'` domPath="/var/www/vhosts/$domName/subdomains/$subName" chown -R $domUser:psacln $wwwRoot chgrp psaserv $wwwRoot [ -d $domPath/etc ] || mkdir $domPath/etc chown $domUser:psacln $domPath/etc touch $domPath/etc/php.ini chown $domUser:psacln $domPath/etc/php.ini touch $domPath/conf/vhost.conf perl -p -n -i -e 's/^\#\#\#mt-opt(\n|[^\n])+\#\#\#mt-opt\n?//g' $domPath/conf/vhost.conf cat <<EndOF >> $domPath/conf/vhost.conf ###mt-opt - comment the following lines to disable mod_suphp for this domain suPHP_Engine On suPHP_UserGroup $domUser psacln suPHP_ConfigPath $domPath/etc ###mt-opt EndOF done -
With everything now configured, the vhost.conf files that have been added for each VirtualHost now need loaded into Apache:
/usr/local/psa/admin/sbin/httpdmng --reconfigure-all
/etc/init.d/httpd restart
The (dv) Dedicated-Virtual is now set to use mod_suphp to handle all PHP code for your domains!