Configurare DANE/TLSA con Postfix, Bind e Let's Encrypt
Di CaptainDNS
Pubblicato il 22 febbraio 2026

- DANE/TLSA lega il certificato TLS del tuo server mail a un record DNS firmato con DNSSEC, eliminando la dipendenza dalle autorità di certificazione
- La combinazione consigliata è
3 1 1(DANE-EE, SPKI, SHA-256): l'hash TLSA sopravvive ai rinnovi Let's Encrypt finché la chiave privata non cambia - Postfix supporta nativamente la verifica DANE in uscita con
smtp_dns_support_level = dnssecesmtp_tls_security_level = dane - L'automazione avviene tramite un deploy-hook Certbot che rigenera l'hash TLSA e ricarica la zona Bind9 a ogni rinnovo
- Verifica il tuo deployment con
dig TLSA,openssl s_cliente l'inspector DANE/TLSA CaptainDNS
Gestisci un server mail Postfix e vuoi proteggere le tue connessioni SMTP contro attacchi di tipo downgrade o man-in-the-middle? DANE (DNS-based Authentication of Named Entities) è la risposta. Pubblicando un record TLSA nella tua zona DNS firmata con DNSSEC, indichi ai server remoti quale certificato TLS il tuo server deve presentare. Nessun intermediario, nessuna autorità di certificazione di cui fidarsi.
La sfida con Let's Encrypt è il rinnovo automatico ogni 90 giorni. Se l'hash TLSA non corrisponde più al certificato, i server che verificano DANE rifiuteranno la connessione. Questo tutorial copre la configurazione completa dello stack Postfix + Bind9 + Let's Encrypt + DANE, inclusa l'automazione del rinnovo per evitare qualsiasi interruzione.
Questa guida è rivolta agli amministratori di sistema Linux che gestiscono un server mail self-hosted. Presuppone una conoscenza base di Postfix, DNS e della riga di comando. Per i fondamenti di DANE e TLSA, consulta la nostra guida completa DANE/TLSA (primo articolo di questa serie).
Prerequisiti
Prima di iniziare, verifica di avere:
| Componente | Versione minima | Verifica |
|---|---|---|
| Debian/Ubuntu | 12+ / 22.04+ | cat /etc/os-release |
| Postfix | 3.4+ (supporto DANE nativo) | postconf mail_version |
| Bind9 | 9.18+ (DNSSEC inline-signing) | named -v |
| Certbot | 2.0+ | certbot --version |
| DNSSEC attivo | Zona firmata + DS presso il registrar | dig +dnssec captaindns.com SOA |
Se DNSSEC non è ancora attivo sulla tua zona, è il prerequisito. Bind9 9.18+ supporta l'inline-signing che semplifica la gestione. Attivalo prima di proseguire.
Porte e accesso di rete
Postfix utilizza la porta 25 (SMTP) e opzionalmente la 587 (submission). Let's Encrypt richiede la porta 80 o 443 per la challenge HTTP-01 (o una challenge DNS-01 se la porta 80 non è disponibile sul server mail). Assicurati che queste porte siano aperte nel tuo firewall.

Configurare DNSSEC con Bind9
Se la tua zona è già firmata con DNSSEC, passa alla sezione successiva. Altrimenti, ecco la configurazione minima con Bind9 e l'inline-signing.
Attivare l'inline-signing
Nel tuo file di configurazione della zona (/etc/bind/named.conf.local o equivalente):
zone "captaindns.com" {
type primary;
file "/var/lib/bind/captaindns.com.zone";
dnssec-policy default;
inline-signing yes;
key-directory "/var/lib/bind/keys";
};
La direttiva dnssec-policy default genera e gestisce automaticamente le chiavi ZSK e KSK. L'inline-signing firma la zona al volo senza modificare il file sorgente.
Pubblicare il DS presso il registrar
Dopo il primo caricamento della zona, Bind9 genera le chiavi. Recupera il DS record:
# Elencare le chiavi generate
ls /var/lib/bind/keys/
# Estrarre il DS record (adattare il nome del file KSK)
dnssec-dsfromkey /var/lib/bind/keys/Kcaptaindns.com.+013+xxxxx.key
Trasmetti il DS record al tuo registrar (interfaccia web o API). La propagazione richiede da pochi minuti a 48 ore a seconda del registrar.
Verificare la catena DNSSEC
dig +dnssec +short captaindns.com SOA
# Deve restituire il SOA con il flag "ad" (Authenticated Data)
dig +dnssec captaindns.com DNSKEY
# Deve restituire le DNSKEY con le firme RRSIG
Generare il certificato Let's Encrypt
Ottenere il certificato
# Installazione di Certbot (se non già installato)
apt install certbot
# Ottenere un certificato per l'hostname del server mail
certbot certonly --standalone -d mail.captaindns.com
Se la porta 80 è già utilizzata da un altro servizio, usa il plugin webroot o la challenge DNS-01:
# Alternativa con webroot (se Apache/Nginx è attivo sul server)
certbot certonly --webroot -w /var/www/html -d mail.captaindns.com
# Alternativa con challenge DNS (se porta 80 non disponibile)
certbot certonly --manual --preferred-challenges dns -d mail.captaindns.com
Configurare Postfix per usare il certificato
Modifica /etc/postfix/main.cf:
# Certificato TLS (ricezione - smtpd)
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.captaindns.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.captaindns.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
# Verifica DANE in uscita (smtp)
smtp_dns_support_level = dnssec
smtp_tls_security_level = dane
smtp_tls_loglevel = 1
I due blocchi hanno ruoli diversi: smtpd_tls_* configura il TLS per le connessioni in entrata (il tuo server presenta il suo certificato), mentre smtp_tls_* configura il TLS per le connessioni in uscita (Postfix verifica il TLSA del destinatario).
Ricarica Postfix:
postfix reload
Creare il record TLSA
Scegliere i parametri TLSA
La combinazione consigliata dalla RFC 7672 per SMTP è 3 1 1:
| Campo | Valore | Significato |
|---|---|---|
| Usage | 3 (DANE-EE) | Verifica diretta del certificato del server |
| Selector | 1 (SPKI) | Hash della chiave pubblica (non dell'intero certificato) |
| Matching type | 1 (SHA-256) | Hash SHA-256 |
Il vantaggio del selector SPKI (1): l'hash non cambia quando rinnovi il certificato Let's Encrypt finché la chiave privata resta la stessa. È essenziale per evitare di aggiornare il TLSA a ogni rinnovo.
Generare l'hash TLSA
# Estrarre l'hash SPKI SHA-256 dal certificato
openssl x509 -in /etc/letsencrypt/live/mail.captaindns.com/cert.pem \
-pubkey -noout | \
openssl pkey -pubin -outform DER | \
openssl dgst -sha256 -binary | \
xxd -p -c 64
Il risultato è una stringa esadecimale di 64 caratteri, ad esempio:
a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890
Puoi anche usare il generatore DANE/TLSA CaptainDNS per generare il record senza comandi.
Aggiungere il TLSA nella zona Bind9
Il nome del record TLSA segue il formato _porta._protocollo.hostname. Per la porta 25 (SMTP):
_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890
Aggiungi questa riga al tuo file di zona, incrementa il serial del SOA, poi ricarica:
# Ricaricare la zona (Bind9 firma automaticamente con inline-signing)
rndc reload captaindns.com
Verificare la pubblicazione
# Verificare che il TLSA sia pubblicato e firmato
dig +dnssec _25._tcp.mail.captaindns.com TLSA
# Risultato atteso: il TLSA con le RRSIG
Automatizzare il rinnovo
Questa è la parte critica. Let's Encrypt rinnova il certificato ogni 90 giorni. Se usi DANE-EE con SPKI (3 1 1), l'hash non cambia finché Certbot riutilizza la stessa chiave privata. Ma devi assicurartene e prevedere il caso in cui la chiave cambi.
Strategia di conservazione della chiave
Di default, Certbot genera una nuova chiave a ogni rinnovo. Per conservare la stessa chiave (e quindi lo stesso hash TLSA), aggiungi l'opzione --reuse-key:
# Forzare il riutilizzo della chiave privata
certbot certonly --standalone -d mail.captaindns.com --reuse-key
Oppure aggiungi in /etc/letsencrypt/renewal/mail.captaindns.com.conf:
[renewalparams]
reuse_key = True
Deploy-hook per l'aggiornamento automatico
Anche con --reuse-key, è prudente predisporre un deploy-hook che verifichi l'hash e aggiorni il TLSA se necessario. Crea lo script /etc/letsencrypt/renewal-hooks/deploy/update-tlsa.sh:
#!/bin/bash
# Deploy-hook Certbot: aggiornamento TLSA se l'hash SPKI cambia
DOMAIN="mail.captaindns.com"
ZONE="captaindns.com"
ZONE_FILE="/var/lib/bind/captaindns.com.zone"
CERT="/etc/letsencrypt/live/$DOMAIN/cert.pem"
# Calcolare il nuovo hash SPKI SHA-256
NEW_HASH=$(openssl x509 -in "$CERT" -pubkey -noout | \
openssl pkey -pubin -outform DER | \
openssl dgst -sha256 -binary | \
xxd -p -c 64)
# Recuperare l'hash attuale nel DNS
CURRENT_HASH=$(dig +short _25._tcp.$DOMAIN TLSA | awk '{print $4}')
if [ "$NEW_HASH" != "$CURRENT_HASH" ]; then
echo "TLSA hash changed, updating zone..."
# Sostituire l'hash nel file di zona
sed -i "s/\(IN TLSA 3 1 1 \)[a-f0-9]\{64\}/\1$NEW_HASH/" "$ZONE_FILE"
# Incrementare il serial (formato YYYYMMDDNN)
CURRENT_SERIAL=$(grep -oP '\d{10}' "$ZONE_FILE" | head -1)
NEW_SERIAL=$((CURRENT_SERIAL + 1))
sed -i "s/$CURRENT_SERIAL/$NEW_SERIAL/" "$ZONE_FILE"
# Ricaricare la zona
rndc reload "$ZONE"
echo "TLSA updated: $NEW_HASH"
else
echo "TLSA hash unchanged, no update needed."
fi
# Ricaricare Postfix per applicare il nuovo certificato
postfix reload
Rendi lo script eseguibile:
chmod +x /etc/letsencrypt/renewal-hooks/deploy/update-tlsa.sh
Testare il rinnovo
# Simulare un rinnovo (dry-run)
certbot renew --dry-run
# Forzare un rinnovo reale (per testare l'hook)
certbot renew --force-renewal

Strategia di rollover SPKI (cambio di chiave)
Se devi rigenerare la chiave privata (compromissione, migrazione), pubblica il nuovo TLSA prima di implementare il nuovo certificato. La RFC 7671 raccomanda un periodo di doppia pubblicazione:
- Generare la nuova chiave e calcolare il suo hash SPKI
- Pubblicare entrambi i TLSA nella zona (vecchio + nuovo)
- Attendere la propagazione DNS (minimo 2x TTL)
- Implementare il nuovo certificato
- Rimuovere il vecchio TLSA dopo la propagazione
; Doppio TLSA durante la transizione
_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 <vecchio-hash>
_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 <nuovo-hash>
Verificare la configurazione
Verifica DNS
# Verificare il TLSA
dig +short _25._tcp.mail.captaindns.com TLSA
# Atteso: 3 1 1 <hash-64-chars>
# Verificare DNSSEC
dig +dnssec _25._tcp.mail.captaindns.com TLSA | grep -c "RRSIG"
# Atteso: >= 1
Verifica TLS
# Testare la connessione TLS con verifica TLSA
openssl s_client -connect mail.captaindns.com:25 -starttls smtp \
-dane_tlsa_domain mail.captaindns.com \
-dane_tlsa_rrdata "3 1 1 $(dig +short _25._tcp.mail.captaindns.com TLSA | awk '{print $4}')"
Il risultato deve mostrare Verification: OK e DANE TLSA 3 1 1 matched EE certificate.
Verifica Postfix in uscita
Verifica che Postfix controlli correttamente DANE per le email in uscita:
# Inviare un'email di test e verificare i log
echo "Test DANE" | mail -s "DANE test" test@gmail.com
grep "Verified TLS connection" /var/log/mail.log | tail -5
I log devono menzionare dane nel livello di sicurezza.
Verifica online
Usa il verificatore di sintassi DANE/TLSA CaptainDNS per validare la sintassi del tuo record, poi l'inspector DANE/TLSA per una verifica completa che includa la catena DNSSEC.
Piano d'azione consigliato
Configurare
dnssec-policy defaulteinline-signing yesnella zona Bind9. Pubblicare il DS record presso il registrar. Verificare la catena di fiducia condig +dnssec.Eseguire
certbot certonly --standalone -d mail.captaindns.com --reuse-keyper ottenere il certificato con conservazione della chiave privata.Modificare
main.cfcon i percorsi del certificato (smtpd_tls_*), attivare la verifica DANE in uscita (smtp_dns_support_level = dnssec,smtp_tls_security_level = dane).Generare l'hash SPKI SHA-256 con
openssl, aggiungere il record_25._tcp.mail.captaindns.com. IN TLSA 3 1 1 <hash>nella zona, ricaricare conrndc reload.Creare il deploy-hook
/etc/letsencrypt/renewal-hooks/deploy/update-tlsa.shche confronta gli hash SPKI e aggiorna il TLSA se necessario. Testare concertbot renew --force-renewal.Validare con
dig TLSA,openssl s_client -dane_tlsa_domain, i log Postfix e l'inspector DANE/TLSA CaptainDNS.
FAQ
Come generare un record TLSA per Let's Encrypt?
Usa il comando openssl x509 -in cert.pem -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | xxd -p -c 64 per estrarre l'hash SPKI SHA-256. Il risultato di 64 caratteri esadecimali forma il dato del TLSA con i parametri 3 1 1.
Bisogna aggiornare il TLSA a ogni rinnovo Let's Encrypt?
No, se usi --reuse-key con Certbot e la combinazione DANE-EE/SPKI (3 1 1). L'hash SPKI dipende dalla chiave pubblica, non dal certificato. Finché la chiave privata resta la stessa, l'hash non cambia. Predisponi un deploy-hook di verifica per sicurezza.
Come attivare la verifica DANE in Postfix?
Aggiungi smtp_dns_support_level = dnssec e smtp_tls_security_level = dane in /etc/postfix/main.cf. Postfix verificherà automaticamente i TLSA dei domini destinatari tramite DNSSEC. Se il TLSA è assente o non valido, Postfix torna al TLS opportunistico.
DANE funziona con certificati auto-firmati?
Sì. Con DANE-EE (usage 3), il certificato è validato dal TLSA nel DNS, non da un'autorità di certificazione. Un certificato auto-firmato con un TLSA corretto e una zona DNSSEC valida viene accettato dai server che verificano DANE.
Come testare che DANE sia configurato correttamente?
Tre livelli di verifica: 1) dig +dnssec _25._tcp.mail.captaindns.com TLSA per il DNS, 2) openssl s_client -connect mail.captaindns.com:25 -starttls smtp -dane_tlsa_domain per la corrispondenza certificato/TLSA, 3) l'inspector DANE/TLSA CaptainDNS per un report completo che includa la catena DNSSEC.
Bind è obbligatorio o si può usare un altro server DNS?
Bind9 non è obbligatorio. Qualsiasi server DNS che supporti DNSSEC funziona: NSD, Knot DNS, PowerDNS. I principi sono identici, cambia solo la sintassi di configurazione. Bind9 è usato in questo tutorial perché è il più diffuso sui server Linux e il suo inline-signing semplifica la gestione DNSSEC.
Cosa succede se il TLSA non corrisponde più al certificato?
I server che verificano DANE (come Postfix con dane o Gmail) rifiuteranno di stabilire la connessione TLS e torneranno in modalità non crittografata o rifiuteranno il messaggio secondo la loro policy. Ecco perché la doppia pubblicazione TLSA durante le rotazioni di chiave è essenziale. Se il tuo TLSA è desincronizzato, rimuovilo temporaneamente per tornare al TLS opportunistico il tempo di correggere.
📚 Guide DANE/TLSA correlate
- DANE/TLSA: la guida completa per autenticare i certificati email via DNS: funzionamento, anatomia TLSA, usi consigliati e confronto con MTA-STS
- Troubleshooting DANE/TLSA: diagnosticare e correggere gli errori comuni (in arrivo)
- Implementare DANE per un server Exchange o Microsoft 365 (in arrivo)


