Secure multi-site Drupal on Linux

Hi all,

Finally I got Drupal up and running on Gentoo Linux. It is actually a simple process, but I managed to make it quite complicated.

Anyway, while researching how to setup a secure multi-site install of Drupal I found a very interesting article on the subject by Justin Hileman.
Instead of simply creating a soft link for each instance pointing at the root of Drupal's install directory, he only creates links to a few required folders and wrappers for the default .php files. This allows to isolate each site's media content, themes and modules.
Read his article for the details. If you use Drupal, you should. It is worth it.

Following his instructions, and taking some examples from the script he posted in his site, I created a script that fits my Linux setup a little better.

The script:

# Creates a Drupal "secure virtual folder".

# Currently sets up the new folder under /var/www and expects a "drupal" folder to be there too.

# By António Maria Torre do Valle based on the article and code by Justin Hileman from:

# Created: April 12, 2008

# Released under the Gnu General Public Licence:

# Usage: ./ (example: ./

# More info at:

# Check parameters or if help was requested.
if [ $# -lt 1 -o $# -gt 1 -o "$1" = "--help" ]; then
echo 1>&2 Usage: $0
exit 127

# Tell the user we're starting the process...
echo "Setting up a new Drupal folder... Should take only a sec."

# Create the base folder structure for the specified vdir.
mkdir /var/www/$1
mkdir /var/www/$1/sites
mkdir /var/www/$1/sites/$1

# Create the folder structure for the current site inside Drupal's folder.
mkdir /var/www/drupal/sites/$1
mkdir /var/www/drupal/sites/$1/modules
mkdir /var/www/drupal/sites/$1/themes
mkdir /var/www/drupal/sites/$1/files

# Make the files folder writable. This is required to add media content to Drupal.
chmod o+w /var/www/drupal/sites/$1/files

# These files are to specify different permissions per site.
cp /var/www/drupal/.htaccess /var/www/$1/
cp /var/www/drupal/robots.txt /var/www/$1/

# Copy the default settings.php file.
cp /var/www/drupal/sites/default/settings.php /var/www/drupal/sites/$1/

# Remove the read only restriction from settings.php.
chmod o+w /var/www/drupal/sites/$1/settings.php

# Append some required configuration variables to settings.php.
# Uncomment the following line to let this script setup the file system configuration options automatically for you.
#echo "\$conf = array('file_directory_path' => 'sites/$1/files', 'file_directory_temp' => '/tmp');" >> drupal/sites/$1/settings.php

# Link to the required folder inside Drupal's directory.
# We need to pass the full path to ln, or the soft links will be wrong.
ln -s /var/www/drupal/misc /var/www/$1/misc
ln -s /var/www/drupal/modules /var/www/$1/modules
ln -s /var/www/drupal/themes /var/www/$1/themes
ln -s /var/www/drupal/sites/all /var/www/$1/sites/all
ln -s /var/www/drupal/sites/$1/files /var/www/$1/sites/$1/files
ln -s /var/www/drupal/sites/$1/modules /var/www/$1/sites/$1/modules
ln -s /var/www/drupal/sites/$1/themes /var/www/$1/sites/$1/themes

# Create the default pages to handle requests.
echo "<?php chdir('/var/www/drupal'); include('./index.php'); ?>" > /var/www/$1/index.php
echo "<?php chdir('/var/www/drupal'); include('./cron.php'); ?>" > /var/www/$1/cron.php
echo "<?php chdir('/var/www/drupal'); include('./update.php'); ?>" > /var/www/$1/update.php
echo "<?php chdir('/var/www/drupal'); include('./xmlrpc.php'); ?>" > /var/www/$1/xmlrpc.php
echo "<?php chdir('/var/www/drupal'); include('./install.php'); ?>" > /var/www/$1/install.php

# Report success to the user.
echo "Created structure for site $1."

# Tell the user the next steps to take.
echo "You should now edit the file /var/www/drupal/sites/$1/settings.php to configure your new website."
echo "Then setup the vdir in Apache (if you haven't already) and browse to http://$1/ to finish the install."
echo "Don't forget to delete the install.php file after properly setting up Drupal."
echo "Good luck!\n"

There's lot of possible tweaking that can be done, but as I said, it was done just to fill my needs.
If you have any comments or suggestions (or improvements), feel free to drop me a line.
I hope you find it useful.


DMSAK is now available on

DMSAK is now available on GitHub.

You can get it here:
Or read the announcement here:

António Maria

Thank you for putting this

Thank you for putting this script together. I stumbled across Justin's site before finding yours and was about to start writing my own script. You saved me a lot of time.

I do, however, have one question for you. Why didn't you use symlinks for index.php, cron.php, etc.?

Hi Everett, I used "wrapper

Hi Everett,

I used "wrapper scripts" to those files because if you simply use symlinks, Drupal will not find the path to the modules and won't execute the requests correctly (note the chdir() command in those files prior to the reference of the php files).

I have created a few more scripts and have put together a small admin kit to manage multi-site Drupal installs. You can read more about it here:

Actually, this script is kind of outdated, but in the next few days, I'll post to GitHub the latest version of DMSAK and make the link available here and at the project page.

Thank you for your message and I'm very glad you found this script helpful. :)

António Maria

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Enter the characters shown in the image.