Hardening Postfix TLS to Pass Internet.nl in 2026
On April 21, 2026, Internet.nl rolled out a fully updated TLS test based on the latest NCSC-NL guidelines. Mail servers that previously passed the test may now show new warnings. This guide walks through the exact fixes on Debian 13 Trixie with Postfix 3.9 or later, based on hands-on troubleshooting on a production server.
The three issues internet.nl now flags are:
- CBC-based cipher suites, marked as insufficient
- Camellia and ARIA cipher suites, marked as phase-out
- SHA1 as a TLS 1.2 key exchange hash function, marked as insufficient
Each has a specific fix. Let’s go through them one by one.
Before you start: the internet.nl rate limit issue
Internet.nl sends a large number of rapid connections to your server during its test suite, checking STARTTLS, DANE, cipher suites, signature algorithms, and more. If your Postfix server has a connection rate limit configured, internet.nl will hit it before the test completes.
Check your current rate limit settings:
postconf smtpd_client_connection_rate_limit
postconf smtpd_client_event_limit_exceptionsA typical production setting of smtpd_client_connection_rate_limit = 200 is enough to trigger the limit during an internet.nl test run. The fix is to add their IP range to the exceptions list in /etc/postfix/main.cf:
smtpd_client_event_limit_exceptions = $mynetworks, 62.204.66.0/24This keeps the rate limit in place for everyone else while allowing internet.nl to complete its test. After editing, run:
postfix reloadAlso check whether CrowdSec has banned the internet.nl IP from a previous incomplete test run:
cscli decisions list | grep 62.204.66If a decision exists, delete it before re-running the test:
cscli decisions delete --range 62.204.66.0/24For a permanent solution, whitelist the internet.nl IP range in CrowdSec so it is never banned during future test runs. This is covered in the Rspamd and CrowdSec part of this mail server series.
Fix 1: cipher suites
The cipher suite fix is straightforward. In /etc/postfix/main.cf, update the exclude list to add CBC, CAMELLIA, and ARIA:
smtpd_tls_exclude_ciphers = aNULL, MD5, DES, 3DES, RC4, CBC, CAMELLIA, ARIA
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5, DES, 3DES, RC4, CBC, CAMELLIA, ARIAAdding CBC drops all CBC-based suites in one directive, including the AES_256_CBC_SHA and AES_128_CBC_SHA variants that internet.nl flags as insufficient, as well as the various CBC_SHA256 and CBC_SHA384 variants marked as phase-out. Adding CAMELLIA and ARIA removes those families entirely.
Your protocol restrictions should already exclude TLS 1.0 and 1.1:
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1Reload Postfix and verify:
postfix reload
postconf smtpd_tls_exclude_ciphersFix 2: SHA1 signature algorithms for TLS 1.2
This is the more complex fix. Internet.nl tests whether your server offers SHA1 as a signature algorithm during the TLS 1.2 handshake. This is entirely separate from cipher suite configuration. The test explanation says it explicitly: “The supported hash functions can be configured via a separate TLS setting (e.g. SignatureAlgorithms in OpenSSL) and are not part of the cipher suite configuration.”
The correct approach is to apply the restriction at the Postfix level only, using a dedicated OpenSSL configuration file. Do not make this change system-wide in /etc/ssl/openssl.cnf, as that would affect every application on the host that uses OpenSSL, not just Postfix.
Postfix 3.9 introduced the tls_config_file and tls_config_name parameters, which allow Postfix to load a dedicated OpenSSL configuration file and select a named application section within it. This scopes the restriction cleanly to Postfix alone.
Create the file:
vi /etc/postfix/tls_config.confWith this exact content, including the named section structure:
postfix = postfix_settings
[postfix_settings]
ssl_conf = postfix_ssl_settings
[postfix_ssl_settings]
system_default = postfix_tls_defaults
[postfix_tls_defaults]
SignatureAlgorithms = RSA+SHA512:RSA+SHA384:RSA+SHA256:ECDSA+SHA512:ECDSA+SHA384:ECDSA+SHA256The section structure is critical. Without the named postfix application section at the top, OpenSSL has no context to apply the SignatureAlgorithms restriction on the server side, and the directive is silently ignored.
Then add both parameters to /etc/postfix/main.cf:
tls_config_file = /etc/postfix/tls_config.conf
tls_config_name = postfixtls_config_file tells Postfix which file to read; tls_config_name tells it which named section within that file to use. Both are required.
Reload and verify:
postfix reload
postconf tls_config_file
postconf tls_config_nameVerify the result
Test that your server correctly rejects a TLS 1.2 handshake offering only SHA1 signature algorithms:
openssl s_client -connect mx1.yourdomain.eu:25 -starttls smtp -no_tls1_3 2>&1 | grep -E "Cipher|Protocol"Replace mx1.yourdomain.eu with the hostname of your own mail server.
A successful TLS 1.2 connection should show an AES-GCM or CHACHA20 cipher, for example ECDHE-ECDSA-AES256-GCM-SHA384. The SHA384 at the end of that cipher name refers to the HMAC used for message authentication, not the handshake signature algorithm; it is not related to the SHA1 issue we are fixing here. What matters is that the cipher family is GCM or CHACHA20, not CBC. You can also check your Postfix logs during an internet.nl test run; connections using SHA1-only handshakes will appear as no shared cipher errors, which is the correct behaviour: the server is refusing to negotiate on those terms.
Summary of changes
| File | Change |
|---|---|
/etc/postfix/main.cf | Add CBC, CAMELLIA, ARIA to smtpd_tls_exclude_ciphers and smtpd_tls_mandatory_exclude_ciphers |
/etc/postfix/main.cf | Add smtpd_client_event_limit_exceptions = $mynetworks, 62.204.66.0/24 |
/etc/postfix/main.cf | Add tls_config_file = /etc/postfix/tls_config.conf |
/etc/postfix/main.cf | Add tls_config_name = postfix |
/etc/postfix/tls_config.conf | Create with named section structure and SignatureAlgorithms directive |
A note on troubleshooting
The SHA1 subtest is the trickiest part of this fix. The key insight, discovered through comparing notes with other communities, is that tls_config_file alone is not sufficient. Without tls_config_name pointing to a named application section in the config file, OpenSSL applies the directives only to the client side and ignores them on the server side. Internet.nl will continue to flag SHA1 even though direct openssl s_client testing shows the server is rejecting SHA1-only handshakes.
The named section structure in tls_config.conf and the matching tls_config_name = postfix directive in main.cf are both required for the server-side restriction to take effect.
This guide is part of the ongoing Debian 13 mail server series on this blog.
