Securing NGINX - Debian/Ubuntu

Step 3a - Perfect Forward Secrecy (PFS) Cipher Suites - Mandatory Step!!!

Configuring Perfect Forward Secrecy (PFS) Cipher Suites

You can alter the cipher suite in order to achieve your preference for connections and order of the ciphers you wish to use. If you desire to make clients follow the preferred order, then ssl_prefer_server_ciphers will need to be turned to on. When the ssl_prefer_server_ciphers is on, clients will connect by the order in the ssl_ciphers list. We will be using TLSv1.3 as our first order of preference, as noted in the next Example paragraph; and then TLSv1.2 if the browser does not accept TLSv1.3 connections. Mozilla has a great config generator for this! Just be cautioned Mozilla will include weak ciphers in their suggested configurations.

You can remove the use of 128 bit ciphers to only use 256 bit, or remove 256 bit ciphers to only use 128 bit ciphers - add at the end of ssl_ciphers :!AES128 or :!AES256 to remove the respective AES ciphers. You can remove 256 bit ciphers without too much of an issue for most clients. Removing 128 bit and only using 256 bit ciphers locks you in to TLSv1.2 (If TLSv1.0 or TLSv1.1 are enabled) and drops support for older clients. Removing the 128 bit ciphers does gain a 100% score across all areas on most security tests. It is recommended you test the order of the ciphers and the effects on secure connections in a sandbox prior to going live on the Internet or Internal Entperise. The config presented here does drop support for TLSv1.0 & TLSv1.1 in order to ensure maximum security and comply with the upcoming TLSv1.3 standard.

Example: (TLSv1.2)

ssl_ciphers "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH:EDH+aRSA:........"

The first two entries are Elliptic Curve using GCM (no preference order): EECDH+ECDSA+AESGCM, then RSA using GCM (no preference order): EECDH+aRSA+AESGCM. A client will try to negotiate in order of the preference we list here. The preference is for Elliptic Curve using GCM, followed by RSA using GCM, Elliptic named curves (EECDH), Ephermeral Diffie-Hellman with RSA (EDH+aRSA) and so on down the list of ciphers. BTW the Cipher list has options: + can be used for generalizing the specification of cipher suites, as in the example for the first cipher (EECDH+ECDSA+AESGCM), we do not specify 128 or 256 bit nor sha 256 or 384. You can use the - sign for specifying the exact cipher or spec you want to use ie (ECDHE-RSA-AES256-GCM-SHA384)

The options are whatever you desire as long as your intended audience can use the ciphers we enable (RFC 7525) to connect to your application or site. You can add Camellia, CHACHA20 (ECDHE+ECDSA+CHACHA20+POLY1305: ECDHE+RSA+CHACHA20+POLY1305:), or anything else in the cipher list, but the procedure uses our preference which works with most clients while remaining secure. We will only use TLSv1.2 & TLSv1.3 in the procedure (Fully mitigate BEAST vulnerability). Think about what other ciphers you desire to add if you remove these ciphers. Unless you are an admin and understand the implications, I would not recommend it.

Example: (TLSv1.3)

RFC 8446 defines the following cipher suites for use with TLS TLSv1.3

    TLS_AES_128_GCM_SHA256
    TLS_AES_256_GCM_SHA384
    TLS_CHACHA20_POLY1305_SHA256
    TLS_AES_128_CCM_SHA256
    TLS_AES_128_CCM_8_SHA256

The following are the ciphers that we shall be using in this procedure for TLSv1.3:

ssl_ciphers "TLS+AES+128+GCM+SHA256:TLS+AES+256+GCM+SHA384:TLS+CHACHA20+POLY1205+SHA256"

Turning off compression

SSL Compression is turned off by default in NGINX. But there is on thing that we need to change in the NGINX Config file. Type in the below command to access the config file and go to Gzip settings. Change the option from "on" to "off"

 nano /etc/nginx/nginx.conf

We will only go over the local use of the Cipher Suites for NGINX

nano /etc/nginx/sites-available/EXAMPLE_com_ssl.conf

Modern Cipher Suite

ssl_ciphers "TLS+AES+256+GCM+SHA384:TLS+CHACHA20+POLY1305+SHA256:TLS+AES+128+GCM+SHA256:TLS+AES+128+CCM+8+SHA256:TLS+AES+128+CCM+SHA256:EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH:EDH+aRSA:!SHA1:!SHA256:!SHA384:!AES128:!AESCCM:!MEDIUM:!RC4:!CHACHA20:!POLY1305:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SEED:!CAMELLIA";

Intermediate Cipher Suite

ssl_ciphers "TLS+AES+128+GCM+SHA256:TLS+AES+256+GCM+SHA384:TLS+CHACHA20+POLY1205+SHA256:EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH:EDH+aRSA:!SHA1:!SHA256:!SHA384:!MEDIUM:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SEED:!CAMELLIA";

Old Cipher Suite

ssl_ciphers "TLS+AES+128+GCM+SHA256:TLS+AES+256+GCM+SHA384:TLS+CHACHA20+POLY1205+SHA256:EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH:EDH+aRSA:!MEDIUM:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SEED:!CAMELLIA";

Add the following to the server block

We went with the Intermediate Cipher Suite for this procedure:

ssl_ciphers "TLS+AES+128+GCM+SHA256:TLS+AES+256+GCM+SHA384:TLS+CHACHA20+POLY1205+SHA256:EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH:EDH+aRSA:!SHA1:!SHA256:!SHA384:!MEDIUM:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SEED:!CAMELLIA";
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2 TLSv1.3;

Close and exit the file

ctrl + o   (Save)
ctrl + x   (Exit)

Restart NGINX

 systemctl restart nginx