Rewrite rule to bulk redirect domains using Apache’s RewriteMap
A component of the server migration I’m currently working on is to move all of the existing virtual host files. Unfortunately, they’re not all consistently setup, which makes them difficult to overview, and from past experience, difficult to manage.
There is also no easy way to tell which of them represent real sites, and which are purely for redirection. Some even have a document root, implying there may actually be a site there, but often I found only a single .htaccess
file that redirected the domain to another site.
In a previous blog post, I proposed several guidelines to effectively manage virtual host files going forward, and one aspect of that, which I’ll talk about more deeply in this blog post, is how to organize and manage the redirects in bulk.
Goals
I’ve thought about what the ideal scenario would be and turned that into a list of actionable goals:
- If there are multiple servers in the farm, one server should be selected as the redirect server to handle all domain redirects.
- All domains pointing to the redirect server that have no specific virtual host file, should automatically be redirected to a predefined, default site.
- There should be a single file containing all redirects, one redirect per line, in the form of source domain followed by destination domain, e.g.,
old-domain.com new-domain.com
. - All redirects should automatically handle requests with and without the
www
prefix.
Let’s look at how to technically implement goals two through four.
Implementation
Using a virtual host architecture as described in my previous blog post (see Guidelines section), I’ll be using two files to implement this:
default.conf
— Contains the actual Apache rewrite rule.redirect_map_master
— Contains where to redirect what domain.
default. conf
This file ensures that all domains pointing to the redirect server get redirected somewhere (goal #2) and that the redirect will occur with and without the “www” prefix (goal #4).
RewriteEngine On
RewriteMap redirect_map_master txt:vhosts.d/other/redirect_map_master
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)
RewriteCond ${redirect_map_master:%2|domain.com} ^(.+)$ [NC]
RewriteRule ^/$ http://%1 [L,R=301]
- Line 1: Enables the Apache rewrite engine.
- Line 2: Tells Apache we’ll be using a file in
vhosts.d/other
calledredirect_map_master
to determine where to redirect what domain. The first reference ofredirect_map_master
is simply a name we assigned to theRewriteMap
, which we’ll reference again on line 4. - Line 3: Checks for and removes, if existent, the
www
prefix from the domain.%1
holdswww.
and%2
holds our domain name without thewww
. - Line 4: Searches within the
redirect_map_master
file for the target domain. If the domain is found, it will pass along the destination domain, but if the domain is not found, it will pass along the defaultdomain.com
. - Line 5: Uses the domain that was passed from line 4 to redirect the user to the destination.
redirect_map_master
All this file contains are source and destination domains (goal #3). Each redirect is one its own line and source and destination domains are separated by a space.
domain.net domain.com
domain.org domain.com
blog.domain.com domain.com/blog
- Line 1: Redirect domain.net to domain.com
- Line 2: Redirect domain.org to domain.com
- Line 3: Redirect blog.domain.com to domain.com/blog
Conclusion
You now have one server, with one file, that’s responsible for all redirects. If you have 100+ domains pointing to your server, you can very quickly see or find (using grep) which domains are being redirected, and where they are being redirected to.
If you wanted, which is what I did, you can create a simple shell script to add, remove and view entries. That way you can sort the list before displaying it and prevent duplicates from being added.
Should you have any questions, concerns or suggestions, leave them in the comments below!
Featured image by Denys Nevozhai.