Configure HSTS (HTTP Strict Transport Security) for Apache and Nginx

HSTS configuration for Apache and Nginx

HTTP Strict Transport Security (or HSTS) is a security capability to force web clients using HTTPS. The idea behind HSTS is that clients which always should communicate as safely as possible. At achieve this, the web server and web browser will prefer the HTTPS protocol instead of HTTP.

Benefits

The clear benefit of “forcing” a client to use HTTPS directly, is decreasing the risk of sharing any sensitive information via a protocol which can be snooped upon. Additionally it improves the performance by eliminating one redirect response (301/302). Another benefit is to force using a secure connection and deny a client if this can not be guaranteed (e.g. expired or self-signed certificate).

Screenshot of HTTPS with HTST, HPKP and forward secrecy

HTTPS configured with HTST, HPKP and forward secrecy.

Configure HSTS on Apache

Load the headers and mod_rewrite module (just to be sure)

# Load modules (or use the IfModule)
LoadModule headers_module modules/mod_headers.so

LoadModule rewrite_module modules/mod_rewrite.so

Rewrite HTTP connections and redirect them to HTTPS:

# Redirect HTTP connections to HTTPS

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

Now configure the virtual host:

<VirtualHost 192.168.1.1:443>
Header always set Strict-Transport-Security “max-age=31536000; includeSubDomains”
</VirtualHost>

Configure HSTS on Nginx

To use HSTS on Nginx, use the add_header directive in the configuration. Then tell clients to use HSTS with a specific age.

add_header Strict-Transport-Security max-age=31536000;

Adjust the related virtual hosts to perform a redirect (301) to the secured version of the website:

server {
  listen 80;
  
  return 301 https://$server_name$request_uri;
}

server {
  listen 443;
  add_header Strict-Transport-Security max-age=31536000;
}

Important notes

The HSTS header should only be sent over a secured channel, therefore HTTP responses should not include them.

max-age

Within the headers, the max-age defines what period the site is willing to accept HTTPS-only (31536000 in the examples are 12 months). Usually, the amount of time is less important. This is because the trend is to keep using HTTPS for privacy and data protection anyways.

Top level domain (TLD)

Additionally, make sure the top level domain itself is also properly configured for HSTS. This reduces attacks on the underlying subdomain names.

Technical details

RFC: RFC6797 (HTTP Strict Transport Security (HSTS))

More resources

See also the Wikipedia page on HTTP Strict Transport Security.

History

March 2015: Added screenshot

Feb 2017: Minor updates

One more thing...

Keep learning

So you are interested in Linux security? Join the Linux Security Expert training program, a practical and lab-based training ground. For those who want to become (or stay) a Linux security expert.

See training package




Lynis Enterprise screenshot to help with system hardeningSecurity scanning with Lynis and Lynis Enterprise

Run automated security scans and increase your defenses. Lynis is an open source security tool to perform in-depth audits. It helps with system hardening, vulnerability discovery, and compliance.


Download

2 comments

  • AnonymousAnonymous

    The header stanza for Apache uses typographical open and close quotes, rather than the standard doublequote required by programming languages and configuration files. Please consider switching the quotation marks to “straight quotes”, to avoid creating problems for people who copy and paste.

    Reply

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.