Configurare il Sender Rewriting Scheme (SRS) su qmail

10 luglio 2023 by Roberto Puzzanghera 0 commenti

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, .qmailextensions addresses.

Aggiungere srs.mydomain.tldrcpthosts 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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. Nel nostro caso esiste il file .qmail-srstest e, trattandosi del forwarder creato prima, istruisce qmail-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"

  1. 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
  2. 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.
  3. 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 usare vadddomain per creare l'alias SRS). Siccome l'utente srs non esiste, qmail-lspawn dà il controllo del messaggio ad alias ed esegue qmail-local.
  4. 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.
  5. Il file alias/.qmail-srs-default contiene le istruzioni per lanciare srsfilter.
  6. 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:

Delivered-To: sender@gmail.com
[...]
Return-Path: <> Received: from smtp.mydomain.tld (smtp.mydomain.tld. [94.23.219.84]) by mx.google.com with ESMTPS id v28-20020a5d591c000000b0030e57d7da1dsi2291075wrd.363.2023.06.21.00.15.28 for <sender@gmail.com> [...] Received-SPF: pass (google.com: domain of postmaster@smtp.mydomain.tld designates <smtp.mydomain.tld IP> as permitted sender) client-ip=<smtp.mydomain.tld IP>; Authentication-Results: mx.google.com; dkim=temperror (no key for signature) header.i=@smtp.remotedomain.tld header.s=default header.b=M9b4zh72; spf=pass (google.com: domain of postmaster@smtp.mydomain.tld designates <smtp.mydomain.tld IP> as permitted sender) smtp.helo=smtp.mydomain.tld smtp.helo=smtp.mydomain.tld
[...]
Date: 20 Jun 2023 22:55:59 +0200 From: postmaster@smtp.remotedomain.tld <---- <bouncefrom>@<bouncehost> To: sender@gmail.com Subject: failure notice Hi. This is the qmail-send program at smtp.remotedomain.tld. <--- control/bouncehost
I'm afraid I wasn't able to deliver your message to the following addresses. This is a permanent error; I've given up. Sorry it didn't work out. <fake@remotedomain.tld>: Sorry, no mailbox here by that name. (#5.1.1) --- Below this line is a copy of the message. Return-Path: <SRS0=YBjh=CJ=gmail.com=sender@srs.mydomain.tld>

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/bouncefromcontrol/bouncehost.

Aggiungi un commento

qmail notes

Pay me a coffee:

PayPal - The safer, easier way to pay online.

LXC scripts
Other contents
Guide per gli utenti
Ultimi commenti
Articoli recenti

RSS feeds