Webmin – Hetzner VPS Debian 6 LAMP + fastcgi + php5 + apache

This tutorial applies to servers preconfigured with LAMP (Debian 6, Apache 2, Mysql 5, PHP 5.2). If the LAMP stack is not installed, it’s pretty straightforward to install the respective components via apt-get install. Since the image I’m using has Webmin preinstalled I use it to quickly get started.

The main thing with this setup is to avoid permission issues when installing and running Drupal and WordPress. Since they depend quite heavily on writing files, changing settings, updating plugins and modules you may end up with a very loose permissions scheme that tends to lead to an insecure installation.

Goals

  • make Apache run PHP applications as an arbitrary user (not www-data)
  • create “sandboxed” websites and users to avoid Apache user gaining access to other sites on the same machine (especially important if you’re using or want to create a shared hosting environment)
  • avoid 777 permissions all over the place

(If Apache is already installed, this is where you begin)

Install modules:

aptitude install apache2-suexec libapache2-mod-fcgid php5-cgi
/etc/init.d/apache2 restart

You might get the following error message, ignore it for now:

"Could not reliably determine the server's fully qualified domain name,
using xxx.xxx.xxx.xxx for ServerName"

Disable the mod_php – we will use fcgid instead:

a2dismod php5

Enable the newly installed Apache modules:

a2enmod rewrite
a2enmod suexec
a2enmod include
a2enmod fcgid

Open and edit /etc/php5/cgi/php.ini

nano /etc/php5/cgi/php.ini

Uncomment or add the following line:

cgi.fix_pathinfo = 1

Restart Apache:

/etc/init.d/apache2 restart

In Webmin, go to Servers > ProFTPD Server > Files and directories

Set "Limit users to directories" to "Home directory". Save.
Apply changes (restart ProFTPD Server).

Create a directory for the site which also will be the home directory for your web user:

mkdir -p /var/www/mynewsite.com/public_html

In Webmin, create a user under System > Users and groups > Create a new user

Username: mynewuser
User ID: Automatic
Home directory: browse to /var/www/mynewsite.com/ and select it
Password: Normal password > (Choose a good, random password)
Primary group: New group with same name as user
Create home directory: Yes
Copy template files to home directory: Yes
Create user in other modules: Yes

Make your new user owner of their webroot:

cd /var/www/mynewsite.com 
chown -R mynewuser:mynewusergroup *
NOTE: sometimes the permissions might get corrupted, in that case, try: chown -R mynewuser:mynewusergroup /var/www/mynewsite.com

Create a fastcgi wrapper script for the new site:

mkdir -p /var/www/php-fcgi/mynewsite.com
nano /var/www/php-fcgi/mynewsite.com/php-fcgi-starter

Add the following to php-fcgi-starter then save:

#!/bin/sh
PHPRC=/etc/php5/cgi/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/lib/cgi-bin/php

Make the script executable and owned by the user:

chmod 755 /var/www/php-fcgi/mynewsite.com/php-fcgi-starter

cd /var/www/php-fcgi/mynewsite.com chown -R mynewuser:nynewusergroup *  

In Webmin, remove the catch-all virtual server if it exists (Handles the name-based server on address *.)

Then remove the leftovers from the virtual host:

rm /etc/apache2/sites-enabled/000-default

Create a new virtual host:

Servers > Apache webserver > Create virtual host:

Specific address:  mynewsite.com Add name virtual server address (if needed): Yes
Listen on address (if needed): Yes
Port: 80
Document root: /var/www/mynewsite.com/public_html
Allow access to this directory: Yes
Server name: mynewsite.com Add virtual server to file: New file under virtual servers directory
Copy directives from: Nowhere

NOTE 1: if you later create sites to be handled by fcgi you may copy/paste the directives from the initial site and then only change document root and user/group info in the new site’s directives.

NOTE 2:  you still need to create new fastcgi wrapper scripts and unique user for each site.

Tell Apache to listen for the new site:

Servers > Apache webserver > Global configuration > Networking and addresses:

Check "Include all addresses".
Under "Adresses for name virtual servers" add:
mynewsite.com:80

Save and restart Apache (“Apply changes” in Webmin).

Add directives for the site. Virtual server > Edit directives:

ServerName mynewsite.com
ServerAlias mynewsite.com
DocumentRoot /var/www/mynewsite.com/public_html
<IfModule mod_fcgid.c>
 SuexecUserGroup mynewuser mynewusergroup 
 <Directory /var/www/mynewsite.com/public_html>
  Options +ExecCGI
  AllowOverride All
  AddHandler fcgid-script .php
  FCGIWrapper /var/www/php-fcgi/mynewsite.com/php-fcgi-starter .php
  Order allow,deny
  Allow from all 
 </Directory></IfModule>
# ErrorLog /var/log/apache2/error.log
# CustomLog /var/log/apache2/access.log combined
ServerSignature Off

Save and restart Apache. Done!

(Based on Falko Timme’s guide)

2 comments

  1. most excellent article! thank you. :)

    the only thing that i had to adjust for my ubuntu 11 server was in the “Make the script executable and owned by the user:” section, the command:

    cd /var/www/php-fcgi/mynewsite.com chown -R mynewuser:nynewusergroup *

    changed it to:

    cd /var/www/php-fcgi/ chown -R mynewuser:nynewusergroup mynewsite.com

    was getting an suexec error about the directory privs not matching the file privs otherwise.

    thanks again.

  2. Nice tutorial, many thanks!

Post a comment

You may use the following HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>