I recently had to set up wildcard hosting on one of my Ubuntu servers. Previously I had only done this on FreeBSD so I had to do a bit of research to find out what the best method would be. It turns out the solution is quite simple and elegant.

Now why would you need a setup like this? Well there are many reasons, perhaps you’ve set up your own free webhosting company where each account gets their own subdomain, or you need to set up a large number of subdomains for your new website but you just can’t be bothered to enter them all by hand.

I will assume you already have your standard LAMP setup, with Bind9 installed. Your first job will be to set up an A record for your wildcard domain. Open up your zone file with your favourite editor, and add the following to the bottom:

*.yourdomain.com. IN A 192.168.0.1

Naturally you’ll be replacing both the domain name and IP with ones that are appropriate to your configuration. Also, make sure you specify any other subdomains that you don’t want to handled by the wildcard. Your final zone record should look something like the following:

yourdomain.com. 86400 IN SOA yourdomain.com. hostmaster.yourdomain.com. ( 2009103004 10800 3600 3600000 86400 ) IN NS ns1.yourdomain.com. IN NS ns2.yourdomain.com. IN MX 10 mail.yourdomain.com. IN A 192.168.0.1 mail IN A 192.168.0.1 ns1 IN A 192.168.0.1 ns2 IN A 192.168.1.1 *.example.com. IN A 192.168.0.1

Great, now that we have our zone configured we need to enable it by reloading bind9:

sudo /etc/init.d/bind9 reload

Next on the list is configuring your virtual host to handle all of these subdomains. There are many ways you can do this, depending on the result you want. You may want one virtual host for your primary subdomain (www) and one for all your subdomains, or you may want to combine them all into one and handle the subdomains with mod_rewrite. For the purpose of this demonstration I will assume the later.

Open up your existing virtual host definition file or create a new one if needed. These are stored in /etc/apache2/sites-available/ and are usually named the same as the domain. You’re going to be adding a ServerAlias definition, and your file should end up looking something like this:

<VirtualHost *> ServerName yourdomain.com ServerAlias *.yourdomain.com DocumentRoot /home/yourdomain.com/www .... </VirtualHost>

I’ve slimmed down this example, your virtual host file may have other declarations in it. Once you’ve finished editing this file, enable it if you haven’t done so already. This involves creating a symlink of the configuration file in /etc/apache2/sites-enabled, which can be done very easily by the use of the a2ensite command which is available only in Debian based distributions. After adding the new site, reload Apache.

sudo a2ensite yourdomain.com sudo /etc/init.d/apache reload

So now you’ve set up your DNS to accept connections on any subdomain, and Apache is set up to direct these connections to a specific folder on your system. Where do we go from here? Once again, that depends on what your trying to accomplish, but I’ll give you a few suggestions.

The simplest way is to setup your index file to check what the subdomain is and generate the output based on that. An example would be switching the database depending on which subdomain is used:

# Determine Subdomain $domain = $_SERVER['HTTP_HOST']; $domain_parts = explode(".", $domain); $subdomain = $domain_parts[0]; # Select Required Database mysql_connect("localhost", "root", "password"); mysql_select_db($subdomain);

Or if you have mod_rewrite enabled you can modify your .htaccess file and redirect any subdomain’s traffic to a matching folder name in the DocumentRoot:

RewriteEngine on RewriteCond %{http_host} . RewriteCond %{http_host} !^www.yourdomain.com [NC] RewriteCond %{http_host} ^([^.]+)\.yourdomain.com [NC] RewriteRule ^(.*) http://www.yourdomain.com/%1/ [R=301,L,QSA]

So if a visitor came to the URL http://example.yourdomain.com they would then be redirected to http://www.yourdomain.com/example/. Beyond that, I’ll let you use your own imagination.