How to redirect domains with Apache

Domains redirection is surprisingly common task which may be required even for the brand new website with no history of changing domains or sub-domains whatsoever. Even in this case it is still a good idea to redirect all requests from www.newdomain.com to newdomain.com for cleaner and shorter URL. Or vice versa to follow the old tradition. In any way, consistently applying permanent redirect to canonical URL is good for the website’s ranking in search results.

If the website is old enough, chances are, it was started on a different domain name. In this case, in order not to loose any potential visitors who may use outdated bookmarks or hyperlinks, we will need to redirect old domain name to the new one.

And than there is HTTP vs HTTPS protocols. We may want to serve all our pages via encrypted HTTPS protocol in order to help our visitors to keep their business private.

Combining all of these in one set of rules may be complicated, but still doable, because Apache provides a few powerful tools for the job.

Let’s pretend we have to setup redirection rules for the website with a shiny new domain name newdomain.com. Formerly, this website was at the olddomain.com and served its pages via HTTPS. And before that there was even olderdomain.com, but the website didn’t have TLS/SSL certificate back then and served its pages via HTTP only.

Before we begin editing virtual host configuration files in the Apache sites-available directory, we need to be sure that the SSL certificate issued for the new domain newdomain.com also includes www.newdomain.com, olddomain.com, and www.olddomain.com. Otherwise, people trying to use links to https://www.olddomain.com/ will get SSL error in their browser and most likely decide against proceeding any further.

For all our redirection needs we can use the configuration file for the SSL version of our new website. This is how it may looks like in its most basic form:

<VirtualHost *:443>
    ServerName newdomain.com
    DocumentRoot /var/www/html
</VirtualHost>

It will make Apache display files from the server’s /var/www/html/ directory for anyone who will type https://newdomain.com into the location bar of their browser.

Let’s sort out non-SSL, non- HTTPS requests now. To do so we can add new virtual host blocks into the same .conf file to keep our configuration clean and tidy. Let’s add the following code right above the main <VirtualHost> block:

<VirtualHost *:80>
    ServerName olderdomain.com
    ServerAlias www.olderdomain.com
    Redirect permanent "/" "https://newdomain.com/"
</VirtualHost>

<VirtualHost *:80>
    ServerName olddomain.com
    ServerAlias www.olddomain.com
    Redirect permanent "/" "https://newdomain.com/"
</VirtualHost>

<VirtualHost *:80>
    ServerName newdomain.com
    ServerAlias www.newdomain.com
    Redirect permanent "/" "https://newdomain.com/"
</VirtualHost>

The first virtual host block will take care of the links to the oldest incarnation of the website. All links like http://olderdomain.com will be redirected to the current domain and will force the browser to use HTTPS protocol for it.

The second and the third block will take care of occasional links to the current or the previous domain name but erroneously using HTTP protocol. Or in cases when the user typing in the domain name (with or without www. in front of it) into a browser that doesn’t check HTTPS first by default. These blocks will redirect all such requests to our shiny new domain via HTTPS protocol.

The Redirect statement is the simplest way to do it, and it is actually recommended by Apache web-server official documentation. The permanent keyword explicitly dictates Apache to use 301 (Permanent) redirect to let the search engine bots know that the destination is in fact a new canonical URL and the one that must be indexed. Keyword temp may be used to force temporary 302 redirect instead.

It doesn’t use RegExp but a very simple syntax instead. The "/" "https://newdomain.com/" part means that everything after the root directory of the request will be passed as is to the URI part of the destination. For example, http://www.olderdomain/about/author.html will be redirected to https://newdomain.com/about/author.html.

Using the same syntax we can redirect other sub-domains to sub-folders or vice versa. The following code will redirect blog.newdomain.com to https://newdomain.com/blog/, allowing the blog to be the part of the main website and contribute to its search engine rankings, but still being able to be advertised as shorter, easier to type in URL in printed media:

<VirtualHost *:80>
    ServerName blog.newdomain.com
    Redirect permanent "/" "https://newdomain.com/blog/"
</VirtualHost>

However, the Redirect statement doesn’t work that good with the encrypted HTTPS traffic on port 443. For it we will need to use mod_rewrite Apache module which can be activated by the sudo a2enmod rewrite command.

Let’s add the following rewrite rules into the main <VirtualHost *:443> block:

RewriteEngine on

# Redirects https://www.newdomain.com to https://newdomain.com
RewriteCond %{HTTP_HOST} ^www\.newdomain\.com$ [NC]
RewriteRule ^ https://newdomain.com%{REQUEST_URI} [R=301,NE,L]

# Redirects https://olddomain.com or https://www.olddomain.com
# to https://newdomain.com
RewriteCond %{HTTP_HOST} ^(www\.)?olddomain\.com$ [NC]
RewriteRule ^ https://newdomain.com%{REQUEST_URI} [R=301,NE,L]

Please note that [NC] flag — No Case — is here to tell Apache to match domain name in case-insensitive manner. It may seem redundant since domain names are almost always in lowercase, but it helps in avoiding occasional problems.

[R=301] flag tells Apache to use permanent 301 redirects. And [NE] tells Apache not to convert (escape) special characters that may occur in URL. [L] means last and tells Apache to stop the processing of the rule set.

These rules will cover redirection of the HTTPS traffic. Note, that the links like https://olderdomain.com will result in browser error, because olderdomain.com is not listed in the SSL certificate. It won’t work even if we will add a special rewrite rule for this domain too. Not all possible errors could be realistically covered.

Additionally, we may want to ensure that the users who would type in the IP address of our site for whatever reason would end up at the site’s canonical URL. Or more realistically and more importantly, ensure that we know what pages the hackers’ bots probing our IP address are getting. For that let’s add another virtual host block at the very top of our configuration file:

<VirtualHost _default_:80>
    ServerName 127.0.0.1
    Redirect permanent "/" "https://newdomain.com/"
</VirtualHost>

This will redirect all HTTP traffic to 127.0.0.1:80 to newdomain.com and force the client to use HTTPS protocol.


Published in as a part of “Servers” topic by Vitalii Kovalenko, a web developer from Sofia, Bulgaria.

anything at domain name