Hetzner - DokuWiki

Apache PHP5 fcgi und SuExec/en


Apache2 with PHP5 as suExec/ Fcgid Variant



  • 06.04.2010 Amdendments in php.ini, the authorization was wrong, the user could change his php.ini
  • 10.02.2010 Amendments in php.ini, so that it can be used
  • 07.02.2010 " removed from EOF, so that people who generate their domains with scripts do not experience problems. Tempdir in fcgistarter exported.
  • 10.08.2009 Apache package amended, port data supplemented in vhosts
  • 16.02.2009 suexec must be activated, spelling mistakes
  • 12.11.2008 chmod supplemented for php-fcgi-starter
  • 01.10.2008 Rights supplemented for php-fcgi-starter, information on web applications
  • 25.07.2008 Gaps filled, errors corrected - should be complete
  • 24.07.2008 first version - still being filled

Author: Jan Scholten

devnull [at] rootsvr [dot] de

Copyright and License

This content is licensed under a Creative Commons License.


You are welcome to provide feedback on this document. Simply send an email to the author.

Introduction/ Abstract

Almost everyone who operates a server (at least if they have clients) will wish or need to use a webserver server.

The PHP interpreter of the simplest variant with mod-php operates with the same rights as web space. This is practical, it can read and write everything, nothing (?) needs to be adjusted.

The disadvantage is: It really can read and write everything e.g. the directories of another client. If you wish, you can use webadmin to test to see if you can come out of your directory.

There there is mod-suphp, which starts an extra interpreter with corresponding user rights for each PHP page.

That is much better! However, unfortunately very, very slow, as PHP really needs to be loaded once for each page callup and the interpreter is closed afterwards.

A (to my mind) better solution would be to start php as fastcgi. This involves PHP being started once per user and then used again. This enables own php.inis and also own php versions (PHP4 anyone?) to be used per user and is considerably faster - only the first callup takes a little longer.

This is the best solution, I feel, even if one should rather go to suphp for really large customer numbers. As php is available for each user (account), this can use up a lot of RAM in the long run.

I use this configuration in suExec + fcgid, which means that each domain runs under one user.

This already harmonizes with the individual FTP users in my PureFTPd HowTo.

For discussions/amendments please use the follwing Forum thread (in German).

Please note

Some limitations to start with:

This is no Copy and Paste Howto. Single steps may have been partially forgotten, spelling mistakes have occurred. Without specialist knowledge, you run the risk of creating a broken system - testing (VMWare) and debugging skills are prerequisite.

If this configuration is to be used, the system is considerably more secure than a standard mod_php installation.

There are disadvantages:

  • It is slower than mod_php (on first starting the system but not excessively)
  • Web applications cannot be installed as Debian packages. More exactly: It is not possible to install Debian packages without tackling the configuration accordingly (vhost/php.ini) afterwards.

The Debian packages require Apache as www-data, suexec and open_base_dir will not play along without it. The easiest way is to install phpmyadmin and Co by downloading it and installing it yourself. You will then need to take care of updates yourself.

  • Storage requirements can be considerable with a lot of users. People planning 1000 different domains and so 1000 users and PHP instances on their machine should look for other options, if necessary.


We install apache2, php5 as cgi/fcgi and mod-fcgid (it should all work with mod-fastcgi in the same way), so that suexec works, we also need (alternative: apache2-suexec-custom)  

aptitude install libapache2-mod-fcgid php5-cgi apache2 apache2-mpm-worker apache2-suexec

Do not be suprised, despite the name the php variant is also fcgi capable.

Then enable the fcgid module. Also suexec needs to be started.

a2enmod fcgid
a2enmod suexec

Create Users

Now we need one user per web account, PHP is to run under their rights.

adduser example

So that Apache can also read the html pages belonging to the user later on, it needs to belong to the relevant group:

adduser www-data example

Generate Directories

Rights are very important for the structure of directories. With the Debian variant, everything needs to be below /var/www for suexec and the user IDs need to be bigger than 1000.

I suggest the following structure, so that all important data are together:

/var/www/example.com/conf/ # the php.ini for this domain is here
/var/www/example.com/docs/ # here is the normal web root
/var/www/example.com/logs/ # logfiles
/var/www/example.com/tmp/ # session data/ temporary data
/var/www/example.com/php-fcgi/ # the start script for fcgid

(in my case I have a domain name or something similar for users and directories below /var/www .. this makes assignment easier.

So, generate and set the (proper) rights:

mkdir -p /var/www/example.com/conf
mkdir /var/www/example.com/docs
mkdir /var/www/example.com/logs
mkdir /var/www/example.com/tmp
mkdir /var/www/example.com/php-fcgi
chown root:example /var/www/example.com
chmod 750 /var/www/example.com
chown example:example /var/www/example.com/*
chmod 750 /var/www/example.com/*
chmod 550 /var/www/example.com/conf

Adjust php.ini

We copy php.ini from /etc/php5/cgi/ in our directory:

cp /etc/php5/cgi/php.ini /var/www/example.com/conf/

We adjust php to our needs and ensure a little security:

open_basedir = /var/www/example.com/docs/:/var/www/example.com/tmp/
upload_tmp_dir = /var/www/example.com/tmp
session.save_path = /var/www/example.com/tmp

The most imporant setting is openbasedir, which locks the php process in both relevant directories. The other two ensure that this instance sets up their session data, uploads etc. in an own tmp directory.

I am open for further suggestions (DocRoot? More storage?)

So that php.ini is used, the rights need to be adjusted

chown example:example php.ini
chmod 440 php.ini

Remember modules that are installed are automatically enabled in each vhost (mysql, pdo, xcache etc.) as Debian reads /etc/php5/cgi/conf.d by default. This can be prevented by deleting the symlink on conf.d. Afterwards, the modules which may be needed have to be installed separately per vhost, which can be annoying for frequently used modules/extensions (gd or mysql). Alternatively, single extensions can be removed from conf.d and only certain vhosts made accessible via their php.ini (Xcache or similar).

Set up fcgi Starter

In /var/www/example.com/php-fcgi we create a file called php-fcgi-starter:

cat > /var/www/example.com/php-fcgi/php-fcgi-starter << EOF
export PHPRC
export TMPDIR=/var/www/example.com/tmp
exec /usr/bin/php5-cgi

Give it all to the user, otherwise suexec will play up and it will not work:

chown example:example /var/www/example.com/php-fcgi/php-fcgi-starter

Now set the correct rights, otherwise suexec brokers - 750 is just right:

chmod 750 /var/www/example.com/php-fcgi/php-fcgi-starter

So that the user cannot change anything we set the immutable bit:

chattr +i -V /var/www/example.com/php-fcgi/php-fcgi-starter

Set up Apache VHost

Apache has to be told that a certain start script is responsible for fcgi for a certain directory (our domains).

I have found the following version useful,

cat > /etc/apache2/sites-available/example.com << EOF
<VirtualHost *:80>
   ServerAdmin me@example.com
   ServerName example.com
   ServerAlias www.example.com
   SuexecUserGroup example example
   AddHandler fcgid-script .php
   DocumentRoot "/var/www/example.com/docs"
   DirectoryIndex index.htm index.html index.php
<Directory />
   Options FollowSymLinks
   AllowOverride None
<Directory "/var/www/example.com/docs">
   Options Indexes MultiViews FollowSymLinks +ExecCGI
   FCGIWrapper /var/www/example.com/php-fcgi/php-fcgi-starter .php
   Order allow,deny
   allow from all
ErrorLog /var/www/example.com/logs/error.log
LogLevel warn
CustomLog /var/www/example.com/logs/access.log combined
ServerSignature On

Then enable the site:

a2ensite example.com

The SuexecUserGroup specifies the user under which everything takes place and has to correspond to the owner of the respective directory.

Error Diagnosis

  • Are the rights correct?
  • What do the log files /var/www/example.com/logs/error.log or /var/log/apache2/suexec.log say?
  • Apache can do php but has no html files -> does www-data belong to the group?

Further Outlook

It should be possible to use other languages with a fastcgi interface in a similar way.

© 2018. Hetzner Online GmbH. Alle Rechte vorbehalten.