Bociek PLD - Pisarz
I. Informacje podstawowe
II. Instalacja
III. Podręcznik użytkownika
IV. Podręcznik administratora
Usługi dostępne w PLD
Exim - Transport poczty elektronicznej (MTA)
V. Tworzenie PLD - Praktyczny poradnik
VI. O podręczniku
O tej książce
Spis treści
Inne wersje tego dokumentu
HTML (jeden plik)
Odnośniki
Tworzymy dokumentację PLD
Strona PLD
Listy dyskusyjne PLD

Exim - Transport poczty elektronicznej (MTA)

<- ->
 

Usługa MTA (ang. message transfer agent) jest odpowiedzialna za przesył m.in. e-mail między serwerami. Najpopularniejszymi przedstawicielami tego typu usług są: Sendmail, Postfix czy opisany przez nas Exim. Oto zalety jakie przemawiają za wybraniem Exim-a jako naszego MTA:

  • Ponieważ Sendmail nie posiada nawet połowy jego funkcji

  • Autoryzacja w Exim-ie zaimplementowana jest domyślnie

  • Współpracuje z bazami MySQL i z Postgres-em, a także ze zwykłymi plikami tekstowymi

  • Tom Kistner napisał do Exim użyteczna łatkę, rozbudowywującą Exim o obsługę programów antywirusowych, demona SpamAssasin (skanera antyspamowego) oraz wykrywania błędów MIME - dzięki temu nie potrzebujemy wielkich i zasobożernych programów w perlu

  • Za to Tomasz Kojm napisał bardzo dobry program antywirusowy: Clam AntiVirus - darmowy, w dodatku rewelacyjnie współpracujący z Exiscanem

Podsumowując - Exim jest rewelacyjnym MTA. Jego możliwości konfiguracji pozwoliły mi na zbudowanie dosyć rozbudowanego serwera poczty obsługującego zarówno konta lokalne jak i konta zapisane w bazie danych MySQL. Dodatkowe możliwości to np. przeszukiwanie plików konfiguracyjnych serwera cvs w poszukiwaniu adresów docelowych dla aliasów w domenie cvs.rulez.pl. O rzeczach takich jak klasyfikowanie maili czy są spamem czy nie już nawet nie wspomnę. W dodatku Exim jest całkiem bezpiecznym MTA (wersja 4.x wg. securityfocus jak narazie dorobiła się jednego błędu - w końcu jakaś cena musi być za te wodotryski). Zresztą konstrukcja omawianego MTA na początku doprowadzała mnie do szału, gdyż Exim nie może sobie poradzić z smtp-auth via PAM z racji braku uruchamiania autoryzacji z własnego uid/gid zamiast root ;-)

Instalacja

Instalacja pakietu jest prosta. Uruchamiamy program: poldek i wykonujemy:

poldek -i exim

Oczywiście zanim wykonamy zalecenie startu demona powinniśmy dokonać konfiguracji, którą opisuje następny rozdział.

Budowa pliku konfiguracji

Wszelkich zmian w konfiguracji dokonujemy w pliku /etc/mail/exim.conf. Na początek wyjaśnimy jak zorganizowany jest plik konfiguracyjny, wygląda to mniej więcej tak:

# główna sekcja ...

opcje i dyrektywy sekcji głównej

begin sekcja1

opcje i dyrektywy sekcji1

begin sekcja3

...

Tak więc plik ten jest zbudowany z sekcji, które rozpoczynają się słowem begin nazwa, z wyjątkiem sekcji głównej, która jest na samym początku pliku i nie posiada swojego begina. Sekcje również nie mają żadnych słów kluczowych, które by je zamykały - po prostu początek begin nowej sekcji oznacza zakończenie poprzedniej. I tak, standardowo mamy następujące sekcje:

  • główna - odpowiedzialna za podstawowe ustawienia Exim

  • acl - listy kontroli dostępu, filtrowania, odrzucania i akceptowania poczty

  • routers - hm, najprościej jest to przetłumaczyć jako routery, czyli reguły kierowania wiadomości do odpowiednich transporterów

  • transports - tutaj tworzymy sposoby doręczenia poczty

  • retry - ustawienia ponowień

  • rewrite - reguły do przepisywania nagłówków

  • authenticators - reguły do autoryzacji

Co to są te całe 'transportery' i 'routery'? Właściwie to serce Exima. Jeżeli Exim dostaje jakiegoś maila to najpierw puszcza go przez routery, które można porównać do reguł ipchains/iptables - jeżeli mail załapie się na jakąś regułę (router) to jest przekazywany do transportu określonego przez ten router. Inaczej mówiąc router w Eximie kieruje maila do odpowiedniego transportera. Transporter natomiast robi już z mailem co należy - doręcza go lokalnie, albo przekierowywuje gdzieś indziej albo odsyła do innego serwera. Wiem, że w tym momencie może wydawać się to skomplikowane, ale nie przejmujcie się, to tylko wiedza teoretyczna która na początku nie będzie wam potrzebna. Musiałem natomiast wam wytłumaczyć, że są sekcje i że musicie nauczyć się tego, iż jak napiszę 'dopisać w sekcji głównej' to należy coś dopisać na początku pliku.

Podstawowa konfiguracja

Zanim zaczniemy konfigurację demona SMTP, musimy koniecznie dodać rekord MX do każdej strefy DNS obsługiwanej przez nasz serwer. Informacje na ten temat zawarto w tym dokumencie.

Domeny lokalne to takie, które Exim ma traktować jako 'swoje' domeny. Mail zaadresowany @jakas.domena.lokalna który dotrze do Exim zostanie dostarczony lokalnie. Domeny takie definiuje w dyrektywie domainlist local_domains. Standardowo, przyjmowana jest poczta wysyłana do domeny identycznej jak hostname serwera:

domainlist local_domains = @

Znak @ oznacza właśnie 'moja nazwa'. Aby dopisać kolejne domeny wystarczy dodać je do tej listy rozdzielając je dwukropkami:

domainlist local_domains = @ : domena.pl : baseciq.org : \
    /etc/mail/local_domains

Poza domena.pl, baseciq.org, Exim będzie teraz także akceptował domeny wypisane w pliku /etc/mail/local_domains. Domeny tam należy wpisywać w oddzielnych linijkach. Exim o tyle fajnie działa, że po dopisaniu ścieżki do pliku, wystarczy go raz zrestartować. Jakiekolwiek kombinacje w /etc/mail/local_domains nie będą wymagały restartu. Tak więc najwygodniej będzie dopisać do pliku konfiguracyjnego:

domainlist local_domains = @ : /etc/mail/local_domains

I po prostu powpisywać wszystkie domeny do /etc/mail/local_domains.

Domeny dla których mamy być zapasowym MX'em tworzy się bardzo łatwo. Linijkę pod domainlist local_domains jest domainlist relay_to_domain. Działa to w taki sam sposób jak konfiguracja domen lokalnych, czyli, piszemy:

domainlist relay_to_domains = /etc/mail/relay_to_domains

Od teraz, Exim będzie akceptował każdą pocztę zaadresowaną do domen zawartych w pliku /etc/mail/relay_to_domains. A co z nią zrobi? Jak wiadomo, jeżeli domena ma kilka MX'ów, to Exim będzie starał się ją dostarczyć do serwera o najniższym priorytecie MX. Chyba że on ma najniższy, to wygeneruje błąd.

Relaying, czyli określenie kto może przez nasz serwer wysyłać pocztę. I tutaj, listę adresów i hostów buduje się w podobny sposób do local_domains i relay_to_domains. Wystarczy stworzyć listę o nazwie relay_from_hosts:

hostlist   relay_from_hosts = 127.0.0.1 : 192.168.0.0/16

Uwaga! Już w tym momencie możemy sprawdzić działania serwera. Wystarczy że przeładujemy demona i wyślemy e-mail do istniejącego konta użytkownika. Przy takiej konfiguracji poczta będzie docierała do skrzynek typu mbox.

Skrzynki pocztowe

Exim potrafi umieszczać pocztę zarówno w skrzynkach typu mbox (pliki tekstowe w /var/mail/) jak i coraz popularniejszych skrzynkach typu Maildir (pliki przechowywanie w katalogu umieszczonym w katalogu domowym użytkownika). Ze względu na wsteczną zgodność Exim domyślnie używa tych pierwszych, aby używać Maildir-a wykonujemy następujące czynności:

W sekcji konfiguracji transporterów odszukujemy opcję "local_delivery", tam wstawiamy znak komentarza przed opcją "file =" i dodajemy linijki:

  maildir_format = true
  directory=${home}/Mail/Maildir

Jak się łatwo domyślić druga z opcji wskazuje miejsce przechowywanie skrzynek. Po modyfikacji omawiana sekcja może wyglądać następująco:

local_delivery:
  driver = appendfile
#  file = /var/mail/$local_part
  delivery_date_add
  envelope_to_add
  return_path_add
  group = mail
  mode = 0660
  maildir_format = true
  directory=${home}/Mail/Maildir

Exim samodzielnie tworzy skrzynki pocztowe (oba rodzaje), wystarczy jedynie wysłać e-mail na konto użytkownika.

Możemy przekazać dostarczanie poczty do skrzynek programowi Procmail. Wystarczy, że w sekcji routerów usuniemy znaki komentarza z kolejnych wierszy zaczynających się od "procmail:", podobnie postępujemy w sekcji transporterów w miejscu zaczynającym się od wiersza "procmail_pipe:". Na koniec musimy jeszcze tylko umieścić plik konfiguracji Procmaila: .procmailrc w katalogu domowym użytkownika.

Różne opcje

Czasami (czytaj: gdy mamy sieczkę w /etc/hosts) Exim zgłasza się nie jako serwer.domena.pl a jako sam 'serwer'. Jeżeli zmiana wpisów w /etc/hosts nie pomaga, albo gdy chcemy aby nasze MTA przedstawiało się inaczej niż hostname maszyny na którym stoi wystarczy ustawić (bądź dodać gdy jej nie ma) opcję primary_hostname w głównej sekcji:

primary_hostname = serwer.domena.pl

W czasach zabawy z Sendmail-em podawałem także sposób na ograniczenie bannera, który się pojawiał po telnecie na port 25. W Exim-ie nie jest to skomplikowane i służy do tego opcja smtp_banner w sekcji głównej:

smtp_banner = $primary_hostname ESMTP $tod_full

Spowoduje to wyświetlanie następującego tekstu jako bannera:

220 serwer.domena.pl ESMTP Wed, 23 Jul 2003 15:18:04
			+0200

Chyba nie muszę tłumaczyć, że aby usunąć datę należy wywalić $tod_full?

Teraz zajmiemy się aliasami. Plik z aliasami powinien znajdować się w /etc/mail/aliases. Jest to czysty plik tekstowy, wprowadzone w nim zmiany wymagają wydania polecenia newaliases. Restart demona nie jest konieczny. Jeżeli jednak nie macie pewności czy tam powinien być plik z aliasami, w sekcji routers odszukajcie ciąg system_aliases: - jest to definicja routera odpowiedzialnego za rozwiązywanie aliasów. Tam też, w linijce data widać ścieżkę do pliku z aliasami:

system_aliases:
  driver = redirect
  allow_fail
  allow_defer
  data = ${lookup{$local_part}lsearch{/etc/mail/aliases}}
  file_transport = address_file
  pipe_transport = address_pipe

Autoryzacja SMTP

Jeżeli z naszego SMTP korzystają użytkownicy spoza sieci lokalnej przyda nam się autoryzacja. Sprawa w Exim-ie jest dosyć zawiła. Otóż Exim zbyt wcześnie zrzuca uprawnienia root, tak że opisywany na wielu stronach opis zrobienia autoryzacji via PAM najczęściej nie działa. Z pomocą przyjdzie nam pakiet cyrus-sasl, a dokładniej pwcheck daemon (w PLD cyrus-sasl-saslauthd). W sekcji AUTHENTICATORS wpisujemy następujące linijki (lub kasujemy komentarze #)

plain:
  driver = plaintext
  public_name = PLAIN
  server_prompts = :
  server_condition = ${if saslauthd{{$1}{$3}}{1}{0}}
  # powyższy wpis zadziała przy saslauthd -a shadow, jeżeli
  # uruchomicie saslauthd -a pam (np. PLD) wpiszcie wtedy:
  # server_condition = ${if saslauthd{{$1}{$3}{smtp}}{1}{0}}
  server_set_id = $2
      
login:
  driver = plaintext
  public_name = LOGIN
  server_prompts = "Username:: : Password::"
  server_condition = ${if saslauthd{{$1}{$2}}{1}{0}}
  # powyższy wpis zadziała przy saslauthd -a shadow, jeżeli
  # uruchomicie saslauthd -a pam (np. PLD) wpiszcie wtedy:
  # server_condition = ${if saslauthd{{$1}{$2}{smtp}}{1}{0}}
  server_set_id = $1

Ostatnią rzeczą przy saslauthd (uruchomionym z opcją -a pam) jaką trzeba stworzyć (lub sprawdzić czy jest) to plik /etc/pam.d/smtp:

#%PAM-1.0
#
# example PAM file for saslauthd - place it as /etc/pam.d/
# (e.g. /etc/pam.d/smtp if you want to use saslauthd for SMTP
# AUTH)
#
auth	required	/lib/security/pam_listfile.so
item=user sense=deny file=/etc/security/blacklist
onerr=succeed
auth	required	/lib/security/pam_unix.so
auth	required	/lib/security/pam_tally.so
file=/var/log/faillog onerr=succeed no_magic_root
auth	required	/lib/security/pam_nologin.so
account	required	/lib/security/pam_tally.so deny=0
file=/var/log/faillog onerr=succeed no_magic_root
account	required	/lib/security/pam_unix.so
session	required	/lib/security/pam_unix.so

Pozostaje mi tylko wam przypomnieć, że przed sprawdzaniem autoryzacji należy także uruchomić pwcheck saslauthd

# echo 'pwcheck_method:saslauthd' > /etc/sasl/smtpd.conf

Syfrowanie SSL

Exim sobie bardzo dobrze radzi z połączeniami szyfrowanymi przy użyciu protokołu SSL (wspiera metodę STARTTLS). Wystarczy wygenerować odpowiednie certyfikaty:

$ openssl genrsa -out /etc/mail/exim.key 1024
Generating RSA private key, 1024 bit long modulus
.......++++++
..............................++++++
e is 65537 (0x10001)
$ openssl req -new -x509 -days 365 -key /etc/mail/exim.key -out \
    /etc/mail/exim.crt
Using configuration from /var/lib/openssl/openssl.cnf
You are about to be asked to enter information that will be
incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:PL
State or Province Name (full name) [Some-State]:Mazowsze
Locality Name (eg, city) []:Warsaw
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Baseciq Ltd.
Organizational Unit Name (eg, section) []:Baseciq's Mail Server
Common Name (eg, YOUR name) []:viper.baseciq.org
Email Address []:baseciq@baseciq.org

Oczywiście na pytania odpowiadajcie podając swoje dane... Po takim zabiegu do sekcji głównej Exim należy dopisać:

tls_certificate = /etc/mail/exim.crt
tls_privatekey = /etc/mail/exim.key
tls_advertise_hosts = *

Po tym zabiegu i restarcie Exim powinien bez problemu komunikować się po SSL, co zresztą widać w logach:

2003-09-07 01:48:36 19vmnC-0006EG-27 <=	bensonzow@beer.com H=plug.atn.pl
[217.8.186.28] U=exim P=esmtp X=TLSv1:DES-CBC3-SHA:168 S=2909
id=ebb601c374e2$80dace00$cab00a12@fv

Dawniej Exim mógł nasłuchiwać porcie 465 jedynie przy użyciu inetd, w nowszych wersjach wystraczy że ustawimy odpowiednie opcje:

daemon_smtp_ports = 25 : 465
tls_on_connect_ports = 465

Warto by było, żeby także pop3d obsługiwał SSL natywnie ssl (bez jakichś stunneli i innych wynalazków). Ja osobiście polecam demonik tpop3d, którego konfiguracja jest bardzo prosta. Instalujemy tpop3d:

# poldek -i tpop3d

a następnie wystarczy że standardowe listen-address w pliku /etc/tpop3d.confzmienimy na takie:

listen-address:	0.0.0.0;tls=stls,/etc/mail/exim.crt,/etc/mail/exim.key \
		0.0.0.0;tls=immediate,/etc/mail/exim.crt,/etc/mail/exim.key

Od teraz tpop3d na porcie 110 będzie obsługiwał SSL po wykonaniu komendy STLS (np. TheBat potrafi tak zacząć sesję SSL) a na porcie 995 będzie od razu używał SSL (TheBat, Outlook Express).

Quota

Generalnie nie ma sensu męczyć kernela i filesystemu żeby pilnował quoty na pocztę. Szczególnie gdy MTA samo sobie może z tym poradzić. Służy do tego parametr quota w konfiguracji transportów. I tak, w najprostszy sposób można lokalną quotę per user ustawić w konfiguracji transportu local_delivery (odpowiedzialnego za lokalne dostarczanie poczty):

local_delivery:
	driver = appendfile
	file = /var/mail/$local_part
	delivery_date_add
	envelope_to_add
	return_path_add
	# A tutaj dodajemy quotę w wysokości 20MB:
	quota = 20M

Proste, prawda? Tak naprawdę ma to zastosowanie w systemach poczty wirtualnej gdzie możemy w bazie danych przechowywać quotę użytkownika i można skonstruować zapytanie SQL do odpytania ile miejsca ma dany użytkownik. Ale jeżeli nie możecie sobie poradzić z quotą systemową, możecie zamiast quota = 20M dopisać coś takiego:

quota =	${lookup{$local_part}lsearch{/etc/mail/quota.conf}{$value}{0M}}

Od tego momentu w pliku /etc/mail/quota.conf możesz trzymać wielkości skrzynek dla poszczególnych użytkowników. Jeżeli ktoś nie zostanie tam wymieniony, to nie będzie miał żadnych limitów na swoją skrzynkę pocztową. Plik taki powinien wyglądać mniej więcej tak:

lukasz:	100M
kflis:	5M
ania:	20M

I tak oto ja mam 100mb na pocztę, kubuś tylko 5, a siostra 20 MB ;) Podobnym parametrem każdego transportera jest message_size_limit. Wystarczy wpisać:

message_size_limit = 10M

Podobnie jak powyżej, można zrobić to na bazie pliku - wystarczy zamiast /etc/mail/quota.conf użyć np. /etc/mail/size_limits.conf ;-) BTW. na końcu linijki z quotą, gdzie mamy '0M' możemy wstawić np. '20M'. Wtedy, osoby nie dopisane do /etc/mail/quota.conf będą miały 20MB limitu (limit domyślny).

Oczywiście jak na Exim przystało, od quoty jest więcej bajerków. Chyba najbardziej pożądanym będzie opcja quota_warn_message. Jest to nic innego jak mail ostrzegający usera o tym, że skrzynka jest zapchana po same brzegi. Zanim jednak polecisz to wdrażać, zainteresuj się jak to działa. Otóż po dostarczeniu każdego maila Exim będzie sprawdzał czy został przekroczony konkretny próg (podany w megabajtach lub w procentowo). Jeżeli tak, wygeneruje on odpowiednią wiadomość. I tak, dodajemy do molestowanego przez nas local_delivery następujące opcje:

quota_warn_message = "\
Content-Type: text/plain; charset=ISO-8859-2\n\
To: $local_part@$domain\n\
Reply-to: Administratorzy sieci <admins@twojadomena.pl>\n\
Subject: Informacja o Twoim koncie pocztowym\n\
\n\
*** Ta wiadomość została wygenerowana automatycznie ***\n\
\n\
Uprzejmie informujemy, iż skrzynka pocztowa została zapełniona w 90%\n\
swojej pojemności. W przypadku 100% nie będą dostarczane\n\
do Ciebie nowe wiadomości. Opróżnij skrzynkę pocztową ze starych\n\
wiadomości.\n"
	quota_warn_threshold = 90%

Dodanie skanerów antywirusowych

Aby Exim współpracował z jakimś antywirusem należy najpierw wybrać i zainstalować program antywirusowy. Doświadczenie uczy, że najlepszy jest program Clamav.

Instalujemy więc Clamav

# poldek -i clamav clamav-database

Po zainstalowaniu Clamav musimy zmodyfikować plik konfiguracyjny /etc/mail/exim.conf w sekcji głównej ustawiamy typ antywirusa:

av_scanner = clamd:/var/lib/clamav/clamd.socket

Po dwukropku ustawiamy ścieżkę do socketu antywirusa (w przypadku clamav - zajrzyj do pliku /etc/clamav.conf). W miejscu gdzie wpisaliśmy clamd, możemy wpisać także i inny typ skanera. Niestety, żaden z innych obsługiwanych (sophie, kavdaemon, drweb) skanerów nie jest darmowy. Jeżeli natomiast wolicie mks, to możecie użyć takiej opcji:

av_scanner = mksd

Kolejnym etapem, jest stworzenie reguł do filtrowania maili z wirusami. W tym celu, dopisujemy do sekcji głównej pliku konfiguracyjnego Exim:

acl_smtp_data = exiscan

Teraz zaczynamy grzebanie w sekcji acl, gdzie dopisujemy (najlepiej na samym początku):

exiscan:
deny	message = Znaleziono wirusa. \n\
	Virus or other harmful content found: $malware_name
	delay = 1s
	malware = *

warn	message = X-MIME-Warning: Serious MIME defect detected ($demime_reason)
	demime = *
	condition = ${if >{$demime_errorlevel}{2}{1}{0}}

warn	message = Message-ID: <E$message_id@$primary_hostname>
	condition = ${if !def:h_Message-ID: {1}}
accept

Pierwszy wpis odpowiednio skanuje cały e-mail i jeśli zostanie znaleziony wirus lub inna zawartość uznana za szkodliwą przez skaner antywirusowy to taki mail jest odrzucany oraz informacja o znalezionym wirusie zostaje wyświetlona z jednosekudnowym opóźnieniem. Te opóźnienie ma na celu unikniecia ewentualnego zapchania serwera poczty poprzez uciążliwego użytkownika co chwila próbujacego wysłać pocztę uznaną za szkodliwą. Kolejny warunek spowoduje iż maile z uszkodzonymi nagłówkami MIME zostaną odpowiednio oznaczone (czyli, także, duże maile podzielone na części, o czym niestety autor exiscana (aut. łatki dla Exim-a) nie wspomina, dlatego ich nie odrzucamy). Ostatni warunek ma na celu wyeliminowanie sytuacji gdy jakaś wiadomość, która dotarła do naszego serwera poczty nie posiada unikalnego identyfikatora. W takim przypadku generujemy i dopisujemy własny Message-ID.

Aby skaner av mógł sprawdzać pocztę Exima musi zostać dodany do grupy exim. Dokonujemy tego poleceniem groupadd albo edytując po prostu plik /etc/group:

[...]
			
exim:x:79:clamav,mail

[...]

Kolejny feature jaki daje exiscan to odrzucanie plików z załącznikiem o określonym rozszerzeniu. W tym celu dopisujemy zaraz po exiscan: następujące linijki:

deny	message = Niedozwolone zalaczniki. \n\
	Blacklisted file extension ($found_extension) detected.
	condition = ${if match \
		{${lc:$mime_filename}} \
		{\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.vbs)$\N} \
		{1}{0}}
		delay = 1s
	log_message = Blacklisted file extension ($found_extension) detected.

Powyższa regółka ma na celu zablokowanie możliwości wysyłanie wiadomości, których załącznikami są pliki: *.exe, *.pif, *.bat, *.scr, *.lnk oraz *.vbs. Teraz, jeżeli nie chcemy aby skanowane były maile pochodzące od danych adresów ip dopisujemy (jeżeli chcemy aby Ci ludzie też nie mogli wysyłać plików *.com, to po poprzedniej regułce, jeżeli oni będą mogli, to przed):

accept	hosts = /etc/mail/dontscan

Teraz, w pliku /etc/mail/dontscan umieszczamy adresy IP bądź klasy adresowe z których poczta ma nie być skanowana.

Jeżeli natomiast chcecie, by poczta przeskanowana u was w przypadku gdy wróci w jakiś sposób z powrotem do naszego serwera (np. poprzez alias na innym serwerze) nie była ponownie skanowana, możecie zacząć oznaczać pocztę odpowiednimi znacznikami oraz przyjąć że poczta z tym znacznikiem nie była ponownie skanowana. Tak więc, przed końcowym accept dodajemy:

warn	message = X-Scan-Signature: ${hmac{md5}{atutajwpiszhaslo} \
		{$body_linecount}}

Exim spowoduje dodanie zaszyfrowanego ciągu znaków składającego się z hasła i wielkości maila. Dzięki temu ktoś kto nie pozna waszego hasła nie będzie mógł sfałszować informacji o tym że mail został już zeskanowany. Teraz, aby taka poczta przechodziła bez skanowania, na samym początku po exiscan: dopisujemy:

accept	condition = ${if eq {${hmac{md5}{atutajwpiszhaslo} \
	{$body_linecount}}}{$h_X-Scan-Signature:} {1}{0}}

Ustawienie takich regułek z tym samym hasłem na kilku serwerach spowoduje że gdy mail będzie przechodził przez kilka z nich, tylko jeden będzie musiał go przeskanować.

Walka ze spamem

Zjawisko spamu jest niezwykle uciążliwe. W niektórych Stanach w USA traktowane jest w kategoriach kryminalnych. Zapewne znasz jego definicję lub przynajmniej wiesz jak spam wygląda. W skrócie jest to wiadomość e-mail, której nie chciałeś otrzymać. Exim posiada wbudowaną obsługę filtra antyspamowego opartego na technice dnsbl, może wykorzystwać zarówno czarne listy jak i białe listy nadawców oraz adresów serwerów.

Kolejnym bardzo prostym ale niezwykle skutecznym w walce ze spamem jest maksymalne opóźnianie procesu komunikacji pomiedzy klientem wysyłającym poczte a serwerem MTA. Nie tylko odcina to część robotów spamerskich ale także zmiejsza ryzyko przeciążenia serwera.

Przejdźmy do konfiguracji. Wszystkie te wpisy powinny znaleść się w sekcji ACL CONFIGURATION w obrębie acl_check_rcpt:.

Wymuszamy helo/ehlo

deny	message = Wymagane RFC HELO/EHLO zanim wyslesz wiadomosc. \n\
	RFCs mandate HELO/EHLO before mail can be sent.
	condition = ${if or{{!def:sender_helo_name}{eq{$sender_helo_name}{}}}{yes}{no}}
	delay = 5s
	log_message = No HELO/EHLO.

Definujemy własne białe listy. Jeśli nasz zestaw regół okazałby się zbyt restrycyjny możemy oznaczyć aby pewne domeny były traktowane "ulgowo".

accept	domain = +local_domains
	condition = /etc/mail/whitelist	

Sprawdzamy czy serwer nadawcy figuruje na listach RBL

deny	message = Serwer nadawcy figuruje na liscie RBL \n\
	Server $sender_host_address is at RBL: \
	$dnslist_domain\n$dnslist_text
	delay = 5s
	dnslists = blackholes.mail-abuse.org : \
	dialup.mail-abuse.org : \
	dnsbl.njabl.org : \
	sbl.spamhaus.org : \
	list.dsbl.org : \
	cbl.abuseat.org : \
	relays.ordb.org : \
	bl.spamcop.net
	hosts = ! +relay_from_hosts
	log_message = Listed at RBL list: $dnslist_domain\n$dnslist_text.

deny	message = Serwer nadawcy figuruje na liscie RBL \n\
	Server $sender_host_address is at RBL: $dnslist_domain.
	hosts = ! +relay_from_hosts
	dnslists = bogusmx.frc-ignorant.org/$sender_host_name : \
	dns.rfc-ignorant.org/$sender_host_name
	delay = 5s
	log_message = Listed at RFC-Ignorant.

Teraz dokonujemy weryfikacji podanego HELO

HELO nie może być postaci localhost.localhomain

deny	message = Niepoprawne HELO. \n\
	$sender_helo_name is a stupid HELO.
	hosts = !+relay_from_hosts
	condition = ${if match {$sender_helo_name}{\N^(127\.0\.0\.1|localhost(\.localdomain)?)$\N}{yes}{no}}
	delay = 5s
	log_message = Stupid localhost HELO.

HELO musi być nazwą domenową (hostname)

deny	message = HELO musi byc nazwa domenowa. \n\
	HELO must be hostname.
	hosts = !+relay_from_hosts
	condition = ${if !match {$sender_helo_name}\
		{\N.*[A-Za-z].*\N}{yes}{no}}
	delay = 5s
	log_message = Helo must be hostname.

Według RFC821 HELO musi być pełną nazwą domenową (Fully Qualifield Domain Name).

deny	message = HELO nie wyglada poprawnie. Zobacz RFC 821. \n\
	HELO must contain a Fully Qualifield Domain Name. See RFC821.
	hosts = !+relay_from_hosts
	condition = ${if !match{$sender_helo_name} \
		{\N.*[A-Za-z].*\..*[A-Za-z].*\N}{yes}{no}}
	delay = 5s
	log_message = HELO is not a FQDN.

Eliminujemy sytuację gdy nadawca jako HELO podaje serwer z naszej domeny np. domena.pl

deny	message = Wykryto zafalszowane RFC HELO. \n\
	Fake HELO detected: $sender_helo_name.
	condition = ${if eq{$sender_helo_name}\
		{\N^(.*\.)?domena\.pl$\N}{yes}{no}}
	hosts = !+relay_from_hosts
	delay = 5s
	log_message = Fake HELO from host $sender_helo_name.

Kolejne dwa warunki są bardzo restrycyjnymi testami. Formalnie przez RFC nie jest wymagane aby domena miała zdefiniowany rekord MX. Lecz każdy szanujący się administrator poważnej domeny zawsze zadba aby odpowiednie serwery figurowaly jako MX. RFC zaleca aby jeśli już jest zdefiniowany rekord MX dla domeny, to aby był on postaci FQDN

deny	message = Brak zdefiniowanego rekordu MX dla domeny. \n\
	No MX envelope sender domain $sender_address_domain.
	hosts = ! : !+relay_from_hosts
	senders = ! :
	condition = ${if eq{${lookup dnsdb{mx=$sender_address_domain}{$value}fail}}{fail}{yes}{no}}
	delay = 5s
	log_message = No MX record in DNS.

deny	message = Rekord MX w DNS musi byc postaci FQDN. \n\
	MX for transport sender domain $sender_address_domain must be FQDN.
	hosts = ! : !+relay_from_hosts
	senders = ! :
	condition = ${if !match {${lookup dnsdb{mx=$sender_address_domain}{$value}fail}}\
		{\N.*[A-Za-z].*\..*[A-Za-z].*\N}{yes}{no}}
	delay = 5s
	log_message = MX record is not a FQDN.

Krótkie wyjaśnienie wykorzystanych opcji

  • deny message

    Określamy jaka informacja zwrotna pojawi się u nadawcy.

  • delay

    Opóźnienie po jakim komunikat określnony jako message zostanie zwrócony nadawcy.

  • dnslist

    Lista systemów z bazami blokującymi serwery open relay. Wymienione tutaj powinny skutecznie powstrzymać spam. Jeżeli nadal dostajesz niechciane maile, wykonaj następujące czynności. Sprawdź w nagłówku wiadomości adres IP serwera, który przekazał Twojemu MTA pocztę. Wejdź na stronę: www.ordb.org/lookup/ i wpisz adres IP do sprawdzenia. Jeżeli wyszukiwanie w bazie ordb.org nie przyniesie rezultatów, wejdź tutaj: http://www.ordb.org/lookup/rbls/?host=w.x.y.z, gdzie zamiast symbolicznego zapisu podajemy adres IP. Skonstruowane w ten sposób zapytanie dokona sprawdzenia, czy dany adres IP figuruje na innych czarnych listach. Pozytywny rezultat testu powinien zwrócić w odpowiedzi listę systemów RBL (Relay Black List). Można ją wykorzystać dopisując do naszej regułki. Uważaj na system block.blars.org figuruje w nim smtp.wp.pl.

  • hosts

    Podana lista serwerów. W powyższym przykładzie jest to !+relay_from_hosts co oznacza, że cała regółka dotyczy połączeń z wszystkich serwerów za wyjątkiem tych zdefiniowanych jako relay_from_hosts.

  • log_message

    Informacja jaka zostanie zapisana w dzienniku systemowym exima czyli /var/log/exim/main.log

Teraz należałoby włączyć wszystkie usługi jakie zainstalowaliśmy

# /etc/rc.d/init.d/exim start
# /etc/rc.d/init.d/saslauthd start
# /etc/rc.d/init.d/clamd start
# /etc/rc.d/init.d/tpop3d start
# /etc/rc.d/init.d/rc-inetd restart

Na koniec przykładowy zapis z dziennika systemowego Exima

2004-03-04 21:05:24 H=(sina.com) [218.79.119.92] F=< jin@sina.com > \
    rejected RCPT < user@domena.pl >: \
    Serwer 218.79.119.92 figuruje na czarnej liście dnsbl.sorbs.net

Obsługa wielu domen w Eximie

Jeżeli czytasz tą część opisu konfiguracji exima stanąłeś przed problemem obsługi przez niego więcej niż jednej domeny. Exim jest jak najbardziej do tego przystosowany. Poniżej zamieszczam listing z pliku /etc/mail/exim.conf

virtusertable_alias:
   driver = redirect
   allow_fail
   allow_defer
   data = ${lookup{$local_part@$domain}lsearch{/etc/mail/virtusertable}}
   file_transport = address_file
   pipe_transport = address_pipe
virtusertable_defaultalias:
   driver = redirect
   allow_fail
   allow_defer
   data = ${lookup{@$domain}lsearch{/etc/mail/virtusertable}}
   file_transport = address_file
   pipe_transport = address_pipe

Powyższy przykład umieść umieść na początku sekcji routers. Dla przypomnienia dodam, że początek sekcji oznacza się słowem kluczowym begin.

Jak słusznie zauważyłeś, wpisy z virtusertable do złudzenia przypominają te z system_aliases. Działa to właściwie w ten sam sposób. Podczas odbierania przesyłki exim czyta linijkę data. Ma w niej zdefiniowane, że ma szukać na podstawie local_partczyli to co jest przed znakiem @ oraz domain czyli części domenowej adresu. Wartości które zostaną podstawione zamiast tych zmiennych zostaną porównane z plikiem /etc/mail/virtusertable. Jeżeli wynik porównania wypadnie pomyślnie poczta zostanie dostarczona do odpowiedniego użytkownika, jeżeli zaś nie, odpytane zostaną aliasy systemowe. Jeżeli i tam użytkownik nie zostanie odnaleziony, zostanie wysłana wiadomość z odpowiednią informacją do nadawcy z komunikatem błędu. Część defaultalias jest prawie identyczna. Różnica tkwi jedynie w opcji data. Sprawdzana jest jedynie część domenowa. Poniżej zamieszczam listing z pliku /etc/mail/virtusertable

user@domena.pl		user
mister@sample.com	user2
@jakasdomena.pl		user3

Jak widać budowa pliku jest prosta i czytelna. User3 będzie otrzymywał całą pocztę z domeny jakasdomena.pl. Po tych zabiegach exim powinien być już przygotowany do obsługi wielu domen. Musisz pamiętać aby go zrestartować po dokonaniu modyfikacji jego pliku konfiguracyjnego.

# /etc/rc.d/init.d/exim restart

Automatyczna odpowiedź - Vacations

W przypadku, gdy masz zamiar gdzieś wyjechać na dłużej i nie będziesz miał dostępu do poczty, dobrym pomysłem jest ustawienie automagicznej odpowiedzi dla ludzi, którzy do Ciebie piszą. Tu z pomocą przychodzi nam opcja w Eximie.

Na początku edytujemy plik /etc/mail/exim.conf i w sekcji routers przed localuser router dodajemy następujące linijki:

user_vacation:
     driver = accept
     check_local_user
     # nie odpisujemy na błędy bądź listy dyskusyjne
     condition = "${if or {{match {$h_precedence:} {(?i)junk|bulk|list}} {eq {$sender_address} {}}} {no} {yes}}"
     no_expn
     require_files = /var/mail/vacation/${local_part}/vacation.msg  
     # nie odpisujemy na maile od list dyskusyjnych oraz na powiadomienia o błędach
     senders = " ! ^.*-request@.*:\
		 ! ^.*@list*.*:\ 
                 ! ^owner-.*@.*:\
                 ! ^postmaster@.*:\
                 ! ^listmaster@.*:\
                 ! ^mailer-daemon@.*\
                 ! ^root@.*"
     transport = vacation_reply
     unseen
     user = ${local_part}
     no_verify

Następnie tworzymy katalog /var/mail/vacation , w którym będą się znajdować katalogi zawierające nazwę użytkownika oraz pliki z informacjami o powodzie jego nieobecności. Powód taki wpisujemy do pliku vacation.msg znajdującego się w /var/mail/vacation/NAZWA_UŻYTKOWNIKA/. Gdy już mamy te ustawienia za sobą w sekcji transport dodajemy następujące linijki:

vacation_reply:
     driver = autoreply
     file = /var/mail/vacation/$local_part/vacation.msg
     file_expand
     from = System Automatycznej Odpowiedzi <$original_local_part@$original_domain>
     log = /var/mail/vacation/$local_part/vacation.log
     once = /var/mail/vacation/$local_part/vacation.db
     once_repeat = 7d
     subject = ${if def:h_Subject: {Re: ${quote:${escape:${length_50:$h_Subject:}}} (autoreply)} {Informacja} }
     text = "\
     Witaj $h_from\n\n\
     Ta wiadomość została wygenerowana automatycznie\n\
     Tekst poniżej zawiera informację od użytkownika:\n\
     ====================================================\n\n\
     "
     to = "$sender_address"

Ważną częścią tutaj jest opcja once_repeat, która sprawdza jak często nadawcy będą otrzymywać odpowiedzi. W tej konfiguracji jest to co 7dni.

To wszystko, teraz musimy jeszcze zrestartować Exima i możemy jechać na urlop.

# /etc/rc.d/init.d/exim restart

 
&lt;- ->