Filtr antyspamowy działał bez błędów, a phishing i tak trafiał do skrzynek

Usługi uruchomione, konfiguracja poprawna, w statusie systemu żadnych błędów. A mimo to phishing lądował w skrzynkach odbiorczych, a newslettery partnerów w folderze spam. Nasi inżynierowie zmierzyli, które mechanizmy wykrywania naprawdę działają, usunęli przyczyny, a trzy miesiące później znaleźli i naprawili regresję, którą było widać dopiero w ujęciu godzinowym.

  • Przykładowy phishing: z −2,7 na 9,1 pkt
  • Filtr Bayesa ocenia 100 % wiadomości
  • Baza przebudowana w tle, bez przerwy w działaniu
Skala punktów od −5 do 10 z przerywanym progiem: koperta phishingu przechodzi pomarańczowym łukiem spod progu daleko ponad próg

Firma niemieckojęzyczna z kilkunastoma domenami i kilkudziesięcioma skrzynkami, około 600 wiadomości zewnętrznych dziennie

Wyzwanie

Użytkownicy zgłaszali dwa problemy naraz: spam i phishing omijały filtr, a część legalnej poczty od partnerów była oznaczana jako spam. Wcześniejsze próby naprawy polegały na dokładaniu własnych reguł i podnoszeniu punktacji, co pogarszało oba problemy.

Środowisko: Debian 12, Postfix z postscreen, Dovecot z LMTP i Sieve, SpamAssassin 4.0 oraz amavis z ClamAV.

Rozwiązanie

Dane zamiast intuicji. Nagłówek, który filtr dodaje do każdej wiadomości, wymienia reguły, które zadziałały. Zebrany z prawdziwej poczty i kilku tygodni logów, pokazuje wprost, które mechanizmy wykrywania pracują, a które milczą. Żadnego ustawienia nie zmieniliśmy bez dowodu w tych danych.

Pierwsza naprawa usunęła przyczyny źródłowe: czarne listy DNS, które nigdy nie odpowiadały, zatrutą i niemal pustą bazę Bayesa, auto-uczenie, które uczyło filtr, że phishing jest w porządku, białe listy całych domen freemail i przesadzone reguły własne. Gdy po trzech miesiącach spam wrócił, godzinowa analiza logów ujawniła zapomniane zadania cron i skurczoną bazę, a bazę przebudowaliśmy w tle, bez przerwy w działaniu poczty.

Wyniki

Spam przed naprawą
Oceniany jako czysty, mediana 1,1 pkt przy progu 3,1
Oceniane przez filtr Bayesa
100 % wiadomości po naprawie, sprawdzone w ujęciu godzinowym
Przebudowana baza Bayesa
5,3 mln tokenów, z 47 828 wiadomości spamowych i 110 302 legalnych
Przykładowy phishing
Z −2,7 pkt w skrzynce odbiorczej na 9,1 pkt w folderze spam
Fałszywe alarmy na newsletterach partnerów
Brak po naprawie
Nocne douczanie
Około 2 minut zamiast wielu godzin

Jak pracowaliśmy

  1. Najpierw pomiar

    Nagłówki filtra z prawdziwej poczty, potem kilka tygodni logów: które reguły zadziałały, a które milczą.

  2. Przyczyny, nie objawy

    Własny rekursywny resolver dla czarnych list DNS, przebudowana baza Bayesa, bezpieczne uczenie, białe listy tylko z poprawnym DKIM lub SPF, skalibrowane wartości domyślne.

  3. Weryfikacja na prawdziwej poczcie

    Newslettery partnerów, wcześniej oznaczane jako spam, spadły do około −3 pkt, a żadna legalna wiadomość nie przekroczyła progu.

  4. Trzy miesiące później: regresja

    Konfiguracja była niezmieniona, resolver działał. Dopiero statystyki godzinowe pokazały, że filtr całymi nocami pracował bez Bayesa.

  5. Naprawa etapami

    Usunięcie dwóch zapomnianych zadań cron i naprawa uprawnień; wyłączenie auto-uczenia i ustawienie limitów bazy; pełna przebudowa z około 158 000 wiadomości w osobnej bazie, około pięć godzin w tle, potem atomowa podmiana.

  6. Nowe nocne douczanie

    Uruchamiane jako użytkownik usługi, tylko na wiadomościach z ostatnich trzech dni, około dwóch minut zamiast godzin.

Wyzwania, które pokonaliśmy

Czarne listy DNS działały, tylko nic nie mówiły

Serwer korzystał z publicznego resolvera. Operatorzy list takich jak Spamhaus blokują zapytania z publicznych resolverów ze względu na ich wolumen. Filtr nie zgłasza wtedy błędu: dodaje regułę z końcówką BLOCKED o wartości zero punktów i pracuje dalej. Najsilniejsze sygnały reputacyjne były martwe, a system wyglądał na zdrowy. SpamAssassin 4.0 nie ma też już domyślnie reguł Spamhaus ZEN; dodaliśmy je tak, żeby punktowane były wyłącznie prawdziwe kody listowania, nigdy kody błędów i limitów.

Filtr nauczył się, że phishing jest w porządku

Współczesny spam często jest perfekcyjnie uwierzytelniony: poprawny DKIM, SPF i DMARC, wysyłka z dużych platform pocztowych. Dostaje za to punkty ujemne, spada poniżej progu auto-uczenia jako poczta legalna, a filtr Bayesa uczy się, że taka treść jest w porządku. Przed pierwszą naprawą baza zawierała 174 wiadomości spamowe wobec 139 600 rzekomo legalnych. Auto-uczenie jest teraz wyłączone na stałe, a wzorcem poczty legalnej są wyłącznie foldery Wysłane. Skrzynka odbiorcza się nie nadaje, bo zawiera właśnie ten spam, który przeszedł.

Domyślny limit po cichu wyrzucił prawie cały trening

Domyślny limit bazy Bayesa to 150 000 tokenów; powyżej niego filtr usuwa najstarsze wpisy, a synchronizacja po dużym treningu wystarcza, żeby to uruchomić. Baza zbudowana z około 147 000 wiadomości miała tuż po treningu 134 000 tokenów; ta sama ilość poczty przy wyłączonym automatycznym czyszczeniu daje 5,3 miliona. Ponad 95 procent pierwszego treningu wyrzucono, zanim filtr zdążył z niego skorzystać.

Zapomniany cron co godzinę wyłączał filtr

Dwa stare wpisy w crontabie roota douczały filtr z folderów Spam co godzinę. Ścieżka bazy była ustawiona globalnie, więc pisały do tej samej bazy, z której korzysta usługa, a pliki tworzone przez roota stawały się nieczytelne dla użytkownika usługi. Statystyki dzienne wyglądały dobrze. Dopiero rozbicie na godziny pokazało noce, w które filtr przez siedem godzin działał bez Bayesa, i dzień, w którym dotyczyło to połowy wszystkich wiadomości.

Fałszywy alarm, który mógł kosztować przebudowę całej architektury

W pewnym momencie około 95 procent wiadomości w skrzynkach nie miało żadnego nagłówka filtra, co wyglądało na masowe obchodzenie. Logi Postfixa to wyjaśniły: były to wewnętrzne powiadomienia systemowe, około 12 000 dziennie, idące osobną, zaufaną ścieżką. Cała poczta zewnętrzna, około 600 wiadomości dziennie, przechodziła przez filtr. Przy okazji wyszła prawdziwa, choć mniejsza luka: program kliencki przepuszcza bez sprawdzania wiadomości większe niż 500 KB, a mniej więcej połowa zewnętrznych wiadomości bez nagłówka przekraczała ten limit, w tym spam z załącznikiem 1,9 MB.

Konfiguracja usługi nadpisywała globalną

Konfiguracja globalna wskazywała amavisa z ClamAV jako filtr treści. Usługi przyjmujące pocztę z internetu miały jednak własny parametr wskazujący SpamAssassin, który ma pierwszeństwo, więc poczta przychodząca nigdy nie przechodziła przez amavisa, choć dokumentacja zakładała co innego. Ma to znaczenie dla założeń o skanowaniu antywirusowym tak samo jak dla spamu.

Serwer pocztowy pyta czarną listę DNS dwoma równymi torami: przez publiczny resolver, narysowany jako chmura, zapytanie kończy się przed listą krzyżykiem; przez własny resolver, pomarańczową ramkę, dociera

Przed i po

Wskaźnik Przed Po
Czarne listy DNS Zablokowane w 100 procentach wiadomości Odpowiadają poprawnie; zero blokad w czterech tygodniach logów
Ocena przez Bayesa Żadna wiadomość nie była oceniana; później przerwy po kilka godzin 100 procent wiadomości, sprawdzone w ujęciu godzinowym
Baza Bayesa 174 spamowe i 139 600 legalnych wiadomości, zatruta 47 828 spamowych i 110 302 legalnych wiadomości, 5,3 mln tokenów
Fałszywe alarmy na newsletterach Newslettery partnerów oznaczane jako spam Brak po naprawie
Przykładowy phishing −2,7 pkt, skrzynka odbiorcza 9,1 pkt, folder spam
Nocne douczanie Wiele godzin, blokowało bazę Około 2 minut, bez blokad

Co z tego wynika

  • Brak błędów to nie skuteczność. Trzeba mierzyć, które reguły faktycznie się uruchamiają, a nie tylko czy usługa działa.
  • Jedna baza, jeden właściciel. Każdy proces, który uczy filtr, działa jako użytkownik usługi.
  • Poczta legalna tylko z wiarygodnego źródła: foldery Wysłane, nigdy skrzynka odbiorcza.
  • Monitoring godzinowy. Statystyki dzienne ukrywają wielogodzinne przerwy.
  • Przegląd starych zadań cron przy każdej zmianie architektury filtra.

Tani i precyzyjny pomiar przeoczeń nie wymaga ankiety: filtr dopisuje znacznik do tematu każdej wiadomości, którą rozpoznał, więc wiadomość w folderze Spam bez tego znacznika przeniósł tam użytkownik. Poza naprawą zaleciliśmy domknięcie kilku punktów: limit 3 MB dla programu klienckiego, codzienne aktualizacje reguł, trzy wąskie reguły na najczęstsze wzorce phishingu oraz douczanie w czasie rzeczywistym, gdy użytkownik przenosi wiadomość do folderu Spam lub z niego.

24 słupki godzinowe od 0 do 24; pomarańczowa ramka zaznacza siedem nocnych godzin bez słupka, w których filtr działał bez Bayesa

Powiązane sytuacje

  • Faktury, oferty lub hasła jednorazowe trafiają do spamu albo wracają do nadawcy? Od listopada 2025 r. Gmail ostrzej egzekwuje zasady dla nadawców, także przez odrzucanie wiadomości (stan: 2026-10). Sprawdzamy SPF, DKIM, DMARC i reputację, a potem przekazujemy pisemną listę poprawek.

  • Państwa system działa, ale nikt nie zna go dokładnie. Spisujemy aplikację, bazę danych, serwer i pocztę, oceniamy ryzyka, na piśmie rekomendujemy dalszą drogę, a na życzenie przejmujemy utrzymanie systemu.

Inne projekty

  • Telefon z kodem QR, plik podzielony na porcje, trzy równoległe strumienie do serwera z dyskiem i siatka galerii

    Aplikacja do zbierania zdjęć od gości weselnych

    Goście weselni skanują kod QR, otwierają jeden sekretny adres i wysyłają zdjęcia oraz filmy prosto z telefonu: bez aplikacji, bez konta, bez logowania. Pliki do 5 GB lądują na dysku klienta, a para młoda ogląda galerię, która zapełnia się jeszcze w trakcie przyjęcia. Jeden wieczór, bez drugiej szansy, i telefony sprzed sześciu lat.

  • Cztery koperty przechodzą przez bramki SPF, DKIM i DMARC, odhaczone na pomarańczowo, w drodze do skrzynki odbiorczej

    Dostarczalność poczty dla czterech domen firmowych

    Serwer pocztowy czterech domen firmowych niczego nie podpisywał, nie publikował polityki DMARC i był odrzucany przez Microsoft. Nasi inżynierowie sprawdzili go, przetestowali zmianę na jednej domenie i wdrożyli ją partiami. Efekt: wszystkie trzy mechanizmy przechodzą sprawdzenie w Gmailu, blokada Microsoftu została zdjęta, a użytkownicy niczego nie odczuli.

W 20 minut ustalimy, jaki pierwszy krok pasuje do Państwa systemu

Państwo opisują cel i obecny stan, my mówimy otwarcie, czy i jak możemy pomóc. Odpowiedź w ciągu jednego dnia roboczego, bez zobowiązań.

Telefon (niemiecki, polski, angielski) +48 501 250 220
E-mail E-mail

Dostępni: poniedziałek–piątek, 9:00–17:00 (czas środkowoeuropejski); wsparcie i awarie całą dobę (24/7)