Automatic unlimited subdomains via Apache mod_rewrite

Wondering how blogger website gives you a subdomain from the blogspot.com domain based on  your username of your choice? Well, the concept for this tutorial is somewhat related with it on setting up unlimited subdomains. I’m not sure how do they do it because it could be done by any script, hardcoded or not, thru static or dynamic way via database, many possibilities, and one possible way is thru URL rewriting via Apache’s mod_rewrite.

Requirements of this setup:

a. Apache 2.x or later
mod_rewrite module should be enable.  To check if it’s enabled you should see this line on your httpd.conf

LoadModule rewrite_module modules/mod_rewrite.so

b. BIND 9.x or later
-Setting up the DNS Server is not part of this tutorial, it will be discussed on another topic.

Anyway to create automatic subdomains, these are the steps.

1. Configure your DNS server to use the wildcard (*) and points to your IP address.
Assuming you already setup the zone of your domain on named.conf , something like:

—@named.conf—

zone “freelinuxtutorials.com” {
type master;
file “/var/named/freelinuxtutorials.com.db”;
};

—@/var/named/freelinuxtutorials.com.db—

$TTL 86400
@   IN  SOA freelinuxtutorials.com. root.freelinuxtutorials.com. (
; dmn [flt.com] timestamp entry BEGIN.
2008092901
; dmn [flt.com] timestamp entry END.
8H
2H
4W
1D )
IN      NS      ns.freelinuxtutorials.com.
IN      NS      ns2.freelinuxtutorials.com.

freelinuxtutorials.com. A   192.168.1.100
ns      IN  A   192.168.1.80
ns2      IN  A   192.168.2.80
*               IN      A       192.168.1.100
; sub [{SUB_NAME}] entry BEGIN.
; sub [{SUB_NAME}] entry END.

As you can see above, 192.168.1.100 is pointed to *. Meaning if you ping any subdomains (existing or non-existing) of freelinuxtutorials.com, it will all points to the same IP address

2. Configure your Apache
-To not really messed up your existing httpd config, is it better to create a new config and include it. Something like

@httpd.conf

Include conf.d/flt/*.conf

Create your virtualhost for your domain and add this rewrite rules on it.

#vi /etc/httpd/conf.d/flt/flt.conf

<VirtualHost 192.168.1.100:80>
DocumentRoot “/var/www/html/flt/subdomains”
ServerName freelinuxtutorials.com
ServerAlias *.freelinuxtutorials.com
<Directory /var/www/html/flt/subdomains>
Options  Includes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>

#Rewrite Starts*
RewriteEngine on
RewriteCond %{HTTP_HOST} !^(www|m|secure|admin).* [NC]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.freelinuxtutorials\.com
RewriteCond /var/www/html/flt/subdomains/%1 -d
RewriteRule ^(.*) /%1/$1 [L]

</VirtualHost>

*Explanation (I’ll try to explain it as easy as I can)

1.RewriteEngine on = tells to enable Rewrite, off to disable it
2. It means only matches URLs that don’t start with www,m,secure or admin subdomains. This is important so it will not redirect to a particular directory e.g. m.freelinuxtutorials.com to /var/www/html/flt/subdomains/m/
3. ^([^\.]+)\. ==> these are combination of regular expression syntax of mod_rewrite, meaning
^ – start of syntax
. any single character
(…) group section
+ is added to make sure there is at least one char that matches
To sum up, it denotes anything that does not have a period, example is “subdomain”
4.the -d is added to checked if that directory does not actually exist
5.  ^(.*) /%1/$1 ==> it will take the requested path and put into a backreference, rewrite it to point to that  directory

%1 = subdomain
$1 = path backreference, based on the Rewrite condition above
L = Last Rule

3. Restart or Reload Apache service (depends on your distro)
something like
#service httpd restart
or #/etc/init.d/apache2 restart

4. Testing
Create a subdirectory named “darwin” under /var/www/html/flt/subdomains

#mkdir -p /var/www/html/flt/subdomains/darwin
#cd /var/www/html/flt/subdomains/darwin

Create a sample php file
#vi index.php

<?php
echo $_SERVER[‘SCRIPT_FILENAME’];
?>

Save and Exit

Access on your browser http://darwin.freelinuxtutorials.com, this should appear:

/var/www/html/flt/subdomains/darwin/index.php

That’s it. The subfolder name created on that directory will be your subdomain and will point it to that directory path.

About the author

tux

View all posts

7 Comments

  • @akbari, no problem. thanks for dropping by

  • Great post, well detailed.

    Do you have a link to the DNS configutation?
    Im having trouble trying to setup mydomain.com -> 127.0.0.1 using localhost environment.

    Im using Ubuntu in VMWare.

  • Very helpful information, thank you – I managed to get Apache configured correctly in a matter of minutes based on your advice. Our hosting provider allows us to edit our server’s DNS record directly (using their own control panel) so this can also save some time.

  • Hello,

    great solution!

    But I have one small problem with this: On my server doesn`t work if the name of subdomain is same as folder in root directory of unix, for example dev.domain.xx etc.domain.xx etc.
    I don`t know why, can you help?

    Thanks

    Thomas

  • Hi Thomas, thanks for dropping by. Bind DNS should work on any flavors of unix/linux. Can post the error you are getting if there’s any or can pls. elaborate more details. thanks.

  • @Noel, no problem, my pleasure. Thanks.

Leave a Reply