Digging into AL2023 system-wide Cryptographic Policies

by Sebastien Mirolo on Wed, 28 May 2025

We ended up running a Vulnerability Assessment and Penetration Test exercise while in the middle of migrating EC2 instances to AL2023. To comply with the findings, CBC ciphers had to be disabled on nginx and dovecot TLS endpoints. This post goes through our journey trying to use system-wide cryptographic policies.

What should have been a 5min task

RedHat introduced system-wide cryptographic policies. Amazon Linux followed in its footsteps. Apparently dovecot and nginx are configured on AL2023 to use system-wide cryptographic policies.

Terminal
$ cat /etc/dovecot/conf.d/10-ssl.conf
...
ssl_cipher_list = PROFILE=SYSTEM

$ cat /etc/nginx/nginx.conf
...
        ssl_ciphers PROFILE=SYSTEM;

So the task to disable CBC ciphers seems pretty straightforward.

Terminal
$ sudo dnf install crypto-policies-scripts
$ sudo cat /etc/crypto-policies/policies/modules/DISABLE-CBC.pmod
cipher = -*-CBC
cipher@TLS = -*-CBC

$ sudo update-crypto-policies --set DEFAULT:DISABLE-CBC
$ sudo reboot

Running tests against the TLS endpoints

Most VAPT teams run testssl.sh, so we will go to a remote machine (i.e. our local development machine) and run the script against the imaps and https endpoints on the AL2023 instance.

Terminal
$ testssl.sh example.com:993
...
Obsolete CBC ciphers (AES, ARIA etc.)         offered
...
$ testssl.sh example.com:443
...
Obsolete CBC ciphers (AES, ARIA etc.)         offered
...

CBC ciphers are still offered by the server. They were not disabled as we would have expected.

It is time to list all the ciphers offered by the server:

Terminal
$ nmap --script ssl-enum-ciphers -p 443 example.com
Starting Nmap 7.93 ( https://nmap.org ) at 2025-05-27 01:24 PDT
Nmap scan report for example.com (***.***.***.***)
Host is up (0.18s latency).

PORT    STATE SERVICE
443/tcp open  https
| 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
|     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

Effectively, CBC ciphers are still offered. If we are to just try one cipher against a TLS endpoint, we would use the command:

Terminal
$ openssl s_client -cipher 'TLS_RSA_WITH_AES_256_CBC_SHA' -connect example.com:993

Digging into system-wide cryptographic policies

We find the default policies in /usr/share/crypto-policies/policies. When running update-crypto-policies, it creates config files in /etc/crypto-policies/back-ends. Some of those config files are loaded by OpenSSL.

Terminal
$ cat /etc/pki/tls/openssl.cnf
...
.include = /etc/crypto-policies/back-ends/opensslcnf.config

Reading through openssl-ciphers, we stumbled upon the following worth noting:

PROFILE=SYSTEM
The list of enabled cipher suites will be loaded from the system crypto policy configuration file /etc/crypto-policies/back-ends/openssl.config. See also update-crypto-policies(8). This is the default behavior unless an application explicitly sets a cipher list. If used in a cipher list configuration value this string must be at the beginning of the cipher list, otherwise it will not be recognized.

On the AL2023 machine, we checking the ciphers available through OpenSSL do not include a CBC cipher.

Terminal
$ openssl ciphers -s -tls1_2 -stdname
ECDHE-ECDSA-AES256-GCM-SHA384
...
DHE-RSA-AES128-SHA

Then make sure dovecot, nginx, and openssl are all linked to the same OpenSSL library.

Terminal
$ ldd /usr/sbin/dovecot
...
	libssl.so.3 => /lib64/libssl.so.3 (0x00007fbf5b29c000)
	libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007fbf5aa00000)

$ ldd /usr/sbin/nginx
...
	libssl.so.3 => /lib64/libssl.so.3 (0x00007fc5aed18000)
	libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007fc5ae600000)

$ ldd /usr/bin/openssl
...
	libssl.so.3 => /lib64/libssl.so.3 (0x00007fc6cb39c000)
	libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007fc6cae00000)

Armed with that knowledge, we thus attempt to modify the back-ends config files directly.

Terminal
$ diff -u /etc/crypto-policies/back-ends/opensslcnf.config
-CipherString = @SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:kRSAPSK:-aDSS:-SHA256:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8
+CipherString = @SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:kRSAPSK:-aDSS:-SHA256:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8:-CBC

No seemingly effect.

Terminal
$ diff -u /etc/crypto-policies/back-ends/openssl.config
-@SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:kRSAPSK:-aDSS:-SHA256:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8
+@SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:kRSAPSK:-aDSS:-SHA256:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8:-CBC

With that change above alone, nginx does no longer offer CBC ciphers, but Dovecot continues to offer CBC ciphers. One out of two.

Conclusion

Either I am misunderstanding configuration of AL2023 system-wide cryptographic policies, or the implementation is still very rough around the edges. In all cases, after two days of poking around, we decided to go back to the true-and-tested approach of specifying the ciphers directly into the dovecot and nginx configuration files.

More to read

If you are looking for related posts, Upgrading to Amazon Linux 2023, and Postfix, Dovecot and OpenLDAP are good reads.

More technical posts are also available on the DjaoDjin blog. For fellow entrepreneurs, business lessons learned running a subscription hosting platform are also available.

by Sebastien Mirolo on Wed, 28 May 2025


Receive news about DjaoDjin in your inbox.

Bring fully-featured SaaS products to production faster.

Follow us on