4

I am trying to configure Nginx to use only TLS1.3 with 2 ciphers: TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256.

So, I tried this configuration:

ssl_protocols TLSv1.3;
ssl_ciphers TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256;

But nginx -s reload errors out with

nginx: [emerg] SSL_CTX_set_cipher_list("TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256") failed (SSL: error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher match)", "operationName": "Default", "category": "Default"}

Looks like I need to append at least one non-TLS1.3 cipher to make the config work. I tried various such combinations and they worked. One of them is:

TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384

Why is it so? I think it's happening because OpenSSL itself doesn't accept the original ciphersuite string. I am using OpenSSL-1.1.1g.

root@2ed6cae6e062:/azure/appgw# openssl ciphers -v TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256
Error in cipher list
140686067873536:error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:ssl/ssl_lib.c:2558:

There are some useful links I came across but couldn't figure out how to achieve what I want - using only TLS1.3 ciphersuites.

https://forum.nginx.org/read.php?2,284909,284914#msg-284914
https://trac.nginx.org/nginx/ticket/1529
https://wiki.openssl.org/index.php/TLS1.3#Ciphersuites

3
  • 1
    Specifying at least one 1.2 (or lower) cipher in the ssl_ciphers directive 'works' in the sense of not giving an error, but it doesn't do what you want: it has no effect on the suites used for 1.3. The ticket you link describes the workaround, using (instead) OpenSSL's configuration file. Jul 1, 2020 at 0:34
  • 2
    TLS 1.3 does not allow you to specify specific cipher suits as far as I know. Why do you want only these two?
    – MechMK1
    Jul 2, 2020 at 14:54
  • @MechMK1, because the two is more secure than the other. May 31, 2021 at 6:25

2 Answers 2

2

I found the answer in the provided links. All the answers by Maxim Dounin are valuable. You should provide a cipher that makes SSL_CTX_set_cipher_list happy and then force the list of ciphers using the ssl_conf_command Ciphersuites directive.

ssl_protocols TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
ssl_prefer_server_ciphers on;

OpenSSL version :

# openssl version
OpenSSL 1.1.1d  10 Sep 2019

Note that TLSv1.3 ciphers are enabled by default.

# openssl ciphers -v ECDHE-ECDSA-AES256-GCM-SHA384
TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD

Using a script proposed at https://superuser.com/a/224263 and particularly the updated version at https://gist.github.com/jahir/23c4202eee12e377ef3acf1dcdc7c776 I checked the above configuration.

$ ./test_ciphers.sh <put IP here>:443
Using OpenSSL 1.1.1k 25 Mar 2021.
Using tls1_1
Testing ECDHE-ECDSA-AES256-SHA         ... NO (tlsv1 alert protocol version)
...
Using tls1_2
Testing ECDHE-ECDSA-AES256-GCM-SHA384  ... NO (tlsv1 alert protocol version)
...
Using tls1_3
Testing TLS_AES_256_GCM_SHA384         ... YES
Testing TLS_CHACHA20_POLY1305_SHA256   ... YES
Testing TLS_AES_128_GCM_SHA256         ... YES

Script included below for reference.

#!/usr/bin/env bash

CIPHERS='ALL:eNULL'
DELAY=${2:-0.1}
SERVER=${1:?usage: $0 <host:port> [delay, default is ${DELAY}s] [ciphers, default is ${CIPHERS}]}
MAXLEN=$(openssl ciphers "$CIPHERS" | sed -e 's/:/\n/g' | awk '{ if ( length > L ) { L=length} }END{ print L}')

echo Using $(openssl version).

declare -A TLSMAP=( [tls1_1]=cipher [tls1_2]=cipher [tls1_3]=ciphersuites )

for tlsver in "${!TLSMAP[@]}"
do
  echo "Using $tlsver"
  ciphers=$(openssl ciphers -$tlsver -s "$CIPHERS" | sed -e 's/:/ /g')
  for cipher in ${ciphers[@]}
  do
    in=$(openssl s_client -$tlsver -${TLSMAP[$tlsver]} "$cipher" -connect $SERVER </dev/null 2>&1)
    if [[ "$in" =~ ":error:" ]] ; then
      result="NO ($(echo -n $in | cut -d':' -f6))"
    else
      if [[ "$in" =~ "Cipher is ${cipher}" || "$in" =~ "Cipher    :" ]] ; then
        result='YES'
      else
        result="UNKNOWN RESPONSE\n$in"
      fi
    fi
    printf 'Testing %-*s ... %s\n' "$MAXLEN" "$cipher" "$result"
    sleep $DELAY
  done
done
0

I succeeded by adding ssl_prefer_server_ciphers off; directive.

3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.