1,998 25/03/2026 07/04/2026 7 min

Un deploy mail può sembrare riuscito e fallire lo stesso lato consegna. Il caso tipico è questo: il server accetta i messaggi, ma finisce in spam o resta in coda.

Qui trovi una mini checklist post-deploy pensata per verificare subito deliverability, header e queue. Lo scenario è concreto: hai appena toccato Postfix, il relay o i record DNS, e vuoi capire se tutto regge prima del traffico reale.

Warning: non fidarti del solo invio locale. Un messaggio “Accepted” non dice nulla su SPF, DKIM, DMARC o reputazione del relay.

Prerequisiti

Serve accesso shell al server SMTP e accesso al DNS del dominio. Devi conoscere almeno:

  • hostname del MTA;
  • dominio mittente;
  • selector DKIM usato in produzione;
  • indirizzo di test esterno, meglio se su Gmail, Outlook o un seed interno.

Installazioni utili:

  • swaks per test SMTP;
  • dig per SPF, DKIM e DMARC;
  • postqueue o mailq per la coda;
  • postcat e grep per leggere gli header dei messaggi in coda;
  • openssl se vuoi validare la catena TLS lato submission.

Note: se usi un relay esterno, controlla anche i limiti del provider. Alcuni accettano il messaggio ma ritardano la consegna per policy o reputazione IP.

Step 1 — Verifica DNS prima di toccare la coda

Perché: SPF, DKIM e DMARC possono sembrare corretti in configurazione locale, ma un record DNS errato rompe tutto in produzione.

Prima controlla i record pubblici. Non andare oltre se qui trovi errori.

dig +short TXT example.com

dig +short TXT selector1._domainkey.example.com

dig +short TXT _dmarc.example.com

# Output:

Devi vedere un record SPF coerente, una chiave DKIM in formato valido e un DMARC presente. Se il TXT DKIM è spezzato male o manca il selector, il firmatario fallisce.

Controllo rapido SPF:

dig +short TXT example.com | tr ' ' '\n' | grep '^v=spf1'

# Output:

Una sola riga con v=spf1 e gli IP o include previsti. Evita catene troppo lunghe. Superare i lookup DNS può far fallire SPF in modo intermittente.

Step 2 — Firma un messaggio di test con swaks

Perché: un invio locale valido non basta. Devi vedere i risultati reali di autenticazione sul messaggio consegnato.

Usa swaks verso la submission del server. Inserisci un destinatario esterno che ti mostri gli header completi.

swaks \
  --to test.destinatario@gmail.com \
  --from postmaster@example.com \
  --server mail.example.com \
  --port 587 \
  --auth LOGIN \
  --auth-user postmaster@example.com \
  --auth-password 'PASSWORD' \
  --tls \
  --header "Subject: Post-deploy deliverability check" \
  --body "Test SPF DKIM DMARC after deploy"

# Output:

Messaggio accettato dal server, con risposta SMTP finale 250. Se compare 5xx o 4xx, fermati e leggi il motivo. Non serve andare avanti con la coda se la submission è già bloccata.

Warning: usa credenziali di test o un account dedicato. Non testare con mailbox operative dell’assistenza se non vuoi sporcare i ticket con falsi positivi.

Step 3 — Leggi gli header ricevuti, non solo il log locale

Perché: il tuo MTA può firmare bene, ma un relay intermedio può riscrivere header, rompere la firma o cambiare il Return-Path.

Apri il messaggio ricevuto e cerca i campi chiave:

  • Received-SPF
  • Authentication-Results
  • DKIM-Signature
  • ARC-Authentication-Results se usi forwarding

Se vuoi fare una verifica lato server su un messaggio in coda, recupera l’ID e ispezionalo.

postqueue -p
postcat -q ABCDEF12345 | sed -n '1,80p'

# Output:

Devi trovare i campi header attesi e un messaggio coerente con il dominio mittente. Se il From è corretto ma il Return-Path no, spesso c’è un rewrite sul relay o sul transport map.

Un esempio sano nei risultati del destinatario è questo:

Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of postmaster@example.com designates 203.0.113.10 as permitted sender) smtp.mailfrom=postmaster@example.com;
       dkim=pass header.i=@example.com;
       dmarc=pass (p=quarantine dis=none) header.from=example.com

# Output:

SPF pass, DKIM pass, DMARC pass. Se uno dei tre fallisce, la deliverability resta fragile anche con inbox placement accettabile su un solo provider.

Step 4 — Controlla la queue e la velocità di svuotamento

Perché: molti problemi di deliverability emergono come accumulo in coda, non come errore immediato.

Osserva il numero di messaggi e lo stato. Una coda che cresce dopo il deploy indica retry, DNS lento, TLS non negoziato o throttling remoto.

mailq
postqueue -p | tail -n +2 | wc -l

# Output:

Un numero basso o in calo. Se i messaggi restano fermi con la stessa età, il problema non è il contenuto: è il trasporto.

Per una lettura più utile, filtra gli errori recenti dal log:

grep -E "status=deferred|status=bounced|warning:|reject:" /var/log/mail.log | tail -n 30

# Output:

Nessun picco di deferred dopo il deploy. Se vedi deferred su tutti i domini esterni, sospetta DNS, TLS o policy di relay.

Step 5 — Valida DMARC con un caso specifico

Perché: DMARC non serve solo a “bloccare spoofing”. Serve a capire se il dominio è allineato con SPF o DKIM.

Prendi un messaggio reale e verifica l’allineamento tra From e il dominio firmato. Un caso tipico: il From usa example.com, ma il DKIM firma mail.example.net. SPF può passare, DMARC no.

Se vuoi un controllo rapido sui record DMARC:

dig +short TXT _dmarc.example.com

# Output:

Un record con policy chiara, ad esempio v=DMARC1; p=quarantine; o p=reject. Se il record è assente, stai volando senza rete.

Note: in fase di rollout puoi partire con p=none e monitorare i report. Dopo la conferma, alza la policy. Non invertire l’ordine.

Step 6 — Fai un test TLS e submission separato dal relay

Perché: molti problemi nascono sul canale 587, non sul 25. Dopo un deploy puoi avere cipher incompatibili o certificati incompleti.

openssl s_client -starttls smtp -connect mail.example.com:587 -servername mail.example.com 

# Output:

Handshake valido, certificato corretto e catena completa. Se il certificato non combacia con l’hostname, alcuni client falliscono in modo silenzioso o degradano su fallback non desiderati.

Per un controllo più pragmatico, verifica il banner e l’ESMTP advertized capabilities:

swaks --server mail.example.com --port 25 --quit-after EHLO

# Output:

Lista capability coerente con la tua configurazione, inclusi STARTTLS e SIZE se previsti.

Verifica finale

Alla fine della checklist, devi avere quattro segnali verdi:

  1. record DNS corretti per SPF, DKIM e DMARC;
  2. messaggio consegnato con SPF pass, DKIM pass, DMARC pass;
  3. queue stabile o in calo;
  4. nessun errore TLS o reject nei log.

Se uno solo di questi manca, non considerare il deploy chiuso. La mail è un sistema a catena. Il punto debole decide la reputazione del dominio.

Un controllo veloce che uso spesso dopo il rilascio è questo:

postqueue -p | sed -n '1,12p'
grep -E "status=deferred|status=bounced" /var/log/mail.log | tail -n 10

# Output:

Queue quasi vuota e nessun errore recente. Se il volume resta fermo, passa alla lettura degli header del destinatario.

Troubleshooting

1) Host or domain name not found. Name service error for name=selector1._domainkey.example.com

Causa: il selector DKIM non esiste o il DNS non è propagato.

Fix:

dig +short TXT selector1._domainkey.example.com
systemctl reload opendkim

# Output:

Il record risponde e il servizio ricarica la chiave senza riavvio completo.

2) status=deferred (SASL authentication failed)

Causa: credenziali submission errate o metodo SASL non allineato al provider.

Fix:

postconf -n | grep -E 'smtp_sasl|smtp_tls'

# Output:

Parametri SASL visibili e coerenti con il relay. Correggi user, password o meccanismo supportato.

3) 550 5.7.1 Message rejected due to local policy

Causa: DMARC fallito, reputazione bassa o envelope non allineato con il From.

Fix:

grep -i "reject" /var/log/mail.log | tail -n 20
postcat -q ABCDEF12345 | grep -E '^(From|Return-Path|DKIM-Signature):'

# Output:

Vedi esattamente quale dominio rompe l’allineamento e puoi correggere il rewriting o la firma.

Conclusione

Una verifica post-deploy fatta bene evita ore di ticket e consegne perse. La combinazione giusta è semplice: DNS corretto, header leggibili, queue pulita.

Il prossimo passo concreto è automatizzare questa checklist con uno script cron o un job di CI che esegua swaks, dig e il controllo della coda dopo ogni rilascio.