- 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:
qmailapre 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-sendantepone 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-lspawncerca 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-localapre 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
forwardercreato prima, istruisceqmail-sendaffinché 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"
qmailriceve 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-lspawnapre 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 usarevadddomainper creare l'aliasSRS). Siccome l'utente srs non esiste,qmail-lspawndà 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.


