Skip to content

Instantly share code, notes, and snippets.

@jult
Last active December 7, 2020 00:10
Show Gist options
  • Save jult/395ad9fd3e9773a54a67aaf689beab27 to your computer and use it in GitHub Desktop.
Save jult/395ad9fd3e9773a54a67aaf689beab27 to your computer and use it in GitHub Desktop.
My nginx include for TLS A+ rating at ssllabs.com/ssltest using nginx/1.14.* and openssl 1.1.1*
# version 2020 feb 24
ssl_certificate /etc/letsencrypt/live/yardomain.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yardomain.org/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/yardomain.org/chain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# generated using:# openssl dhparam -dsaparam -out /etc/ssl/dh4096.pem 4096
ssl_dhparam /etc/ssl/dh4096.pem;
ssl_ecdh_curve secp384r1;
ssl_stapling on;
ssl_stapling_verify on;
# I use local dnsmasq for faster lookups, highly recommend it!
resolver 127.0.0.1 [::1] valid=4h;
resolver_timeout 9s;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:18m;
ssl_session_tickets off;
ssl_buffer_size 4k;
include /etc/nginx/headers;
@Sudrien
Copy link

Sudrien commented Mar 21, 2018

Came across this looking for a good cipher list -

resolver 127.0.0.1 valid=300s ipv6=off;

is also an option if you don't have ipv6 support.

@jult
Copy link
Author

jult commented Feb 28, 2019

@jult
Copy link
Author

jult commented Feb 24, 2020

my include /etc/nginx/headers file contents;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Referrer-Policy no-referrer-when-downgrade always;
# add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:;" always;
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Feature-Policy "accelerometer 'none';ambient-light-sensor 'none';autoplay 'none';camera 'none';encrypted-media 'none';fullscreen 'self';geolocation 'self';gyroscope 'none';magnetometer 'none';microphone 'none';midi 'none';payment 'self';picture-in-picture 'none';speaker 'self';sync-xhr 'none';usb 'none';vibrate 'none';vr 'none';";

See https://hstspreload.org/ for the stuff relating to HSTS preload.

Note that as soon as some nginx config (could be any snippet you use for a server) has a 'new' add_header entry, all previously set ones are gone. So, here's my pro tip:
Put an
include /etc/nginx/headers;
after every new header you've set, or at the bottom of your server/vhost conf file.

Then test if the headers are still sent using ssllabs, https://www.immuniweb.com/ssl/ and/or https://securityheaders.com/

@jult
Copy link
Author

jult commented Dec 7, 2020

don't use
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:;" always;
it ruins all iframes and/or embedded remote media.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment