HTTPS hardening Nginx

Photo by Niranjan _ Photographs on Unsplash

Photo by Niranjan _ Photographs on Unsplash

In the HTTPS suite of protocols, there are several versions that can be used to secure end-to-end encryption. Today all SSL versions and even TLS version 1.0 are unsafe to use because they are vulnerable to man-in-the-middle attacks.

In this article, I will provide a short description of how to ensure that HTTPS degradation attacks are impossible to perform on your Nginx webserver.

Degradation Attacks

Donwgrading to a old and unsafe protocols.

To understand why this configuration is important to perform, you first have to understand a bit about how TLS connections are established.

TLS (Transport Layer Security) and SSL (Secure Sockets Layer) are often used interchangeably. But it's important to know that SSL was replaced by TLS all the way back in 1999.

TLS runs in the application layer of the OSI model and is used for encrypted communication between a server and a client.

In 2018 the Chrome web browser started giving users warning that web pages that were not using TLS were not secure. Because of Chrome's popularity and market share, this effectively forced most of the web to start securing their websites with TLS.

TLS uses a 4-way handshake when initializing a connection between a client and a server. The handshake starts with the client connecting to the server. This first message specifies which TLS version the client supports. If says it only supports insecure SSL or TLS versions, the webserver will by default use that version when continuing the 4-way handshake to establish a connection.

Once the SSL/TLS version is selected the server selects a cipher suite (encryption algorithm) that will be used to generate a symmetric session key that will be used once the handshake is completed.

To prevent an SSL/TLS degradation attack from happening, the webserver has to be limited in what protocols can be used to establish an encryption connection.

Nginx config

Thankfully it's very easy to limit what SSL/TLS version Nginx support. Similar to an Allow-list (whitelist), you just have to specify what versions you want to support, and the unspecified version will not be supported.

To make these changes the main config file for Nginx has to be modified

sudo vim /etc/nginx/nginx.conf
/etc/nginx/nginx.conf
...
        # SSL Settings
        ##
        ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; 
        ssl_prefer_server_ciphers on;
...

As you can read from the file dump above, only TLS version 1.1, 1.2, and 1.3 is supported. The ss_prefer_server_cipher option is turned on to define that the webserver will not allow the client to define what cipher suite is to be used for encryption.

Save the changes, and restart the webserver to apply the changes.

sudo systemctl restart nginx

Congratulations, you have now hardened your webserver to only support safe TLS versions for HTTPS 🎉