Create a DNS redirector with Apache RewriteMaps

Ever wanted to make a clean URL like http://site.example.com/ refer to a specific page op your web server (e.g. http://www.example.com/blog/site/)? Many hosting providers offer you this option with a redirector service, but it is also easy to create your own redirector.

Requirements

To create a redirector you need to meet a couple of requirements:

  • Full access to your Apache httpd configuration;
  • The ability to create new DNS records;
  • In this tutorial it is assumed that name based virtual hosts is already configured and working in Apache.

How it works

An DNS redirector works in two steps. First, when the web browser visits the website it will end up at the redirector site, which will then instruct it to fetch the webpage in the correct location. To make this work the redirector keeps a record of which URL belongs to which hostname.

Configuration

DNS

In the DNS we need to create new records for each of the hostnames we want to use with our redirector. The DNS record will refer to the IP Address of our redirector, either directly through an A record or through a CNAME record that points to the hostname of our redirector. If we assume the redirector resides at redirector.example.com your DNS record  for site.example.com could look like this:

site    CNAME    redirector.example.com.

If all your hostnames belong to the same domain you could also create a wildcard DNS entry. Your DNS record would then look like this:

*    CNAME    redirector.example.com

Apache

Now that we have configured DNS we need to make the redirector work. This requires us to create two new configuration files. First of all we need a new virtual host configuration for the redirector, and next to that we need a file that describes the mappings between the hostnames and the URLs they should resolve to.

Since this mapping file is referred to in the virtual host configuration we will start with the mapping file. There are different options for the mapping file, but in its easiest form it could be a plain text file with the hostname and the URL on a line separated by a space, like this:

site.example.com http://www.example.com/blog/site

When you have more than one redirection, each one goes on its own line.

So with the mapping file there we now have a look at the virtual host configuration.

<VirtualHost *:80>
    ServerName redirector.example.com
    ServerAlias *.example.com
    DocumentRoot /var/www/vhosts/redirector.example.com

    RewriteEngine On
    RewriteMap redirector txt:/etc/apache2/redirector-map.txt
    RewriteRule ^/ ${redirector:%{HTTP_HOST}|http://www.example.com}/}? [R,L]

</VirtualHost>

The virtual host configuration is mostly quite standard. The important lines are the following:

ServerAlias *.example.com
Allow Apache to serve any hostname within the example.com domain with this virtual host configuration
RewriteEngine On
Enables the RewriteEngine
RewriteMap redirector txt:/etc/apache2/redirector-map.txt
Tell that we use the file /etc/apache2/redirector-map.txt as a plain text mapping file, and refer to it by the name “redirector”.
RewriteRule ^/ ${redirector:%{HTTP_HOST}|http://www.example.com/}? [R,L]
Probably the most complex line, so we’ll take it apart below:

RewriteRule ^/
Rewrite any request that matches the pattern ^/. The pattern is a regular expression, and will match any request starting with a /, so this rule will match all requests.
${redirector:%{HTTP_HOST}|http://www.example.com/}?
Instruct Apache to use the map named redirector and use the hostname passed by the browser as the lookup key (%{HTTP_HOST}). If no match is found in the map the URL behind the | will be used instead. The question mark at the end removes any parameters on the URL.
[R,L]
Options for the RewriteRule: R instructs the rewrite engine to construct a redirection response and L instructs it that no further rewrite rules should be evaluated.

Testing

If you are ready you can quickly test your configuration, even before the DNS updates are available with the curl command line utility. The following command will show the Location header as returned by the redirector for the given hostname (after Host:).

curl --silent -H "Host: site.example.com" --head redirector.example.com | egrep '^Location'

Concluding remarks

In this example we created a very simple redirector. There is room for a lot of improvements. An obvious improvement would be to offer an administrative interface. This could be done by changing the redirector to a script that reads the records from a database and a small admin site that allows you to add or remove records from this database. However if you only serve a few dozen redirects and they don’t change often this is probably overkill.

With the same technique we can not only create a redirector that is based on the hostname, but just as easy we can create one that uses the path as the key for the mapping file. In essence this is the same as URL shortening services like tinyurl.com offer.

2 thoughts on “Create a DNS redirector with Apache RewriteMaps”

  1. Rob, that’s true. However it is very easy to change that and add the path to the redirect by changing the RewriteRule to this:

    RewriteRule ^/(.*) ${redirector:%{HTTP_HOST}|http://www.example.com}/}$1? [R,L]

    The .* is a regular expression matching everything and by putting it in parenthesis you tell the rewrite engine that you want to refer to it again later. The $1 is the back reference to this.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.