TommyBlue.it

DNS e Postfix: come non generare "spam"

Edit (29/01/2010): Aggiunte una correzione per far funzionare la firma DKIM su server di relay

Ho recentemente configurato alcuni server per l’invio di email. Parte del lavoro ha riguardato la corretta configurazione di Postfix e del server DNS per evitare che le email inviate venissero rilevate come spam. In una diversa guida spiegherò come ottimizzare la configurazione di Postfix per grandi quantità  di email (≥1.000.000/mese). Dato che già  in molti me lo hanno chiesto: no, non si tratta di server per l’invio di spam, ma server per il mail marketing (quando il servizio sarà  pubblico potrò tranquillamente rivelarne il nome).

La configurazione ha riguardato tre punti principali:

  • Impostazione del record A e del reverse address
  • Impostazione di SPF
  • Configurazione di DKIM e DomainKeys

Record A e Reverse Address

Per iniziare, il server SMTP deve avere un record DNS di tipo A associato. Quindi, ad esempio:
mailer1.mydomain.com IN A 12.34.56.78
Tale impostazione è a carico del proprietario del dominio mydomain.com (ovvero: voi). Allo stesso tempo bisogna impostare il DNS inverso per una corretta risoluzione: infatti il server che riceverà  una mail dall'ip 12.34.56.78, che dice di essere mailer1.mydomain.com, vorrà  avere riscontro di tale associazione IP<=>Dominio. Effettuerà  quindi una risoluzione DNS inversa che, nel caso in esempio, dovrà  restituire mailer1.mydomain.com. Questa configurazione è a carico del fornitore della connettività  e dell'ip, generalmente coloro che vi forniscono l'hosting.

Per verificare la corretta configurazione basta usare dig:

~$ dig +short mailer1.mydomain.com
12.34.56.78 

~$ dig +short -x 12.34.56.78
mailer1.mydomain.com.

Sender Policy Framework

Sender Policy Framework abbreviato in SPF è un metodo per limitare gli abusi del nome del mittente nei messaggi di posta elettronica. Si tratta di un protocollo tramite il quale è possibile definire da dove viene spedita la posta elettronica per una certa classe di mittenti. (WikiPedia)
Sebbene non nuovissimo, SPF è largamente utilizzato e una sua corretta configurazione permette già  una certa sicurezza nel fatto che le mail inviate non vengano riconosciute come spam. Si tratta semplicemente di impostare un record DNS di tipo TXT indicante quali server sono autorizzati ad inviare email per tale dominio.

Le configurazioni possibili sono molte (potete consultarle nell'RFC 4404), nel nostro caso il record potrebbe essere:

v=spf1 mx ip4:12.34.56.78 ~all

Oltre alla versione (v=spf1), indica che gli host con associato un record MX per il dominio, oltre al server con ip 12.34.56.78, possono inviare email. Inoltre indica, con ~all, che tale configurazione comprende tutti i possibili host che inviano email per il dominio.

Potete utilizzare questo tool per creare i vostri record SPF.

DKIM e DomainKeys

DomainKeys e DKIM sono due sistemi per la verifica del mittente nel dominio e l'integrità  del messaggio. Entrambi utilizzano il sistema a chiave pubblica/privata: la chiave pubblica è distribuita in un record DNS e la chiave privata viene utilizzata dal server SMTP per firmare l'email prima del suo invio. DomainKeys è nata in casa Yahoo (che, tra i grandi ISP, è l'unica che lo utilizza, a quanto ne so), DKIM (DomainKeys Identified Mail) è la sua evoluzione.

Nel mio caso uno tra i requisiti del server è quello di permettere la personalizzazione dei campi From e Reply-To mentre il collegamento col server di invio è rappresentato dal campo Return-Path valorizzato con il dominio del server. Data la difficoltà  nell’impostare DomainKeys con tale configurazione e data la sua scarsa diffusione, mi sono intanto limitato alla configurazione di DKIM per la quale ho seguito questa guida con alcune modifiche.

Si inizia installando dkim-filter:

~$ sudo apt-get install dkim-filter

e generando le chiavi per il server con l’apposito tool

~$ dkim-genkey -s mailer1 -d mydomain.com -t

Dopo questo comando nel file mailer1.private vi sarà  la chiave privata mentre nel file mailer1.txt una possibile configurazione per il record DNS:

mailer1._domainkey IN TXT "v=DKIM1; g=*; k=rsa; t=y; p=MIGfMA0GC[...cut...]8FsXOPbuUQIDAQAB" ; ----- DKIM mailer1 for mydomain.com

Sebbene questo record sia corretto, le opzioni sono molte e consiglio un’attenta lettura degli RFC (linkati sulla pagina dedicata di WikiPedia), in particolare potreste essere interessati a modificare “t=y;” in “t=;” dichiarando che il servizio di firma non è in fase di test. A tale record consiglio di aggiungerne un secondo, più generale:

_domainkey.mydomain.com. IN TXT "o=~"

che indica che non tutte le email generate dal dominio vengono firmate (l’alternativa è “o=-").

A questo punto si prosegue con la configurazione del file /etc/default/dkim-filter. Basta decommentare una delle righe che specificano un socket. Io ho scelto di utilizzare:

SOCKET="inet:20209@localhost"

Proseguiamo quindi con /etc/dkim-filter.conf. Riporto tutte le configurazioni fatte, ricordandovi che tale configurazione è studiata per permettere la personalizzazione dei campi From e Reply-To (e quindi una sorta di configurazione multidominio):

Syslog                  yes
SyslogSuccess           yes
UMask                   022
UserID                  dkim-filter:dkim-filter
Socket                  inet:20209@localhost
Domain                  *
Selector                mailer1
AutoRestart             yes
Background              yes
Canonicalization        simple
DNSTimeout              5
Mode                    sv
SignatureAlgorithm      rsa-sha1
SubDomains              no
X-Header                yes
Statistics              /var/log/dkim-filter/dkim-stats
AllowSHA1Only           no
AlwaysAddARHeader       no
AutoRestartRate         10/1h
Canonicalization        simple/simple
KeyList                 /etc/mail/dkim/keylist
MTA                     MSA
On-Default              reject
On-BadSignature         reject
On-DNSError             tempfail
On-InternalError        accept
On-NoSignature          accept
On-Security             discard
PidFile                 /var/run/dkim-milter/dkim-milter.pid
RemoveOldSignatures     yes

Il file /etc/mail/dkim/keylist contiene:

*:mydomain.com:/etc/mail/dkim/keys/mydomain.com/mailer1

mentre il file /etc/mail/dkim/keys/mydomain.com/mailer1 contiene la chiave privata, ovvero il file mailer1.private precedentemente creato, spostato in una cartella adatta e con i giusti permessi:

~$ mv mailer1.private /etc/mail/dkim/keys/mydomain.com/mailer1
~$ chmod 600 /etc/mail/dkim/keys/mydomain.com/mailer1
~$ chown dkim-filter:dkim-filter /etc/mail/dkim/keys/mydomain.com/mailer1

Se il server di invio email riceverà  email da altri server (di cui è quindi un relayhost) sarà  necessario specificare quali sono i server “fidati”. Quindi nel file /etc/dkim-filter.conf bisogna aggiungere:

InternalHosts           /etc/mail/dkim/trusted-hosts

e bisogna creare il file /etc/mail/dkim/trusted-hosts contenente (uno per linea) gli indirizzi ip dei server (attenzione che contenga anche l’indirizzo ip di localhost, 127.0.0.1).

Per concludere è necessario configurare Postfix per firmare le email, aggiungendo nel file /etc/postfix/main.cf:

smtpd_milters = inet:localhost:20209
non_smtpd_milters = inet:localhost:20209
milter_protocol = 2
milter_default_action = accept

Adesso basta far partire i due demoni e si può provare ad inviare una email:

~$ sudo /etc/init.d/dkim-filter start
~$ sudo /etc/init.d/postfix start
~$ echo "Questa email è una prova" | mail -a "From: qualcosa@miodominio.it" -a "Reply-To: dilloame@dominio.it" -s "Email di test" recipient@dominioricevente.it -- -f mailer1@mydomain.com

In /var/log/mail.log potete verificare l’avvenuta firma:

Jan 18 00:26:35 mailer1 dkim-filter[21178]: XXXXXXXXXX "DKIM-Signature" header added

Se inviate la mail a un dominio yahoo.com o gmail.com potete verificare subito se la firma ha avuto successo. Ad esempio ecco l’header di una mail ricevuta da Yahoo:

Authentication-Results: mta1169.mail.mud.yahoo.com  from=miodominio.it; domainkeys=neutral (no sig); from=mydomain.com; dkim=pass (ok)

Questa prima guida è conclusa. Spero di riuscire a trovare a breve una soluzione per la configurazione di DomainKeys in modo da poter integrare questo articolo