Na domácím routeru (PC s Debian/Etch) mi běží i pošta. Při upgradu komplet celého systému jsem přemýšlel, jak to udělat, aby – když už to jednou dělám – tam běžela nějak rozumně pošta pro asi tři domény a čtyři uživatele s použitím podpory pro virtuální mailhosting postfixu a přitom nezabřednout do ldap, mysql, protože ono PC má docela mizerný výkon a je zbytečné střílet vrabce kanónem. Zrealizoval to a výsledek si zaslouží malé howto (téměř vše jsem čerpal z obyčejné dokumentace postfixu a courieru, co se do linuxu obvykle dává do /usr/share/doc/[postfix|courier], dále jsem spoustu věcí převzal od Zdendy Burdy odsud http://www.zdenda.com/mailserver-postfix-imap-maildrop-mysql:
Použité technologie
– MTA postfix
– MDA maildrop z balíku courier
– POP/IMAP server courier
– webmail klient squirrelmail
Konvence
Pokud hovořím o nějakém konfiguráku, že má nějakou hodnotu “vlevo” a druhou hodnotu “vpravo”, míním tím to, že na každém řádku jsou dvě informace oddělené alespoň jednou mezerou (lépe tabulátory) například takto:
#cat /etc/postfix/relay | tail -n 1
nejakamojedomena.cz relay
Tato konvence je obecná, setkáte se s ní v popisech postfixu leckde.
Postfix
Vynechám popis standardních nastavení konfiguráku main.cf (například že pro použití jako lokální brány je potřeba vyplnit parametr “mynetworks”, že je dobré si udělat pořádek v tom, co určíte jako “myhostname” a “mydomain” atd.).
Obecně: pokud direktiva má před svou hodnotou slůvko “hash:”, je očekáván nikoli textový soubor, ale jeho databázový hash (stejně nazvaný soubor, ale s příponou .db – takový soubor se vyrobí pomocí příkazu
postmap /cesta/k/souboru
No a přejdeme rovnou k tomu, čím se můj konfigurák odlišuje od výchozího nastavení a vezmu to po řádcích s komentáři:
# tento řádek říká, jaké mechanismy se mají použít pro doručování pro které domény, v souboru transports je vlevo název domény a vpravo technika doručení. Nejčastěji se používají local:, virtual: a maildrop: – já v tomto řešení používám pouze maildrop:
transport_maps = hash:/etc/postfix/transports
# mydestination je velice důležitý parametr, říká postfixu, pro které domény přijímáme poštu (a setkáme se tam kromě klasických “workaroundů” typu $myhostname, localhost atd. především s $transport_maps. Pokud (jako já) potřebujete kromě virtuálních domén jejich jakoby aliasy (tzn. máte schránku jménem nekdo@nekde.cz a potřebujete, aby do té stejné schránky padaly i maily pro nekdo@jestejinde.cz a nekdo@uplnejinde.cz uveďte tuto “virtuální” doménu rovnou do parametru mydestination a NEuvádějte to do transport_maps)
mydestination = $myhostname, localhost, localhost.$myhostname, $transport_maps, jestejinde.cz, uplnejinde.cz
# následující direktiva říká postfixu, kam se má koukat po schránkách svých oveček, u souboru hodnot každého parametru je na každém řádku očekávána e-mailová adresa, co následuje na řádku dál, je jedno. Lze tedy použít soubor, který využívá POP/IMAP server courier jako zdroj informací o svých uživatelích. Pozor, při změně tohoto souboru je potřeba nejen vygenerovat db soubor pro courier, ale i pro postfix (a ano, v adresáři /etc/courier se pak nacházejí dva různé db soubory – jeden pro courier, druhý pro postfix – viz dále)
local_recipient_maps = $alias_maps, hash:/etc/courier/userdb
# svůj servřík používám jako záložní pro pár dalších domén, v souboru relay je vlevo uveden název domény, vpravo slovo relay
relay_domains = hash:/etc/postfix/relay
# virtual alias maps jsou dost praktické pro vytváření různých doménových košů a aliasů, které se nemají vlevo username ale mailovou adresu, v mém případě vznikaly zkoumáním logu postfixu, když se různé démony (apcupsd, mdadm atd) pokoušely doručovat poštu různě pojmenovanému rootovi tak, že na to byl soubor /etc/aliases nedostatečný, vznikl tak např. řádek typu “root@mojedomena.cz vitek@mojedomena.cz”. Doménový koš vyrobíte nějak tak “@domena.cz lokalnischranka@domena.cz”. Můžete to udělat ještě fikaněji takto “@domena.cz franta12345@seznam.cz” – čímž se váš mailserver použije jen jako výhybka či sběrna pro mailbox, který vůbec není u vás a je přeposílán mimo váš systém.
virtual_alias_maps = hash:/etc/postfix/virtual
# následující direktiva říká, od koho bude přijímat maily. Povolíme naše sítě (a je třeba nezapomenout do mynetworks uvést i něco jako 127.0.0.1/8, aby nám systém neodmítal maily od mailsystému samotného – například z webmailu nebo od démonů), dále tam mám povolen příjem od lidí, co se autentizovali přes sasl, odmítneme přijmout mail od známých spammerů (tento seznam mám dlouhodobě vyzkoušený) a vše ostatní též odmítáme (implicitní politika)
smtpd_client_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_rbl_client blackholes.wirehub.net
reject_rbl_client dul.dnsbl.sorbs.net
reject_rbl_client list.dsbl.org,
reject_rbl_client bl.spamcop.net,
reject_rbl_client sbl-xbl.spamhaus.org,
reject_rbl_client relays.mail-abuse.org,
reject_rbl_client dialups.mail-abuse.org,
reject_rbl_client blackholes.mail-abuse.org,
reject_rbl_client blackholes.easynet.nl,
reject_rbl_client dnsbl.njabl.org,
reject_rbl_client dev.null.dk,
reject_rbl_client sbl.spamhaus.org,
reject_rbl_client dnsbl.ahbl.org
reject_unauth_destination
# tato restrikce se vztahuje na to, co odesílatel uvede v komunikaci s naším mailserverem jako adresáta. Nejdůležitější je kupodivu úplně poslední restrikce (možností je více) – pokud tam nebude, postfix odmítne přijímat poštu (je to pojistka proti chybě admina, kdyby chtěl omylem vyrobit open_relay systém).
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unknown_sender_domain
reject_unauth_destination
Další věc je soubor master.cf – v něm stačí změnit (upravit) pouze toto:
maildrop unix – n n – – pipe
flags=DRhu user=virtual:virtual argv=/usr/bin/maildrop -V1 -d ${recipient}
V podstatě se jedná o vysvětlení postfixu, jak má používat transport “maildrop” – že má být spouštěn pod uživatelem virtual (kterého samozřejmě musíme mít v systému! nezapomeňte na to). Je více než užitečné mít v /etc/passwd uveden home directory pro tohoto uživatele tam, kde bude úložiště pro maily. A shell tento uživatel neptořebuje.
Další fičurky jsou už docela běžné, asi se mi nechce se o nich teď rozepisovat, možná příště 😉
Courier
Když se podíváte do /etc/courier/authdaemonrc tak je tam direktiva authmodulelist. Obvykle tam bývá authpam nebo tak něco. Pro naše řešení je to nahrazené slůvkem “authuserdb”. A je potřeba to mít nainstalované v systému (dohledejte ve svých instalačních balíčcích, pro debian etch se to jmenuje courier-authlib-userdb. Jedná se o techniku výroby virtuálních uživatelů co nejjednodušší možnou cestou. Userdb je (…) soubor v /etc/courier, kde každý uživatel má pro sebe svůj řádek. Na prvním místě je dobré uvést e-mailovou adresu (stačilo by teoreticky username, ale pro naše účely lépe vyhoví celá mailová adresa), dále následuje “whitespace” (alespoň jedna mezera, tabulátor – optimálně jeden tabulátor) a dále pak seznam konfiguračních direktiv oddělených svislítky, takový řádek pak vypadá takto:
uzivatel@mojedomena.cz uid=4001|mail=mojedomena.cz/uzivatel/Maildir/|home=/home/virtual|gid=4001|quota=3000000000S|systempw=_heslo_sifrovane_metodou_crypt_neni-li_uvedeno_jinak
Takovýhle řádek můžete vyrobit příkazem “userdb” (více man userdb) nebo ručně textovým editorem. V obou případech je potřeba změny zrealizovat příkazem makeuserdb, které z toho vyrobí (updatne) binární soubor userdb.dat, který pak je čten authdaemonem courieru. A teď k jednotlivým položkám příkladového řádku:
uid – systémové userid, které bude použito pro přístup do schránky, je velice výhodné dávat všem uživatelům stejné uid, o práva se stará courier, nemusíte mít strach, že si jednotliví uživatelé polezou do zelí. Dost podobné věci platí o gid.
mail – relativní cesta k mailboxu, kam se bude mapovat POP/IMAP démon po nalogování uživatele
home – absolutní cesta k základně virtuálních účtů
systempw – heslo ve formátu crypt
quota – kvóta na celkový objem uživatelovy pošty – v příkladu použita kvóta 3GB. Pokud napíšete 1024S,5C znamená to, že pokud budou mít maily ve schránce 1kB nebo pokud jich bude víc jak pět, bude to systém považovat za překročenou kvótu. V mém příkladu tedy není počet mailů omezen. Celá tato sranda funguje jen u maildiru.
Jak již bylo napsáno, používá soubor /etc/courier/userdb i postfix, proto je potřeba po provedení příkazu makeuserdb provést i příkaz postmap /etc/courier/userdb – v případě, že se změní něco na levé straně tohoto seznamu. Pokud budete např. pouze měnit kvótu nějakému uživateli, není to potřeba.
Maildrop
Maildrop si většinu své konfigurace bere z /etc/courier/userdb – pokud byste mu chtěli říci nějaké další informace (a nepochybujte, že chtěli), umistěte do home uživatele, který poštu doručuje (virtual), což je v našem případě i home všech ostatní mailboxů – například tedy /home/virtual, soubor .mailfilter, který maildrop čte a respektuje. Já v něm mám toto:
xfilter “/usr/bin/spamassassin”
if (/^X-Spam-Flag: YES/ )
{
to “/home/virtual/spam/”
}
LOGNAME=tolower($LOGNAME)
include “/home/virtual/.mailfilters/$LOGNAME”
první řádek profiltruje mail spamassassinem – vzhledem k objemu pošty se mi nevyplatí nechat běžet spamd. Ovšem je vhodné mít adresář .spamassassin s dílčími výsledky různcých kontrol a sa-learn výsledků. Další řádky jsou podmínka – pro všechny uživatele to likviduje spam bez nějakých uživatelských dovychytávek. Poslední řádek importne mailfiltr pro každéhu usera zvlášť, pro další uživatelská nastavení (např. přeposílání upozornění na mobil atd.). Příklad:
logfile “/home/virtual/log/nekdo@domena.cz”
`/usr/bin/test -d /home/virtual/domena.cz/nekdo`
if ($RETURNCODE == 1)
{
`/bin/mkdir -p /home/virtual/domena.cz/nekdo`
}
`/usr/bin/test -d /home/virtual/domena.cz/nekdo/Maildir/`
if ($RETURNCODE == 1)
{
`/usr/bin/maildirmake /home/virtual/domena.cz/nekdo/Maildir/`
}
if (/^X-Original-To: czdebian/)
{
to “/home/virtual/domena.cz/nekdo/Maildir/.archiv.debkonfera/”
}
if (/^Reply-To: mandrake/)
{
to “/home/virtual/domena.cz/nekdo/Maildir/.archiv.mandrake/”
}
to “/home/virtual/domena.cz/nekdo/Maildir/”
Takto sestavený soubor se postará o vytvoření maildiru a například o přesunutí mailů z konferencí do správných adresářů.
SASL
Implementaci saslu mám zaběhnutou dělat v MySQL a potřeboval jsem to vyřešit rychle, takže se nedostalo na to, na co jsem se chystal – prozkoumat pam knihovny dotfile a pwdfile, jistě by jedna z nich vyhověla jako náhrada za libpam-mysql, které používám normálně. Příště!