Portál AbcLinuxu, 4. května 2025 19:24
Minule představená konfigurace programu Postfix sloužila jen k předávání zpráv na jiný server, bez jakýchkoli dalších aktivit. S tím se lze samozřejmě málokdy spokojit. Obvykle požadujeme výrazně více – server musí vykazovat určitou dávku vlastní „inteligence“.
Přeposílající SMTP server se hodí pro případy, kdy potřebujeme jen přebírat zprávy (ať už od běžných poštovních klientů, nebo třeba od PHP skriptů) a předávat je skutečnému serveru, který už se postará o všechno ostatní. Pokud je ale potřeba zprovoznit skutečný server, který už vše doručuje sám a navíc se rozhoduje, od koho zprávy převezme, vyžaduje to už trochu více práce.
V zásadě bude potřeba vyřešit tyto úkoly:
Všimněte si, že v seznamu chybí doručování místním uživatelům. To je zcela úmyslně, protože v tuto chvíli se bude jednat o server, který slouží pouze k odesílání, o místní doručování se nestará.
Základem nového konfiguračního souboru bude samozřejmě ten z minulého dílu. Změní se jen to, co bude v tomto případě jinak. Především zmizí parametr relayhost a dále bude dobré změnit ještě pár dalších položek. Tady je výsledný konfigurační soubor main.cf
:
myhostname = postak.moje.domena myorigin = $mydomain inet_interfaces = all biff = no local_transport = error:no local mailboxes
Odebrání relayhost
způsobí, že bude server provádět dotazy na MX záznamy v DNS a podle nich se pokoušet doručovat zprávy na cílové servery. V souboru ale přibyla ještě jedna položka. Správně měla být už i v předchozím dílu (protože ani tam se nevyužívalo místní doručování), nicméně bylo cílem konfiguraci maximálně zjednodušit a Postfix funguje i bez ní. Parametr local_transport
definuje místní transport (službu, která se použije k místnímu doručování). Výchozí službou je local
, lze to ovšem změnit na error
(tedy „chyba“) a službu local
vypnout (viz dále). Za slovo error
lze přidat dvojtečkou oddělenou zprávu, kterou klient dostane, pokud by se pokusil o lokální doručení.
Vypnutí služby local
je potřeba provést v souboru master.cf
. Prostě se příslušný řádek služby local
zakomentuje nebo smaže. Po každé změně konfiguračních souborů je potřeba vynutit nové načtení těchto souborů. Záleží na konkrétní distribuci, obvykle se to provádí přes /etc/init.d/postfix reload
, případně obecně postfix reload
. U některých změn (jmenovitě třeba nastavení síťových rozhraní, kde má Postfix naslouchat) to ale nestačí a celý Postfix se musí restartovat (např. /etc/init.d/postfix restart
nebo postfix stop && postfix start
).
Předchozí část byla zcela triviální. Nyní ovšem přichází něco trochu složitějšího, nicméně zcela nezbytného. Pokud bychom totiž server, který přijímá zprávy od kohokoliv (nebo aspoň od relativně široké množiny klientů), vystavili do Internetu, fungoval by jako tzv. open relay. Brzy by ho objevili spammeři a využili ho pro odesílání masivních dávek spamu. Zřejmě jen o něco později (nebo možná ještě dříve) by se dostal na černé listiny, které mnozí provozovatelé poštovních serverů využívají jako zdroj informací při boji proti spamu. Čili nic lákavého.
Proto je potřeba říci, kdo bude smět odesílat přes tento server poštu, a podle toho pak také server nakonfigurovat. Obecně se používají tyto režimy:
Metod je obecně ještě víc, ale v tuto chvíli jsou důležité jen ty zde uvedené. Lze je různě kombinovat, a to jak ve smyslu logického součtu (tedy stačí vyhovět jednomu požadavku), tak součinu (všechny požadavky) nebo jinému vyhodnocení. Podívejme se nejdřív na problematiku adres počítačů a sítí, protože takto lze poměrně jednoduše vyřešit odesílání například z firemní sítě nebo ze serverů s pevnou adresou.
Postfix má konfigurační parametr mynetworks
. Používá se k definici „vlastních“ sítí, tedy těch, které mají větší práva, v tomto případě k odesílání pošty. S tímto parametrem úzce souvisí ještě parametr mynetworks_style
, kterým se definuje výchozí hodnota parametru mynetworks
. Tady je několik příkladů:
mynetworks_style = class mynetworks_style = subnet mynetworks = 127.0.0.0/8, 192.168.1.0/24, [::1]/128 mynetworks = $config_directory/mynetworks mynetworks = hash:/etc/postfix/mynetworks
První dva příklady využívají výchozí hodnotu. Úplně nejobecnější je příklad první, který povoluje přístup z celé třídy IP. Vychází se samozřejmě ze síťových masek jednotlivých rozhraní, na nichž Postfix naslouchá. Čili pokud by měl například adresu 147.32.80.9/24, pak bude k serveru přístup z celé třídy C, konkrétně ze sítě 147.32.80.0. Druhý příklad je velmi podobný, ovšem s tím rozdílem, že lze specifikovat masku sítě jemněji než po celých třídách (pokud by při použití třídy byla maska např /28, stejně by se uplatnila maska třídy, tj. /24).
Další tři příklady už používají přímo definice konkrétních adres. První z nich povoluje přístup ze všech lokálních adres a dále ze sítě 192.168.1.0 nacházející se ve vyhrazeném prostoru (typicky třeba firemní síť). Podobně lze uvést i přímo jedinou adresu bez masky. Při použití IPv6 se musí používat hranaté závorky, jak je vidět ze zde uvedené lokální IPv6 adresy (to proto, že dvojtečky mají jinak jiný význam, používají se pro nastavení datového zdroje – viz hash
).
Zbývající dva příklady ukazují využití vnějších zdrojů informací (mimo konfigurační soubor). První využívá obyčejný textový soubor, kde jsou povolené adresy uvedeny ve stejné formátu, jako by se uváděly přímo v konfiguraci. Druhý příklad pracuje s hešovou tabulkou – jednotlivé adresy se nejprve vloží do souboru /etc/postfix/mynetworks
v textové formě (vždy adresa a libovolný řetězec oddělené mezerou) a pak se na soubor zavolá postmap
(tj. zde postmap /etc/postfix/mynetworks
), který vygeneruje vlastní tabulku. Soubor s vygenerovanou tabulkou bude mít příponu .db
, ta se ale v konfiguraci neuvádí.
Zadefinovat si jen příslušné parametry nestačí. Je potřeba ještě říci Postfixu, aby podle nich řídil přístup. Začneme tím, že bude odesílání omezeno pouze podle příslušnosti odesílajícího počítače k definovaným „vlastním“ sítím. Tady je to ovšem bez práce, protože výchozí konfigurace Postfixu je taková, že se automaticky zakazuje odesílání pošty z adres mimo mynetworks
. Výchozí nastavení je ekvivalentní tomuto:
smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
Restrikční pravidla vždy fungují stylem, že pokud některé z nich zafunguje (při vyhodnocování v pořadí, jak jsou napsána), další se již nevyhodnocují. Zde se tedy nejdřív povolí přístup pro adresu z vlastních sítí a pak se případně odmítne přístup všem ostatním (ovšem viz dále). K odmítnutí v tomto případě dojde v okamžiku, kdy protistrana poskytne adresu příjemce (SMTP příkaz RCPT TO
). Povolen je přístup z vlastních sítí a odmítne se doručení do neautorizovaných cílů. To je z hlediska ochrany proti spamu v zásadě dostatečné, nicméně je to zbytečně pozdě a spammera lze „zaříznout“ hned zčerstva, navíc to lze udělat ještě důkladněji. Tady je nastavení, které lze použít:
smtpd_client_restrictions = permit_mynetworks, reject smtpd_delay_reject = no
První parametr je podobný tomu předchozímu, tedy definuje přístup klientů, ovšem v tomto případě již pro samotné připojení. Protože ale ve výchozím stavu Postfix kontrolu stejně odloží až na okamžik po příkazu RCPT TO
, druhým parametrem se tento odklad vypne. Neoprávněný klient tedy dostane odmítací zprávu okamžitě po připojení. Je otázka, nakolik je to v pořádku. Na jednu stranu se tím šetří výkon, který by spammeři požírali – současně s tím však některé klientské programy nemusí počítat, byť jde o chování v souladu se specifikací protokolu. Proto je dobré zvážit, nakolik je přidání druhého řádku potřebné (obvykle spíše ne).
Zde se sluší připomenout, jaký je rozdíl mezi reject_unauth_destination
a pouhým reject
. reject
odmítá zcela bezpodmínečně, kdežto reject_unauth_destination
povolí doručení do lokálních schránek (zde bezpředmětné – lokální doručování je vypnuto) a také předávání pro specifikované domény, pokud tak má server činit.
Dále se můžeme rozhodnout, že půjdou odesílat jen zprávy s odesílatelem v definovaných doménách. Sice by šlo pak vynechat kontrolu IP adres klientů, ale to už by poměrně slušně otevíralo dvířka spammerům. Takže postup bude opačný – kontrola sítí se ponechá v platnosti a ještě se přidá kontrola domén:
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/access, reject
Příklad ukazuje hned několik věcí současně. Jednak je to využití víceřádkového nastavování parametru (čistě pro přehlednost; další řádky se vždy odsazují), dále je to využití blacklistu/whitelistu v hešové tabulce a nakonec použití parametru pro omezení odesílatele. Pokud není nastaveno smtpd_delay_reject = no
, kontrola se provede opět až při příkazu RCPT TO
. Povolen bude přístup pouze pro adresy odesílatele odpovídající whitelistu – viz dále.
V Postfixu lze s výhodou využít kombinovaný blacklist/whitelist dostupný prostřednictvím jednoho datového zdroje. Ve výše uvedeném případě je to hešová tabulka, ale může to být klidně třeba databáze nebo nějaký externí server. Tabulka slouží pro dotazy – a to jak na kompletní adresy, tak na uživatelská jména (jméno@
) a na domény, což je to, co je využito výše.
V tabulce (datovém zdroji) jsou obsaženy dvojice klíč-hodnota, což znamená, že se Postfix dotáže klíčem a zdroj vrátí hodnotu (nebo nic, pokud není klíč nalezen). Konkrétně v black/whitelistu je to tak, že je vždy e-mailová adresa, uživatel nebo doména jako klíč a jako hodnota je uvedeno, jaká akce se má udělat.
Je-li uvedeno OK
, znamená to v tomto případě, že je klíč na whitelistu (tedy zde konkrétně, že se smí z dané domény odesílat; podobně lze vkládat do seznamu i jednotlivé adresy). Je-li uvedeno REJECT
, nemá to pro výše uvedený příklad žádný význam, nicméně to vkládá adresu/doménu/uživatele na blacklist, což lze využít například takto:
smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/access, permit
Tato definice zakáže posílání zpráv příjemcům (a do domén) na blacklistu. V tomto případě to nemá příliš uplatnění, ale velmi podobně by se blacklist uplatnil pro příchozí zprávy, pokud by je server přijímal z vnějšího světa. Ještě pro úplnost – hodnot vracených datovým zdrojem může být víc, podrobnosti najdete v manuálové stránce access(5)
.
V rámci nastavování restrikcí pro přístup k serveru lze také zapnout různé formální kontroly zpráv. K čemu je to dobré? Třeba pro boj s odchozím spamem. Některý z uživatelů může mít na počítači nějakou „havěť“, která začne odesílat spam. Protože si tvůrci často nelámou hlavu s dodržováním nějakých specifikací, lze důslednou kontrolou tento spam omezit.
Následující příklad bude ukazovat společně celý úsek věnovaný restrikcím (kromě definice mynetworks
). Navíc se v něm objeví ještě pár dalších parametrů vysvětlených níže.
smtpd_client_restrictions = permit_mynetworks, reject smtpd_sender_restrictions = reject_non_fqdn_sender, reject_unknown_sender_domain, check_sender_access hash:/etc/postfix/access, reject smtpd_recipient_restrictions = reject_non_fqdn_recipient, reject_unknown_recipient_domain, check_recipient_access hash:/etc/postfix/access, permit smtpd_error_sleep_time = 30 smtpd_soft_error_limit = 10 smtpd_hard_error_limit = 20 smtpd_helo_required = yes
V uvedených pravidlech toho není až tolik nového. Důležité jsou však kontroly reject_non_fqdn_sender
a reject_non_fqdn_recipient
– tyto kontroly způsobí odmítnutí adresy odesílatele, resp. příjemce, pokud neobsahuje plně kvalifikované doménové jméno (podle RFC 2822). Další kontroly jdou ještě dál. reject_unknown_sender_domain
, resp. reject_unknown_recipient_domain
odmítnou neexistující domény (podle kontroly v DNS), a to dokonce i v případě, že jsou uvedeny ve whitelistu. Oba druhy kontrol zabraňují odesílání pošty z nesmyslných zpátečních adres a na nesmyslné cílové adresy (kontroluje se zde samozřejmě jen doména, ne celá adresa). Obě kontroly zde sdílí jediný datový zdroj, nicméně mohou mít samozřejmě každá svůj vlastní.
Ochranný význam mají i tři parametry ke konci příkladu. První hodnota říká, kolik sekund má Postfix čekat, pokud klient dosáhne „měkkého“ limitu počtu chyb (chybou je cokoliv, co vyvolá kód 4xx nebo 5xx), aniž by byla předána zpráva. Tento měkký limit se nastavuje druhým parametrem. Třetí parametr je pak tvrdý limit počtu chyb – po jeho dosažení je klient odpojen.
Úplně poslední parametr zakazuje vynechání příkazu HELO
nebo EHLO
. Na tento příkaz lze navázat další kontroly, nicméně to není příliš dobrý nápad, protože podpora správného použití je u mnohých klientů dost svérázná, takže by to zadělalo na slušné problémy. Ovšem protože tento úvodní identifikační příkaz musí podle specifikace poslat každý klient, je dobré z toho udělat povinnost, což eliminuje spamující software, který pravidla nedodržuje.
Kde jsou? Zatím nikde. Zato příště už budou, a to hned ve dvou verzích – jako systémové (schránky místních uživatelů) a jako virtuální (pro uživatele, kteří nemají účet v systému). Na scénu se dostane už i druhý z programů, Dovecot, který zatím odpočíval.
A domain name that is not in FQDN form is no more than a local alias. Local aliases MUST NOT appear in any SMTP transaction.V jiných variacích se to objevuje ještě na dalších místech specifikace.
nejak mi nedochazi ten nadpis clanku... ano je to o zabezpecni pouzivat nas mail server jako relay apod, ale kde je ten boj proti spamu?Ten nadpis je redakční (tj. nepsal jsem ho já - moje chyba, že jsem žádný nedodal
jinak existuji nastaveni kde jde blokovat hodne rovnou postfixem bez zatezovani systemu spamassissinem apod (body_checks, header_checks...).Ano, mám v plánu se tím zabývat v pozdějších dílech.
smtpd_sender_restrictions = reject_invalid_hostname, reject_unknown_sender_domain, reject_non_fqdn_sender, ...- takto to používame odjakživa (cca. od roku 2003) a nikdy s tým nebol problém. Pritom nehostujeme len naše veci, ale aj mailboxy pre cca stovku zákazníkov a ich domén. Budem sa opakovať, ale ak si niekto nevie nastaviť mailový server (a vyriešiť s providerom správne doménové meno), tak nech si ten mailový server nedáva na internet.
Presne, tyto pravidla se v praxi bohuzel pouzit nedaji, nebot hrozi pruser.To není úplně přesné, přísná pravidla se použít mohou, pokud je legitimní klienti mají šanci obejít - buďto whitelistem, nebo tím, že náhradní MX servery nejsou tak přísné. Pokud je v důsledku chybné konfigurace odesílající server nepřipuštěn k primárnímu mailserveru, může poslat mail skrz sekundární (např. mailserver poskytovatele připojení). Protože postupné vyzkoušení všech mailserverů z MX záznamu je povinnou částí SMTP, tak s tím legitimní klienti nemají problém, ale odřízne to minimálně 90% spamu.
Kombinace pravidel
Dobry den, v clanku se pise, ze lze ruzne kombinovat restrikce. Chtel bych se zeptat jak lze zkombinovat nasledujici dve situace, ktere nastavaji zaroven. Samostatne bych celkem vedel jak restrikce nastavit, ale jak je nastavit tak, aby zafungovaly dohromady to moc netusim.
1) smtp server pro odesilani mailu do internetu
mail (domena.cz) (klient) => serv1 (192.168.0.21) => postfix (192.168.0.1) => internet
2) stahovani pop3 schranky a dorucovani na serv1
pop3.domena.cz (internet) => fetchmail (192.168.0.1) => postfix (192.168.0.1) => serv1 (192.168.0.21)
Za odpoved dekuji.
mynetworks = 127.0.0.0/8 smtpd_client_restrictions = permit_mynetworks, check_client_access hash:/etc/postfix/client-access, reject smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender-access, reject smtpd_recipient_restrictions = check_client_access hash:/etc/postfix/client-access, check_recipient_access hash:/etc/postfix/recipient-access, rejectPřičemž v client-access by byla adresa 192.168.0.21, v sender-access doména domena.cz (případně jednotlivé adresy) a v recipient-access opět doména domena.cz. Klíčová práce by se odehrávala v smtpd_recipient_restrictions, kde by to nejdřív povolilo klienta 192.168.0.21 pro odesílání odkudkoliv a potom příjemce v doméně domena.cz, ostatní by bylo zakázáno. Podle mě by to mělo fungovat, tedy aspoň pokud jsem správně pochopil, co má být cílem.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.