Instalacja PAM przebiega standardowo, źródło należy pobrać z http://www.kernel.org/pub/linux/libs/pam/library/ Po skompilowaniu i zainstalowaniu tworzymy katalog /etc/pam.d – tam znajdować się będą pliki konfigurujące poszczególne usługi. Aby PAM działał poprawnie musi być też plik domyślny – dla niezdefiniowanych usług - other. Tworzymy więc pliki: other i exim.
auth required pam_deny.so account required pam_deny.so password required pam_deny.so session required pam_deny.so
auth required pam_unix.so account required pam_unix.so session required pam_permit.so
To wszystko - PAM powinien działać.
Do instalacji wystarczy rozpakować, skompilować i zainstalować bibliotekę. Tzn: ./configure, make, make install
Instalować można dwojako: poprzez źródła dostępne na stronie albo przez cpan. Łatwiej zainstalować jest go przez CPAN
cpan Mail::SpamAssassin
Na pewno wyświetli się wiele złamanych zależności i cześć pakietów trzeba będzie doinstalować ręcznie ( nie wszystkie testy będą chciały przejść itp.)
Potem należy stworzyć katalog /.spamassassin i nadać zmienić właściciela na nobody:nogroup
Spamassassina uruchamia się za pomocą polecenia spamd
Ściągamy źródła z http://exim.org/ Następnie kopiujemy plik przykładowy src/EDITME do Local/Makefile.
a. EXIM_USER oraz EXIM_GROUP – odpowiada za użytkowników na jakich będzie działał demon exima – należy później ręcznie utworzyć tego użytkownika i grupę.
Ważne: użytkownik exima musi należeć (też) do grupy mającej prawo odczytu pliku shadow – jeśli PAM dla exima ustawiony jest na pam_unix.so.
b. Odhashować SUPPORT_MAILDIR – format pliku(katalogu) z pocztą użytkownika.
c. Odhashować LOOKUP_MYSQL – obsługa MySQL – przyda się do greylistingu
d.Odhashować WITH_CONTENT_SCAN – obsługa skanera spamu / antywirusa
e.Odhashować AUTH_PLAINTEXT – obsługa uwierzytelniania w otwartym tekście, w połączeniu z TLS jest to dobre rozwiązanie.
f.Odhashować SUPPORT_TLS oraz TLS_LIBS
g.Odhashować EXPERIMENTAL_SPF=yes, CFLAGS += -I/usr/local/include/spf2 oraz LDFLAGS += -lspf2
Teraz można skompilować program – wykonujemy:
./configure && make && make install
Jeśli przy kompilacji pokazują się błędy o brakach plików bibliotek należy odpowiednio pododawać katalogi zawierające pliki nagłówkowe do zmiennych include w pliku Makefile.
Po zainstalowaniu należy ustawić zmienna PATH do binarek exima: wykonuje się to ręcznie dopisując do plików login.defs lub profile. W pliku login.defs można jeszcze ustawić katalog z pocztą dla użytkowników z kontami shellowymi – linia „MAIL_DIR Maildir/” , gdzie Maildir to nazwa katalogu z pocztą.
1. Bazę dla greylistingu
CREATE DATABASE nazwa_bazy;
2. Tablicę greylisty
CREATE TABLE exim_greylist ( id integer NOT NULL auto_increment, relay_ip varchar(64), from_domain varchar(255), block_expires datetime NOT NULL, record_expires datetime NOT NULL, create_time datetime NOT NULL, PRIMARY KEY (id) );
3. tablice whitelisty
CREATE TABLE exim_whitelist ( id integer NOT NULL auto_increment, relay_ip varchar(64), from_domain varchar(255), create_time datetime NOT NULL, PRIMARY KEY (id) );
Główny plik konfiguracyjny znajduje się w /usr/exim/configure.
1. GREYLIST_TEST sprawdza czy okres greylistingu upłynął oraz czy wpis nie wygasł. Zwraca: 0 – nie ma na greyliście, 1 – jeszcze jest blokowany, 2 – czas greylistowania dobiegł końca – można pozwolić na wysyłkę poczty.
GREYLIST_TEST = SELECT CASE WHEN now() - block_expires > 0 THEN 2 ELSE 1\ END \ FROM exim_greylist WHERE relay_ip='${quote_mysql:$sender_host_address}'\ AND from_domain = '${quote_mysql:$sender_address_domain}'
2. WHITELIST_TEST sprawdza czy damy wpis nie znalazł się już na whiteliście. Wpisy w whiteliście nie wygasają, są kasowane za pomocą skryptu shellowego. Zwraca: 0 – brak wpisu, 1 - istnieje wpis.
WHITELIST_TEST = SELECT CASE WHEN id > 0 THEN 1 ELSE 0 END \ FROM exim_whitelist WHERE relay_ip='${quote_mysql:$sender_host_address}'\ AND from_domain = '${quote_mysql:$sender_address_domain}';
3. GREYLIST_ADD - dodaje domenę oraz IP do greylistowania.
GREYLIST_ADD = INSERT INTO exim_greylist (relay_ip, from_domain, \ block_expires, record_expires, create_time) \ VALUES ( '${quote_mysql:$sender_host_address}', \ '${quote_mysql:$sender_address_domain}', \ DATE_ADD(now(), INTERVAL 10 MINUTE), \ DATE_ADD(now(), INTERVAL 3 DAY), \ now() \ )
4. WHITELIST_ADD - dodaje domenę oraz IP jako zaufane - do whitelisty.
WHITELIST_ADD = INSERT INTO exim_whitelist(relay_ip, from_domain,\ create_time)VALUES( '${quote_mysql:$sender_host_address}',\ '${quote_mysql:$sender_address_domain}', now());
5. GREYLIST_REMOVE – usuwa wpis z greylisty (aby go dodać do whitelisty)
GREYLIST_REMOVE = DELETE FROM exim_greylist \ WHERE '${quote_mysql:$sender_host_address}' = relay_ip \ AND '${quote_mysql:$sender_address_domain}' = from_domain;
Następnie należy ustawić parametry bazy dla exima:
hide mysql_servers = adres_servera/nazwa_bazy/nazwa_użytkownika/hasło
Definicja głównej domeny:
primary_hostname = nazwa_domeny
Definicja domen dodatkowych:
domainlist local_domains = @:domena2:domena3
Hosty z których wyślemy pocztę gdziekolwiek, prawie bezwarunkowo:
relay_from_hosts = 127.0.0.1
Pozwala wszystkim używać TLS:
tls_advertise_hosts = *
Zwiększenie wydajności przy dużej ilości poczty:
split_spool_directory = true
Ludziom z whitelisty pozwalamy wysyłać pocztę:
warn set acl_m3 = ${lookup mysql{WHITELIST_TEST}{$value}{0}} accept condition = ${if eq{$acl_m3}{1}{1}}
Tak samo jeśli istnieje poprawny wpis SPF dla domeny:
accept spf = pass
Ludzie podszywający się są blokowani:
deny message = SPF check FAILED for $sender_address_domain spf = fail
Sprawdzamy greylistę:
warn set acl_m2 = ${lookup mysql{GREYLIST_TEST}{$value}{0}} #case 1 – nowa poczta, wpisujemy na greyliste defer message = Greylisted - please try again a little later. condition = ${if eq{$acl_m2}{0}{1}} condition = ${lookup mysql{GREYLIST_ADD}{yes}{no}} #case 2 - nowy mail jeszcze greylistowany defer message = Greylisted - please try again shortly. condition = ${if eq{$acl_m2}{1}{1}} #case 3 - greylistowanie dobiegło końca, wpisujemy na whiteliste accept condition = ${if eq{$acl_m2}{2}{1}} condition = ${lookup mysql{WHITELIST_ADD}{yes}{no}} condition = ${lookup mysql{GREYLIST_REMOVE}{yes}{no}}
Sprawdzanie wielkości maila:
deny message = message too big: $message_size bytes condition = ${if > {$message_size}{10M}}
Sprawdzanie przez spamassassina:
#więcej niż 10pkt deny message = This message scored $spam_score spam points. condition = ${if < {$message_size}{100K}} spam = nobody condition = ${if >{$spam_score_int}{100}{1}{0}} #5-10pkt warn condition = ${if < {$message_size}{100K}} condition = ${if >{$spam_score_int}{50}{1}{0}} add_header = X-Spam_score: $spam_score\n\ X-Spam_score_int: $spam_score_int\n\ X-Spam_bar: $spam_bar
Ustawienie dla formatu Maildir, w przypadku braku katalogu jest tworzony automatycznie.
local_delivery: driver = appendfile maildir_format = true directory = /home/users/$local_part\ /Maildir/${if eq{$local_part_suffix}{}{}\ {/.${substr_1:$local_part_suffix}}} maildirfolder_create_regex = /\.[^/]+$ use_fcntl_lock = true
LOGIN: driver = plaintext server_set_id = $auth1 server_prompts = <| Username: | Password: server_condition = ${if pam{$auth1:$auth2}{1}{0}} server_advertise_condition = yes
mysql -u nazwa_użytkownika --password=hasło nazwa_bazy < db_cl.sql
DELETE from exim_whitelist \ where from_domain not like '%.pl' \ and from_domain not like '%.com' \ and from_domain not like '%.org';
Skrypt uruchamiany jest raz na miesiąc (umieszczony w /etc/cron.monthly), wykonuje polecenie SQL z pliku db_cl.sql. Polecenie kasuje wszystkie wpisy z domen nie będących domenami pl, com, .org.
mysql -u nazwa_użytkownika --password=hasło nazwa_baz> < db_cl.sql
DELETE FROM exim_greylist WHERE record_expires < now();
Skrypt uruchamiany jest raz dziennie (umieszcozny w /etc/cron.daily), wykonuje polecenie SQL z pliku db_cl.sql. Polecenie kasuje wszystkie wpisy z domen, gdzie czas ważności wpisu wygasł.
GREYLIST_TEST = SELECT CASE \ WHEN now() - block_expires > 0 THEN 2 \ ELSE 1 \ END \ FROM exim_greylist \ WHERE relay_ip = '${quote_mysql:$sender_host_address}' \ AND from_domain = '${quote_mysql:$sender_address_domain}' GREYLIST_ADD = INSERT INTO exim_greylist (relay_ip, from_domain, \ block_expires, record_expires, create_time) \ VALUES ( '${quote_mysql:$sender_host_address}', \ '${quote_mysql:$sender_address_domain}', \ DATE_ADD(now(), INTERVAL 10 MINUTE), \ DATE_ADD(now(), INTERVAL 3 DAY), \ now() \ ) hide mysql_servers = adres_servera/baza/nazwa_usera/haslo WHITELIST_TEST = SELECT CASE WHEN id > 0 THEN 1 ELSE 0 END \ FROM exim_whitelist \ WHERE relay_ip = '${quote_mysql:$sender_host_address}'\ AND from_domain = '${quote_mysql:$sender_address_domain}'; WHITELIST_ADD = INSERT INTO exim_whitelist(relay_ip, from_domain,\ create_time) VALUES( '${quote_mysql:$sender_host_address}',\ '${quote_mysql:$sender_address_domain}', now()); GREYLIST_REMOVE = DELETE FROM exim_greylist \ WHERE '${quote_mysql:$sender_host_address}' \ =relay_ip AND '${quote_mysql:$sender_address_domain}' = from_domain; ###################################################################### # MAIN CONFIGURATION SETTINGS ###################################################################### primary_hostname =domena.pl domainlist local_domains = @:costam.pl domainlist relay_to_domains = hostlist relay_from_hosts = 127.0.0.1 acl_smtp_rcpt = acl_check_rcpt acl_smtp_data = acl_check_data spamd_address = 127.0.0.1 783 tls_advertise_hosts = * tls_certificate = /sciezka_do_certyfikatu/exim.crt tls_privatekey = /sciezka_do_klucza_prywatnego/exim.pem daemon_smtp_ports = 25 never_users = root:nobody host_lookup = 0 rfc1413_hosts = rfc1413_query_timeout = 1s ignore_bounce_errors_after = 1d timeout_frozen_after = 2d split_spool_directory = true ###################################################################### # ACL CONFIGURATION ###################################################################### begin acl acl_check_rcpt: accept hosts = : 127.0.0.1 deny message = Restricted characters in address domains = +local_domains local_parts = ^[.] : ^.*[@%!/|] deny message = Restricted characters in address domains = !+local_domains local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ #tutaj dopisani wybredni accept local_parts = postmaster : abuse domains = +local_domains require verify = sender accept hosts = +relay_from_hosts control = submission accept authenticated = * control = submission require message = relay not permitted domains = +local_domains : +relay_to_domains require verify = recipient #sprawdzamy whiteliste warn set acl_m3 = ${lookup mysql{WHITELIST_TEST}{$value}{0}} #pozwalamy whitelistowanym accept condition = ${if eq{$acl_m3}{1}{1}} #sprawdzamy czy ma dobrego SPFa jesli tak to mu pozwalamy accept spf = pass #jesli gosciu 100% sie podrabia to go deny deny message = SPF check FAILED for $sender_address_domain spf = fail #nie znalazl sie? to moze jest w greyu? warn set acl_m2 = ${lookup mysql{GREYLIST_TEST}{$value}{0}} #case 1 - nowy mail, wpisujemy na greyliste defer message = Greylisted - please try again a little later. condition = ${if eq{$acl_m2}{0}{1}} condition = ${lookup mysql{GREYLIST_ADD}{yes}{no}} #case 2 - nowy mail jeszcze greylistowany defer message = Greylisted - please try again shortly. condition = ${if eq{$acl_m2}{1}{1}} #case 3 - greylisotwanie dobieglo konca, wpisujemy na whiteliste accept condition = ${if eq{$acl_m2}{2}{1}} condition = ${lookup mysql{WHITELIST_ADD}{yes}{no}} condition = ${lookup mysql{GREYLIST_REMOVE}{yes}{no}} accept acl_check_data: deny message = message too big: $message_size bytes condition = ${if > {$message_size}{100M}} deny message = This message scored $spam_score spam points. condition = ${if < {$message_size}{100K}} spam = nobody condition = ${if >{$spam_score_int}{100}{1}{0}} warn condition = ${if < {$message_size}{100K}} condition = ${if >{$spam_score_int}{50}{1}{0}} add_header = X-Spam_score: $spam_score\n\ X-Spam_score_int: $spam_score_int\n\ X-Spam_bar: $spam_bar #X-Spam_bar: $spam_bar\n\ #X-Spam_report: $spam_report accept ###################################################################### # ROUTERS CONFIGURATION ###################################################################### begin routers dnslookup: driver = dnslookup domains = ! +local_domains transport = remote_smtp ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 no_more system_aliases: driver = redirect allow_fail allow_defer data = ${lookup{$local_part}lsearch{/etc/aliases}} file_transport = address_file pipe_transport = address_pipe #AUTO-REPLAY uservacation: driver = accept domains = +local_domains require_files = /home/$local_part/.vacation # do not reply to errors or lists condition = ${if or { \ {match {$h_precedence:} {(?i)junk|bulk|list}} \ {eq {$sender_address} {}} \ } {no} {yes}} # do not reply to errors or bounces or lists senders = ! ^.*-request@.*:\ ! ^bounce-.*@.*:\ ! ^.*-bounce@.*:\ ! ^owner-.*@.*:\ ! ^postmaster@.*:\ ! ^webmaster@.*:\ ! ^listmaster@.*:\ ! ^mailer-daemon@.*:\ ! ^root@.* no_expn transport = uservacation_transport unseen no_verify userforward: driver = redirect check_local_user file = $home/.forward no_verify no_expn check_ancestor file_transport = address_file pipe_transport = address_pipe reply_transport = address_reply localuser: driver = accept check_local_user transport = local_delivery cannot_route_message = Unknown user ###################################################################### # TRANSPORTS CONFIGURATION ###################################################################### begin transports remote_smtp: driver = smtp uservacation_transport: driver = autoreply file = /home/$local_part/.vacation file_expand once = /home/$local_part/.vacation.db once_repeat = 14d from = $local_part@$domain to = $sender_address subject = "Auto reply: $h_subject" headers = Content-Type: text/plain; charset=ISO-8859-2; format=flowed local_delivery: driver = appendfile # maildir_use_size_file = true # quota = 50M maildir_format = true directory = /home/$local_part\ /Maildir/${if eq{$local_part_suffix}{}{}\ {/.${substr_1:$local_part_suffix}}} maildirfolder_create_regex = /\.[^/]+$ use_fcntl_lock = true address_pipe: driver = pipe return_output address_file: driver = appendfile delivery_date_add envelope_to_add return_path_add address_reply: driver = autoreply ###################################################################### # RETRY CONFIGURATION ###################################################################### begin retry # Address or Domain Error Retries # ----------------- ----- ------- * * F,2h,10m; G,16h,1h,1.5; F,4d,6h ###################################################################### # REWRITE CONFIGURATION ###################################################################### begin rewrite ###################################################################### # AUTHENTICATION CONFIGURATION ###################################################################### begin authenticators LOGIN: driver = plaintext server_set_id = $auth1 server_prompts = <| Username: | Password: server_condition = ${if pam{$auth1:$auth2}{1}{0}} server_advertise_condition = yes
email: johnx@elwico.pl
Template: designsbydarren.com on license
All trademarks belong to their respective owners. All materials presented here for informational purposes only.