Hlavní navigace

Stavíme vlastní e-mailový server: nastavení serveru, spam a IMAP

20. 6. 2017
Doba čtení: 22 minut

Sdílet

V dnešním článku z naší série si dokončíme nastavení serveru jako takového, nastavíme si ochranu proti SPAMu, virům a nainstalujeme si Dovecot, který nám poskytne zbývající služby.

Na úvod bych rád doplnil konfiguraci firewallu pro DNS, kde se mi vytratilo nastavení pro rdnc – TCP port 953, který slouží pro lokální komunikaci s Bindem, do souboru/etc/sysconfig/iptables tedy doplníme

-A INPUT -i lo -p tcp --dport 953 -j ACCEPT
-A OUTPUT -o lo -p tcp --dport 953 -j ACCEPT

a načteme

# systemctl reload iptables
# systemctl reload ip6tables

SPF, DKIM a DMARC

Nejdříve krátký popis těchto technik. Všechny tři techniky jsou závislé na DNS, proto je na místě upozornit, že bez DNSSEC ztrácejí smysl. Nicméně, ačkoliv se to na mnoha místech uvádí, DNSSEC není nutnou podmínkou a kontroly fungují i bez něj.

  • SPF (sender policy framework) – tento záznam nám říká, které servery jsou oprávněny posílat poštu z naší domény
  • DKIM (DomainKeys Identified Mail) – je určen pro validaci obsahu zprávy a to pomocí podpisů.
  • DMARC (Domain Message Authentication Reporting and Conformance) – využívá a doplňuje SPF a DKIM, umožňuje nastavit akce, které se mají provést, pokud se nepodaří SPF ani DKIM ověřit. Tím se rozumí akce, které provede protistrana s naším e-mailem.

Abych neopakoval, co již bylo napsáno, doporučuji přečíst seriál o těchto technologiích.

SPF

Můžeme se opět přihlásit do administrace DNS, kam vložíme záznam:

Hostname:       testemail.cz
Typ:            TXT
TTL:            300
Hodnota:        v=spf1 mx -all

Tímto jednoduchým záznamem říkáme, že pošta pro naši doménu vždy pochází z našich mail serverů, jinak se k ní nehlásíme a je možno ji zahodit.

V tento moment je často uváděna instalace nějaké služby, která nám validuje příchozí SPF, ale my nic takového neuděláme, o to se nám postará opendmarc, který si nainstalujeme za chvíli. Provádět dvojí kontrolu by bylo zbytečné.

DKIM

DKIM bude poněkud komplikovanější, nejdříve nainstalujeme opendkim:

# yum install -y opendkim

Dále si vytvoříme adresář pro konfigurace a zároveň pro naši doménu, přesuneme se do něj a vygenerujeme si klíče. K tomu bude potřeba tzv selektor, použijeme třeba testemail2017, může to být celkem libovolný řetězec:

# mkdir /etc/opendkim/testemail.cz
# cd /etc/opendkim/testemail.cz
# opendkim-genkey -s testemail2017 -b 2048 -d testemail.cz

V aktuálním adresáři jsou nyní vygenerovány soubory testemail2017.private a testemail2017.txt, první přesuneme a nastavíme oprávnění

# mkdir /etc/opendkim/keys/testemail.cz
# mv testemail2017.private /etc/opendkim/keys/testemail.cz
# chown opendkim:opendkim /etc/opendkim -R
# cd ~

Upravíme konfiguraci /etc/opendkim.conf :

PidFile /var/run/opendkim/opendkim.pid
Mode    sv
Syslog  yes
SyslogSuccess   yes
LogWhy  yes
UserID  opendkim:opendkim
Socket  inet:8891@localhost
Umask   002
SendReports     yes
SoftwareHeader  yes
Canonicalization        relaxed/relaxed
MinimumKeyBits  1024
OversignHeaders From
InternalHosts   /etc/opendkim/TrustedHosts
KeyTable /etc/opendkim/KeyTable
SigningTable /etc/opendkim/SigningTable

a další soubory

/etc/opendkim/KeyTable

testemail2017._domainkey.testemail.cz testemail.cz:testemail2017:/etc/opendkim/keys/testemail.cz/testemail2017.private

/etc/opendkim/SigningTable

testemail.cz testemail2017._domainkey.testemail.cz

/etc/opendkim/TrustedHosts

127.0.0.1
::1
testemail.cz

nastavíme Postfix, aby OpenDKIM používal ke kontrole

# postconf -e milter_default_action=accept
# postconf -e milter_protocol=6
# postconf -e smtpd_milters=inet:localhost:8891
# postconf -e non_smtpd_milters=inet:localhost:8891

Nyní opět přejdeme ke konfiguraci DNS a nastavíme nový TXT záznam dle souboru /etc/opendkim/testemail.cz/testemail2017.txt , tedy přibližně takto:

testemail2017._domainkey.nasmail.cz IN TXT v=DKIM1; k=rsa; p=MIIBIjANB...zkráceno...60BrWUi

přičemž samotná hodnota je

v=DKIM1; k=rsa; p=velmi_dlouhy_retezec

Pozor, hodnota je v souboru rozdělena na části, je třeba ji tam dát celou.

Ještě je třeba povolit komunikace ve firewallu

-A INPUT -i lo -p tcp --dport 8891 -j ACCEPT
-A OUTPUT -o lo -p tcp --dport 8891 -j ACCEPT

a načteme nové konfigurace:

systemctl enable opendkim
systemctl start opendkim
systemctl reload postfix
systemctl reload iptables

DMARC

A posledním bodem je nastavení DMARC. DMARC nastavíme tak, že budeme odmítat všechny e-maily, které neprojdou kontrolou a to samé budeme vyžadovat od ostatních. Zprávy o chybách, ani agregované reporty si posílat nenecháme, protože to v našem případě nemá cenu, ale pokud to chcete vyzkoušet, nic vám nebrání. Doporučuji prostudovat článek o DMARC z výše zmíněného odkazu, třeba se vám to bude líbit jinak.

DNS záznam tedy bude v našem případě:

Hostname:       _dmarc.testemail.cz
Typ:            TXT
TTL:            300
Hodnota:        v=DMARC1; p=reject; adkim=s; aspf=s; pct=100;

Tímto záznamem jsme řekli, jak se mají ostatní chovat k našim e-mailům. Zde je na místě popsat jeden zásadní problém a tím je nakládání s nepodepsanými e-maily. Dříve k tomuto účelu sloužil záznam v DNS ADSP, který se bohužel nikdy příliš nevyužíval a v současnosti je označován jako zastaralý a doporučuje se náhrada DMARCem.

Problém je v tom, že ADSP nám umožnil sdělit světu, že všechny naše e-maily mají DKIM podpis a ty co jej nemají, jsou neplatné a je možné je zahodit. DMARC projde vždy, když je alespoň DKIM, nebo SPF v pořádku. Pokud nám tedy někdo cestou e-mail upraví, sice selže kontrola DKIM, ale e-mail může být stále doručen. Máme možnost například upravit pravidla spam filtru, který standardně za nevalidní DKIM, nebo SPF, dává velmi málo bodů, ale nemáme žádnou standardní možnost vyjádření protistrany, jak přísně s podobnými e-maily zacházet. Je to trochu škoda, zůstává nám možnost ověřovat DKIM v klientu – pro Thunderbird existuje doplněk a Rainloop, který později nainstalujeme, nás na validní, či nevalidní podpis upozorní ikonkou vedle adresy odesílatele.

Přejdeme tedy k instalaci opendmarc:

# yum install -y opendmarc

otevřeme soubor /etc/opendmarc.conf , ve kterém upravíme, odkomentujeme, nebo přidáme následující volby:

IgnoreHosts /etc/opendmarc/ignore.hosts
RejectFailures true
Socket inet:8893@localhost
SoftwareHeader true
SPFIgnoreResults true
SPFSelfValidate true
Syslog true
SyslogFacility mail
UMask 007
UserID opendmarc:mail

a vytvoříme soubor/etc/opendmarc/ignore.hosts s obsahem

127.0.0.1
::1

čímž zabráníme kontrole vlastních e-mailů. To je nezbytné, protože naše e-maily pochází z lokálních adres, které nejsou a nemohou být uvedeny v DNS v SPF záznamu, případně zvenku z různých jiných adres od klientů a proto by kontrola SPF a následně i DMARC vždy selhala.

do konfiguraci postfixu zařadíme opendmarc k opendkim:

# postconf -e smtpd_milters=inet:localhost:8891,inet:localhost:8893

Do firewallu přidáme

-A INPUT -i lo -p tcp --dport 8893 -j ACCEPT
-A OUTPUT -o lo -p tcp --dport 8893 -j ACCEPT

Spustíme a obnovíme potřebné služby

# systemctl enable opendmarc
# systemctl start opendmarc
# systemctl reload postfix
# systemctl reload iptables

Nejjednodušším testem je poslat e-mail na gmail

# echo Test | mailx -s "test" nejaka_adresa@gmail.com

a když si na gmailu zobrazíme podrobnosti zprávy, je tam krásně rozepsané SPF, DKIM i DMARC.

Pokud testy SPF, DKIM i DMARC prošly, máme server nastaven tak, že se „umí pěkně chovat“ v internetu a můžeme začít řešit, aby se choval pěkně i k nám. Pokud se někdo diví, proč jsem zvolil zrovna toto pořadí úkonů, tak vysvětlení je prosté. Internet je „zlé“ místo, ve kterém se dá velmi rychle ztratit dobrá reputace a špatně se získává zpátky. Proto považuji část nastavení směrem k internetu za prioritní a uživatelé počkají.

Politiky, jak se chovat ke „špatným“ e-mailům, jsme nastavili tvrdě. Ale musíme si uvědomit, že všechny techniky v této kapitole jsou nepovinné. Pokud je někdo nepoužívá, nemáme co kontrolovat a e-mail pustíme dál. Odmítneme jej pouze ze dvou důvodů:

  • je to podvodný e-mail, odeslaný něčím jménem, nebo upravený cestou
  • někdo má špatně nastavené servery

Snažte se nepřidávat výjimky. Pokud zjistíte, že máte problém s regulérní poštou z určité domény, tak jim to oznamte. Spousta lidí si myslí, že proti velkým firmám nic nezmůže, ale je to přesně naopak – obzvláště firmy zajímá nejvíc, jestli jejich pošta nekončí někde ve spamu a pokud je upozorníte na to, že mají něco špatně, ještě vám poděkují.

Dovecot

Dovecot nám poslouží primárně jako IMAP server a LDA, ale pomůže nám i s filtrováním pošty přes sieve a ověřením uživatele pro submission. Začneme tedy s jeho instalací:

# yum install -y dovecot dovecot-mysql dovecot-pigeonhole

Hlavní konfigurace je umístěna v souboru /etc/dovecot/dovecot.conf , ale většina věcí se konfiguruje přes tématicky rozdělené soubory v adresáři /etc/dovecot/conf.d . Soubory jsou pěkně komentované, nicméně ve spoustě komentářů se poněkud ztrácí samotná konfigurace. Pokud se chcete přesvědčit, co máte vlastně nastaveno, použijte následující příkaz: grep -E -v '[\ ]*#|^$' nazev_souboru

který nám vypíše soubor bez komentářů a prázdných řádků. Následně budu pro lepší přehlednost uvádět takto „ořezané“ konfigurace, nicméně doporučuji soubory zachovat s komentáři a pouze je upravovat. Vyhnete se tím případnému pozdějšímu zdlouhavému prohledávání manuálů.

Nejdříve soubor /etc/dovecot/dovecot.conf , ve kterém povolíme pouze IMAP, nastavíme si dict pro načítání quota a ponecháme načítání dalších konfigurací:

protocols = imap
dict {
  quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
}
!include conf.d/*.conf
!include_try local.conf

Pokračujeme souborem /etc/dovecot/conf.d/10-mail.conf , ve kterém si nastavíme cestu k naší poště na disku, %d znamená doménu, %n jméno, tedy uživatel test@testemail.cz bude mít emaily ve složce/home/vmail/testemail.cz/test a dále povolíme quoty:

mail_location = maildir:/home/vmail/%d/%n
mail_home = /home/vmail/%d/%n
namespace inbox {
  inbox = yes
}
first_valid_uid = 10000
mail_plugins = quota

dále si nastavíme soubor/etc/dovecot/conf.d/10-auth.conf následovně:

disable_plaintext_auth = yes
auth_mechanisms = plain
!include auth-sql.conf.ext

první volbou zakážeme login plaintextem tak dlouho, dokud není spojení šifrováno, druhou volbou povolíme mechanismy ověření a poslední je include souboru s konfigurací způsobu autentizace. Zde pozor, ostatní je třeba zakomentovat (pokud už nejsou).

Dále soubor /etc/dovecot/conf.d/10-master.conf , v něm povolíme IMAP a zakážeme IMAPS (IMAP funguje přes STARTTLS). Upozorňuji, že lokálně je IMAP vždy povolený i nešifrovaný, to je vlastnost dovecotu, ale ničemu to nevadí (lokálně ignoruje volbu disable_plaintext_auth). V tomto souboru také nastavujeme autentizaci

service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
    port = 0
  }
}
service imap {
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
  }
}
service auth-worker {
}
service dict {
  unix_listener dict {
    mode = 0600
    user = vmail
  }
}

v souboru/etc/dovecot/conf.d/10-ssl.conf nastavíme vyžadování šifrování a cesty k certifikátům

ssl = required
ssl_cert = </etc/pki/tls/certs/mail.testemail.cz.combined.pem
ssl_key = </etc/pki/tls/private/mail.testemail.cz.key

Jak vidíme, použili jsme certifikáty, které byly nachystány pro Postfix. Upravíme si opět soubor /root/.acme.sh/mail.testemail.cz/mail.testemail.cz.conf , kde do volby Le_ReloadCmd přidáme ještě reload dovecotu, aby po automatické obnově certifikátu vše fungovalo, bude tedy vypadat takto:

Le_ReloadCmd='systemctl reload httpd; cat /etc/pki/tls/certs/mail.testemail.cz.cert.pem /etc/pki/tls/certs/mail.testemail.cz.chain.pem > /etc/pki/tls/certs/mail.testemail.cz.combined.pem; systemctl reload postfix; systemctl reload dovecot'

V souboru/etc/dovecot/conf.d/15-lda.conf nastavíme adresu postmastera – je důležitá, z ní se posílají zprávy o nedoručení atd, povolíme automatické vytváření a odběr složek a pro lda povolíme quoty a sieve filtry

postmaster_address = postmaster@testemail.cz
lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes
protocol lda {
  mail_plugins = $mail_plugins quota sieve
}

Povolíme si imap_quota v souboru /etc/dovecot/conf.d/20-imap.conf

protocol imap {
  mail_plugins = $mail_plugins quota imap_quota
}

V rámci Dovecotu si nastavíme ještě sieve protokol, který se stará o filtrování pošty na straně serveru. Skládá se ze dvou součástí:

  • sieve filter pro LDA, který se stará o samotné filtrování
  • sieve démon – managesieve, přes který je možné filtry konfigurovat

Upravíme soubor/etc/dovecot/conf.d/20-managesieve.conf do následující podoby:

protocols = $protocols sieve
service managesieve-login {
  inet_listener sieve {
    port = 4190
  }
}
protocol sieve {
}

a soubor/etc/dovecot/conf.d/90-sieve.conf

plugin {
  sieve = ~/.dovecot.sieve
  sieve_dir = ~/sieve
  sieve_before = /etc/dovecot/sieve
}

V souboru/etc/dovecot/conf.d/90-quota.conf nastavíme načítání přes dict, který jsme definovali v dovecot.conf . Uživatelům povolíme 10 procent místa navíc, jako rezervu.

plugin {
  quota = dict:user::proxy::quota
  quota_grace = 10%%
}

Teď se podíváme na soubory s konfigurací potřebnou pro čtení z MySQL

soubor /etc/dovecot/conf.d/auth-sql.conf.ext :

passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}

který nám udává, kde najdeme konkrétní nastavení pro hesla a uživatele.

Otevřeme/etc/dovecot/dovecot-sql.conf.ext a zapíšeme do něj následující konfiguraci:

driver = mysql
connect = host=localhost dbname=postfix user=postfix password=tajne_heslo_ro
password_query = \
  SELECT username as user, password \
  FROM mailbox WHERE username = '%u' AND active=1
user_query = \
  SELECT 10000 as uid, 10000 as gid,\
  CONCAT('*:storage=', CAST(quota AS CHAR),'b') AS quota_rule\
  FROM mailbox WHERE username = '%u' AND active=1
iterate_query = SELECT local_part AS username, domain FROM mailbox

První řádek nám říká, že použijeme mysql, na druhém řádku je nastavení připojení k databázi – použijeme údaje zadané u konfigurace postfixadmina, z jehož databáze si uživatele bereme a následují tři SQL dotazy, na heslo, na uživatele, a na procházení uživatelů pro počítání quota. které jsou upravené tak, aby odpovídaly databázi postfixadmina.

a soubor /etc/dovecot/dovecot-dict-sql.conf.ext , který obsahuje nastavení pro quota. Zde bych rád upozornil, že jsem narazil na velmi podivné chování služby dict, která si při připojení na socket příliš nerozumí s SELinuxem, ale nakonec se to povedlo, podrobnosti jsou níže.

connect = host=localhost dbname=postfix user=postfixadmin password=tajne_heslo_rw option_file=
map {
   pattern = priv/quota/storage
   table = quota2
   username_field = username
   value_field = bytes
}
map {
   pattern = priv/quota/messages
   table = quota2
   username_field = username
   value_field = messages
}

Dále sdělíme postfixu, že má používat dovecot

# postconf -e virtual_transport=dovecot

do/etc/postfix/master.cf přidáme

dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient} -m ${extension}

nastavíme firewall, kam přidáme

-A INPUT -p tcp --dport 143 -j ACCEPT
-A INPUT -p tcp --dport 4190 -j ACCEPT
-A OUTPUT -o lo -p tcp --dport 4190 -j ACCEPT

čímž povolíme protokol imap (143) a sieve (4190) a použijeme nová nastavení:

# systemctl reload iptables
# systemctl reload ip6tables
# systemctl enable dovecot
# systemctl start dovecot
# systemctl reload postfix

Nastavíme si TLSA záznamy, opět zkopírováním již existujícího záznamu:

_443._tcp.mail.testemail.cz ...

do nových stejných záznamů, pouze s odlišným portem – port 4190 nám asi zatím k ničemu nebude, ale nic tím nepokazíme

_143._tcp.mail.testemail.cz …
_4190._tcp.mail.testemail.cz …

Pokud si nyní pošleme e-mail

# echo Test | mail -s Test test@testemail.cz

tak by se nám měla vytvořit složka/home/vmail/testemail.cz/test a v ní struktura inboxu. Konkrétně tento nový e-mail bude ve složce new. Původní nesprávný soubor s poštou/var/mail/1 můžeme nyní smazat:

# rm -f /home/vmail/1

V logu se nám vyskytne problém s kvótami, může za to výše zmíněný SELinux a přiznám se, že kvůli tomu jsem na tomto místě měl původně připojení na127.0.0.1 místo localhost . Tento problém byl poněkud skrytý, protože byl způsoben dontaudit pravidlem, které v logu není vidět. Nejdříve tedy musíme zakázat dontaudit pomocí příkazu

# semodule -DB

znovu si pošleme e-mail

# echo Test | mail -s Test test@testemail.cz

a nyní si vytvoříme nový modul pro SELinux, pomocí audit2allow, nejdříve jen výpis

# grep dict /var/log/audit/audit.log | audit2allow -a

#============= dovecot_t ==============

#!!!! This avc has a dontaudit rule in the current policy
allow dovecot_t mysqld_etc_t:dir open;

#!!!! The file '/var/lib/mysql/mysql.sock' is mislabeled on your system.
#!!!! Fix with $ restorecon -R -v /var/lib/mysql/mysql.sock
#!!!! This avc can be allowed using the boolean 'daemons_enable_cluster_mode'
allow dovecot_t mysqld_t:unix_stream_socket connectto;

a pokud vypadá výpis podobně, vytvoříme samotný modul a nainstalujeme jej

# grep dict /var/log/audit/audit.log | audit2allow -a -M dovecotdict
# semodule -i dovecotdict.pp

Pokud se vám zdá, že Dovecot nemá co pohledávat v konfiguraci MySQL, máte částečně pravdu, ale dict se snaží přečíst konfiguraci MySQL a nějakým způsobem ji použít. Samotné čtení konfiguračního souboru jsme zakázali prázdným parametrem option_file= , ale do adresáře si vynucuje přístup pořád, jinak padá na nesmyslné chyby. Opět si pošleme e-mail a pokud je vše v pořádku, můžeme opět povolit dontaudit a přepočítáme kvóty pro všechny uživatele:

# semodule -B
# doveadm quota recalc -A

Pokud neplánujeme využít MySQL pro další účely, je dokonce možné mu zcela vypnout naslouchání na TCP portu (stejně není povolen ve firewallu) a to volbouskip-networking v sekci [mysqld] v konfiguračním souboru/etc/my.cnf a samozřejmě restartem

# systemctl restart mariadb

Nyní můžeme v libovolném klientu (třeba Thunderbird) vyzkoušet, jestli je vše v pořádku a to nastavením příchozí pošty následovně:

Server: mail.nasmail.cz
Protokol: IMAP
Zabezpečení: STARTTLS
Port: 143
Jméno: test@testemail.cz
Heslo: to_vite_jen_vy

Schválně vyzkoušejte i bez zabezpečení, jak se klient zachová.

Submission

Submission je v podstatě další SMTP server a postará se nám o něj opět Postfix. Původně byla veškerá pošta jak mezi MTA, tak od klienta k MTA posílána pouze přes SMTP (port 25). Aby v tom byl trochu větší pořádek, vznikl protokol SMTPS, což je na aplikační vrsvě smtp, zabezpečený na transportní vrstvě pomocí SSL/TLS.

Byl mu byl přidělen port 465, nicméně po zavedení STARTTLS byl opět odebrán a SMTPS se přestěhovalo na port 25, kde díky STARTTLS koexistuje i se SMTP. Původní port 465 je stále používaný pro předávání pošty klient – MTA, nicméně tento způsob je zastaralý a nedoporučuje se. Speciálně pro komunikaci klient-MTA se začal užívat submission na portu 587, který funguje na protokolu ESMTP a stejně jako běžné SMTP používá STARTTLS.

Nastavíme si tedy postfix, otevřeme/etc/postfix/master.cf a povolíme submission – odkomentujeme a upravíme:

submission inet n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
  -o smtpd_milters=inet:localhost:8891

nastavíme

# postconf -e smtpd_sasl_type=dovecot
# postconf -e smtpd_sasl_path=private/auth
# postconf -e smtpd_sasl_auth_enable=yes
# postconf -e smtpd_relay_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination

Ve firewallu si povolíme submission

-A INPUT -p tcp --dport 587 -j ACCEPT

nová nastavení načteme

# systemctl reload iptables
# systemctl reload postfix

opět zkopírujeme TLSA záznam v DNS, tentokrát s portem 587

_587._tcp.mail.testemail.cz ...

a můžeme si v klientu nastavit smtp následovně:

Server: mail.testemail.cz
Zabezpečení: STARTTLS
Port: 587
Jméno: test@testemail.cz
Heslo: to_vite_jen_vy

Můžeme vyzkoušet poslat poštu a přesunout se k další části.

SPAM a viry

Posledním zásadním krokem je ochrana proti SPAMu a virům. Spamassassin se nám postará o detekci SPAMu, ClamAV o antivirovou kontrolu a AMaViS tyto řešení spojuje do jednoho rozhraní. Nečekejte zde žádné velké nastavování, pokud instalujeme nový server, necháme většinu věcí ve výchozím stavu a případné změny potom provádíme podle situace.

Často používanou metodou pro zachytávání SPAMu je tzv. greylisting, který ale nepoužijeme. Ve zkratce se jedná o to, že příchozí e-mail od odesílatele, který ještě není založen v databázi, je záměrně odmítnut s chybou Temporary Failure a čeká se na další pokus. Pokud další pokus proběhne příliš rychle, jedná se o SPAM a pokud nedorazí vůbec, tak pravděpodobně také. Tato metoda byla v minulosti velmi účinná, nicméně v posledních letech bych ji označil spíše za problematickou. Poměrně velká část serverů má nastaveno první opakování po nesmyslně dlouhé době, proto může dojít až k několikahodinovému zpoždění, aniž by o tom byl odesílatel, nebo příjemce informován. Navíc servery, které se starají o odesílání SPAMu, jsou dnes často nastavené lépe, než ty „hodné“, aby měli vůbec šanci něco doručit, proto účinnost této metody značně poklesla.

Nainstalujeme potřebné balíčky:

# yum install -y amavisd-new clamav clamav-update clamav-scanner-systemd pyzor

v souboru/etc/freshclam.conf zakomentujeme, nebo smažeme řádek

Example

a v souboru/etc/sysconfig/freshclam zakomentujeme, nebo smažeme poslední řádek

FRESHCLAM_DELAY=disabled-warn  # REMOVE ME

provedeme aktualizaci clamav a spamassassin

# freshclam
# sa-update

a pomocí příkazu

# crontab -e

připíšeme do cronu řádek

10 */4 * * * sa-update

čímž se nám bude aktualizace Spamassasinu spouštět každé čtyři hodiny. ClamAV se aktualizuje každé tři hodiny a cron se vytvořil již při instalaci.

v souboru/etc/amavisd/amavisd.conf uděláme následující úpravy:

$inet_socket_port = [10024,10026];
$interface_policy{'10026'} = 'MYNETS';

posloucháme na dvou portech, 10024 využijeme pro příchozí zprávy (smtp), 10026 pro odchozí (submission). Příchozím spojením na portu 10026 přidělíme politiku MYNETS, takže vše přijaté přes submission bude považováno za naše zprávy. Dále nastavíme:

@mynetworks = qw(127.0.0.0/8 [::1]/128 [2001:15e8:110:99e::1]/128 81.2.241.158/32);
$mydomain = 'testemail.cz';
$sa_spam_subject_tag = '';
$sa_tag_level_deflt  = -9999;
$sa_tag2_level_deflt = 7;
$sa_kill_level_deflt = 15;
$sa_dsn_cutoff_level = -9999;
$sa_crediblefrom_dsn_cutoff_level = -9999;
$warnvirusrecip = 1;
$enable_dkim_verification = 0;
$enable_dkim_signing = 0;

Nastavení úrovní je možné měnit dle uvážení a aktuální situace, popsané nastavení přidá hlavičky do všech e-mailů, od úrovně 7 označí zprávu jako SPAM a od úrovně 15 spam zahodí. Odesílatele spamu zásadně neinformujeme, úroveň 15 je dost vysoká, odpovídání by mohlo být použito k útokům na cizí servery. Spam subject jsme nastavili na prázdný, takže email je označen jen pomocí X-Spam hlaviček. Má to jednoduchý důvod – pokud přepíšeme předmět, porušíme DKIM a s tím i související DMARC. Test se sice provede před změnou předmětu, takže projde v pořádku, ale pokud by jsme chtěli provést kontrolu dodatečně, už to bude špatně. Pokud nám někdo pošle zavirovaný email, je zahozen, ale dostaneme upozornění, odesílatel informován není a to ze stejného důvodu, jako v případě SPAMu. Zakázali jsme také Amavisu vlastní test DKIM, protože ten pro nás provádí OpenDKIM.

Pokud chceme, můžeme provést drobnou estetickou úpravu. RainLoop, který si nainstalujeme příšte (ale i někteří další klienti), nás upozorňuje na DKIM ve zprávách, ale pouze na základě vložených hlaviček. Pokud zpráva přijde na náš server zvenku, zkontroluje ji opendkim a hlavičky vloží, pokud odchází od nás, opendkim ji podepíše a kontrolu už samozřejmě neprovádí. Pokud jsme odesílatelem i příjemcem (myšleno server, ne konkrétní adresa), zpráva je podepsána, ale opendkim hlavičky rovněž nepřidá, takže RainLoop nám DKIM neukáže. Pokud chceme mít zprávu zkontrolovanou, využijeme k tomu amavis a v politice MYNETS povolíme kontrolu DKIM, čímž docílíme kontroly pouze v případě, že jsme odesílatelem zprávy, ale zároveň je amavis natolik chytrý, že hlavičku nepřidá, pokud nejsme příjemcem.

$policy_bank{'MYNETS'} = {
  originating => 1,
  os_fingerprint_method => undef,
  enable_dkim_verification => 1,
};

Aby se nám načítal seznam domén z databáze, použijeme následující nastavení:

@local_domains_maps = ();
@lookup_sql_dsn = ( ['DBI:mysql:database=postfix;host=localhost;port=3306','postfix','tajne_heslo'] );
$sql_select_policy = 'SELECT domain FROM domain WHERE active=1 AND domain=%d';

Častým požadavkem je zrušení omezení na přípony souborů, pokud nechceme takové přílohy blokovat, zakomentujeme celou část, případně si ji jinak upravíme k obrazu svému

$banned_filename_re = new_RE(
...
);

pozor, je to roztaženo přes mnoho řádků.

Ještě zablokujeme testy AHBL, protože už delší dobu nefungují, a na každý dotaz posílají falešné body, těžko říct, proč je nikdo nevyřadil:

# echo "score DNS_FROM_AHBL_RHSBL 0" >> /etc/mail/spamassassin/local.cf

Přidáme potřebnou konfiguraci do /etc/postfix/master.cf

smtp-amavis unix -    -    n    -    2 smtp
  -o smtp_data_done_timeout=1200
  -o smtp_send_xforward_command=yes
  -o disable_dns_lookups=yes
127.0.0.1:10025 inet n    -    n    -    - smtpd
  -o content_filter=
  -o local_recipient_maps=
  -o relay_recipient_maps=
  -o smtpd_restriction_classes=
  -o smtpd_client_restrictions=
  -o smtpd_helo_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o strict_rfc821_envelopes=yes
  -o smtpd_milters=

a sdělíme postfixu, že má zprávy předávat ke kontrole na port 10024

postconf -e content_filter=smtp-amavis:localhost:10024

a domaster.cf doplníme na konec submission následující řádek, který nám posílá zprávy přijaté přes submission na druhý port amavisu

  -o content_filter=smtp-amavis:[127.0.0.1]:10026

Posledním krokem je nastavení přesouvání pošty do složky SPAM, což provedeme vytvořením sieve pravidla. Vytvoříme si adresář

mkdir /etc/dovecot/sieve

a v něm vytvoříme soubor /etc/dovecot/sieve/99-SPAM.sieve , do něhož zapíšeme následující:

require ["fileinto", "imap4flags"];
if header :contains ["X-Spam-Flag"] "YES"
{
    addflag "\\Seen";
    fileinto "Spam";
    stop;
}

který zkompilujeme

# sievec /etc/dovecot/sieve/99-SPAM.sieve

Tím se nám všechny e-maily, označené jako spam, přesunou do složky Spam. Pokud je nechceme rovnou označovat jako přečtené, vynecháme addflag…

Zbývá nastavit firewall

-A INPUT -i lo -p tcp --dport 10024 -j ACCEPT
-A INPUT -i lo -p tcp --dport 10025 -j ACCEPT
-A INPUT -i lo -p tcp --dport 10026 -j ACCEPT
-A INPUT -p udp --sport 24441 -j ACCEPT
-A OUTPUT -o lo -p tcp --dport 10024 -j ACCEPT
-A OUTPUT -o lo -p tcp --dport 10025 -j ACCEPT
-A OUTPUT -o lo -p tcp --dport 10026 -j ACCEPT
-A OUTPUT -p tcp --dport 2703 -j ACCEPT
-A OUTPUT -p udp --dport 24441 -j ACCEPT

Porty 10024 a 10026 jsou pro amavis, na 10025 poslouchá opět postfix, odchozí port 2703 je pro Razor2, což je online databáze pro testování spamu, 24441 je Pyzor – služba podobná Razoru. Nastavíme služby a použijeme konfigurace

# systemctl enable amavisd
# systemctl start amavisd
# systemctl reload dovecot
# systemctl reload postfix
# systemctl reload iptables
# systemctl reload ip6tables

Nyní ještě inicializujeme a otestujeme pyzor

# pyzor discover
# pyzor ping

Můžeme otestovat, jestli nám funguje ochrana proti spamu a virům a to pomocí testovacích zpráv, na spam GTUBE a na antivirus EICAR. Jedná se o krátké řetězce, které slouží k testování, ale vzhledem ke komplikacím, které mi způsobovalo jejich vložení přímo do návodu, je zde neuvádím.

Dokončení

Pokud jsme neprovedli dříve, bylo by dobré založit následující emailové adresy, případně je přidělit jako alias k nějakému jinému, existujícímu účtu:

  • postmaster
  • hostmaster
  • webmaster
  • abuse
  • root

Pro jistotu srovnáme SELinux kontexty na všech souborech

# restorecon -vR /

a celý server restartujeme příkazem reboot ,aby bylo jisté, že jsme něco nezapoměli nastavit po startu a vše funguje.

Pokud vše funguje, můžeme nastavit větší TTL v administraci DNS, například 3600.

root_podpora

Závěr

Tímto by se dalo říct, že server máme nainstalovaný, v další části už se budeme věnovat webovému rozhraní RainLoop, a velmi lehce si popíšeme zálohování, čímž bude server opravdu kompletní. Po bouřlivých debatách pod minulým dílem bych opět rád upozornil, že se jedná především o server pro osobní použití. Po příštím díle bude vyčerpáno vše, co jsem prozatím napsal, to ale nutně neznamená, že už nic dalšího nebude.

Ve hře je také popis populárního webmailu RainLoop, ne tak známého, ale přesto zajímavého webmailu SOGo, který umožňuje používat technologie známé z MS Exchange serveru a stále váhám, jestli přidat i nějaký díl o provozování v produkčním prostředí. Zde mám rozporuplné pocity, protože tam už může jít o značně individuální potřeby a požadavky a správce takového serveru už by měl mít velmi dobrý přehled a nejsem si jistý, jestli nějaké obecné nastavování podle návodů má smysl.

Byl pro vás článek přínosný?