DEV Community

Bidhan Khatri
Bidhan Khatri

Posted on • Updated on • Originally published at bidhankhatri.com.np

How to enable TLS 1.3 in Nginx with OpenSSL Centos 7

Here, we are going to enable TLS 1.3 on our production CentOS 7 server.

OpenSSL is a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. OpenSSL is a software library for applications that secure communications over computer networks against eavesdropping or need to identify the party at the other end. It is licensed under an Apache-style license, which means that you are free to get and use it for commercial and non-commercial purposes subject to some simple license conditions. For a list of vulnerabilities, and the releases in which they were found and fixes, see the OpenSSL Vulnerabilities page.

TLS 1.3 is the newest and most secure version of the TLS protocol. It has improved latency over older versions and several new features. It is currently supported in both Chrome (starting with release 66) and Firefox (starting with release 60) and in development for Safari and Edge browsers.

If you download the Nginx from the centos 7 repo you will get Nginx built with OpenSSL 1.0.2k-fips. But If you want to enable TLS 1.3 then you must fulfill the few requirements. To enable TLS 1.3 on any distributions please look at the below-required details.

Requirements:

  • Apache version 2.4.37 or greater.

  • Nginx version 1.13.0 or greater.

  • OpenSSL version 1.1.1 or greater.

  • A valid domain name with correctly configured DNS records.

  • A valid TLS certificate.

As we are planning to deploy TLS 1.3 on our production CentOS7 server, we already have a valid domain name, valid TLS certificate, and Nginx version 1.16.1 which is greater than the minimum version required for TLS 1.3. But the current Nginx version is built with OpenSSL 1.0.2k-fips so first we need to install OpenSSL version 1.1.1 through the compile process and again recompile our Nginx with a new OpenSSL version.

As we can see below the OpenSSL version is OpenSSL 1.0.2k-fps 26 Jan 2017 and Nginx 1.16.1

Alt Text

yum install gcc gcc-c++ pcre-devel zlib-devel make unzip gd-devel perl-ExtUtils-Embed libxslt-devel openssl-devel perl-Test-Simple
yum groupinstall 'Development Tools'
Enter fullscreen mode Exit fullscreen mode

Install OpenSSL

cd /usr/src
wget [https://www.openssl.org/source/old/1.1.1/openssl-1.1.1f.tar.gz](https://www.openssl.org/source/old/1.1.1/openssl-1.1.1f.tar.gz)
tar xvf openssl-1.1.1f.tar.gz
mv openssl-1.1.1f openssl
cd openssl
./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl --libdir=/lib64 shared zlib-dynamic
make -j4
make test
make install
Enter fullscreen mode Exit fullscreen mode

We downloaded the latest version of OpenSSL which is openssl-1.1.1f at the time of writing this post. After that decompress the file, rename the folder name and navigate to the OpenSSL folder. --prefix and --openssldir control the configuration of installed components. The behavior and interactions of --prefix and --openssldir are slightly different between OpenSSL 1.0.2 and below and OpenSSL 1.1.0 and above. Also set --prefix and --openssldir to the same location. shared will force creating shared libraries and Zlib means that compression will be performed by using zlib library. It is worth running the make test to see if there are any unexpected errors. If there are any, you need to fix them before installing the library.

Now rename the existing OpenSSL binary and add a new symlink.

mv /usr/bin/openssl /usr/bin/openssl-backup
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
Enter fullscreen mode Exit fullscreen mode

Here, ldd showing dependencies of the binary OpenSSL.

Your newly installed OpenSSL should show TLSv1.3 like below.

openssl ciphers -v | awk '{print $2}' | sort | uniq
Enter fullscreen mode Exit fullscreen mode

We have completed the OpenSSL installation part. Now we have to recompile Nginx again to built from the newly installed OpenSSL.

Recompile Nginx

Download the installed Nginx version source code from the web. In my case Nginx version 1.16.1 is installed on my production server so I will download the same version and start compiling.

cd /usr/src
wget [http://nginx.org/download/nginx-1.16.1.tar.gz](http://nginx.org/download/nginx-1.16.1.tar.gz)
tar xvf nginx-1.16.1.tar.gz
cd nginx-1.16.1
Enter fullscreen mode Exit fullscreen mode
make -j4
make install
Enter fullscreen mode Exit fullscreen mode

As we can see now that Nginx has been built with newly installed OpenSSL. built with OpenSSL 1.1.1f 31 Mar 2020

nginx -V

nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.1.1f 31 Mar 2020
TLS SNI support enabled
Enter fullscreen mode Exit fullscreen mode

Alt Text

Update your Nginx configuration to enable TLS 1.3. Add below lines on your Nginx vhost configuration’s server block.

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
Enter fullscreen mode Exit fullscreen mode

check the configuration and restart Nginx.

nginx -t
service nginx restart
Enter fullscreen mode Exit fullscreen mode

Now you can verify your web application from your browser or from the command line to check whether it uses TLS 1.3 or not.

In Google Chrome browser, go to the website https://link.bdn.com.np
Right Click >> Inspect >> Security Tab

Alt Text

You can also check from your command line. If you have installed OpenSSL version 1.1.1 on your end device then your connection to the server will be through TLS 1.3 on first priority.

openssl s_client -connect link.bdn.com.np:443 -tls1_3
Enter fullscreen mode Exit fullscreen mode

You will see the output below.

New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Enter fullscreen mode Exit fullscreen mode

That’s it. We have enabled the TLS 1.3 on our Nginx server and it’s running as expected. Somehow if your application breaks down due to the new OpenSSL version then you might also need to recompile your PHP with the new headers.

Top comments (2)

Collapse
 
usmanmaqsood profile image
Usman Maqsood

Hello Bidhan, while following the tutorial
-NGINX updated to the latest ~Done
-OpenSSL updated to the latest ~Done
-./configure nginx with new openssl binary path ~shows that it was completed successfully but the new nginx keeps pointing to the old OpenSSL module, instead of the newly installed : OpenSSL 1.1.1g 21 Apr 2020
description:

nginx -V
nginx version: nginx/1.19.3
built by gcc 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var --add-module=/home/ec2-user/nginx_accept_language_module --with-http_ssl_module

Collapse
 
usmanmaqsood profile image
Usman Maqsood

I faced this issue while trying to upgrade my NGINX from an older version.
This tutorial instructs to INSTALL new NGINX and NOT up-gradation of an older one, in order to use it for an upgrade, you might need to uninstall existing NGINX installation.