Ostatnimi czasy zdecydowana większość spamu rozsyłana jest nie, jak
dawniej, przez open relaye, ale przez specjalnie spreparowane trojany lub
wirusy. Takie spamowarki
występują zbyt licznie (przyczyny tego stanu
to osobna kwestia), aby miało sens ich ręczne blacklistowanie; również
systemy RBL typu SpamCop nie zdają egzaminu, ponieważ zwykle w momencie
zgłoszenia i odnotowania w RBL jest już za późno - spamowarka zdążyła wysłać
tysiące sztuk spamu. Programy wyłapujące spam przez analizę treści maila
(SpamAssassin, bogofilter) nie zawsze sobie radzą z nowszymi formami spamu,
w których często dodawane są losowe słowa, aby zaburzyć działanie
statystyczno-heurystycznych analizatorów.
Wdrożyłem ostatnio na AGH rozwiązanie, które w znacznym stopniu - o niemal 99% - zredukowało problem spamu (a przy okazji także zredukowało o ok. 90% liczbę wirusów, odciążając skaner antywirusowy). Jest to tzw. greylisting - metoda pozwalająca na wyeliminowanie spamowarek bez potrzeby korzystania z zewnętrznych źródeł informacji typu RBL.
Greylisting polega na wykorzystaniu podstawowej różnicy pomiędzy
spamowarkami a serwerami pocztowymi: te ostatnie, jeśli przy próbie
dostarczenia maila do serwera docelowego otrzymają odpowiedź "4xx" (kod
błędu tymczasowego), powtórzą próbę dostarczenia poczty po jakimś czasie i
będą powtarzać do skutku lub do upłynięcia limitu czasu (zwykle kilka dni),
po którym odeślą informację o niedostarczeniu (zwrotkę
) do nadawcy.
Spamowarki, jak dotąd, tego nie robią - błąd tymczasowy traktują na równi z
permanentnym i po prostu rezygnują z wysłania spamu, przechodząc do następnego
adresata.
Wystarczy zatem działać zgodnie z następującym schematem:
450 Service temporarily unavailable
;
serwer za chwilę spróbuje znowu i zostanie wpuszczony.Oczywiście, istnieje ryzyko, że za jakiś czas spamowarki zostaną udoskonalone i będą powtarzać próby np. co godzinę - wtedy metoda przestanie być skuteczna. Wtedy będziemy się martwili, co dalej. Na razie zamiast dotychczasowych ok. 300 spamów dziennie dostaję góra 3.
Po pierwsze, potrzebny jest program, który będzie pracował jako tzw. policy
server (Uwaga: policy servers są obsługiwane począwszy od
wersji 2.1 Postfixa, dla starszych wersji należy zacząć od upgrade...)
- poniżej załączam taki program napisany przeze mnie w Perlu
na podstawie przykładu dołączonego do dystrybucji Postfixa (Uwaga: przykład
nie nadaje się do bezpośredniego użytku ze względu na zastosowany mechanizm
filelockingu - jeśli kogoś to interesuje, to tu
jest objaśnione, co w nim złego); w razie potrzeby należy w nim pozmieniać
parametry $database_name
i $greylist_delay
.
Program korzysta z modułów DB_File::Lock, Fcntl i Sys::Syslog, z których
pierwszy nie jest częścią standardowej dystrybucji Perla i trzeba go sobie
doinstalować.
Po drugie, trzeba kazać Postfixowi uruchamiać ten program jako usługę - w
tym celu należy wpisać do master.cf
taką linię:
policy unix - n n - 0 spawn user=nobody argv=/usr/bin/perl /usr/lib/postfix/greylist -v
(ścieżki zmienić w razie potrzeby; opcja -v może wystąpić od 0 do 3 razy, co wpływa na poziom szczegółowości logów; alternatywnie można napisać np. -v3).
Po trzecie, w main.cf
trzeba się jakoś odwołać do policy
servera, najprawdopodobniej w smtpd_recipient_restrictions, np. jakoś
tak:
smtpd_recipient_restrictions = # pozwalamy wysyłać z sieci lokalnej lub uwierzytelnionym użytkownikom permit_mynetworks permit_sasl_authenticated # poza tym nikomu reject_unauth_destination # dodatkowe usprawnienie - odrzucamy pocztę do nieistniejących użytkowników # lub od na pewno nieistniejących nadawców (z nieistniejących domen) # jeszcze przed greylistingiem reject_unlisted_recipient reject_unknown_sender_domain # greylisting check_policy_service unix:private/policy # jeśli greylisting nie odrzucił, to wpuszczamy permit
No i jeszcze trzeba się upewnić, że wszystko ma właściwe prawa - u mnie to wygląda tak:
drwxr-xr-x 2 nobody nogroup 4096 Jan 6 14:46 /var/mta -rw------- 1 nobody nogroup 258048 Jan 11 19:12 /var/mta/greylist.db -rwxr-xr-x 1 root root 7049 Jan 7 15:31 /usr/lib/postfix/greylist
Mam nadzieję, że nie zapomniałem o niczym istotnym... aha, raz na jakiś czas można oczyścić bazę ze śmieci za pomocą skryptu greylist_expire.
UWAGA: Ten program nie jest już rozwijany. Z przyczyn wydajnościowych zdecydowałem się na migrację do postgrey (zob. niżej). Pozostawiam jednak mój kod dostępny dla zainteresowanych, raczej w celach edukacyjnych niż exploatacyjnych.
Warto też rzucić okiem na rozwiązanie konkurencyjne: postgrey Davida Schweikerta. W odróżnieniu od mojego kodu, jest porządnie udokumentowane; poza tym ma parę dodatkowych możliwości, które jednak uważam za nie tylko zbędne, ale wręcz szkodliwe - konkretnie chodzi mi o to, że domyślnie ma ustawione:
--auto-whitelist-clients=1 --lookup-by-subnet
Pierwsza z tych opcji powoduje, że każdy host, z którego choć raz został dostarczony mail (tzn. przeszedł greylisting) zostaje automatycznie uznany za serwer SMTP i od tej pory nie podlega greylistingowi; miałoby to głęboki sens, gdyby nie fakt, że w małych sieciach serwer SMTP często równocześnie jest routerem zapewniającym NAT (maskaradę) dla sporej liczby klientów; wyłączając z greylistingu serwer, równocześnie wyłączamy wszystkich NAT-owanych klientów, którzy mogą teraz spamować do woli...
Druga opcja oznacza, że jeśli adres IP powiedzmy x.y.z.n został uznany za OK, to automatycznie OK jest cała podsieć x.y.z/24, a przecież w tej sieci poza x.y.z.n (serwerem SMTP) może być jeszcze mnóstwo klientów - potencjalnych spamowarek.
Tym niemniej, po ustawieniu:
--auto-whitelist-clients=0 --lookup-by-host
postgrey powinien działać sensownie.
Szymon Sokół <szymon@agh.edu.pl>, 11.01.2006 (last modified 10.08.2020)