TLS 1.3 is a version of the Transport Layer Security (TLS) protocol that was published in 2018 as a proposed standard in RFC 8446. It offers security and performance improvements over its predecessors. TLS 1.3 now removes obsolete and insecure features from TLS 1.2, including the following SHA1, MD5, RC4, DES, 3DES, AES-CBC. TLS 1.3 is an overhaul of the TLS protocol with a simpler, less error-prone design that improves both efficiency and security. The new design reduces the number of round-trips required to establish a connection and removes legacy insecure options, making it easier to securely configure a server. It additionally encrypts more of the handshake and makes the resumption mode more resilient to key compromise.

This guide will demonstrate how to enable TLS 1.3 using the Nginx web server on Ubuntu 18.04.4 LTS server.

Requirements

  • Nginx version 1.13.0 or greater
  • OpenSSL version 1.1.1 or greater
  • Server running Ubuntu 18.04.4
  • A valid domain name and properly configured A/AAAA/CNAME DNS records for your domain.
  • A valid TLS certificate. We will get one from Let's Encrypt.

Before you begin

Check the Ubuntu version.

lsb_release -ds
# Ubuntu 18.04.4 LTS

Create a new non-root user account with sudo access and switch to it.

adduser johndoe --gecos "John Doe"
usermod -aG sudo johndoe
su - johndoe

NOTE: Replace johndoe with your username.

Set up the timezone.

sudo dpkg-reconfigure tzdata

Ensure that your system is up to date.

sudo apt update && sudo apt upgrade -y

Install build-essential, socat and git packages.

sudo apt install -y build-essential socat git

Install acme.sh client and obtain TLS certificate from Let's Encrypt

It is recommended to install acme.sh as root. Become a root user with su command.

sudo su - root

Install acme.sh.

git clone https://github.com/acmesh-official/acme.sh
cd acme.sh 
./acme.sh --install --accountemail your_email@example.com
cd ~
source ~/.bashrc

Check the version.

acme.sh --version
# https://github.com/acmesh-official/acme.sh
# v2.8.6

Obtain RSA and ECDSA certificates for your domain.

# RSA
acme.sh --issue --standalone -d example.com --keylength 2048
# ECC/ECDSA
acme.sh --issue --standalone -d example.com --keylength ec-256

NOTE: Replace example.com in commands with your domain name.

Create sensible directories to store your certs and keys in. We will use /etc/letsencrypt.

mkdir -p /etc/letsencrypt/example.com
mkdir -p /etc/letsencrypt/example.com_ecc

Install and copy certificates to /etc/letsencrypt.

# RSA
acme.sh --install-cert -d example.com --cert-file /etc/letsencrypt/example.com/cert.pem --key-file /etc/letsencrypt/example.com/private.key --fullchain-file /etc/letsencrypt/example.com/fullchain.pem 
# ECC/ECDSA
acme.sh --install-cert -d example.com --ecc --cert-file /etc/letsencrypt/example.com_ecc/cert.pem --key-file /etc/letsencrypt/example.com_ecc/private.key --fullchain-file /etc/letsencrypt/example.com_ecc/fullchain.pem

After running the above commands, your certificates and keys will be in the following locations:

  • RSA: /etc/letsencrypt/example.com
  • ECC/ECDSA: /etc/letsencrypt/example.com_ecc

You can now return to the normal sudo user.

exit

Install Nginx

Nginx added support for TLS 1.3 in version 1.13.0. Ubuntu 18.04.4 comes with OpenSSL 1.1.1, so we don't need to build Nginx ourselves. Let's install Nginx.

Download and install mainline Nginx version:

Install the prerequisites:

sudo apt install -y curl gnupg2 ca-certificates lsb-release

To set up the apt repository for mainline nginx packages, run the following commands:

echo "deb https://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \ | sudo tee /etc/apt/sources.list.d/nginx.list
    
# Next, import an official nginx signing key so apt could verify the packages authenticity:
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

Verify that you now have the proper key:
sudo apt-key fingerprint ABF5BD827BD9BF62

To install nginx, run the following commands:

sudo apt update
sudo apt install nginx

Check the Nginx version:

nginx -v
# 1.17.9

Start and enable Nginx.

sudo systemctl start nginx.service
sudo systemctl enable nginx.service

Configure Nginx for TLS 1.3

Now that we have successfully installed Nginx, we are ready to configure it to start using TLS 1.3 on our server.

Run sudo vim /etc/nginx/conf.d/example.com.conf and populate the file with the following configuration.

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # RSA
    ssl_certificate /etc/letsencrypt/example.com/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/example.com/example.com.key;
    # ECDSA
    ssl_certificate /etc/letsencrypt/example.com_ecc/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/example.com_ecc/example.com.key;

    ssl_protocols TLSv1.3;
    ssl_prefer_server_ciphers off;
}

Save the file and exit.

Notice the new TLSv1.3 parameter of the ssl_protocols directive. This parameter is necessary to enable TLS 1.3.

Check the configuration.

sudo nginx -t

Reload Nginx.

sudo systemctl reload nginx.service

To verify TLS 1.3, you can use browser dev tools or SSL Labs service. The screenshots below shows Chrome's security tab that shows that TLS 1.3 is working.

Congratulations! You have successfully enabled TLS 1.3 on your Ubuntu 18.04.4 web server.