0

I am checking the HSTS header here: https://hstspreload.org/

This is my non-www conf

server {

    listen 443
    server_name example.com;
    return 301 https://www.$server_name$request_uri;
    ##SSL
    add_header Strict-Transport-Security "max-age=xxxx; includeSubDomains; preload" always;

}

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

I get the error "Response error: No HSTS header is present on the response"

The header is visible when I remove the redirect from 443 server.

Basically for HSTS to work I neeed to redirect http://example.com to https://example.com and then to https://www.example.com

Arsh Dhillon
  • 3
  • 1
  • 2

1 Answers1

0

HTTP Strict Transport Security (HSTS) can be implemented in two different ways:

1) HSTS by Setting HSTS Headers

Example for Nginx: add_header Strict-Transport-Security "max-age=15768000; preload" always;

First time visitors will get this header and their browsers will redirect internally to HTTPS (see redirect 307 in your network tab, if you inspect the web site). Browsers are caching this HSTS for the given max-age and recurring visitors will use HTTPS if they request your site.

2) HSTS by Preload

For this you can use the service provided by the site https://hstspreload.org/

Here you can add a 2nd level domain (e.g. my-company.com) to a list mainstream browsers will use to load the website via HTTPS. Before you can add a site to this list, this site has to set proper HSTS headers.

Additionally you should consider following details:

  • removing a domain from the list needs some time and you'd better avoid this
  • preload includes all sub domains for this 2nd level domain (e.g. www.my-company.com, abc.my-company.com, printer.my-company.com)
  • HTTP access to subdomains (e.g. for local print services) may not work anymore
  • beside from above issues HSTS preloading accelerates the access to a website for first time visitors and improves it's security

Regarding redirecting HTTP to HTTPS traffic and HSTS I recommend following setup:

Nginx Virtual Host Config

# HTTPS server section
server {
    listen          443 ssl http2;
    listen          [::]:443 ssl http2;
    server_name     www.my-company.com;

    # include SSL configuration
    include         mycompany-ssl.conf;

    # web root path
    root            /var/www/www.my-company.com/htdocs;

    # allow access to .well-known (PKI validation folder)
    location ~ ^/\.well-known {
        allow       all;
    }
    ...
}

# redirect HTTPS and non-www requests
server {
    listen          443 ssl http2;
    listen          [::]:443 ssl http2;
    server_name     my-company.com;

    # include SSL configuration
    include         mycompany-ssl.conf;

    # web root path
    root            /var/www/www.my-company.com/htdocs;

    # allow access to .well-known (PKI validation folder)
    location ~ ^/\.well-known {
        allow       all;
    }

    # default redirect
    location / {
        return      301 https://www.$http_host$request_uri;
    }
}

# redirect HTTP to HTTPS
server {
    listen          80;
    listen          [::]:80;
    server_name     my-company.com www.my-company.com;

    # web root path
    root            /var/www/www.my-company.com/htdocs;

    # allow access to .well-known (PKI validation folder)
    location ~ ^/\.well-known {
        allow       all;
    }

    # default redirect
    location / {
        return      301 https://$http_host$request_uri;
    }
}

Nginx Include Config for SSL/TLS

ssl                             on;
ssl_protocols                   TLSv1.2;
ssl_ciphers                     "EECDH+AESGCM:EDH+AESGCM:EECDH:EDH:!MD5:!RC4:!LOW:!MEDIUM:!CAMELLIA:!ECDSA:!DES:!DSS:!3DES:!NULL";
ssl_prefer_server_ciphers       on;
# Create session ticket key:    openssl rand -out /etc/nginx/ssl/session_ticket_key 48
ssl_session_ticket_key          /etc/nginx/ssl/session_ticket_key;
# Create dhparam4096.pem:       openssl dhparam -out /etc/nginx/ssl/dhparam4096.pem 4096
ssl_dhparam                     /etc/nginx/ssl/dhparam4096.pem;
ssl_ecdh_curve                  secp384r1;

# Enable SSL stapling
ssl_stapling                    on;
ssl_stapling_verify             on;
resolver                        8.8.8.8 8.8.4.4 valid=1800s;
resolver_timeout                15s;

# set security headers (see http://securityheaders.io/ for more details)
add_header                      Strict-Transport-Security "max-age=15768000; preload" always;
add_header                      X-Frame-Options "SAMEORIGIN" always;
add_header                      X-XSS-Protection "1" always;
add_header                      X-Content-Type-Options "nosniff" always;
add_header                      Referrer-Policy "strict-origin" always;

# set certificate files
ssl_certificate                 /etc/letsencrypt/www.my-company.com/fullchain.pem;
ssl_certificate_key             /etc/letsencrypt/www.my-company.com/privkey.pem;
ssl_trusted_certificate         /etc/letsencrypt/www.my-company.com/fullchain.pem;
Jens Bradler
  • 6,503
  • 2
  • 17
  • 13
  • Now the redirect works fine and https://hstspreload.org/ can see the header for example.com. but not for www.example.com unless I add it under location ~ \.php$ – Arsh Dhillon Jul 04 '18 at 16:00
  • If you have an add_header directive in a sub level as location{...} it will replace all other add_header from parent level. You have to repeat all add_header directives in this sub level. My recommendation: Don't do it until you really have to. – Jens Bradler Jul 04 '18 at 16:15
  • Yes, there was another add_header, all working fine now. As you advised for now I have decide not to go for the 'list' , just a short HSTS header, Thx – Arsh Dhillon Jul 05 '18 at 05:17