Hello,
After running an Internet.nl mail test on a self-hosted grommunio server, I worked on improving the SMTP, TLS and DNS configuration. The score improved significantly after applying the changes below.
I am sharing the steps that worked in my setup because they may be useful to other grommunio users. It might also be helpful if some of these checks or helpers could eventually be integrated into grommunio setup tools, or provided as optional post-install hardening scripts.
The setup was broadly as follows:
grommunio on openSUSE
Postfix as SMTP server
OpenSSL 3.x
DNSSEC enabled
Postfix using the grommunio SMTP certificate
DKIM signing through grommunio-antispam / Rspamd
DANE/TLSA enabled for SMTP
The examples below use:
example.org
mail.example.org
Please replace them with your own domain and MX hostname.
1. Postfix TLS hardening
First, I disabled obsolete TLS versions and forced Postfix to prefer its own cipher order:
postconf -e 'smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
postconf -e 'smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
postconf -e 'tls_preempt_cipherlist = yes'
Then I restricted TLS 1.2 cipher suites to modern ECDHE suites:
postconf -e \
'smtpd_tls_ciphers = high' \
'smtpd_tls_mandatory_ciphers = high' \
'tls_high_cipherlist = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'
Reload Postfix:
systemctl reload postfix
Useful checks:
postfix check
echo QUIT | openssl s_client -starttls smtp -connect 127.0.0.1:25 -tls1_2 -servername mail.example.org 2>/dev/null | grep -E 'Protocol|Cipher|Verify return code'
echo QUIT | openssl s_client -starttls smtp -connect 127.0.0.1:25 -tls1_3 -servername mail.example.org 2>/dev/null | grep -E 'Protocol|Cipher|Verify return code'
Expected examples:
TLSv1.2 with ECDHE-RSA-AES256-GCM-SHA384
TLSv1.3 with TLS_AES_256_GCM_SHA384
2. DMARC policy
SPF and DKIM should be checked first. In my case, DKIM was already configured and Postfix was using the Rspamd/grommunio-antispam milter:
postconf -n | grep -Ei 'milter|rspamd|smtpd_milters|non_smtpd_milters'
Expected example:
smtpd_milters = inet:localhost:11332
non_smtpd_milters = inet:localhost:11332
The DMARC policy was then changed from monitoring mode:
v=DMARC1; p=none
to a stricter policy:
v=DMARC1; p=quarantine
Example DNS record:
_dmarc.example.org. TXT "v=DMARC1; p=quarantine"
Useful checks:
dig +short TXT example.org
dig +short TXT dmarc.example.org
dig +short TXT dkim.domainkey.example.org
3. DANE/TLSA for SMTP
Since DNSSEC was enabled, I added a TLSA record for SMTP on port 25.
Check DNSSEC first:
dig +short DS example.org
Extract the SMTP certificate actually presented by Postfix:
echo QUIT | openssl s_client -starttls smtp -connect 127.0.0.1:25 -servername mail.example.org -showcerts 2>/dev/null \
| sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' \
| awk 'BEGIN{c=0} /BEGIN CERTIFICATE/{c++} c==1{print}' > /tmp/mail-smtp.crt
Generate the TLSA value:
openssl x509 -in /tmp/mail-smtp.crt -noout -pubkey \
| openssl pkey -pubin -outform DER \
| openssl dgst -sha256 -binary \
| xxd -p -c 256
DNS record format:
25.tcp.mail.example.org. TLSA 3 1 1 <sha256-public-key-hash>
Validation:
dig +short TLSA 25.tcp.mail.example.org
delv TLSA 25.tcp.mail.example.org
Expected delv result:
; fully validated
4. CAA record for the mail server
When using a self-signed SMTP certificate authenticated through DANE, a restrictive CAA record can be used:
mail.example.org. CAA 0 issue ";"
Validation:
dig +short CAA mail.example.org
delv CAA mail.example.org
This tells public certificate authorities that no public CA is authorised to issue a certificate for this hostname.
Of course, if you use Let’s Encrypt, Actalis, Sectigo or another public CA for the mail host, the CAA record must be adapted accordingly.
5. Replacing the SMTP certificate with RSA 3072
Internet.nl may report RSA 2048-bit SMTP certificates as “phase out”. I replaced the SMTP certificate with a self-signed RSA 3072 certificate.
Generate the new certificate:
openssl req -newkey rsa:3072 -nodes -keyout /root/mail-example-rsa3072.key \
-x509 -days 365 -out /root/mail-example-rsa3072.crt \
-subj "/CN=mail.example.org" \
-addext "subjectAltName=DNS:mail.example.org" \
-sha256
Check it:
openssl x509 -in /root/mail-example-rsa3072.crt -noout -subject -issuer -dates -text \ | grep -Ei 'Subject😐Issuer😐Not Before|Not After|Public-Key|Signature Algorithm|DNS:'
Important for DANE users: before replacing the live certificate, generate and publish the new TLSA record first, while keeping the old TLSA record during the transition.
Generate the new TLSA value:
openssl x509 -in /root/mail-example-rsa3072.crt -noout -pubkey \
| openssl pkey -pubin -outform DER \
| openssl dgst -sha256 -binary \
| xxd -p -c 256
Temporarily publish both TLSA records:
25.tcp.mail.example.org. TLSA 3 1 1 <old-hash>
25.tcp.mail.example.org. TLSA 3 1 1 <new-hash>
After DNS propagation, replace the certificate files.
On my grommunio system, Postfix used:
/etc/grommunio-common/ssl/server-bundle.pem
/etc/grommunio-common/ssl/server.key
Replacement example:
install -o gromox -g gromox -m 0644 /root/mail-example-rsa3072.crt /etc/grommunio-common/ssl/server-bundle.pem
install -o gromox -g gromox -m 0600 /root/mail-example-rsa3072.key /etc/grommunio-common/ssl/server.key systemctl reload postfix
Verify the certificate presented by Postfix:
echo QUIT | openssl s_client -starttls smtp -connect 127.0.0.1:25 -servername mail.example.org -showcerts 2>/dev/null \
| sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' \
| awk 'BEGIN{c=0} /BEGIN CERTIFICATE/{c++} c==1{print}' \
| openssl x509 -noout -subject -issuer -dates -text \
| grep -Ei 'Subject😐Issuer😐Not Before|Not After|Public-Key|Signature Algorithm|DNS:'
6. Removing SHA224 from TLS SignatureAlgorithms
Internet.nl may also report:
Hash function for key exchange: SHA224
On openSUSE, the OpenSSL crypto policy may explicitly allow SHA224 in:
cat /etc/crypto-policies/back-ends/opensslcnf.config
In my case, the relevant line contained:
SignatureAlgorithms = ... ECDSA+SHA224:RSA+SHA224
I created a dedicated OpenSSL configuration for Postfix, keeping the openSUSE crypto policy structure but removing SHA224 from SignatureAlgorithms.
This structure worked:
cat > /etc/postfix/openssl-postfix.cnf <<'EOF'
postfix = postfix_settings
[postfix_settings]
ssl_conf = postfix_ssl_settings
[postfix_ssl_settings]
system_default = postfix_tls_defaults
[postfix_tls_defaults]
CipherString = @SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:kRSAPSK:-aDSS:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256
MinProtocol = TLSv1.2
MaxProtocol = TLSv1.3
SignatureAlgorithms = rsa_pss_rsae_sha512:rsa_pss_rsae_sha384:rsa_pss_rsae_sha256:RSA+SHA512:RSA+SHA384:RSA+SHA256:ECDSA+SHA512:ECDSA+SHA384:ECDSA+SHA256
Groups = X25519:secp256r1:X448:secp521r1:secp384r1:ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192 EOF
Then enable it in Postfix:
postconf -e 'tls_config_file = /etc/postfix/openssl-postfix.cnf' 'tls_config_name = postfix' systemctl reload postfix
Checks:
postconf -n | grep -Ei 'tls_config_file|tls_config_name'
postfix check
systemctl status postfix --no-pager
Expected:
tls_config_file = /etc/postfix/openssl-postfix.cnf
tls_config_name = postfix
After this change, Internet.nl no longer reported the SHA224/SHA1 hash function warning.
7. Suggested improvements for grommunio tooling
It would be very useful if grommunio could provide optional post-install hardening helpers for:
- checking SPF, DKIM, DMARC and DANE readiness;
- generating a safe Postfix TLS hardening configuration;
- generating a RSA 3072 or ECDSA SMTP certificate;
- generating the correct TLSA record for the active SMTP certificate;
- assisting with DANE certificate rollover;
- generating a suitable CAA suggestion depending on whether the user uses a public CA or a self-signed DANE-based certificate;
- applying a Postfix/OpenSSL configuration that removes SHA224 from SignatureAlgorithms without weakening the system crypto policy;
- running local checks before the user re-runs Internet.nl.
This would make it easier for self-hosted grommunio administrators to reach a stronger security baseline without manually reconstructing every Postfix, OpenSSL and DNSSEC setting.