Bloccare gli HELO/EHLO con falso DNS

26 febbraio 2022 Roberto Puzzanghera 0 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.

Non 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:

  1. HELO/EHLO che non possono essere risolti, come stringhe random o domini senza alcun A record.
  2. falsi HELO/EHLO contenenti addirittura uno dei nostri domini, riconoscibili dal fatto che il record DNS non corrisponde a uno dei nostri IP mentre la variabile RELAYCLIENT non è stata definita;
  3. client il cui A record non corrisponde al dominio presente nel HELO/EHLO. Ciò è palesemente contro la RFC-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 e Ren Bing. Ecco il plugin originale e quello da me modificato:

La logica del plugin originale è di bloccare i client del tipo 3, che ovviamente includono quelli del tipo 1 e 2, ma senza poter all'occorrenza selezionare solo quelli di tipo 1 e 2, 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://notes.sagredo.eu/files/qmail/patches/qmail-spp/plugins/helodnscheck/helodnscheck6.c
gcc -o /var/qmail/plugins/helodnscheck helodnscheck6.c -lresolv

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=PLRIV

In questo modo solo gli HELO cattivi del tipo 1 (I) e 2 (V) saranno bloccati a meno che RELAYCLIENT non sia stato definito (R). Tutti gli altri errori nel controllo del DNS non verranno bloccati (P) ma saranno comunque 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="PLRIV"

Il comportamento del programma è quindi definito dalla variabile HELO_DNS_CHECK:

  • [default] - blocca se l' HELO non viene risolto in alcun A record
  • P - passthrough, non blocca nemmeno nel caso HELO non sia risolvibile in un A record (naturalmente andrebbe usato con  L e/o H)
  • B - Blocca se TCPREMOTEIP non è contenuto nell'indirizzo risolto
  • L - Logga il tutto
  • H - aggiunge un Header del tipo "X-Helo-Check"
  • R - se "RELAYCLIENT" è stato definito non fa nulla
  • D - modalità Debug (da usare con L)
  • V - blocca se "RELAYCLIENT" NON è stato definito e HELO è uno dei nostri IP contenuti nel file control/moreipme. Inutile usarlo insieme a B.
  • I - blocca gli hostname in HELO/EHLO non validi, ovvero che non si è riusciti a risolvere. Anche qui, usare questo con B è ridondante.

I codici di cui sopra possono essere combinati insieme, ad esempio BL significa blocca & logga se TCPREMOTEIP non è stato settato.

Nota: se non c'è alcun argomento nell' HELO/EHLO, il comportamento di default è un blocco permanente.

Aggiungi un commento