Perché conta
Il modello di fiducia TLS classico è “tutti i browser e sistemi operativi accettano circa 150 Certification Authority, e ciascuna può emettere un certificato valido per qualsiasi dominio”. Basta che una sola CA venga compromessa, costretta da un governo o semplicemente commetta un errore di validazione — è successo più volte, da DigiNotar nel 2011 a diversi incidenti minori registrati nei log di Certificate Transparency — perché un attaccante ottenga un certificato illegittimo per il tuo nome. Certificate Transparency aiuta a scoprirlo dopo, ma non impedisce che un client accetti quel certificato nel frattempo.
DANE (RFC 6698) attacca il problema da un’altra direzione: pubblica l’ancora di fiducia direttamente nel DNS,
sotto forma di record TLSA, e protegge quel record con DNSSEC. Chi controlla
le firme DNSSEC della tua zona — tu — decide quali certificati sono legittimi per il tuo nome, indipendentemente
da quante CA esistono nel mondo.
Come funziona
Un record TLSA vive sotto un nome speciale che codifica porta e protocollo, nella forma
_porta._protocollo.host. Per HTTPS su www.example.com:
|
|
Quattro campi dopo il tipo:
- Usage (0–3):
0/1validano anche tramite la PKI pubblica (CA constraint / certificate pinning classico),2/3ignorano le CA e si fidano solo del DNS (3è il più comune: DANE-EE, pinning diretto della chiave del certificato end-entity). - Selector (0–1):
0pinna il certificato intero,1solo la sua chiave pubblica (SubjectPublicKeyInfo) — utile perché la chiave può restare la stessa attraverso un rinnovo del certificato. - Matching type (0–2):
0dato raw,1SHA-256,2SHA-512 del campo selezionato. - Dati di associazione: l’hash (o il dato raw) da confrontare con quanto il server presenta in TLS.
Un client DANE-aware fa due verifiche indipendenti:
sequenceDiagram
participant C as Client
participant R as Resolver DNSSEC
participant S as Server TLS
C->>R: TLSA _443._tcp.www.example.com?
R-->>C: record TLSA + firme RRSIG valide
C->>S: TLS handshake
S-->>C: certificato presentato
Note over C: calcola hash(selector) del certificato ricevuto
alt hash coincide con TLSA e catena DNSSEC valida
C->>C: connessione fidata
else hash diverso o DNSSEC non valido
C->>C: rifiuta la connessione
end
Senza DNSSEC il meccanismo non vale nulla: un attaccante on-path potrebbe falsificare sia il certificato che il record TLSA. È per questo che DANE è, di fatto, un’applicazione di DNSSEC — non un’alternativa a esso.
Il limite: dove DANE non arriva
DANE non è un “attacco” da dimostrare con un exploit: è un meccanismo di difesa, e il suo punto debole è
operativo, non un bug sfruttabile. Il problema principale è l’adozione lato client: nessun browser maggiore
(Chrome, Firefox, Safari) verifica TLSA per HTTPS, per scelta di design — i proponenti di Chrome e Firefox
hanno ritenuto DNSSEC troppo fragile come unico fattore di fiducia su scala globale, dopo discussioni pubbliche
durate anni. DANE per HTTPS resta quindi un controllo che solo strumenti dedicati (openssl, kdig, librerie
come getdns) verificano davvero.
Dove DANE è invece ampiamente operativo è SMTP (RFC 7672): molti grandi provider di posta (tra cui diversi
operatori .de e .nl, oltre a Mailbox.org e Posteo) pubblicano TLSA per i propri MX e, quando un mittente
lo supporta, rifiutano la consegna in chiaro o verso un server che presenta un certificato diverso da quello
pinnato — mitigando il downgrade a cui SMTP opportunistico (STARTTLS senza verifica) è altrimenti esposto, e
che un attaccante on-path può forzare semplicemente rimuovendo l’annuncio STARTTLS in transito.
Per verificare se un MX pubblica TLSA, senza bisogno di alcun exploit, basta interrogare il DNS:
|
|
La difesa (ovvero: come attivarlo)
1. Firmare la zona con DNSSEC. Prerequisito assoluto; senza questo passo i record TLSA sono inutili e
anzi un falso senso di sicurezza. La maggior parte dei DNS hosting (Cloudflare, Route 53, PowerDNS, BIND con
dnssec-policy) lo attiva con un comando o una casella di spunta.
2. Generare e pubblicare il record TLSA. Con OpenSSL, per il certificato end-entity usato da un MX:
|
|
Usare selector 1 (chiave pubblica, non certificato intero) e pubblicare due record TLSA — uno per la chiave corrente e uno per quella del prossimo rinnovo — evita l’interruzione di servizio nella finestra tra rinnovo del certificato e propagazione del nuovo TLSA (RFC 7671 ne parla esplicitamente).
3. Attivare la verifica DANE lato Postfix, per chi invia posta verso domini che la pubblicano:
|
|
Le righe evidenziate: smtp_dns_support_level = dnssec impone che le risposte DNS usate per il TLS siano
validate DNSSEC (altrimenti Postfix non alza mai il livello di sicurezza a dane); smtp_tls_security_level = dane dice a Postfix di cercare un TLSA per il destinatario e, se lo trova, di autenticare solo tramite
quello (bypassando la PKI pubblica); se il domino di destinazione non pubblica TLSA, Postfix ricade comunque
su TLS opportunistico, quindi l’attivazione non rompe la consegna verso chi non supporta DANE.
Si verifica l’esito nei log con postconf -n più grep dane /var/log/mail.log, oppure inviando un test con
swaks --tls ... -s mx.example.com.
Lab
Obiettivo: generare manualmente il record TLSA per un certificato locale e verificarlo con openssl, simulando
cosa farebbe un client DANE.
- Genera un certificato self-signed di prova:
1 2openssl req -x509 -newkey rsa:2048 -nodes -keyout test.key -out test.crt \ -days 30 -subj "/CN=test.example.com" - Calcola l’hash SHA-256 della sua chiave pubblica (selector 1, matching type 1):
1 2openssl x509 -in test.crt -noout -pubkey | openssl pkey -pubin -outform DER \ | openssl dgst -sha256 -hex - Avvia un listener TLS con quel certificato:
1openssl s_server -accept 8443 -cert test.crt -key test.key -www - Da un altro terminale, connettiti e recupera il certificato effettivamente presentato, poi confronta il suo hash con quello calcolato al passo 2: se coincidono, un client DANE con quel TLSA accetterebbe la connessione.
Domanda: cosa succede, concettualmente, se rinnovi il certificato (nuova chiave) ma non aggiorni il TLSA prima della propagazione DNS? E perché pubblicare due TLSA risolve il problema?
Soluzione
Finché il DNS serve ancora il vecchio TLSA ma il server presenta già il nuovo certificato, l'hash calcolato dal client non coincide più con quello pubblicato: ogni client DANE-aware rifiuta la connessione, anche se il certificato è perfettamente valido per la PKI pubblica. È un'interruzione di servizio autoinflitta, non un attacco. Pubblicare in anticipo due record TLSA — quello della chiave attuale e quello della chiave che verrà usata dopo il prossimo rinnovo — elimina la finestra di rottura: qualunque dei due certificati il server presenti, uno dei due TLSA coincide sempre. RFC 7671 raccomanda esplicitamente questo schema a "rotazione sovrapposta" per chiunque automatizzi il rinnovo dei certificati (ad esempio con Let's Encrypt via ACME) e voglia usare DANE in produzione.
Conclusione
DANE non sostituisce la PKI pubblica né Certificate Transparency: li completa, spostando l’ancora finale di fiducia da “una qualunque tra 150 CA” a “chi controlla le firme DNSSEC della zona”. Il prezzo è un prerequisito pesante (DNSSEC configurato e mantenuto correttamente) e un’adozione lato client quasi nulla per HTTPS. Per SMTP invece, dove TLS è spesso solo opportunistico e quindi facilmente degradabile da chi sta on-path, DANE è oggi uno dei pochi strumenti che rende quel downgrade rilevabile e, per i mittenti che lo rispettano, bloccante.
Articoli correlati: Certificate Transparency · TLS in profondità · DNS tunneling detection