Backscatter? Bé, sí, això passa quan tenim un filtre de correu que està davant d’un MTA on hi ha les bústies d’e-mail, però el filtre no sap quins destinataris existeixen al MTA i quins no.

Aquí expliquem com dir-li a un filtre Postfix quins son els destinataris d’un MTA Exchange i així evitar fer backscatter (en català seria algo així com “retrodispersió”).

Què és el Backscatting?

Al rebre un correu per una adreça que no existeix, el servidor hauria de rebutjar-lo durant la conversa SMTP, quan l’origen encara està connectat. Així l’origen pot informar del problema al remitent real del correu. En canvi, si el servidor accepta el correu, al no poder-lo lliurar ha de generar un bounce que anirà a parar al remitent que posi al correu. Els spammers manipulen els remitents dels missatges, i un servidor mal configurat acaba enviant spam en forma de bounces. A aquest tipus de spam se l’anomena Backscatter.

Postfix davant d’un Exchange

En el nostre escenari tenim un Postfix que es dedica a rebre correu, passar-lo per l’antispam, per l’antivirus i demés, per finalment lliurar-lo a un Microsoft Exchange. Com que aquest servidor no té les bústies, acceptàvem tot el correu que fos per als dominis propis i al cap d’un temps ja teníem la IP a una llista negra per enviar Backscatting.

Per solucionar-ho hem de saber quines bústies hi ha a l’Exchange. Només així podrem rebutjar correus dirigits a destinataris que no existeixen.

La part senzilla és configurar el Postfix, al main.cf afegim relay_recipient_maps, per a que comprovi les adreces a més dels dominis.

relay_domains = example.com
relay_recipient_maps = hash:/etc/postfix/relay_recipients

i creem /etc/postfix/relay_recipients amb la llista de bústies, té aquesta pinta:

foo@example.com     OK
bar@example.com     OK

cal fer un postmap i un reload del postfix

postmap /etc/postfix/relay_recipients
/etc/init.d/postfix reload

Mantenir el llistat actualitzat

Ara ja no generem Backscatting, però cal mantenir actualitzat el llistat de bústies. Aquest llistat està a l’ActiveDirectory i per obtenir-lo hem agafat aquest script en VBS, i l’hem adaptat:

' Export all valid recipients (= proxyAddresses) into a
' file virtual.txt
'
' Ferdinand Hoffmann & Patrick Koetter
' 20021100901
' Shamelessly stolen from
' http://www.microsoft.com/windows2000/techinfo/ \
' planning/activedirectory/bulksteps.asp


'Global variables
Dim Container
Dim OutPutFile
Dim FileSystem

'Initialize global variables
Set FileSystem = WScript.CreateObject("Scripting.FileSystemObject")
Set OutPutFile = FileSystem.CreateTextFile("virtual.txt", True)

Set Container=GetObject("LDAP://DC=example,DC=com")
EnumerateUsers Container

'Clean up
OutPutFile.Close
Set FileSystem = Nothing
Set Container = Nothing

'Say Finished when your done
WScript.Echo "Finished"
WScript.Quit(0)

'List all Users
Sub EnumerateUsers(Cont)
Dim User

'Go through all Users and select them
For Each User In Cont
Select Case LCase(User.Class)

'If you find Users and Groups
'Added groups after Милен Панков mailed me about it :)
Case "user", "group"
  'Select all proxyAddresses
 Dim Alias
  If IsEmpty(User.proxyAddresses) Then
    ' do nothing.
 ElseIf (TypeName(User.proxyAddresses) = "String") Then
      OutPutFile.WriteLine "alias: " & User.proxyAddresses
  Else
    For Each Alias in User.proxyAddresses
    OutPutFile.WriteLine "alias: " & Alias
    Next
  End If
 
Case "organizationalunit", "container"
  EnumerateUsers User

End Select
Next
End Sub

la sortida de l’script té aquesta pinta:

alias: smtp:foo@example.com
alias: smtp:bar@example.com

l’script el cridem diàriament amb una “tarea programada” i ens deixa el llistat a virtual.txt
Per accedir al llistat, hem optat per muntar el directori amb cifs+autofs. Instal·lem autofs i el configurem:

# /etc/auto.master
/auto /etc/auto.cifs

# /etc/auto.cifs
activedirectory -fstype=cifs,rw,username=Administrador,domain=EXAMPLE,password=secret   ://192.168.1.17/spamassassin

així quan accedim a /auto/activedirectory es muntarà per samba //192.168.1.17/spamassassin que és on hem deixat l’script VBS i el llistat virtual.txt

per últim hem fet un script bash que actualitza el fitxer relay_recipients i si cal reinicia el postfix, i l’hem afegit al cron

#!/bin/bash

USERSFILE=/auto/activedirectory/virtual.txt
TMPFILE=/root/exchangesync/users_exchange.txt
TMPFILE2=/root/exchangesync/users_exchange.parsed

echo "--- Inici: `date` ----------"

# Intentem accedir al fitxer 10 vegades perque l'autofs
# tingui temps de muntar el directori via smb
for i in `seq 1 10`;
do
  if [ -f $USERSFILE ]; then
    echo "found $USERSFILE"
    break
  else
    if [ $i -eq 10 ]; then
      echo "can't access $USERSFILE after 10 retries"
      echo "------ Fi: `date` ----------"
      exit 1
    fi
    echo "can't access $USERSFILE, retrying..."
    sleep 2
  fi
done

cat $USERSFILE > $TMPFILE
dos2unix $TMPFILE
awk -F: '/alias: (SMTP|smtp):/ {printf("%s\tOK\n",$3)}' $TMPFILE | sort > $TMPFILE2
oldmd5=`cat /etc/postfix/relay_recipients.md5`
newmd5=`md5sum $TMPFILE2 | cut -d" " -f1`
if [ "$oldmd5" != "$newmd5" ]; then
  echo "md5 differ, reloading postfix"
  diff -b /etc/postfix/relay_recipients $TMPFILE2
  cp /etc/postfix/relay_recipients /etc/postfix/relay_recipients.old
  cp $TMPFILE2 /etc/postfix/relay_recipients
  echo -n $newmd5 > /etc/postfix/relay_recipients.md5
  /usr/sbin/postmap /etc/postfix/relay_recipients && /etc/init.d/postfix reload
else
  echo "md5 match, not reloading postfix"
fi

echo "------ Fi: `date` ----------"
echo