HSTS vs 301 redirect from http to https

melbo

Well-known member
So I'm currently forcing all of my http traffic to SSL/TLS via an Apache RewriteCond/RewriteRule in httpd.conf:
Code:
# Force non-ssl and non www to https
RewriteCond %{SERVER_PORT} 80 [OR]
RewriteCond %{HTTP_HOST} !^www.DOMAIN\.com$
RewriteRule ^(.*)$ https://www.DOMAIN.com/$1 [R=301,L]



I'm reading up on HSTS and it looks like I can do this better with the following:
http://linux-audit.com/configure-hsts-http-strict-transport-security-apache-nginx/
I'm assuming this would be in httpd.conf (replacing my above rewrites?)
Code:
# Redirect HTTP connections to HTTPS
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    </IfModule>



With this in ssl.conf:
Code:
Strict-Transport-Security: max-age=10886400; includeSubDomains; preload


I currently fail the HSTS Chrome preload submission test and its likely due to this 301. Anyone successfully set this up? Can I set this up in ssl.conf and remove all rules from https.conf? Confused as to where I add this.
https://hstspreload.appspot.com/
 
Last edited:
Not real familar with implementing it in Apache, but in nginx (if I remember correctly) it was simply
Code:
Strict-Transport-Security: max-age=10886400;
.
I get an A+ from SSL Labs with that on my Linux site and also on my Motorcycle site (one using nginx, the other using OpenLiteSpeed 1.4.3).
 
Thanks Tracy.
I have an A+ on SSL Labs too but this seems new.
Chrome and others are going to start adding 'preload' lists of sites that are HSTS preload compliant. I'm not because of the way I'm 301 rewriting to https. SSL Labs says my HSTS is fine, I just want to make sure I'm doing the other part correctly as I think the old RewriteRule/RewriteCond is getting to be an old fashioned way of forcing http > https
 
For nginx, the correct way to implement to HSTS is;

PHP:
map $scheme $hsts_header {
    https   "max-age=31536000;  includeSubDomains";
}

server {
    listen  80;
    listen  443 ssl spdy deferred;

    add_header Strict-Transport-Security $hsts_header;
}
 
For nginx, the correct way to implement to HSTS is;

PHP:
map $scheme $hsts_header {
    https   "max-age=31536000;  includeSubDomains";
}

server {
    listen  80;
    listen  443 ssl spdy deferred;

    add_header Strict-Transport-Security $hsts_header;
}
Why is that better than this:

Code:
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always;

just wondering if i should change.
 
Code:
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always;

just wondering if i should change.
Once you submit for preload status you are pretty much ALWAYS stuck in using SSL. No changing your mind later if you are unhappy with it. It takes a while (if ever) to be taken out of it.
In order to be included on the HSTS preload list through this form, your site must:

  1. Have a valid certificate.
  2. Redirect all HTTP traffic to HTTPS—i.e. be HTTPS only.
  3. Serve all subdomains over HTTPS, specifically including the www subdomain if a DNS record for that subdomain exists.
  4. Serve an HSTS header on the base domain for HTTPS requests:
    • Expiry must be at least eighteen weeks (10886400 seconds).
    • The includeSubdomains token must be specified.
    • The preload token must be specified.
    • If you are serving an additional redirect from your HTTPS site, that redirect must still have the HSTS header (not the page it redirects to).

And special attention to this statement (about Chrome but sure it applies to any)
Be aware that inclusion in the preload list cannot really be undone. You can request to be removed, but it will take months for the deleted entry to reach users with a Chrome update and we cannot make guarantees about other browser vendors. Don't request inclusion unless you're sure that you can support HTTPS for the long term.
 
Top Bottom