Mailserver - Postfix
Pokud máme připravenou databázi, přichází čas na nainstalování a nastavení MTA. Já jsem se rozhodl pro postfixe. Při psaní tohoto návodu byl použit postfix verze 2.5.5, takže případně u jiných verzí se může chování se stejným konfigurákem nějak lišit. Postfix musí mít podporu sasl, ssl a postgres (mysql).
Co tedy budeme po našem MTA chtít? Takže zaprvé jej musíme naučit rozeznávat, které maily má akceptovat a na které kašlat. Vysvětlíme mu tedy, jaké e-mailové schránky a aliasy máme, vysvětlíme mu, jak si je má vzít z databáze a jak je má následně doručit. Následně mu také povolíme SSL a povolíme se uživatelům přihlašovat. Příhlášení uživatelé pak můžou e-mail poslat kamkoliv.
Na začátek bude ještě třeba vytvořit si na stroji uživatele, pod kterým budou doručovány e-maily všem virtuálním schránkám. Můžete použít klidně i nějakého existujícího uživatele; já jsem si vytvořil nového. Respektive vytvořil jsem si skupinu mailsystem a následně uživatele mailsystem, který do této skupiny spadá. Tento uživatel musí být vlastníkem daných virtuálních schránek! Vlastník virtuální schránky se konkrétně nastavuje v databázi ve sloupcích uid a gid. Uid a gid uživatele jde zjistit například z /etc/passwd.
V konfiguraci se tedy budeme zabývat hlavně soubory /etc/postfix/main.cf a master.cf. Dále vytvoříme složku /etc/postfix/pgsql a do ní budeme vkládat konfiguraci pro selektování jednotlivých položek z databáze. V případě, že použijete MySQL databázi, nebudou cesty k souborům uvozeny pgsql:/, ale mysql:/.
main.cf
Konfigurák main.cf v mém případě tedy vypadá takto:
- home_mailbox = .maildir/
- alias_maps = pgsql:/etc/postfix/pgsql/aliases.cf
- transport_maps = pgsql:/etc/postfix/pgsql/transport.cf
- virtual_maps = pgsql:/etc/postfix/pgsql/virtual.cf pgsql:/etc/postfix/pgsql/email.cf pgsql:/etc/postfix/pgsql/trash.cf
- local_recipient_maps = $alias_maps $virtual_mailbox_maps unix:passwd.byname
- virtual_mailbox_base = /home/mails/
- virtual_mailbox_maps = pgsql:/etc/postfix/pgsql/virtual-maps.cf
- virtual_uid_maps = pgsql:/etc/postfix/pgsql/virtual-uid.cf
- virtual_gid_maps = pgsql:/etc/postfix/pgsql/virtual-gid.cf
- smtpd_recipient_restrictions = check_recipient_access pgsql:/etc/postfix/pgsql/recipient.cf, reject_unknown_sender_domain, permit_mynetworks, permit_sasl_authenticated, check_relay_domains, reject
- queue_directory = /var/spool/postfix
- command_directory = /usr/sbin
- daemon_directory = /usr/lib/postfix
- mail_owner = postfix
- myhostname = spamik.cz
- mydomain = spamik.cz
- inet_interfaces = all
- unknown_local_recipient_reject_code = 550
- mail_spool_directory = /var/spool/mail
- smtpd_banner = $myhostname ESMTP $mail_name
- debug_peer_level = 2
- debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin xxgdb $daemon_directory/$process_name $process_id & sleep 5
- sendmail_path = /usr/sbin/sendmail
- newaliases_path = /usr/bin/newaliases
- mailq_path = /usr/bin/mailq
- setgid_group = postdrop
- html_directory = /usr/share/doc/postfix-2.5.5/html
- manpage_directory = /usr/share/man
- sample_directory = /etc/postfix
- readme_directory = /usr/share/doc/postfix-2.5.5/readme
- message_size_limit = 504857600
- mailbox_size_limit = 9504857600
- virtual_mailbox_limit = 9504857600
- dovecot_destination_recipient_limit = 1
- smtpd_sasl_type = dovecot
- smtpd_sasl_path = private/auth
- smtpd_sasl_auth_enable = yes
- smtpd_sasl_security_options = noanonymous
- smtpd_sasl_tls_security_options = noanonymous
- smtpd_use_tls = yes
- smtpd_tls_key_file = /etc/ssl/cert.key
- smtpd_tls_cert_file = /etc/ssl/cert.pem
- smtpd_tls_CAfile = /etc/ssl/ca.pem
- tls_random_source = dev:/dev/urandom
- smtpd_tls_loglevel = 2
- smtpd_tls_auth_only = yes
Konfigurák není uplně nejkratší a některé volby si zaslouží podrobnějí vysvětlění. Takže popořadě:
- home_mailbox značí, kde se nachází mailbox lokálních uživatelů. Cesta je zadaná relativně od jejich home složky.
- alias_maps vrací seznam všech aliasů, v tomto případě opět pro lokální uživatele (tedy ty, co v systému skutečně existují). Jako hodnota se uvádí cesta k souboru, kde bude nastavení, jak tyto data dostat z databáze.
- transport_maps je množina záznamů určující, jak se které e-maily budou doručovat (možnosti jako hledání v lokálních uživatelích, virtuálních, doručení přes MDA apod.)
- virtual_maps jsou víceméně aliasy pro virtuální uživatele. Navíc je zde přidán doménový koš a e-mailové adresy, které spadají mimo doménový koš.
- local_recipient_maps určuje platné příjemce mailů, obsahuje tedy aliasy pro lokální uživatele, mailboxy virtuálních uživatelů a seznam lokálních uživatelů
- virtual_mailbox_base je cesta k místu, kde budou mailboxy virtuálních uživatelů. Kompletní cesta k mailboxu vznikne tím, že se k virtual_mailbox_base přidá část maildir v databázi u uživatele.
- virtual_mailbox_maps je seznam virtuálních uživatelů
- virtual_uid_maps a virtual_gid_maps je mapování uid a gidu na skutečného uživatele/skupinu, pod kterým se e-mail doručí. V databázi by měla být v políčkách hodnota uid a gid uživatele, kterého jsme si vytvořili.
- smtpd_recipient_rescription vyjadřuje na základě jakých podmínek bude e-mail přijat po tom, co je znám adresát. V tomto případě je tedy přijato vše, co postfix zná jako své uživatele, které může doručit; můžou se libovolně posílat e-maily ze síťových rozsahů, které jsou na stroji nastaveny a také autorizovaní uživatelé můžou posílat kamkoliv. Ostatní je odmítnuto
- myhostname je hostname daného stroje. Od samotné domény pro maily se může lišit (například maily pro doménu spamik.cz můžou chodit na mail s hostname mail.spamik.cz)
- mydomain je samotná doména
- message_size_limit je limit velikosti jedné zprávy (doporučuju nastavit nižší číslo než mám já; já to trochu přepísk :) )
- mailbox_size_limit je limit velikosti schránky
- virtual_mailbox_limit je limit velikosti virtuální schránky
- smtpd_sasl_type - hodnota dovecot označuje, že se budeme autorizovat proti dovecotu. Tedy v tomto případě bude autorizace k SMTP serveru naprosto shodná, jako k POP3/IMAP
- smtpd_sasl_auth_enable povolí autorizaci přes SASL
- smtpd_use_tls povolí SSL spojení
- smtpd_tls_key_files - cesta ke klíči, který patří k SSL certifikátu
- smtpd_tls_cert_file - cesta k našemu SSL certifikátu
- smtpd_tls_CAfile - cesta ke kořenovému certifikátu certifikační autority, která náš certifikát vydala
- smtpd_tls_auth_only zajistí, že autorizovat se mohou pouze šifrovaná spojení
master.cf
Pravděpodobně master.cf budete mít nějaký defaultní, nicméně některé věci do něj musíme doplnit. Master.cf může vypadat takto:
- smtp inet n - n - - smtpd
- smtps inet n - n - - smtpd -o smtpd_tls_wrappermode=yes
- mailsystem unix - n n - - mailsystem
- pickup fifo n - n 60 1 pickup
- cleanup unix n - n - 0 cleanup
- qmgr fifo n - n 300 1 qmgr
- tlsmgr unix - - n 1000? 1 tlsmgr
- rewrite unix - - n - - trivial-rewrite
- bounce unix - - n - 0 bounce
- defer unix - - n - 0 bounce
- trace unix - - n - 0 bounce
- verify unix - - n - 1 verify
- flush unix n - n 1000? 0 flush
- proxymap unix - - n - - proxymap
- smtp unix - - n - - smtp
- relay unix - - n - - smtp -o fallback_relay=
- showq unix n - n - - showq
- error unix - - n - - error
- discard unix - - n - - discard
- local unix - n n - - local
- virtual unix - n n - - virtual
- lmtp unix - - n - - lmtp
- anvil unix - - n - 1 anvil
- scache unix - - n - 1 scache
- dovecot unix - n n - - pipe flags=DRhu user=mailsystem:mailsystem argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}
Dosti pravděpodobně vám budou chybět 3 věci:
- smtps: bez tohoto řádku postfix nebude poslouchat na zabezpečeném portu 465
- mailsystem: tato položka je shodná se jménem uživatele, kterého jsme si vytvořili pro virtuální schránky
- dovecot: specifikuje, jak se budou e-maily předávat delivery agentu od dovecotu
Nastavení databáze
To hlavní bysme měli, nyní ještě musíme nastavit jednotlivé soubory, které jsme uvedli v main.cf, pro přístup do databáze. Poznámka: pokud je v položce table napsáno neco.necojineho, znamená to, že tabulka je pojmenována necojineho a je ve schématu neco. MySQL schémata nemá, tudíž se píše jenom necojineho. Zároveň u MySQL je potřeba dávat pozor na podmínky - MySQL nemá datový typ boolean a pokud tedy použijete třeba tinyint jako tuto hodnotu, nebudete porovnávat 't', 'f', ale třeba '0', '1'!.
Uváděné hodnoty jsou myslím celkem srozumitelné, tak pouze uvedu konfigurační soubory a nebudu je blíže komentovat.
aliases.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_alias
- select_field = destination
- where_field = alias
client.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.posftix_access
- select_field = access
- where_field = source
- additional_conditions = and type = 'client'
email.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_email
- select_field = email
- where_field = email
recipient.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_access
- select_field = access
- where_field = source
- additional_conditions = and type = 'recipient'
sender.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_access
- select_field = access
- where_field = source
- additional_conditions = and type = 'sender'
transport.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_transport
- select_field = destination
- where_field = domain
trash.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_trash
- select_field = destination
- where_field = email
virtual-gid.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_users
- select_field = gid
- where_field = email
- additional_conditions = and postfix = 't'
virtual-maps.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_users
- select_field = maildir
- where_field = email
- additional_conditions = and postfix = 't'
virtual-uid.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_users
- select_field = uid
- where_field = email
- additional_conditions = and postfix = 't'
virtual.cf
- user = postfix
- password = heslo
- dbname = mailsystem
- hosts = 127.0.0.1
- table = hellmachine.postfix_virtual
- select_field = destination
- where_field = email