- open-spf.org
- Sito
libsrs2
- Patch per qmail di Marcelo Coelho
SPF è in conflitto con il reindirizzamento delle email. SRS è un metodo che consente di risolvere questo problema mediante la riscrittura degli indirizzi email.
NB: Se si è effettuata 'configurazione rapida' basata sullo script config-all
, il sistema SRS è stato già configurato. E' solo necessario tener presente che il dominio srs_domain coincide con il dominio in control/me domain, ovvero il nome della propria MTA.
Configurazione
Configurare srsfilter
in modo tale che il programma sia lanciato ogni qual volta viene ricevuto un messaggio per l'utente srs:
echo "| /var/qmail/bin/srsfilter" > /var/qmail/alias/.qmail-srs-default
Quindi creare e configurare un dominio virtuale da usare esclusivamente per l'SRS
. Si tenga presente questo dominio virtuale non deve essere creato, come siamo abituati a fare, dal programma vadddomain
, poichè esso ha il solo scopo di lanciare srsfilter
attraverso l'account fittizio alias/.qmail-srs-default che abbiamo creato prima. Notare la differente sintassi di questa linea nel file virtualdomains rispetto ai domini virtuali regolari:
echo srs.mydomain.tld:srs >> /var/qmail/control/virtualdomains
Quell'srs
dopo i due punti :
sarà usato da qmail-local
come un prefisso negli indirizzi locali associati a srs.mydomain.tld e sarà gestito da .qmail-srs-default, dal momento che nessun altro utente srs esiste. Per esempio:
2023-06-20 22:55:51.265166500 starting delivery 62: msg 32560286 to local srs-SRS0=jiQ3=CI=gmail.com=sender@srs.mydomain.tld
Fare riferimento alla "bibbia" Life With Qmail
per comprendere meglio la logica sottostante, specialmente per quanto concerne i concetti relativi a virtual domains, aliases, .qmail
e extensions addresses
.
Aggiungere srs.mydomain.tld
a rcpthosts di modo che qmail-smtpd
sappia che deve spedire localmente i messaggi per quel dominio. Non aggiungerlo al file control/locals altrimenti il file virtualdomains sarà ignorato e srsfilter
non verrà lanciato.
echo srs.mydomain.tld >> /var/qmail/control/rcpthosts
Porre srs.mydomain.tld nel file srs_domain
, di modo che srsfilter
lo utilizzi nella riscrittura degli indirizzi per tutti i domini virtuali. Creare anche il file srs_secret
. E' una stringa casuale che serve a generare e controllare gli indirizzi SRS
.
echo srs.mydomain.tld > /var/qmail/control/srs_domain echo "xxxxxxxxxxxxxxxxxxxxxx" > /var/qmail/control/srs_secrets
Queste sono le uniche impostazioni obbligatorie; vedere i link in testa a questa pagina per avere informazioni riguardanti gli altri parametri che è possibile impostare.
Naturalmente è necessario dotare, nel proprio DNS
, il dominio srs_domain
appena creato di un record MX
valido e anche di un record SPF
come il seguente:
srs.mydomain.tld. IN TXT "v=spf1 a mx -all"
E' anche necessario configurare i record DKIM
e DMARC
per il dominio srs.mydomain.tld. Questo per soddisfare le politiche di google, che è uno dei provider più stringenti.
Inoltre, dovremmo aver già creato un analogo record SPF
anche per il dominio che compare in control/me. Se non lo si è ancora fatto, sarà bene farlo ora.
Possiamo ora riavviare qmail
e testare il nostro sistema SRS
.
Test
Andremo a testare la capacità del nostro sistema SRS
di riscrivere gli indirizzi nel caso estremo di un forwarder
non funzionante. Useremo un account gmail.com come mittente originale, dal momento che gmail è noto per essere un provider molto restrittivo e con un sistema anti spam efficientissimo.
In ciò che segue mydomain.tld è un dominio virtuale nello stesso server dove abbiamo configuraro SRS
, srs.mydomain.tld è il dominio SRS
definito in control/srs_domain, sender@gmail.com è il mittente originale del messaggio, mentre fake@remotedomain.tld è l'account inesistente ove il forwarder
dovrebbe reindirizzare la posta che gli viene recapitata. Naturalmemnte essa verrà respinta e la nostra MTA
dovrà eseguire la riscrittura (attraverso il programma srsfilter
) e notificare il mittente originale senza violare le regole SPF
.
Creare un forwarder
nel proprio server, tale che i messaggi verso srstest@mydomain.tld siano reindirizzati a fake@remotedomain.tld:
echo "&fake@remotedomain.tld" > ~vpopmail/domains/mydomain.tld/.qmail-srstest chown vpopmail:vchkpw ~vpopmail/domains/mydomain.tld/.qmail-srstest chmod 600 ~vpopmail/domains/mydomain.tld/.qmail-srstest
Nel server remotedomain.tld, disabilitare chkuser
nel proprio run file (commentare CHKUSER_START=ALWAYS
) e impostare il file .qmail-default del dominio remotedomain.tld in modo che i messaggi per le mailbox inesistenti non vengano cancellati, ma respinti
|~vpopmail/bin/vdelivermail '' bounce-no-mailbox
Dal momento che fake@remotedomain.tld è un destinatario inesistente, remotedomain.tld ci rimanderà indietro il messaggio, e noi dovremo informare sender@gmail.com in accordo con le regole SRS
, dopo la riscrittura dell'indirizzo.
Vediamo il viaggio di questo messaggio nella rete
Questo invece è ciò che si vede dai nostri log di qmail
.
1. qmail-smtpd
riceve e accetta il messaggio dal mittente orginale
2023-06-20 22:54:52.607641500 tcpserver: pid 16574 from 209.85.128.49 2023-06-20 22:54:52.627258500 tcpserver: ok 16574 smtp.mydomain.tld:10.0.0.4:25 mail-wm1-f49.google.com:209.85.128.49::44523 2023-06-20 22:55:13.058900500 qlogenvelope: result=accepted code=250 reason=rcptto detail=chkuser helo=mail-wm1-f49.google.com mailfrom=sender@gmail.com rcptto=srstest@mydomain.tld <---- questo è il forwarder ................ qp= pid=16574
2. qmail-send
passa il messaggio al forwarder
srstest@mydomain.tld
2023-06-20 22:55:19.493086500 info msg 32560286: bytes 3377 from <sender@gmail.com> qp 16615 uid 89 2023-06-20 22:55:19.493086500 starting delivery 60: msg 32560286 to local mydomain.tld-srstest@mydomain.tld <---- qmail converte srstest@mydomain.tld in mydomain.tld-srstest@mydomain.tld e tratta il risultato come se mydomain.tld fosse un indirizzo locale 2023-06-20 22:55:19.493087500 status: local 1/10 remote 0/20 2023-06-20 22:55:19.495105500 delivery 60: success: did_0+1+0/qp_16617/
Vediamo un po' più in dettaglio le cose:
qmail
apre il file control/virtualdomains alla ricerca di una riga relativa al dominio destinatario ovvero mydomain.tld. Ecco il contenuto di quella riga:mydomain.tld:mydomain.tld
Ora, i due campi prima e dopo i : non sono affatto un doppione. Quello alla sinistra è il dominio, mentre quello alla destra è l'utente il cui file .qmail andrà a gestire i messaggi per quel dominio.qmail-send
antepone il campo alla destra dei due punti:
all'indirizzo destinatario, che diventa quindi mydomain.tld-srstest@mydomain.tld, e tratta mydomain.tld come un indirizzo locale a cui recapitare il messaggio.qmail-lspawn
cerca l'utente mydomain.tld (tecnicamente è un semplice utente, prima ancora che un dominio) nel file users/assign (in realtà la sua versione compilata users/cdb) trovando qualcosa del genere:+mydomain.tld-:mydomain.tld:89:89:/home/vpopmail/domains/mydomain.tld:-::
e ne ricava la cartella home, che in questo esempio è /home/vpopmail/domains/mydomain.tld.qmail-local
apre dunque la cartella home e cerca il file srstest/.qmail che dovrà gestire la spedizione del messaggio (delivery). Se non lo trova cercherà nell'ordine un file ~mydomain.tld/.qmail-srstest e infine un file ~mydomain.tld/.qmail-default.- Nel nostro caso esiste il file .qmail-srstest e, trattandosi del
forwarder
creato prima, istruisceqmail-send
affinché giri il messaggio a qualcun alttro.
3. L'indirizzo del primo mittente viene riscritto in SRS0=jiQ3=CI=gmail.com=sender@srs.mydomain.tld e il messaggio spedito al server remoto da qmail-remote
2023-06-20 22:55:19.495905500 info msg 32560301: bytes 3491 from <SRS0=jiQ3=CI=gmail.com=sender@srs.mydomain.tld> <----- il controllo SPF, se effettuato, sarebbe soddisfatto qp 16617 uid 89 2023-06-20 22:55:19.495918500 starting delivery 61: msg 32560301 to remote fake@remotedomain.tld 2023-06-20 22:55:19.495920500 status: local 0/10 remote 1/20 2023-06-20 22:55:23.822750500 delivery 61: success: <From:SRS0=jiQ3=CI=gmail.com=sender@srs.domain.tld_To:fake@remotedomain.tld>_<remoteip>_accepted_message./Remote_host_said:_25>
4. qmail-smtpd
riceve il messaggio di rifiuto (bounce, in realtà nel caso il server remoto abbi la teconologia SRS
esso sarà lui stesso in grado di inviare il messaggio di rifiuto a gmail.com senza passare per mydomain.tld)
2023-06-20 22:55:24.049537500 tcpserver: pid 16687 from <remoteip> 2023-06-20 22:55:24.049945500 tcpserver: ok 16687 smtp.mydomain.tld:10.0.0.4:25 <remoteip>.<remotehost>:<remoteip>::37391 2023-06-20 22:55:44.826126500 qlogenvelope: result=accepted code=250 reason=rcptto detail=chkuser helo=<remotehelo> mailfrom= <------ null sender, dato che si tratta di un messaggio di sistema rcptto=SRS0=jiQ3=CI=gmail.com=sender@srs.mydomain.tld <------- il destinatario ha il dominio definito in srs_domain ................. qp= pid=16687
5. qmail-send
spedisce il bounce all'indirizzo locale SRS0=jiQ3=CI=gmail.com=sender@srs.mydomain.tld, che ha il dominio SRS
che noi abbiamo legato a srsfilter
2023-06-20 22:55:51.265166500 info msg 32560286: bytes 5688 from <> <------- null sender, l'SPF è soddisfatto qp 16716 uid 89 2023-06-20 22:55:51.265166500 starting delivery 62: msg 32560286 to local srs-SRS0=jiQ3=CI=gmail.com=sender@srs.mydomain.tld <------- il prefisso srs fa in modo che il messaggio sia gestito dall'account srs di default, che a sua volta lancerà srsfilter 2023-06-20 22:55:51.265167500 status: local 1/10 remote 0/20 2023-06-20 22:55:51.270712500 delivery 62: success: srsfilter:_qp_16720/did_0+0+1/ <------- srsfilter in azione... lui sa cosa fare di quell'indizzo
Anche qui è necessario mettere bene a fuoco cosa succede "dietro le quinte"
qmail
riceve un messaggio per un utente del dominio srs.mydomain.tld e controlla la presenza di una riga che il campo srs.mydomain.tld alla sinistra dei due punti:
nel file virtualdomains:srs.mydomain.tld:srs
- La parte alla destra dei due punti
:
viene anteposto all'indirizzo locale del ricevente, che diventa quindi srs-SRS0=jiQ3=CI=gmail.com=sender@srs.mydomain.tld, che ha ora ha il prefisso srs. Questo prefisso rappresenta l'utente il cui file .qmail dovrà gestire la spedizione del messaggio. qmail-lspawn
apre il file users/assign (in realtà la sua versione compressa users/cdb) alla ricerca di una riga che abbia srs nel primo campo ma non lo trova, dato che non abbiamo un utente srs (e questo è il motivo per cui abbiamo evitato di usarevadddomain
per creare l'aliasSRS
). Siccome l'utente srs non esiste,qmail-lspawn
dà il controllo del messaggio ad alias ed esegueqmail-local
.- Dato che non esiste alcun utente srs, viene cercato un alias alias/.qmail-srs, che non viene nemmeno trovato. In ultimis viene individuato il file alias/.qmail-srs-default, che funge da file .qmail deputato alla gestione del messaggio.
- Il file alias/.qmail-srs-default contiene le istruzioni per lanciare
srsfilter.
srsfilter
è in grado di "smontare" l'indirizzo SRS0=jiQ3=CI=gmail.com=sender@srs.mydomain.tld per ricavare l'indirizzo del destinatario ultimo, che sarà sender@gmail.com.
6. qmail-send
spedisce il bounce al mittente originale, il campo mailfrom
è il null sender <>
2023-06-20 22:55:51.271507500 info msg 32560301: bytes 5707 from <> <------ null sender qp 16720 uid 1000 2023-06-20 22:55:51.271507500 starting delivery 63: msg 32560301 to remote sender@gmail.com 2023-06-20 22:55:51.271508500 status: local 0/10 remote 1/20 2023-06-20 22:55:51.915441500 delivery 63: success: <From:_To:sender@gmail.com>_74.125.133.26_accepted_message./Remote_host_said:_250_2.0.0_OK__1687294551_f7-20020adff8c700000>
e gmail mostrerà un controllo SPF
avvenuto con successo. Questa la parte importante dell'intestazione così come viene vista da sender@gmail.com:
Si noti come il controllo SPF
sia stato fatto su smtp.mydomain.tld,
ovvero il dominio contenuto in control/me, dato che il messaggio verso il mittente originale è stato spedito dal null sender <>
. Questo dominio è stato recuperato dall'HELO
. Questa è la ragione per cui dobbiamo definire un record SPF
anche per il dominio posto in control/me.
Il bounce che abbiamo reindirizzato ha il campo From: postmaster@smtp.remotedomain.tld
. Come si può notare, l'indirizzo è stato ricavato dai file control/bouncefrom e control/bouncehost.