Apache: redirect non-www to www & HTTP to HTTPS with a single domain security certificate

I recently had to set up a new virtual host on Apache for work, and I ran into a small problem.

I wanted to ensure that visitors to the site are using HTTPS on the canonical domain, and using permanent redirects to do so. The biggest hiccup here is that I did not have a wildcard (*.example.com) security certificate for example.com, only specifically for http://www.example.com.

  1. Redirect to canonical domain: ensuring that visitors entering the site through example.com are properly redirected to http://www.example.com
  2. Redirecting HTTP to HTTPS: Visitors entering the site via simple HTTP are redirected to use the HTTPS extension; e.g. http://www.example.com to https://www.example.com
  3. Cannot use https://example.com as a virtual host: If I try to do this, the user will get a security warning before the redirect, as the handshake will happen before the redirect.

solution

My solution, after a bit of working through it, was pretty simple:

<VirtualHost *:443>
  DocumentRoot /web/example_com
  ServerName www.example.com
  ServerAlias example.com
  <If "%{HTTP_HOST} != 'www.example.com'">
    Redirect permanent "/" "https://www.example.com/"
  </If>
  SSLCertificateFile ...
</VirtualHost>

<VirtualHost *:80>
  DocumentRoot /web/example_com
  ServerName www.example.com
  ServerAlias example.com
  Redirect permanent / https://www.example.com/
</VirtualHost>

Above, I implemented a solution that I found in the Apache docs, under Redirecting and Remapping with mod_rewrite; I use the <If> directive within the VirtualHost black to detect if the ServerAlias has been used, and if it has, redirect to the canonical domain.

This allows me to to redirect https://example.com to https://www.example.com without having to have a security certificate for the former, while still taking advantage of the Redirect directive and serving https://www.example.com.

The second block simply redirects any non-HTTPS request to the canonical HTTPS domain.

And that’s it. There are a few other ways to do this, but I found this to be the simplest, and it doesn’t depend on using mod_rewrite or an .htaccess file, which provides a few speed advantages.

Update: multisite with subdomains

If you’re running a multisite WordPress with subdomains, the above solution doesn’t work. To solve this, one could use a regular expression in the <If> directive—normally I shy away from regex, but if the alternative is still using a Rewrite I don’t really care. Here’s what it looks like with a regular expression:

  <If "%{HTTP_HOST} =~ /^exampledomain.com/i">
    Redirect permanent / https://www.exampledomain.com/
  </If>

So in this case, the regex checks to see if the host name starts with example.com. If it does match, it will redirect to use the canonical www domain.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s