How to Easily Enable TLS 1.3 in Nginx on Ubuntu 20.04, 18.04, 16.04
In a previous article, I explained the steps of compiling Nginx source code with OpenSSL 1.1.1 in order to enable TLS 1.3 protocol, which was officially released in August 2018. In this tutorial, I will show you a simpler way to enable TLS 1.3 on Ubuntu 20.04, 18.04 and 16.04
TLS 1.3 Brings Improved Performance and Security
Performance-wise, TLS 1.2 needs two round trips to establish HTTPS connection. With TLS 1.3, only one round trip is required. TLS 1.3 also supports zero round trip mode (0-RTT session resumption), allowing clients who have previously connected to your website to send HTTP request on the first message to the server. This makes a big difference for users on mobile networks or at far distant locations.
In terms of security, TLS 1.3 removed support for old cipher suites, which is responsible for exploits like ROBOT attack. This, of course, is an oversimplified explanation. CloudFlare has a good detailed explanation of TLS 1.3.
Requirements to Enable TLS 1.3
There are two requirements when it comes to enable TLS 1.3 with Nginx.
- Your Nginx version must support TLS 1.3. That means Nginx 1.13 or above.
- Nginx needs to be built with OpenSSL 1.1.1 or above.
Ubuntu 18.04 and 20.04 Ships with OpenSSL 1.1.1
OpenSSL 1.1.1 is included in Ubuntu 18.10 and 20.04 repository and the Nginx package from Ubuntu 18.10/20.04 repository is built with OpenSSL 1.1.1.
When Ubuntu 18.04 first came out, it comes with only OpenSSL 1.0.2. However, OpenSSL 1.1.1 is backported to Ubuntu 18.04.3.
If you are still using Ubuntu 18.04.2, simply run the following commands to upgrade to 18.04.3.
sudo apt update sudo apt upgrade
Install Latest Version of Nginx Built with OpenSSL 1.1.1 on Ubuntu 16.04
The Nginx package from Ubuntu 16.04 repository isn’t built with OpenSSL 1.1.1. You can manually compile Nginx with OpenSSL 1.1.1, but it takes extra time and you have to re-compile when a new version of Nginx comes out. Luckily, we can install Nginx from a PPA (personal package archive) by Ondřej Surý, who is a Debian developer and an important figure in the DNS community. He maintains many packages for Debian repository, including Apache, BIND, MariaDB, PHP etc. He is also one of the maintainers of the official certbot PPA. So I have trust in his PPA and use it on my servers.
If you have previously added another Nginx repository (like nginx.org), then disable it. For example, I have another Nginx repository defined in /etc/apt/sources.list.d/nginx-repo.list
file. I simply comment out all lines in that file to disable it.
To add Ondřej Surý Nginx PPA on Ubuntu, run the following command.
sudo add-apt-repository ppa:ondrej/nginx sudo apt update
Then remove your existing Nginx package. (Your Nginx configuration files won’t be removed.)
sudo apt remove nginx
If you use iRedMail and Nginx, then run sudo apt remove nginx-full
to remove Nginx.
And install Nginx from PPA.
sudo apt install nginx
When asked if you want to install new version of configuration file, choose N
. Your certbot Nginx plugin might be removed along with Nginx, so install it back.
sudo apt install python3-certbot-nginx
Now check Nginx version.
sudo nginx -V
You should see that Nginx is built with OpenSSL 1.1.1.
nginx version: nginx/1.14.1
built with OpenSSL 1.1.1 11 Sep 2018 (running with OpenSSL 1.1.0g 2 Nov 2017)
TLS SNI support enabled
This PPA also provides OpenSSL 1.1.1 for Ubuntu 16.04. If your Nginx on Ubuntu 16.04 is still running with OpenSSL 1.1.0, you need to upgrade your OpenSSL package.
sudo apt upgrade
Note that if you are using Google compute engine, you will see the following message while running the above command.
The following packages have been kept back: libssl1.1 openssl
This is because the OpenSSL 1.1.1 package is conflict with some Google compute engine packages. You will need to run the following command to upgrade OpenSSL.
sudo apt dist-upgrade
Enable TLS 1.3 in Nginx Virtual Host on Ubuntu 20.04, 18.04 and 16.04
Once you have Nginx with OpenSSL 1.1.1, open your Nginx virtual host file.
sudo nano /etc/nginx/conf.d/site.conf
or
sudo nano /etc/nginx/sites-enabled/site.conf
To enable TLS 1.3, simply add TLSv1.3
to ssl_protocols
directive in the SSL server block.
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
If you are using Let’s Encrypt certificate, your SSL configuration can be set in /etc/letsencrypt/options-ssl-nginx.conf
file. By the way, certbot by default enables TLSv1
, which is insecure, you can remove it. If you are using iRedMail and Nginx, then you need to edit SSL configurations in /etc/nginx/templates/ssl.tmpl
file.
Save and close the file. Then restart Nginx for the change to take effect.
sudo systemctl restart nginx
Checking TLS Version in Web Browser
Using Firefox 63 or above, reload your web page, right click on a blank area and select View Page Info
in the context menu. Go to Security
tab and you will see TLS 1.3 is being used.
Using Google Chrome 70 or above, reload a web page on your site. Then press Ctrl+Alt+I
to open Developer Tools. Go to Security
tab and you will see that TLS 1.3 is being used.
Is TLSv1.3 Being Used Between Cloudflare and Your Origin Server?
Yes. Cloudflare supports TLS 1.3 on the front end server, and it also uses TLSv1.3 when connecting to your origin server. To check what TLS version is being used, you can create a custom log format in /etc/nginx/nginx.conf
file.
sudo nano /etc/nginx/nginx.conf
Add the following text in the http
context.
log_format combined_ssl '$remote_addr - $remote_user [$time_local] ' '$ssl_protocol/$ssl_cipher ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"';
Save and close the file. Then add an access_log
directive in your SSL server
context. The log is in combined_ssl
format.
access_log /var/log/nginx/your-site.access.log combined_ssl;
Save and close the file. Then reload Nginx. In the access log file, you will see something like below, which indicates TLS 1.3 is being used.
172.68.132.115 - - [25/Feb/2020:16:07:26 +0800] TLSv1.3/TLS_AES_256_GCM_SHA384 "GET / HTTP/1.1"
Next Step
I hope this tutorial helped you enable TLS 1.3 in Nginx on Ubuntu 20.04, Ubuntu 18.04, and Ubuntu 16.04. You may also want to set up the ModSecurity web application firewall to protect your website from hacking.
As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂
In case anyone is interested, I made a mainline version (1.15.x) with 1.1.1 OpenSSL ppa using the statically-linked method, so no extra dependencies to install. Only built for Bionic (18.04) for now.
https://launchpad.net/~jrnewell/+archive/ubuntu/nginx/
OpenSSL 1.1.1 is now backported to Ubuntu 18.04 and the Nginx package in 18.04 repository is built with OpenSSL 1.1.1.
Thanks, works perfectly on Ubuntu 16.04
Excelente tutorial