Changelog
- Aug 17, 2023
- C++ version - Aug 13, 2023
- v. 8.2.0 bug fix: segfault in case of no result in DNS record
- default action changed to GNLR - 27 luglio 2023
-P
lascia passare il client e ignora tutti i filtri. E' necessario rimuovere o rivedere questa opzione se già si usa il programma.
- aggiunto il filtroG
, ovveroHELO/EHLO
con una sintassi non valida sono bloccati (stringhe casuali ma anche errori di digitazione come sagredo..eu). Compilare con-lpcre
- ampia revisione del codice. Per favore riportare ogni problema nei commenti.
La Sezione 3.5 del documento RFC-821 afferma che
The sender-SMTP MUST ensure that the <domain> parameter in a HELO command is a valid principal host domain name for the client host. As a result, the receiver-SMTP will not have to perform MX resolution on this name in order to validate the HELO parameter.
The HELO receiver MAY verify that the HELO parameter really corresponds to the IP address of the sender. However, the receiver MUST NOT refuse to accept a message, even if the sender's HELO command fails verification.
Ammettere i client con un record DNS
bacato nel proprio HELO/EHLO
può essere sensato non solo perché suggerito dalla RFC di cui sopra, ma anche una cosa conveniente per l'amministratore, che non dovrà perdere il suo tempo ad aggiungere continuamente record alla whitelist per colpa dei client regolari che non hanno settato bene il proprio record DNS
.
Ma d'altra parte, è un dato di fatto che praticamente tutti gli spammers utilizzino nel loro HELO
domini che non appartengono loro -spesso addirittura uno dei nostri stessi domini (cosa ovviamente intollerabile)-, oppure delle stringhe random o domini che non sono riconducibili ad alcun IP.
Per esempio, consideriamo le seguenti righe del mio log (ne ho sempre moltissime):
2022-02-01 10:19:53.142643500 helo-dns-check: HELO [yq3H9cDKgS] from [109.237.103.41] doesn't solve 2022-02-01 09:53:05.772497500 helo-dns-check: HELO [sagredo.eu] is a local domain but IP [183.240.55.119] is not a RELAYCLIENT
Penso che, a prescindere da cosa dica l'RFC sopra menzionato, non si commetta un peccato mortale se si respingono almeno i client che riportano gli errori di cui sopra.
Spiegherò quindi qui sotto come settare un filtro che respinga i seguenti problemi a livello DNS
:
HELO/EHLO
con una sintassi non valida. Stringhe casuali ma anche domini non validi a causa di una errata digitazione come ad esempio sagredo..eu non verranno ammessi.- falsi
HELO/EHLO
contenenti addirittura uno dei nostri domini, riconoscibili dal fatto che il recordDNS
non corrisponde a uno dei nostriIP
mentre la variabileRELAYCLIENT
non è stata definita; HELO/EHLO
contenenti un dominio non riconducibile con alcun recordA
. In questo caso si otterranno alcuni falsi positivi, ad esempio i client il cui amministratore ha dimenticato di creare il recordA
nel proprioDNS
verranno bannati.- client il cui
A
record non corrisponde all'indirizzoIP
remoto. Ciò è palesemente contro laRFC-821
, pertanto la mia configurazione non rifiuterà queste connessioni, che però saranno loggate.
Faremo uso di un plugin "helodnscheck" di qmail-spp che ho derivato da un vecchio lavoro di Perolo Silantico, Jason Frisvold con modifiche di Ren Bing. Ecco il programma da me modificato:
- Versione C++ 9.0.1
- Versione C 8.2.1 (stesse modalità di utilizzo della precedente)
La logica del plugin originale è di bloccare i client del tipo 3, che ovviamente includono quelli del tipo 1 2 e 3, ma senza poter all'occorrenza selezionare solo quelli di tipo 1 2 o 3, cosa che invece fa la mia versione modificata, che comunque può -se si vuole- funzionare come il programma originario.
Installazione e configurazione
Assumo qui che si abbia già patchato qmail
con qmail-spp
. Se si sta usando la mia patch combinata si è a posto.
Scarichiamo, compiliamo e installiamo:
cd /usr/local/src wget https://raw.githubusercontent.com/sagredo-dev/helodnscheck/main/helodnscheck.cpp g++ -o /var/qmail/plugins/helodnscheck helodnscheck.cpp -lpcre
Ora abilitiamo il plugin, aggiungiamolo a /var/qmail/control/smtpplugins nella sezione [helo]
:
[helo] plugins/helodnscheck
Creiamo ora una lista con tutti i nostri IP
nel file control/moreipme (probabilmente ce l'abbiamo già se abbiamo installato la patch "moreipme"):
1.2.3.4 5.6.7.8
Poi abilitiamo qmail-spp
e settiamo i parametri relativi al plugin. Io suggerisco i seguenti sia nel run file di qmail-smtpd
che in quello di qmail-submission
:
export ENABLE_SPP=1 export HELO_DNS_CHECK=RLNG
In questo modo solo gli HELO
cattivi del tipo 1 (G
) e 2 (N
) saranno bloccati a meno che RELAYCLIENT
non sia stato definito (R
). Tutti gli altri errori nel controllo del DNS
verranno loggati (L
).
Si tenga presente che il controllo dell'HELO
non può funzionare bene con il servizio submission
, poichè l'IP
remoto non potrà risolvere l'HELO
usato. Di conseguenza la variabile HELO_DNS_CHECK
non dovrà essere definita nel run file di qmail-submission
.
Naturalmente si può sempre definire HELO_DNS_CHECK
nelle tcprules
o porre un particolare IP
in whitelist attraverso la variabile NOHELODNSCHECK
come qui mostrato:
111.222.333.444:allow, NOHELODNSCHECK="" :allow,HELO_DNS_CHECK="RNLG"
Il comportamento del programma è definito dalla variabile HELO_DNS_CHECK
:
L
- (default) LogH
- aggiunge un Header "X-Helo-Check
"D
- Modalità debugR
- (default) seRELAYCLIENT
è impostato non viene fatto nullaP
- modalità lasciapassare. Usare conL
e/oH
.
I filtri sono eseguiti nel seguente ordine:
G
- (Garbage, default)HELO/EHLO
con una sintassi non valida sono bloccati.A
- i domini inHELO/HELO
che non possono essere risolti sono bloccati. Si tratta di hostname che non corrispondono ad alcun recordA
registrato. UsareG
insieme adA
è ridondante (è sufficiente usareA
).I
- ComeA
per compatibilità con le versioni precedenti. Obsoleto e sarà rimosso.N
- (Not me, default) blocca se l'IP
remoto non è unRELAYCLIENT
NON è impostato e se l'hostname inHELO/EHLO
viene risolto verso uno degli nostriIP
contenuti in control/moreipme. Anchelocalhost
sarà bloccato. UsareN
insieme adA
è ridondante (usare semplicementeA
).V
- ComeN
per compatibilità con le versioni precedenti. Obsoleto e sarà rimosso.B
- Blocca se l'IP
remoto (TCPREMOTEIP
) non è contenuto in uno degli indirizzi risolti. E' la modalità originale di funzionamento. UsareG
e/oA
e/oN
insieme aB
è ridondante (usare semplicementeB
).
I precedenti possono essere combinati, ovvero BL
significa blocca & logga.
Se P
è definito, allora tutti i filtri G
, A
, B
e N
vengono ignorati.
Nota: l'opzione di default è GNLR
, usata se HELO_DNS_CHECK
è vuoto, ovvero HELO_DNS_CHECK=""
.
Test
E' possibile testare il buon fnzionamentodel programma in questo modo:
HELO_DNS_CHECK="BLRD" \ SMTPHELOHOST="test.tld" \ TCPREMOTEIP="111.222.333.444" \ ./helodnscheck helo-dns-check: dbg: action is BLRD helo-dns-check: dbg: no_helo_check is (null) helo-dns-check: dbg: helo_domain is test.tld helo-dns-check: dbg: remote_ip is 111.222.333.444 helo-dns-check: dbg: G filter 'nomatch': [2] helo-dns-check: dbg: no result in A record helo-dns-check: HELO [test.tld] from [111.222.333.444] doesn't solve R553 sorry, invalid host name in HELO/EHLO command. (#5.7.1) helo-dns-check: blocked with: invalid host name in HELO/EHLO command. [111.222.333.444]
Esempi
Utilizzo con le tcprules
111.222.333.444:allow, NOHELODNSCHECK="" // lascia passare IP :allow,HELO_DNS_CHECK="LB" // blocca & logga gli altri
Utilizzo nel file run di qmail-smtpd
export HELO_DNS_CHECK="" // default (GNLR) export HELO_DNS_CHECK // HELO_DNS_CHECK non attivo #export HELO_DNS_CHECK // HELO_DNS_CHECK non attivo export HELO_DNS_CHECK=RLGN // consenti i RELAYCLIENT, logga, blocca HELO con sintassi errata, blocca i client con i miei domini nell'HELO/EHLOs (scelta sicura)