As you might have heard, there’s a new version of HTTP out there that’s far superior to HTTP/1.1. I won’t go into what exactly has changed in HTTP/2, but it’s faster and more secure, and allows for some even more neat security features down the line.
Enabling HTTP/2 on NGINX is rather straight forward, but do keep in mind two things. First and foremost, HTTP/2 can break a lot of more advanced websites, so if you’re running a CMS or something similar, do your homework before enabling HTTP/2. It’s not irreversible, just remove any changes you did to your sites-available config and you should be back to normal if you run into problems. Secondly, HTTP/2 requires SSL/TLS, so make sure that you have a certificate installed and that SSL/TLS works as intended on HTTP/1.1 before continuing. If you don’t have HTTPS working on your server, check out my previous guide on how to secure your site with Let’s Encrypt on NGINX.
First, we need to add the http2 option to our listen directives in the server block. So find the following lines and add http2 before the semicolon.
listen [::]:443 ssl http2 ipv6only=on; listen 443 ssl http2;
Then, we need to specify which SSL protocols we allow. Anything but TLSv1.2 and TLSv1.3 are insecure at the time of writing, so enable only those if you don’t care about backwards compatibility (we’re talking Windows XP/IE6 here).
ssl_protocols TLSv1.2 TLSv1.3;
If you’re using an older version than NGINX 1.13.0, TLS 1.3 isn’t supported, so you need to use only TLSv1.2
That’s it, but there’s one caveat. If you followed my guide on how to Get Started with Let’s Encrypt there’s another place that this can defined. Certbot, being forever almost too helpful, adds the following line to your server blocks
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
This file contains the SSL options that Certbot thinks are optimal, but they are a bit outdated regarding the TLS version.
# This file contains important security parameters. If you modify this file # manually, Certbot will be unable to automatically provide future security # updates. Instead, Certbot will print and log an error message with a path to # the up-to-date file that you will need to refer to when manually updating # this file. ssl_session_cache shared:le_nginx_SSL:1m; ssl_session_timeout 1440m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";
As you can see, there’s a line defining the ssl_protocols used by NGINX. Since this is included in a server block, it supersedes the main configuration /etc/nginx/nginx.conf, which might lead to unwanted results.
I personally changed this file directly by commenting out the ssl_protocol line, which also stops Certbot from updating this file in the future.
This should set you up quite nicely. In the next instalment of this series, we’ll talk a bit more about cipher suites and how to further secure you SSL/TLS settings in NGINX.
Make sure to check out the previous parts of this series, some of them more useful than others.
Part 1 – Redirecting IP Traffic to HTTPS with NGINX
Part 2 – Implementing HTTP 418 Errors on NGINX