Latest Nginx with TLSv1.3 and Brotli

Since August 2014, the members of IETF and other stakeholders have been working on the upcoming TLS version 1.3. After some delay due to the surprisingly negative field test results caused by middleboxing, the current draft is now submitted.

It will probably take a few more days until the draft (currently 23) is accepted, but technically it will not change.
Various browsers and open source projects do not wait for the IEFT and have already implemented draft 18 of the upcoming standard, among other things to test the new protocl in the field. I would now like to update my web server to offer TLS 1.3 now.

NSS 3.35 contains the TLSv1.3 draft 23, which will use Firefox with version 59 (see NSS 3.35 Release Notes, Mozilla Bug #1420060 - Upgrade Firefox 59 to NSS 3.35). Firefox 59 will be released on 13.03.2018.

Since the standard has not yet been adopted and this is a major update of the TLS protocol, I can assume that this update will not be available so quickly for my server running Centos 7. Nevertheless, I would like to use the protocol in my Nginx web server. This should should also be easy to update.

Update 17.09.2018
The standard TLSv1.3 is now adopted.

I use the Fedora COPR Infrastructure, where you can host your own package repositories. So I can package my Nginx updates by myself and use these package sources for my servers.


The requirements to offer TLSv1.3 in nginx are the following:

  • nginx 1.13
  • openssl 1.1.1

Centos 7.4 uses OpenSSL version 1.0.2k, so the Nginx cannot use OpenSSL of the OS.

The upcoming OpenSSL version, which is not yet released at this time, will support TLSv1.3 (see the OpenSSL blog post). To be able to use it already, I use the tls1.3-draft18 branch on Github. This draft 18 is already implemented in Firefox and Chrome. As soon as the major browser manufacturers have implemented and rolled out the final standard, I can use the 1.1.1-pre versions of OpenSSL or later the final version 1.1.1 for nginx.

Update 17.09.2018
OpenSSL version 1.1.1 is now released as final and is a Long-Term-Support release.

Compile Nginx

Since a newer version of OpenSSL is required, the Nginx and OpenSSL itself must be compiled and statically linked to the SSL library. I use the default options specified in the official Nginx RPMs. Since I build packages myself, I use the latest SRPM from Nginx and customize it.

Update 20.08.2018
The branch ’tls1.3-draft-18’ is outdatet.
in openssl 1.1.1, tlsv1.3 is already active.

# yum -y groupinstall 'Development Tools'
# wget
# tar xvfz nginx-1.13.8.tar.gz
# cd nginx-1.13.8
# git clone
# # not needed anymore
## cd openssl
## git checkout tls1.3-draft-18
## cd ..

Important 2 options to activate TLSv1.3:
--with-openssl=openssl --with-openssl-opt=enable-tls1_3

  • --with-openssl=openssl determines the directory where the OpenSSL sources are located.
  • --with-openssl-opt=enable-tls1_3 activates tls 1.3
# ./configure --prefix=/etc/nginx
# make -j2
# ./objs/nginx -V
nginx version: nginx/1.13.8
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
built with OpenSSL 1.1.1-dev  xx XXX xxxx
TLS SNI support enabled

Nginx paktieren

For the automatic packaging with Fedora’s COPR I use a Fedora Gitrepo, which can be linked to the COPR. Each git push triggers a COPR build.
The above mentioned changes, plus a few customizations, like the Brotli compression module from Google I added to the SPEC file and created the Nginx RPM with it.

! These package versions are experimental
! The package is currently built with OpenSSL 1.1.1 (final, LTS).

Here is the SPEC-File:

Nginx update

Now I update my webserver. To do this, I integrate the COPR repository into YUM and install my version of Nginx.

# yum install yum-plugin-copr
# yum copr enable bpereto/nginx-latest
# yum update nginx
# systemctl restart nginx

Nginx Konfiguration

With TLS 1.3 only AEAD ciphers are allowed, the existing ones are not used for this protocol version. Therefore, the new ciphers must be specified in the Nginx configuration if nginx (as I configured it) does not use the default cipher.

There are only 2 small changes in the Nginx configuration to activate TLS1.3:

  • The new protocol TLSv1.3
  • The new ciphers TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256 must be added to the Nginx SSL options.
ssl_protocols TLSv1.3 TLSv1.2;


Brotli is not a new, hip pastry with no umlaut, but a compression algorithm. The algorithm developed by Google in its Zurich offices produces smaller files at comparable compression speeds than the popular gzip format for websites. from Cyon-Blog

The Brotli module for nginx is not included by default, so I add this to my package.

I download the source and activate the module with the configuration parameter --add-module=ngx_brotli.

git clone                                  
cd ngx_brotli && git submodule update --init

./configure {options} --add-module=ngx_brotli

this is also available in my RPM.

Now I can activate Brotli in my Nginx configuration: /etc/nginx/nginx.conf

brotli on;
brotli_static on;
brotli_buffers 16 8k;
brotli_comp_level 6;
brotli_types *;
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# systemctl restart nginx


TLSv1.3 Test

You can test your site with SSL Labs. It should now support TLS 1.3 draft 18:


To test this in Firefox, the option security. tls. version. max in about: config must be set to 4.
After that Firefox should connect with TLS v1.3:

Firefox Connectoptions

Brotli Test

br in the firefox connection options indicates that the Brotli algorithm has been used for compression.

Firefox Developer Log