Weryfikacja nadawcy maila część 1.

Podczas dotychczasowych opisów konfiguracji Exima umknęła mi kwestia weryfikacji nadawcy, czy nadawca jest taki sam jak użytkownik, który się zautoryzował poprzez SMTP AUTH. Na tą sytuację zwrócił mi uwagę Adrian H. Dzięki :)

Przykładowo, mamy konto pocztowe zbieram_spam@kolekcja.mejor.pl , w programie pocztowym konfigurujemy w połączenie do serwera SMTP użytkownika zbieram_spam@kolekcja.mejor.pl , natomiast w ustawieniach konta możemy wprowadzić: prezes_firmy@kolekcja.mejor.pl . Czyli w mailu pojawi nam się From:  prezes_firmy@kolekcja.mejor.pl pomimo tego, że nie mamy prawa korzystać z tego konta.

Musimy więc porównać, czy sender, czyli nadawca jest taki sam jak użytkownik, który odmeldował nam się loginem i hasłem. Zatem w acl_check_data (czyli tak naprawdę w acl_smtp_data) , gdzieś blisko początku, dodajemy:

deny     authenticated  = *
condition      = ${if eq {$authenticated_id}{${lc:$sender_address}}{no}{yes}}
message         = rejected: Nie
prawidłowy nadawca.

Tutaj pojawił mi się mały dylemat, pisząc poprzednie teksty, przyjąłem odruchowo, że alias do konta jest aliasem służącym tylko do odbierania poczty. Pisząc obrazowo, jest konto zbieram_spam@kolekcja.mejor.pl do którego zakładamy aliasy: uwielbiam_ICIC@kolekcja.mejor.pl oraz icic_to_miedzynarodowi_spamerzy@kolekcja.mejor.pl

to mail przychodzący pod dowolny w/w adres wyląduję w jednym i tym samym maildirze. Natomiast pocztę można wysyłać jedynie jako zbieram_spam@kolekcja.mejor.pl . Natomiast Adrian zasugerował, że zbieracz_spamu mógłby także chcieć wysłać maila jako icic_to_miedzynarodowi_spamerzy@kolekcja.mejor.pl . A tego powyższy wpis nie dopuszcza.

Jak to zrobić jest w drugiej części.

Jak odrzucić maila i zostawić sobie jednocześnie jego kopię

Ten post będzie o tym jak zapewnić większą ilość raportów wysyłanych przez SpamCopa do abuse@…

Zwykle (czyli tak jak np. ja miałem ;) ) serwer pocztowy jest tak skonfigurowany, że w momencie uznania iż dany mail jest spamem wysyła komunikat 550 i kończy sesję. Może to się stać zarówno podczas testów samego nagłowka, czyli zwykle jest to sprawdzenie poprawności syntaktycznej nagłówka i przede wszystkim odpytanie RBL, jak i po odebraniu całego maila, wtedy system wykrywający spam ( np. Spamassassin ) analizuje jego treść i oznacza go jako ham/spam.

Tak czy inaczej mail taki zostaje odrzucony, my wiemy, że była próba zaproponowania nam viagry ale nie mamy corpus delicti do zaraportowania.

Uważam, że jeśli nadawca siedzi już w RBLu to są dwa powody aby zakończyć konwersację natychmiast, bez przyjmowania całości maila. Pierwszy powód to taki, że skoro jest już na czarnej liście to znaczy, że został już zgłoszony odpowiednią ilość razy. Drugim jest fakt, że po to korzystam z czarnych list aby zmniejszyć obciążenie łącza jak i samego serwera, ciężkim SpamAssasinem. Czyli wybór prosty, jeżeli mail zostanie odrzucony poprzez antyspama to wtedy chciałbym mieć jego kopię do zaraportowania.

Do zaimplementowania tej funkcji w Eximie wykorzystałem fakereject .

Plan działania jest taki: oznaczam takiego maila zmienną, dodaje nowy router, przed routerem, który normalnie doręczył by maila do maildira. W nim sprawdzam stan zmiennej oznaczającej czy dany mail jest spamem czy nie. Jeśli wynik testu jest pozytywny to kieruje przesyłkę do oddzielnego transportu.

O to szczegóły, kolorem czerwonym oznaczam dodatkowe wpisy obok standardowo występujących.

acl_check_data:

……

deny warn message           = This message scored $spam_score spam points.

spam                  = nobody:true
condition         = ${if >{$spam_score_int}{44}{1}{0}}
set acl_m1        = spam
control              = fakereject/This message scored $spam_score spam points.SC.

begin routers

dnslookup:

………

spam_fakereject:

driver = accept
condition = ${if eq {$acl_m1}{spam}{true}{false}}
transport = spam_transport

……..

begin transports

spam_transport:

driver = appendfile
directory = /home/spam
maildir_format
delivery_date_add
envelope_to_add

To zapewni nam, że w katalogu /home/spam wyląduje wszystko ze zbyt wysoką punktacją. Teraż możemy sobie poczytać wszelkie oferty ;) oraz zgłosić je komu trzeba.

Jeżeli chcemy automagicznie, bez czytania, wysłać zgłoszenie do SpamCopa to możemy to zrobić poprzez modyfikację transportu tak aby wołaj od razu spamassassina (za pomocą którego będziemy wysyłać raport).

Skorzystamy z drivera pipe

spam_transport:

driver = pipe
command = /usr/bin/spamassassin -r

Potrzebujemy także uaktywnić wymagany plugin w Spamassassinie.

W pliku v310.pre dodajemy:

loadplugin Mail::SpamAssassin::Plugin::SpamCop

a w pliku local.cf podajemy adres do submitowania przypisany do naszego konta na SC:

spamcop_to_address      submit……@…..

Voila.


Tanie mięso psy jedzą, czyli moja opinia o Hekko

Skusiłem się na wykupienie domeny tym razem dla siebie. Znalazłem tanią ofertę, wybrana domena była wolna, poszedł przelew. I nastąpiło pierwsze zdziwienie, tak wiem, nie przeczytałem uważnie oferty ale dla mnie to był standard że kupując domenę dostaje się dnsy. Tutaj, za darmo, mogłem jedynie zrobić delegację.

I to powinno dać mi do myślenia i powstrzymać od dalszej współpracy.. Zakupiłem więc hosting. I ogólnie parametry mieszczą się tym co oferują. Tylko jakoś nie jestem zachwycony tym, że kilka razy w miesiącu są „pady” po kilkanaście minut. Albo tym, że kilkanaście razy dziennie jest restartowany apache co owocuje zwykle 50 sekundową niedostępnością. A ostatnio to pół godzinne pady także nie są czymś nadzwyczajnym.

A żeby było ciekawiej to firma Hekkonet monitoruje dostępność, a co za tym idzie stanowi to dla nich punkt odniesienia w przypadku reklamowania usługi, za pomocą http://host-tracker.com , któraż to sprawdza działanie serwera www co 10 minut. W co się nie łapią przerwy wynikające z reloadu apache.

Tak więc jeśli ktoś mnie zapyta, to moja opinia o Hekkonet jest negatywna. Co nie znaczy, że inni nie będą zadowoleni z jakości ich usług w stosunku do ceny.

Edit 1 : Okazuje się, że nie uznają nawet host-trackera. Wygląda na to, że nie uznają żadnych pomiarów, które wskazywałyby na to, że ich obiecane 99.5% dostępności nie byłyby spełnione.  Dzisiaj ( 2008-12-15) znowu była długa przerwa, serwer się położył na około 20 minut. Nie działały nawet dnsy dla mojej domeny. Koszmar.

2009-01-21, to juz chyba trzeci dzień, kiedy wykłąda się baza mysql. Jak nie restart apache to wysypka bazy danych. Coooool.

Ciąg dalszy http://blog.mejor.pl/2009/02/problemy-z-hekko-ciag-dalszy/

Migracja systemu Gentoo na LVM2 na raid

Z okazji zmiany dysku na większy chciałem w ramach zyskania nowych doświadczeń przenieść system na LVMa.

Przyjąłem założenie, że LVM zostanie zainstalowany na zdegradowanym raidzie, łatwiej jest potem dołożyć nowy dysk, niż kombinować jak przenieść LVM na raida (chociaż według opisu http://akademia.linuksa.pl/readme/lvm/ nie jest to zbyt problematyczne) . Bootloader GRUB w obecnej, szeroko dostępnej wersji (~0.97) nie obsługuje LVM więc partycja /boot będzie umieszczona bezpośrednio na raidzie. Również poza LVM zostanie umieszczona root partycja czyli / . Wynika to z tego, że mam dużą niechęć do initrd , a jest on niestety niezbędny aby powstał system z główną partycją umieszczoną na LVM.

O to jak to zrobiłem to na gentoo:

( O „emerge lvm2” i „rc-update add lvm boot” nie będe wspominał ;)  )

Dysk ma pojemność 250GB, podzieliłem go na takie partycje:

Device Boot      Start         End      Blocks   Id  System
/dev/sdc1   *           1          73      586341   83  Linux
/dev/sdc2              74       30103   241215975    5  Extended
/dev/sdc5              74       13690   109378521   fd  Linux raid autodetect
/dev/sdc6           13691       29252   125001733+  fd  Linux raid autodetect
/dev/sdc7           29253       29434     1461883+  fd  Linux raid autodetect
/dev/sdc8           29435       30103     5373711   fd  Linux raid autodetect

sdc1 to będzie partycja /boot

sdc5 i sdc6 to będą partycje pod lvm

sdc7  to swap

sdc8 będzie partycją / (przeznaczyłem na nią 5.5G aby nie martwić się jak ją powiększyć,)

I na wszelki wypadek zostawiłem 2.4G wolnego miejsca. Root partycję umieściłem właśnie na końcu i po niej zostawiłem to wolne miejsce dodatkowo po to aby np. właśnie móc powiększyć tą partycję,

Zrobiłem dwie mniejsze partycje LVMowe zamiast jednej dużej, ponieważ nie jestem pewny czy nie najdzie mnie ochota zrobić raida używając mniejszych dysków znajdujących się w szufladzie.

Czytaj dalej Migracja systemu Gentoo na LVM2 na raid

Problemów z Reiserfs ciąg dalszy (not directory or indirect item)

Zawsze byłem zadowolony z tego systemu plików, szybki, nie zauważyłem aby robił mi jakieś świństwa po gwałtownym padzie zasilania. Po prostu sprawdza się na domowym komputerku. Za to przysparza problemów tam gdzie pracuje Firebird 1.5 .  Ma dziwną tendencję do psucia się na partycji /tmp , wrzucając do dmesga następujące komunikaty:

ReiserFS: md2: warning: vs-8115: get_num_ver: not directory or indirect item

Konsekwencje tego są bardzo problematyczne i nieciekawe. Z bazy firebirdowej zaczęły znikać rekordy, a może wyrywkowo nie pojawiały się nowe. Trudno powiedzieć, najważniejsze, że nie było tych danych, które powinny tam być. Jest to kolejny powód dla którego zaczynam odchodzić od tego systemu plików. Moim „idolem” jest na obecną chwilę XFS , niestety nie zawsze mogę go zastosować (nie wszędzie jest UPS).

Uzupełnienie: problem pojawiał mi się na różnych wersjach kerneli, poczynając od aruoxowego 2.6.9-coś tam , poprzez gentoo-sources 2.6.16 , 2.6.18, 2.6.23 . Na innych wersjach jądra nie miałem okazji sprawdzać.

Firebird i Reiserfs

Głównymi bohaterami są Firebird 1.5 oraz system plików reiserfs 3.6 .

Baza danych jest pojedynczym (jak to zwykle przy firebirdzie bywa ;) ) plikiem o wielkości od 1 GB do ~5 GB. Podaje taki przedział ponieważ obserwacji dokonywałem na wielu serwerach dla baz o różnej wielkości. Partycja jest zwykle o wielkości ~15-20 GB czyli jest znacznie większa od wielkości pliku.

Sposób pracy na bazie jest klasyczny, czyli dane są dokładane i to w dosyć sporej ilości.

W efekcie już po kilku tygodniach takiej pracy, plik bazodanowej jest bardzo mocno sfragmentowany. Filefrag zgłasza od kilkudziesięciu do nawet 200-300 tysięcy „extentsów”.

W ramach testów przeszedłem na XFS, efekt? Po kilku tygodniach pracy fragmentacja dla pliku ~2GB wynosi: 3 extents. Różnica jest olbrzymia.

Planuję obserwować jak będzie to zachowywać się na EXT3 w ramach alternatywy dla XFSa. I należałoby dać chyba jeszcze szansę reiserowi i zamontować go z opcją „notail”, być może to będzie miało pozytywny wpływ.

Epilog:

Po 3 tygodniach obserwacji, baza na XFS nadal jest w 3 częściach.

Baza umieszczona na Reiserfs zamontowanego z opcją notail, po kilku dniach zwiększyła ilość swoich kawałków z ponad dwóch tysięcy do ponad czterech tysięcy.

Exim i aliasy z bazy postgresowej

Aliasy trzymam w bardzo prostej tabelce:

CREATE TABLE aliasy
(
id serial NOT NULL,
alias text NOT NULL DEFAULT ”::text,
destination text NOT NULL DEFAULT ”::text,
CONSTRAINT aliasy_pkey PRIMARY KEY (id)
);

CREATE UNIQUE INDEX ind_alias
ON aliasy
USING btree
(alias);

CREATE TRIGGER cleanup_aliases
BEFORE INSERT OR UPDATE
ON aliasy
FOR EACH ROW
EXECUTE PROCEDURE cleanup_aliases();

CREATE OR REPLACE FUNCTION cleanup_aliases()
RETURNS „trigger” AS
$BODY$
DECLARE
BEGIN
NEW.alias := trim(both FROM lower(NEW.alias));
NEW.destination := trim(both FROM lower(NEW.destination));
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql’ VOLATILE;

Do tego jest trigger mający na celu zapisać w bazie dane małymi literami z obciętymi spacjami na początku oraz końcu. Ten trigger jest zapożyczony z blogu depesza.

Sam ruter w eximie wygląda następująco:

aliasy_postgres:
driver = redirect
allow_fail
allow_defer
data = ${lookup pgsql{ SELECT destination FROM aliasy where alias = (’${quote_pgsql:$local_part}@${quote_pgsql:$domain}’) }}

Exim + postgresql

Nadeszła chwila, kiedy to unixowe konta nie wystarczają do obsługi poczty. Witajcie wirtualni userzy.

Dlaczego postgres? Ponieważ bardzo nie lubię mysqla.

Podczas migracji korzystałem z różnych opisów dostępnych w sieci, wiele informacji (oraz trigerów :)  ) zaczerpnąłem ze strony depesza oraz ze strony Baseciqa . Okazało się jednak, że w powyższych opisach,  oraz w wielu innych jakie google podsuwały, brakowało kilku kluczowych elementów aby exim działał tak jak powinien działać serwer pocztowy. Tym „drobiazgiem” była przede wszystkim nieomówiona autoryzacja użytkowników wysyłających pocztę. Silnie podpierając się stroną ( http://devel.reinikainen.net/attachments/Exim/configure ) uruchomiłem możliwość wysyłania poczty wirtualnym użytkownikom.

Uff, następuje pierwsza próba wysłania maila. I zonk. Okazuje się, że exim dokleja swój primary hostname do adresu mailowego nadawcy. Czyli miałem nadawce takiego:

„user@wirtualna.domena.tld@moj.komputer.tld”

Tutaj wszystko zamykało się w jednej linijce:

control       = submission/sender_retain

Kolejna próba.. I? Pełny sukces! Zadziałało!

Kolejnym etapem będzie uruchomienie aliasów.