How to Enable TLS 1.3 in Nginx on Ubuntu 18.04 LTS

Published on: Fri, Mar 22, 2019 at 11:09 am EST

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.

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


  • Nginx version 1.13.0 or greater.
  • OpenSSL version 1.1.1 or greater.
  • Vultr Cloud Compute (VC2) instance running Ubuntu 18.04.
  • 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.1 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 client and obtain TLS certificate from Let's Encrypt

Download and install

sudo mkdir /etc/letsencrypt
git clone
sudo ./ --install --home /etc/letsencrypt --accountemail
cd ~
source ~/.bashrc

Check the version. --version
# v2.8.0

Obtain RSA and ECDSA certificates for your domain.

# RSA 2048
sudo /etc/letsencrypt/ --issue --standalone --home /etc/letsencrypt -d --ocsp-must-staple --keylength 2048
sudo /etc/letsencrypt/ --issue --standalone --home /etc/letsencrypt -d --ocsp-must-staple --keylength ec-256

NOTE: Replace in commands with your domain name.

After running the previous commands, your certificates and keys will be accessible at:

  • For RSA: /etc/letsencrypt/ directory.
  • For ECC/ECDSA: /etc/letsencrypt/example.com_ecc directory.

Build Nginx from Source

Nginx added support for TLS 1.3 in version 1.13.0. On most Linux distributions, including Ubuntu 18.04, Nginx is built with the older OpenSSL version, which does not support TLS 1.3. Consequently, we need our own custom Nginx build linked to the OpenSSL 1.1.1 release, which includes support for TLS 1.3.

Download the latest mainline version of the Nginx source code and extract it.

wget && tar zxvf nginx-1.15.5.tar.gz

Download the OpenSSL 1.1.1 source code and extract it.

# OpenSSL version 1.1.1
wget && tar xzvf openssl-1.1.1.tar.gz

Delete all .tar.gz files, as they will not be needed anymore.

rm -rf *.tar.gz

Enter the Nginx source directory.

cd ~/nginx-1.15.5

Configure, compile and install Nginx. For the simplicity's sake, we will compile only essential modules that are required for TLS 1.3 to work. If you need a full Nginx build, you can read this Vultr guide about Nginx compilation.

./configure --prefix=/etc/nginx \
            --sbin-path=/usr/sbin/nginx \
            --modules-path=/usr/lib/nginx/modules \
            --conf-path=/etc/nginx/nginx.conf \
            --error-log-path=/var/log/nginx/error.log \
            --pid-path=/var/run/ \
            --lock-path=/var/run/nginx.lock \
            --user=nginx \
            --group=nginx \
            --build=Ubuntu \
            --builddir=nginx-1.15.5 \
            --http-log-path=/var/log/nginx/access.log \
            --http-client-body-temp-path=/var/cache/nginx/client_temp \
            --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
            --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
            --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
            --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
            --with-compat \
            --with-http_ssl_module \
            --with-http_v2_module \
            --with-openssl=../openssl-1.1.1 \
            --with-openssl-opt=no-nextprotoneg \
            --without-http_rewrite_module \

sudo make install

Create Nginx system group and user.

sudo adduser --system --home /nonexistent --shell /bin/false --no-create-home --disabled-login --disabled-password --gecos "nginx user" --group nginx

Symlink /usr/lib/nginx/modules to /etc/nginx/modules directory. etc/nginx/modules is a standard place for Nginx modules.

sudo ln -s /usr/lib/nginx/modules /etc/nginx/modules

Create Nginx cache directories and set proper permissions.

sudo mkdir -p /var/cache/nginx/client_temp /var/cache/nginx/fastcgi_temp /var/cache/nginx/proxy_temp /var/cache/nginx/scgi_temp /var/cache/nginx/uwsgi_temp
sudo chmod 700 /var/cache/nginx/*
sudo chown nginx:root /var/cache/nginx/*

Check the Nginx version.

sudo nginx -V

# nginx version: nginx/1.15.5 (Ubuntu)
# built by gcc 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
# built with OpenSSL 1.1.1  11 Sep 2018
# TLS SNI support enabled
# configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx . . .
# . . .

Create Nginx systemd unit file.

sudo vim /etc/systemd/system/nginx.service

Populate the file with the following configuration.

Description=nginx - high performance web server

ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID


Start and enable Nginx.

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

Create conf.d, sites-available and sites-enabled directories in /etc/nginx directory.

sudo mkdir /etc/nginx/{conf.d,sites-available,sites-enabled}

Run sudo vim /etc/nginx/nginx.conf and add the following two directives to the end of file, just before the closing }.

    . . .
    . . .
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*.conf;

Save the file and exit with :+W+Q.

Configure Nginx for TLS 1.3

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

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

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

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

  ssl_protocols TLSv1.2 TLSv1.3;

  ssl_prefer_server_ciphers on;


Save the file and exit with :+W+Q.

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 web server.