Mass Virtual Hosting with mod_rewrite RewriteMap and PHP

Here is a simple possibility to control a lot of virtual hosts using a simple PHP script to map them to the right path.

First of all you need to make sure that mod_rewrite is loaded:

a2enmod rewrite

 

Further we need these packages:

php5-cli php5-mysql mysql-server

 

What we're doing now is a simple Url-Rewriting to a PHP script, so we're changing /etc/apache2/apache2.conf:

RewriteEngine on

RewriteMap lowercase int:tolower
RewriteMap vhost prg:/etc/apache2/vhost.php
RewriteLock /var/run/apache2/vhost.lock

RewriteCond %{REQUEST_URI} !^/icons/
RewriteCond %{REQUEST_URI} !^/cgi-bin/
RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
RewriteCond ${vhost:%1} ^(/.*)$
RewriteRule ^/(.*)$ %1/$1

RewriteCond %{REQUEST_URI} ^/cgi-bin/
RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
RewriteCond ${vhost:%1} ^(/.*)$

 

As backend, the simpliest solution is a mysql database (replacing username and password):

mysql –user=XXXXXXXXXX –password=XXXXXXXXXX;

CREATE DATABASE srvadm;
USE srvadm;
CREATE TABLE `vhosts` (
  `vhost_id` int(5) NOT NULL auto_increment,
  `domain` varchar(100) NOT NULL,
  `document_root` varchar(255) NOT NULL,
  `created` datetime NOT NULL,
  `lastmodified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`vhost_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

 

Finally you have to create your PHP script /etc/apache2/vhosts.php (replacing username and password):

#!/usr/bin/php

<?php
//Configuration
define('DB_HOST','localhost');
define('DB_USER', 'XXXXXXXXXX');
define('DB_PASSWORD', 'XXXXXXXXXX');
define('DB_NAME', 'srvadm');

$db = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die('COULD NOT CONNECT TO DB');
mysql_select_db(DB_NAME) or die('DATABASE NOT FOUND OR NOT ACCESSIBLE');

if ($stdin=fopen("php://stdin","r")) {
    while (!feof($stdin)) {

          //Domain name via STDIN auslesen
          $domain = fgets($stdin,4096);

          //document_root anhand der Domain aus der Datenbank auslesen
          $result = mysql_query("SELECT document_root FROM vhosts WHERE domain='".trim($domain)."' ");
          $arr = mysql_fetch_assoc($result);

          $output = $arr[‘document_root’];

          if ($stdout = fopen("php://stdout", "w")) {
                fwrite($stdout,$output."n");
                fclose($stdout);
          }

     }
     fclose($stdin);
}

mysql_close($db);
?>

Then just restart apache to make it work:

/etc/init.d/apache2 restart