Skip to content

Conversation

@ekohl
Copy link
Member

@ekohl ekohl commented Mar 10, 2025

The default built in ciphers can be less secure. On Red Hat there is the special cipher that's PROFILE=SYSTEM where OpenSSL will respect what's configured in crypto-policies. This keeps the configuration out of the installer while still giving the user control. Out of the box this is also more secure.

I don't know how to test this. When I tried openssl s_client -connect localhost:1883 it disconnects me. Same with sslscan --show-ciphers localhost:1883. @adamruzicka any idea?

@adamruzicka
Copy link
Contributor

Either you can comment out require_certificate true in /etc/mosquitto/mosquitto.conf and restart mosquitto or you can give certs to openssl. Reusing some of the certs that the proxy already has seems to work

openssl s_client -connect localhost:1883 \
  -cert /etc/foreman-proxy/foreman_ssl_cert.pem \
  -key /etc/foreman-proxy/foreman_ssl_key.pem

I'm not familiar with sslscan, but I'm quite sure there some way to give it client certs.

@ekohl
Copy link
Member Author

ekohl commented Mar 11, 2025

I think I know why I couldn't easily test it: I tried it on puppet-mosquitto which by default ships with an empty config. If you then add ciphers, it still won't have TLS enabled.

I also found that sslscan doesn't show all ciphers and I fell back to nmap --script ssl-enum-ciphers localhost -p 1883.

When I test on EL9 I have difficulty disabling the CBC cipher entirely. https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/security_hardening/using-the-system-wide-cryptographic-policies_security-hardening#customizing-system-wide-cryptographic-policies-with-subpolicies_using-the-system-wide-cryptographic-policies suggests this should work:

# echo "cipher = -*-CBC" > /etc/crypto-policies/policies/modules/DISABLE-CBC.pmod
# update-crypto-policies --set DEFAULT:DISABLE-CBC
Setting system policy to DEFAULT:DISABLE-CBC
Note: System-wide crypto policies are applied on application start-up.
It is recommended to restart the system for the change of policies
to fully take place.
# systemctl restart mosquitto

If I do this without ciphers PROFILE=SYSTEM I get:

# nmap --script ssl-enum-ciphers localhost -p 1883
Starting Nmap 7.92 ( https://nmap.org ) at 2025-03-11 10:13 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000034s latency).
Other addresses for localhost (not scanned): ::1 127.0.0.1 127.0.0.1

PORT     STATE SERVICE
1883/tcp open  mqtt
| ssl-enum-ciphers: 
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|       TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (ecdh_x25519) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (ecdh_x25519) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|     compressors: 
|       NULL
|     cipher preference: server
|   TLSv1.3: 
|     ciphers: 
|       TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|       TLS_AKE_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
|       TLS_AKE_WITH_AES_128_CCM_SHA256 (ecdh_x25519) - A
|     cipher preference: server
|_  least strength: A

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

With ciphers PROFILE=SYSTEM:

# nmap --script ssl-enum-ciphers localhost -p 1883
Starting Nmap 7.92 ( https://nmap.org ) at 2025-03-11 10:12 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000034s latency).
Other addresses for localhost (not scanned): ::1 127.0.0.1 127.0.0.1

PORT     STATE SERVICE
1883/tcp open  mqtt
| ssl-enum-ciphers: 
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CCM (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CCM (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 2048) - A
|       TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CCM (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CCM (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
|     compressors: 
|       NULL
|     cipher preference: server
|   TLSv1.3: 
|     ciphers: 
|       TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|       TLS_AKE_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
|       TLS_AKE_WITH_AES_128_CCM_SHA256 (ecdh_x25519) - A
|     cipher preference: server
|_  least strength: A

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

Those not wanting to diff, it removes these ciphers:

  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
  • TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_128_CBC_SHA256

It struck me as odd that there were still CBC ciphers in there so I did a more drastic test:

echo "cipher = -*-CBC -AES-128-*" > /etc/crypto-policies/policies/modules/DISABLE-CBC.pmod
# update-crypto-policies --set DEFAULT:DISABLE-CBC
Setting system policy to DEFAULT:DISABLE-CBC
Note: System-wide crypto policies are applied on application start-up.
It is recommended to restart the system for the change of policies
to fully take place.
# systemctl restart mosquitto
# nmap --script ssl-enum-ciphers localhost -p 1883
Starting Nmap 7.92 ( https://nmap.org ) at 2025-03-11 10:19 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000034s latency).
Other addresses for localhost (not scanned): ::1 127.0.0.1 127.0.0.1

PORT     STATE SERVICE
1883/tcp open  mqtt
| ssl-enum-ciphers: 
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CCM (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 2048) - A
|       TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CCM (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|     compressors: 
|       NULL
|     cipher preference: server
|   TLSv1.3: 
|     ciphers: 
|       TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|     cipher preference: server
|_  least strength: A

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

So it certainly is following crypto-policies with this, but I haven't found the magic invocation to get rid of all CBC ciphers. Still, this way we hand control over to the user without needing to expose many parameters for users to tune.

The default built in ciphers can be less secure. On Red Hat there is the
special cipher that's PROFILE=SYSTEM where OpenSSL will respect what's
configured in crypto-policies. This keeps the configuration out of the
installer while still giving the user control. Out of the box this is
also more secure.
@ekohl ekohl force-pushed the 38279-mosquitto-ciphers branch from 8ab0b93 to 3857449 Compare March 11, 2025 10:59
@ekohl
Copy link
Member Author

ekohl commented Mar 11, 2025

Lint fixes in #860.

@evgeni evgeni merged commit af23995 into theforeman:master Mar 17, 2025
15 of 17 checks passed
@ekohl ekohl deleted the 38279-mosquitto-ciphers branch March 17, 2025 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants