nmap ssl-enum-ciphers / haproxy / tls / no results

nmap ssl-enum-ciphers / haproxy / tls / no results

  • Written by
    Walter Doekes
  • Published on

When doing an nmap ssl-enum-ciphers scan on a Haproxy machine, I got zero working ciphers. But connecting with TLS worked just fine. What is up?

While updating TLS ciphers to disable certain unsafe ciphers, we wanted to test the current offers. nmap with the ssl-enum-ciphers script should work fine for this, and it is reasonably fast:

$ nmap -Pn --script=ssl-enum-ciphers -p 443 google.com
...
443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.0:
...
|   TLSv1.1:
...
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
...
|     warnings:
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|_  least strength: C

Nmap done: 1 IP address (1 host up) scanned in 1.27 seconds

Okay, that is convenient. On to the relevant host.

On the host, we've configured TLSv1.2 and TLSv1.3 with a limited set of ciphers. Let's go:

$ nmap -Pn --script=ssl-enum-ciphers -p 443 x.x.x.x
...
443/tcp open  https

Nothing?!

Apparently the nmap 7.91 scripts on Ubuntu/Jammy are a bit outdated and have no TLSv1.3 support. It was added in nmap commit 7c61f7c.

We can patch our Ubuntu/Jammy nmap with this adapted patch:
nmap-ssl-enum-ciphers-tls13-for-ubuntu-jammy.patch

$ cd /usr/share/nmap
$ sudo patch -p1 < /PATH/TO/nmap-ssl-enum-ciphers-tls13-for-ubuntu-jammy.patch

Try again:

$ nmap -Pn --script=ssl-enum-ciphers -p 443 $haproxy
...
443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.3:
|     ciphers:
|       TLS_AKE_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
|       TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|     cipher preference: client
|_  least strength: A

Nice! TLSv1.3 results. But where is the TLSv1.2?

We know that the script supports TLSv1.2, as seen with the google.com example above. In fact, rerunning it now shows that google.com also does TLSv1.3, as you'd expect.

The Haproxy config looks sane:

global
    # "server ciphers"
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305
    ssl-default-bind-ciphersuites TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256
    ssl-default-bind-options prefer-client-ciphers no-tls-tickets ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.3

And openssl s_client -no_tls1_3 -connect will happily connect with TLSv1.2.

If we try a kube-apiserver with the same set of ciphers configured, it does yield both TLSv1.2 and TLSv1.3:

# kube-apiserver [...] --tls-cipher-suites=\
TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,\
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
$ nmap -Pn --script=ssl-enum-ciphers -p 443 $kube-apiserver
...
443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 - unknown
|       TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - unknown
|       TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - unknown
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.3:
|     ciphers:
|       TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|       TLS_AKE_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
|       TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|     cipher preference: server
|_  least strength: unknown

So, something is different with Haproxy.

The openssl s_client output did not give many clues, but there was one:

Client Certificate Types: RSA sign, ECDSA sign for the kube-apiserver and
Client Certificate Types: RSA sign, DSA sign, ECDSA sign for Haproxy.

And indeed, there is a related fix in nmap commit 034ea73.

Apply the following patch as well:
nmap-ssl-enum-ciphers-tls12-ecdsa-in-ubuntu-jammy.patch

$ cd /usr/share/nmap
$ sudo patch -p1 < /PATH/TO/nmap-ssl-enum-ciphers-tls12-ecdsa-in-ubuntu-jammy.patch

And now a rescan finally shows both TLS protocols on Haproxy as well.

$ nmap -Pn --script=ssl-enum-ciphers -p 443 $haproxy
...
443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (secp256r1) - A
|     compressors:
|       NULL
|     cipher preference: client
|   TLSv1.3:
|     ciphers:
|       TLS_AKE_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
|       TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|     cipher preference: client
|_  least strength: A

(Aha! That “unknown” is now gone too.)


Back to overview Newer post: systemd-networkd-wait-online / stalling and failing Older post: gpg-agent / ssh / ed25519 / agent refused