Table of Contents

SPF check con Postfix

Installare il pacchetto Debian postfix-policyd-spf-python. Secondo quanto riportato dal sito openspf.org l'implementazione Python è tecnicamente superiore a quella Perl.

Secondo le specifiche Sender Policy Framework si possono effettuare dei controlli di validità durante una sessine SMTP verificando il contenuto dei comandi HELO/EHLO e MAIL FROM.

Per implementare il check SPF su MAIL FROM si deve aggiungere al DNS un record di tipo TXT relativamente al dominio mittente, un esempio per il dominio example.org:

example.org.  IN  TXT  "v=spf1 a:mail.example.org -all"

Per implementare il check SPF su HELO/EHLO si deve anzitutto configurare correttamente il comando HELO sul server di posta che invia i messaggi, supponendo che il comando sarà EHLO mail.example.org e che un record di tipo A sia correttamente configurato per quel nome, si deve aggiungere un record TXT del tipo:

mail.example.org.  IN  TXT  "v=spf1 a -all"

ATTENZIONE! Nei record TXT è necessario specificare il nome esatto del dominio e quello dell'host, inoltre il nome dell'host deve avere un corrispondente record di tipo A (IPv4) ed eventualmente di tipo AAA (IPv6). Non è possibile definire i nome dell'host con un CNAME poiché il software Bind non accetta che un CNAME coesista con altri record, in questo caso un TXT.

Configurazione

Il file di configurazione del programma è /etc/postfix-policyd-spf-python/policyd-spf.conf.

debugLevel = 2
TestOnly = 1
HELO_reject = Fail
Mail_From_reject = Fail
PermError_reject = False
TempError_Defer = False
skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0/104,::1

Il parametro HELO_reject determina il comportamento durante il check di HELO/EHLO, l'impostazione predefinita Fail significa che il reject avviene solo nel caso di SPF Fail, cioè di una situazione esplicitamente vietata. Si può essere più restrittivi con l'opzione SPF_Not_Pass, in tal caso il reject avviene anche nei casi di Softfail (weak statement, ad esempio la clausola ~all), Neutral (il DNS fornisce informazioni, ma vuote) e PermError (es. record SPF non valido).

L'impostazione predefinita prevede il log su /var/log/syslog.

Attenzione al parametro TestOnly che fa esattamente il contrario di quello che si intuisce! Impostando TestOnly = 1 significa che il filtro è attivo (restituisce a Postfix il codice dell'azione da intraprendere), invece con un valore zero si ha solo il log del risultato, ma nessuna azione conseguente.

Attenzione che il reload o il restart del servizio dopo aver cambiato configurazione non esiste, in quanto il processo viene avviato da Postfix solo quando necessario (vedi più avanti la configurazione). Pertanto in caso di variazione della configurazione è necessario fare il restart di Postfix.

Manual Testing

Per verificare il funzionamento del programma con la configurazione corrente è sufficiente eseguire da linea di comando policyd-spf, sullo standard input si forniscono alcune righe che caratterizzano un messaggio di posta, seguite da una riga vuota:

request=smtpd_access_policy
protocol_state=RCPT
protocol_name=ESMTP
helo_name=testhost.rigacci.org
queue_id=8045F2AB23
instance=12345.6789
sender=test.sender@rigacci.org
recipient=test.recipient@rigacci.org
client_address=192.222.46.168
client_name=testhost.rigacci.org

il programma risponde con qualcosa del tipo:

action=550 5.7.23 Message rejected due to: SPF fail - not authorized.
    Please see http://www.openspf.net/Why?s=mfrom;id=...

L'invocazione da riga di comando risponde ad una sola richiesta.

IPv6 e record AAAA

Nei record SPF è possibile indicare direttamente anche degli indirizzi IPv6, usando la sintassi ip6:2a01:4f8:d16:1355::2. Più comodo è indicare il nome di un host, con la sintassi a:testhost.rigacci.org si includono automaticamente tutti i record di tipo A (IPv4) e di tipo AAAA (IPv6) associati al nome. Nel test del paragrafo precedente è possibile specificare un indirizzo IPv6 come client_address.

Problema recort TXT ed helo_name

ATTENZIONE! Per motivi non chiari il programma policyd-spf richiede il record TXT di helo_name prima di richidere quello del dominio del sender. Se tale record esiste, viene utilizzato il suo contenuto SPF per controllare l'indirizzo IP di client_address.

Per questo motivo - quando si configura un server di posta - è opportuno controllare l'helo_name: se ad esso è associato un record TXT, questo deve includere l'indirizzo IP che verrà usato come client_address.

Ad ogni modo - dopo che policyd-spf ha controllato la corrispondenza fra SPF di helo_name e client_address - verrà fatto anche il controllo tra SPF del dominio di sender e il client_address.

Configurazione di Postfix

Anzitutto si configura Postfix in modo che attivi uno Unix socket collegato al programma policyd-spf; nel file di configurazione /etc/postfix/master.cf si deve aggiungere:

policyd-spf  unix  -       n       n       -       0       spawn
  user=policyd-spf argv=/usr/bin/policyd-spf

Il socket viene creato in /var/spool/postfix/private/policyd-spf. Si deve quindi configurare Postfix per aggiungere il controllo SPF alle smtpd_recipient_restrictions, di solito subito dopo il reject_unauth_destination. Nel file /etc/postfix/main.cf si imposta:

smtpd_recipient_restrictions =
        permit_sasl_authenticated,
        permit_mynetworks,
        ...
        reject_unauth_destination,
        check_policy_service unix:private/policyd-spf

Il programma policyd-spf non viene eseguito immediatamente, ma quando necessario; cioè quando viene ricevuto un messaggio da controllare. In quel momento risulterà un processo a nome dell'utente postfix del tipo:

spawn -z -n policyd-spf -t unix user=policyd-spf argv=/usr/bin/policyd-spf

inoltre a nome dell'utente policyd risulta:

/usr/bin/python3 /usr/bin/policyd-spf

Web References