How to enable HSTS on Apache2

It's way too simple!

HSTS further protects your HTTPS enabled website. Read on to figure out how enable it in Apache2 and also why you want it!

Prerequisites

  • HTTPS already working with legit certificate, no browser errors
  • Apache mod_headers enabled

Enabling mod_headers

On a Debian based system, simply run:

a2enmod headers
systemctl reload apache2

That was easy!

Adding the HSTS header

Next, on your HTTPS config, right after your (HTTPS) VirtualHost definition you’ll want to add this line:

Header always set Strict-Transport-Security "max-age=63072000"

This will force any browser to remember your site for two years, and access it through HTTPS only. And if the certificate is invalid, the browser will not allow you to ignore the warning. This of course means you either need to buy a certificate that lasts long enough, or set up Let’s Encrypt with automatic renewal, otherwise no one will be able to access your site without HTTPS, and that’s the whole point.

You can change the time it should be remembered, to something longer or shorter. The value max-age is defined in seconds.

Protecting all sub-domains too

If you want to be paranoid, you can also force all your sub-domains to use HTTPS, by adding a statement, which will change the line to the following:

Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains"

But make sure that all your sub-domains are using HTTPS already! Otherwise, things will break…

Submitting to the HSTS Preload List

Want to make sure your site will always be accessed through HTTPS with valid certificate only, before even visiting your site for the first time?
You can! By including it in the HSTS Preload List here: https://hstspreload.org/
But for that you need to add the “preload” statement.

The final config line would look like this:

Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"

And that’s all there is to it. 😀

[UPDATE] There should be no semicolon at the end of the directive. A semicolon indicates that something will follow. I updated the lines to not include the semicolon at the end.

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.