Mailserver – Postfix, Dovecot a MySQL

Přibližně před šesti lety jsem publikoval článek o stavbě mailserveru na svém webu www.zdenda.com. V dnešní době je článek již dost zastaralý. Dlouhou dobu jsem sliboval aktualizaci no a konečně je tu :-) Nedávno jsem instaloval nový firemní server a pro poštu jsem zvolil kombinaci:

  • Postfix
  • Dovecot
  • MySQL
  • Amavis + ClamAV a Spamassasin
  • Roundcube
  • Postfixadmin


Základní popis služeb mailserveru

Všichni uživatelé mailserveru jsou evidováni v databázi MySQL, správa uživatelů probíhá přes (dnes už) standardní rozhraní Postfixadmin. Postfix, který slouží jako SMTP server, je napojen na MySQL a uživatele z MySQL bere jako „virtuální“. O doručování pošty do schránek uživatelů, filtrování při doručování a přístup k poště přes IMAP/POP3 se stará Dovecot. Amavis ve spolupráci s ClamAV a Spamassasinem poskytuje antivirovou a antispamovou ochranu. Webmail Roundcube zajišťuje uživatelům webové rozhraní pro přístup k poště, změnu hesla a nastavení filtrovacích pravidel.

Níže popisovaná instalace neimplementuje kvóty na schránky uživatelů – na serveru kde jsem instalaci prováděl jsou pouze uživatelé, kteří jsou rozumní :-) Pokud máte někdo zájem o konfiguraci Dovecotu tak aby se využívaly kvóty, tak je možné se inspirovat například na domácí stránce Dovecotu. Pokud budete mít zapnuté kvóty, tak je možné informace o obsazeném místě dostat do MySQL jak popisuji v jiném článku.

Použitý software

Většinu použitého software jsem instaloval z balíčků z repositářů CentOSu. Pouze Postfixadmin a Roundcube jsou instalované přímo z archivů stažených z domácí stránky.

Instalace a konfigurace

Příprava operačního systému

V operačním systému jsem vypnul Selinux. Také jsem upravil konfiguraci firewallu – iptables: V souboru „/etc/sysconfig/iptables“ jsem povolil komunikaci na tcp porty 25, 465, 443, 993, 995 z venku:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:SRV-INPUT - [0:0]
-A INPUT -j SRV-INPUT
-A FORWARD -j SRV-INPUT
-A SRV-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A SRV-INPUT -p icmp -j ACCEPT
-A SRV-INPUT -i lo -j ACCEPT
-A SRV-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A SRV-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
-A SRV-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A SRV-INPUT -m state --state NEW -m tcp -p tcp --dport 465 -j ACCEPT
-A SRV-INPUT -m state --state NEW -m tcp -p tcp --dport 993 -j ACCEPT
-A SRV-INPUT -m state --state NEW -m tcp -p tcp --dport 995 -j ACCEPT
-A SRV-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

Co komunikuje na jednotlivých tcp portech:

  • 22 – SSH
  • 25 – SMTP – Postfix (komunikaci je možné šifrovat – TLS)
  • 443 – HTTPs – Apache (komunikace šifrována SSL)
  • 465 – SMTPs – Postfix (komunikace šifrována SSL)
  • 993 – IMAPs – Dovecot (komunikace šifrována SSL)
  • 995 – POP3s – Dovecot (komunikace šifrována SSL)

YUM

Software pro OS instaluji pokud možno z živých repositářů o které se stará někdo jiný než já :-) Nejčastěji využívám repositář EPEL a RPMForge. Postup jak si přidat uvedené repositáře do konfigurace YUMu je uvedený na jejich webu:

Z RPMforge nechci brát clamav a spamassasina, tak jsem je zakázal: V souboru „/etc/yum.repos.d/rpmforge.repo“ jsem přidal do sekce [rpmforge] a [rpmforge-extras] řádek

exclude=clamd,clamav*,spamassassin,perl-IO-Compress

který zkazuje instalaci uvedených balíčků z tohoto repository.

Uživatel pro poštu

Uživatelé poštovního serveru jsou „virtuální“ – neexistují v operačním systému. V operačním systému je veškerá pošta zpracovávaná pod jedním uživatelským účtem, který je nutné založit:

useradd -r -m -d /home/mail -c "Uzivatel pro mailserver" -s /sbin/nologin -U vmail

Výše uvedený příkaz založí uživatele „vmail“,  skupinu „vmail“ a vytvoří adresář /home/mail do kterého budeme ukládat poštu.

Instalace software

Pomocí YUMu nainstalujte balíčky:

amavisd-new
clamav
clamav-db
spamassassin
postfix
postfix-perl-scripts
postgrey
dovecot
dovecot-pigeonhole
dovecot-mysql

k tomu nainstalujte MySQL databázi a webserver – používám Apache, takže pokud budu něco uvádět ke konfiguraci webserveru tak pro něj.

Databáze MySQL

Jak si si máte správně nainstalovat a nastavit databázi MySQL tu popisovat nebudu, postupů je plný google. Snad jen připomenu abyste nezapoměli spustit skript „mysql_secure_installation“.

Vytvoření databáze pro postfix a roundcube, uživatele a nastavení práv:

# mysql -u root
CREATE DATABASE postfix;
CREATE USER 'postfix'@'localhost' IDENTIFIED BY 'HESLO';
GRANT ALL PRIVILEGES ON `postfix` . * TO 'postfix'@'localhost';
CREATE DATABASE roundcube;
CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'HESLO';
GRANT ALL PRIVILEGES ON `roundcube` . * TO 'roundcube'@'localhost';
flush privileges;

Heslo si samozřejmě vyberte své :-)

V databázi „postfix“ budou evidování uživatelé mailserveru ke kterým bude mít přístup Postfix, Dovecot a Postfixadmin. Databáze Roundcube bude použita pro webmail Roundcube, který si do ní ukládá uživatelská nastavení.

Tip na vylepšení: Do databáze Postfix potřebuje zapisovat pouze Postfixadmin, takže by z hlediska bezpečnosti bylo lepší mít uživatele dva – jednoho pro Postfixadmin s právem zápisu a druhého pro ostatní software s právem čtení.

Postfixadmin

Stáhněte a rozbalte poslední stabilní verzi Postfixadmina z jeho domácí stránky. Zpřístupněte si Postfixadmina přes https. Na mém serveru je Postfixadmin dostupný na adrese „https://server/postfixadmin“.

V konfiguračním souboru Postfixadmina config.inc.php nastavte spojení k databázi a URL k Postfixadminu:

$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'HESLO';
$CONF['database_name'] = 'postfix';
$CONF['postfix_admin_url'] = 'https://server/postfixadmin';

a změňte $CONF['configured'] = false; na $CONF['configured'] = true;

Po provedené změně vstupte do instalátoru na adrese https://server/postfixadmin/setup.php

Instalátor zkontroluje stav serveru a vytvoří strukturu v databázi.

Vytvořte si ve formuláři na konci instalátoru hash hesla, který obratem vložte do konfiguračního souboru config.inc.php místo hodnoty „changeme“, která je tam ve výchozím stavu.

Potom pokračujte vytvořením účtu superadministrátora ve formuláři instalátoru. Zadejte původní instalační heslo jehož hash jste vložili do konfiguráku, emailovou adresu, která bude sloužit jako login do postfixadmina, a vytvořte heslo uživatele.

Postfix Admin setup

Postfix Admin pass

Instalátor vytvořil databázové tabulky:

CREATE TABLE `admin` (
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Admins';

CREATE TABLE `alias` (
  `address` varchar(255) NOT NULL,
  `goto` text NOT NULL,
  `domain` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`address`),
  KEY `domain` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Aliases';

CREATE TABLE `alias_domain` (
  `alias_domain` varchar(255) NOT NULL,
  `target_domain` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`alias_domain`),
  KEY `active` (`active`),
  KEY `target_domain` (`target_domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Domain Aliases';

CREATE TABLE `config` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '',
  `value` varchar(20) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 COMMENT='PostfixAdmin settings';

CREATE TABLE `domain` (
  `domain` varchar(255) NOT NULL,
  `description` varchar(255) CHARACTER SET utf8 NOT NULL,
  `aliases` int(10) NOT NULL DEFAULT '0',
  `mailboxes` int(10) NOT NULL DEFAULT '0',
  `maxquota` bigint(20) NOT NULL DEFAULT '0',
  `quota` bigint(20) NOT NULL DEFAULT '0',
  `transport` varchar(255) NOT NULL,
  `backupmx` tinyint(1) NOT NULL DEFAULT '0',
  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Domains';

CREATE TABLE `domain_admins` (
  `username` varchar(255) NOT NULL,
  `domain` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT '1',
  KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Domain Admins';

CREATE TABLE `fetchmail` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `mailbox` varchar(255) NOT NULL,
  `src_server` varchar(255) NOT NULL,
  `src_auth` enum('password','kerberos_v5','kerberos','kerberos_v4','gssapi','cram-md5','otp','ntlm','msn','ssh','any') DEFAULT NULL,
  `src_user` varchar(255) NOT NULL,
  `src_password` varchar(255) NOT NULL,
  `src_folder` varchar(255) NOT NULL,
  `poll_time` int(11) unsigned NOT NULL DEFAULT '10',
  `fetchall` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `keep` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `protocol` enum('POP3','IMAP','POP2','ETRN','AUTO') DEFAULT NULL,
  `usessl` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `extra_options` text,
  `returned_text` text,
  `mda` varchar(255) NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `log` (
  `timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `username` varchar(255) NOT NULL,
  `domain` varchar(255) NOT NULL,
  `action` varchar(255) NOT NULL,
  `data` text NOT NULL,
  KEY `timestamp` (`timestamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Log';

CREATE TABLE `mailbox` (
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 NOT NULL,
  `maildir` varchar(255) NOT NULL,
  `quota` bigint(20) NOT NULL DEFAULT '0',
  `local_part` varchar(255) NOT NULL,
  `domain` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`username`),
  KEY `domain` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Mailboxes';

CREATE TABLE `quota` (
  `username` varchar(255) NOT NULL,
  `path` varchar(100) NOT NULL,
  `current` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`username`,`path`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `quota2` (
  `username` varchar(100) NOT NULL,
  `bytes` bigint(20) NOT NULL DEFAULT '0',
  `messages` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE `vacation` (
  `email` varchar(255) NOT NULL,
  `subject` varchar(255) CHARACTER SET utf8 NOT NULL,
  `body` text CHARACTER SET utf8 NOT NULL,
  `cache` text NOT NULL,
  `domain` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`email`),
  KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Postfix Admin - Virtual Vacation';

CREATE TABLE `vacation_notification` (
  `on_vacation` varchar(255) CHARACTER SET latin1 NOT NULL,
  `notified` varchar(255) CHARACTER SET latin1 NOT NULL,
  `notified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`on_vacation`,`notified`),
  CONSTRAINT `vacation_notification_pkey` FOREIGN KEY (`on_vacation`) REFERENCES `vacation` (`email`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Postfix Admin - Virtual Vacation Notifications';

Uvedené tabulky jsou všechny, které používá Postfixadmin pokud ho budete využívat naplno. Tabulky quota, quota2, vacation, vacation_notification a fetchmail budou při mnou popisovaném postupu instalace nevyužité.

tabulka použití
admin Seznam administrátorů Postfixadminu
alias

Aliasy (z jednoho mailu na druhý: alias@domain.tld→user2@domain.tld,
doménový koš: @domain.tld→user@domain.tld,
alias na skupinu: alias@domain.tld→user@mail.tld,user2@domain.tld)

alias_domain Doménové aliasy (pošta pro doménu domain.tld bude posílána uživatelům v doméně domain2.tld)
config Nastavení Postfixadmina
domain Seznam domén pro které mailserver přijímá poštu
domain_admins Seznam administrátorů jednotlivých domén
log Logy Postfixadmina
mailbox Informace o uživatelích mailserveru a jejich schránkách

Konfigurace Postfixadmina se provádí ručně editací souboru config.inc.php. Zkontrolujte nastavení a případně nastavení změňte u položek, které jsou pro nás důležité:

$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
$CONF['transport'] = 'NO';
$CONF['transport_default'] = 'virtual';
$CONF['vacation'] = 'NO';
$CONF['quota'] = 'NO';
$CONF['smtp_server'] = 'localhost';
$CONF['smtp_port'] = '25';

Ukázka mého celého konfiguračního souboru:

$CONF['configured'] = true;
$CONF['setup_password'] = 'b1f69a23aa49d729989b2a8eaa941459:a88145151251258455c4268566420576753485bce';
$CONF['postfix_admin_url'] = 'https://server/postfixadmin';
$CONF['postfix_admin_path'] = dirname(__FILE__);
$CONF['default_language'] = 'en';
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'HESLO';
$CONF['database_name'] = 'postfix';
$CONF['database_prefix'] = '';
$CONF['database_tables'] = array (
    'admin' => 'admin',
    'alias' => 'alias',
    'alias_domain' => 'alias_domain',
    'config' => 'config',
    'domain' => 'domain',
    'domain_admins' => 'domain_admins',
    'fetchmail' => 'fetchmail',
    'log' => 'log',
    'mailbox' => 'mailbox',
    'vacation' => 'vacation',
    'vacation_notification' => 'vacation_notification',
    'quota' => 'quota',
    'quota2' => 'quota2',
);
$CONF['admin_email'] = 'postmaster@domain.tld';
$CONF['smtp_server'] = 'localhost';
$CONF['smtp_port'] = '25';
$CONF['encrypt'] = 'md5crypt';
$CONF['authlib_default_flavor'] = 'md5raw';
$CONF['dovecotpw'] = "/usr/sbin/dovecotpw";
$CONF['min_password_length'] = 8;
$CONF['generate_password'] = 'NO';
$CONF['show_password'] = 'NO';
$CONF['page_size'] = '20';
$CONF['default_aliases'] = array (
    'abuse' => 'abuse@domain.tld',
    'hostmaster' => 'hostmaster@domain.tld',
    'postmaster' => 'postmaster@domain.tld',
    'webmaster' => 'webmaster@domain.tld'
);
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
$CONF['maildir_name_hook'] = 'NO';
$CONF['aliases'] = '20';
$CONF['mailboxes'] = '20';
$CONF['maxquota'] = '10';
$CONF['quota'] = 'NO';
$CONF['quota_multiplier'] = '1024000';
$CONF['transport'] = 'NO';
$CONF['transport_options'] = array (
    'virtual',  // for virtual accounts
    'local',    // for system accounts
    'relay'     // for backup mx
);
$CONF['transport_default'] = 'virtual';
$CONF['vacation'] = 'NO';
$CONF['vacation_domain'] = 'autoreply.domain.tld';
$CONF['vacation_control'] ='NO';
$CONF['vacation_control_admin'] = 'NO';
$CONF['alias_control'] = 'YES';
$CONF['alias_control_admin'] = 'YES';
$CONF['special_alias_control'] = 'NO';
$CONF['alias_goto_limit'] = '0';
$CONF['alias_domain'] = 'YES';
$CONF['backup'] = 'NO';
$CONF['sendmail'] = 'NO';
$CONF['logging'] = 'YES';
$CONF['fetchmail'] = 'NO';
$CONF['fetchmail_extra_options'] = 'NO';
$CONF['show_header_text'] = 'NO';
$CONF['header_text'] = ':: Postfix Admin ::';
$CONF['user_footer_link'] = "https://server/postadmin/users";
$CONF['show_footer_text'] = 'NO';
$CONF['footer_text'] = 'Return to server';
$CONF['footer_link'] = 'http://server';
$CONF['welcome_text'] = <<<EOM
Hi,

Welcome to your new account.
EOM;
$CONF['emailcheck_resolve_domain']='NO';
$CONF['show_status']='NO';
$CONF['show_status_key']='NO';
$CONF['show_status_text']='  ';
$CONF['show_undeliverable']='NO';
$CONF['show_undeliverable_color']='tomato';
$CONF['show_undeliverable_exceptions']=array("unixmail.domain.ext","exchangeserver.domain.ext","gmail.com");
$CONF['show_popimap']='NO';
$CONF['show_popimap_color']='darkgrey';
$CONF['show_custom_domains']=array("domain.tld");
$CONF['show_custom_colors']=array("lightgreen");
$CONF['recipient_delimiter'] = "";
$CONF['create_mailbox_subdirs_prefix']='INBOX.';
$CONF['used_quotas'] = 'NO';
$CONF['new_quota_table'] = 'NO';
$CONF['theme_logo'] = 'images/logo-default.png';
$CONF['theme_css'] = 'css/default.css';
$CONF['xmlrpc_enabled'] = false;

Přihlašte se do Postfixadmina jako superadmin, založte si doménu a zkuste založit uživatele (schránku). Zkontrolujte, zda je v databázi založena schránka ve správném stavu:

mysql> select * from mailbox limit 1;
+-------------------+------------------------------------+--------------+--------------------+-------+------------+------------+---------------------+---------------------+--------+
| username          | password                           | name         | maildir            | quota | local_part | domain     | created             | modified            | active |
+-------------------+------------------------------------+--------------+--------------------+-------+------------+------------+---------------------+---------------------+--------+
| zdenda@zdenda.com | $1$582e4483$bapnENa32a0OIz.ngyTEW/ | Zdeněk Burda | zdenda.com/zdenda/ |     0 | zdenda     | zdenda.com | 2011-08-20 21:48:33 | 2011-08-20 21:48:33 |      1 |
+-------------------+------------------------------------+--------------+--------------------+-------+------------+------------+---------------------+---------------------+--------+

Pokud se podařilo a váš záznam v MySQL vypadá nějak podobně jako u mne, tak můžete postoupit na další krok – nastavení Postfixu.

Postfix

Postfix má na starosti pouze SMTP provoz – přijme maila, předá ho do Amavisu na kontrolu obsahu a po tom co se mail vrátí z Amavisu zkusí postfix mail doručit.

Doručení se bude provádět třemi způsoby:

  • lokální doručení – lokálně se doručují maily pro unixové uživatele evidované v operačním systému,
  • dovecot – pro domény spravované naším mailserverem (domény jsou evidovány v MySQL) se bude používat doručení přes LDA dovecot.
  • smtp – maily pro domény, které nespravuje náš mailserver, se předávají přes SMTP na další mailservery,

Konfigurace virtuálních uživatelů mailserveru v souboru /etc/postfix/main.cf

virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_alias_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
virtual_mailbox_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
virtual_transport = dovecot

smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname
smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated
smtpd_sender_restrictions = permit_mynetworks, reject_unknown_sender_domain
smtpd_recipient_restrictions = permit_mynetworks,
                               reject_unknown_sender_domain,
                               reject_unknown_recipient_domain,
                               reject_unlisted_recipient,
                               reject_unauth_destination,
                               reject_unauth_pipelining

default_destination_concurrency_limit = 1
local_destination_concurrency_limit = 1
dovecot_destination_concurrency_limit = 1
dovecot_destination_recipient_limit = 1

disable_vrfy_command=yes
strict_rfc821_envelopes=yes
smtpd_soft_error_limit=5
smtpd_hard_error_limit=10
smtpd_helo_required=yes
smtpd_delay_reject=no
maximal_queue_lifetime = 6d
delay_warning_time = 8h
biff = no
enable_original_recipient = yes
append_at_myorigin = yes

Konfigurační soubor /etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf

user = postfix
password = HESLO
hosts = unix:/var/lib/mysql/mysql.sock
dbname = postfix
query  = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

Konfigurační soubor /etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf

user = postfix
password = HESLO
hosts = unix:/var/lib/mysql/mysql.sock
dbname = postfix
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'

Konfigurační soubor /etc/postfix/sql/mysql_virtual_alias_domain_maps.cf

user = postfix
password = HESLO
hosts = unix:/var/lib/mysql/mysql.sock
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

Konfigurační soubor /etc/postfix/sql/mysql_virtual_alias_maps.cf

user = postfix
password = HESLO
hosts = unix:/var/lib/mysql/mysql.sock
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
#expansion_limit = 100

Konfigurační soubor /etc/postfix/sql/mysql_virtual_domains_maps.cf

user = postfix
password = HESLO
hosts = unix:/var/lib/mysql/mysql.sock
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'

Konfigurační soubor /etc/postfix/sql/mysql_virtual_mailbox_maps.cf

user = postfix
password = HESLO
hosts = unix:/var/lib/mysql/mysql.sock
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
#expansion_limit = 100

Výše uvedená konfigurace umožní mailserveru přijímat poštu pro domény spravované Postfixadminem v MySQL.

Autentizace uživatele při odesílání pošty přes mailserver

Aby mohli uživatelé posílat poštu ze svého tlustého klienta odkudkoliv, je nutné zapnout podporu autentizace uživatele v Postfixu. Postfix bude uživatele ověřovat pomocí Dovecotu, který bude sloužit jako autentizační služba. Dovecot bude obhospodařovat socket /var/spool/postfix/private/auth (konfigurace Dovecotu je popsána dále) přes který bude Postfix uživatele ověřovat. Do konfiguračního souboru /etc/postfix/main.cf je nutné dopsat:

smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = server.domain.tld
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = noanonymous
smtpd_sasl_authenticated_header = yes
broken_sasl_auth_clients = yes

Protože je nevhodné posílat přihlašovací údaje uživatelů nešifrovaným kanálem, je vhodné nastavit podporu pro TLS na straně mailserveru:

smtpd_tls_auth_only = yes
smtpd_use_tls = yes
smtpd_tls_security_level = may
smtpd_tls_key_file = /etc/pki/dovecot/private/dovecot.pem
smtpd_tls_cert_file = /etc/pki/dovecot/certs/dovecot.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
smtp_use_tls = yes

Také je nutné dopsat do „smtpd_recipient_restrictions“ permit_sasl_authenticated což povolí poslání pošty přihlášeným uživatelům.

smtpd_recipient_restrictions = permit_mynetworks,
                               permit_sasl_authenticated,
                               reject_unknown_sender_domain,
                               reject_unknown_recipient_domain,
                               reject_unlisted_recipient,
                               reject_unauth_destination,
                               reject_unauth_pipelining

Někteří provideři poskytující připojení na Internet domácím uživatelům jsou trubky a blokují tcp port 25 nebo ho přesměrovávají na svůj vlastní mailserver. Takovéto chování znemožňuje posílání pošty z tlustého klienta přes SMTP na portu 25 s využitím TLS, je proto vhodné nabídnout i jiný port. Proto spouštím na portu 465 ještě SSL variantu – v konfiguračním souboru /etc/postfix/master.cf je třeba doplnit smtps službu:

smtps     inet  n       -       n       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o milter_macro_daemon_name=ORIGINATING

Greylisting

Na mailserveru jsem si zvykl používat jako první linii ochrany proti spamu greylisting, sice to není 100% ochrana proti spamu, ale dost pomáhá. Jedna z možných implementací greylistingu je Postgrey.

Pro zapojení Postgrey do Postfixu stačí zapnout službu postgrey v operačním systému

# chkconfig postgrey on
# service postgrey start

a na konec smtpd_recipient_restrictions přidat check_policy_service unix:/var/spool/postfix/postgrey/socket:

smtpd_recipient_restrictions = permit_mynetworks,
                               permit_sasl_authenticated,
                               reject_unknown_sender_domain,
                               reject_unknown_recipient_domain,
                               reject_unlisted_recipient,
                               reject_unauth_destination,
                               reject_unauth_pipelining,
                               check_policy_service unix:/var/spool/postfix/postgrey/socket

Někdy se hodí vyřadit pro nějakou konkrétní doménu nebo odesílající server greylisting z činnosti. U Postgrey je připsání na „whitelist“ snadné, stačí zapsat odesílající server do /etc/postfix/postgrey_whitelist_clients.local nebo uživatele/doménu příjemce do /etc/postfix/postgrey_whitelist_recipients.

Dovecot

Konfigurace postfixu

Pro doručování pošty do schránek virtuálních uživatelů vedených v MySQL se na mailserveru používá Dovecot. Aby Postfix předával poštu Dovecotu je nutné dopstat definici transportu „dovecot“ do konfiguračního souboru /etc/postfix/master.cf:

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

V souboru /etc/postfix/main.cf by měl být řádek definující výchozí transport pro virtuální uživatele:

virtual_transport = dovecot

Konfigurace Dovecotu

Ve verzi 1.x měl Dovecot jeden hlavní konfigurační soubor /etc/dovecot/dovecot.conf, který obsahoval vše potřebné. Ve verzi 2, kterou používáme, je konfigurace rozstrkána do více souborů umístěných v adresáři /etc/dovecot/conf.d/. V Hlavním konfiguračním souboru /etc/dovecot/dovecot.conf zůsalo už jen:

!include conf.d/*.conf
protocols = imap pop3 sieve
dict {
}

Aby Dovecot uměl zpracovat poštu předanou postfixem, připojit přes IMAP/POP3 správně uživatele nebo správně zacházet se Sieve filtry je nutné nakonfigurovat napojení na MySQL.

Do konfiguračního souboru /etc/dovecot/dovecot-sql.conf.ext je nutné dopsat parametry pro připojení k MySQL a vytvořit správný SQL dotaz na heslo a uživatele:

driver = mysql
connect = host=/var/lib/mysql/mysql.sock dbname=postfix user=postfix password=HESLO
default_pass_scheme = MD5
password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'
user_query = SELECT CONCAT('/home/mail/', maildir) AS home, 'Maildir/' AS maildir, 491 AS uid, 489 AS gid FROM mailbox WHERE username = '%u' AND active='1'

Použitá UID v SQL dotazu user_query na uživatele by měla odpovídat uživateli a skupině vmail, které jste si vytvořili na začátku instalace v operačním systému.

V konfiguračním souboru /etc/dovecot/conf.d/auth-sql.conf.ext zkontrolujte správnou cestu ke konfiguráku s SQL dotazy:

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

a v konfiguračním souboru /etc/dovecot/conf.d/10-auth.conf zkontrolujte zda se správně vkládá auth-sql.conf.ext konfigurák.

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

V konfiguračním souboru /etc/dovecot/conf.d/10-mail.conf je nutné správně nastavit základní hodnoty závislé na operačním systému:

mail_location = maildir:/home/mail/%d/%n/Maildir
mail_uid = vmail
mail_gid = vmail
first_valid_uid = 491
last_valid_uid = 491
first_valid_gid = 489
last_valid_gid = 489
auth_socket_path = /var/run/dovecot/auth-userdb
maildir_copy_with_hardlinks = yes
mbox_write_locks = fcntl

Konfigurační soubor /etc/dovecot/conf.d/10-master.cf obsahuje definici IMAP a POP3 služeb a jejich portů. IMAP na portu 143 bude použit pouze z localhostu pro přístup z webmailu. POP3 bez ssl je zakázáno.

V souboru 10-master.cf je také definice listeneru autorizační služby, kterou bude používat postfix pro ověření uživatele při odesílání pošty.

service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
    port = 993
    ssl = yes
  }
}

service pop3-login {
  inet_listener pop3 {
    port = 0
  }
  inet_listener pop3s {
    port = 995
    ssl = yes
  }
}

service lmtp {
  unix_listener lmtp {
    #mode = 0666
  }
}

service imap {
  process_limit = 1024
}

service pop3 {
  process_limit = 256
}

service auth {
  unix_listener auth-userdb {
    mode = 0600
    user = vmail 
    group = vmail
  }
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
  }
}
service auth-worker {
}

Aby bylo možné používat SSL varianty služeb definované v konfiguračním souboru 10-master.conf je potřeba Dovecotu předhodit SSL certifikát. To se provádí zápisem atributů ssl_cert a ssl_key do konfiguračního souboru /etc/dovecot/conf.d/10-ssl.conf:

ssl_cert = </etc/pki/dovecot/certs/dovecot.pem
ssl_key = </etc/pki/dovecot/private/dovecot.pem

Konfigurace doručovacího agenta dovecotu, kterému postfix předává poštu k uložení do schránek (LDA) je v souboru /etc/dovecot/conf.d/15-lda.conf. V tomto konfiguračním souboru je vhodné zapnout plugin „sieve“ (mail_plugins=sieve), který umožňí filtrovat poštu při doručování do schránky pomocí definovaných pravidel. Sieve pravidla definuje buď administrátor centrálně nebo uživatel přes webmail.

postmaster_address = postmaster@domain.tld
hostname = server
rejection_subject = Rejected: %s
rejection_reason = Your message to < %t> was automatically rejected:%n%r
lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes
protocol lda {
  mail_plugins = sieve
}

Když už je v LDA zapnuta podpora pro Sieve filtry, je vhodné také provést nastavení managesieve serveru, který umožní uživatelům měnit filtry z webmailu. Je také nutné definovat podporované funkce (capability) Sieve filtrů. Konfigurace se provádí v souboru /etc/dovecot/conf.d/20-managesieve.conf:

service managesieve-login {
  inet_listener sieve {
    port = 4190
  }
}
service managesieve {
}
protocol sieve {
  mail_max_userip_connections = 100
  managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date
  managesieve_notify_capability = mailto
}

Konfiguraci Sieve – umístění souborů s definicí sieve filtrů – definujte v konfiguráku /etc/dovecot/conf.d/90-sieve.conf:

plugin {
  sieve = ~/.dovecot.sieve
  sieve_dir = ~/sieve
  sieve_extensions = +notify +imapflags
  recipient_delimiter = +
}

Znak ~ odpovídá domácímu adresáři uživatele, adresář je získáván SQL dotazem v user_query (viz soubor dovecot-sql.conf.ext).

Výpis kompletní konfigurace (<code># doveconf -n</code>), kterou používáme na našem serveru:

auth_socket_path = /var/run/dovecot/auth-userdb
first_valid_gid = 489
first_valid_uid = 491
hostname = server
last_valid_gid = 489
last_valid_uid = 491
lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes
mail_gid = vmail
mail_location = maildir:/home/mail/%d/%n/Maildir
mail_uid = vmail
mbox_write_locks = fcntl
passdb {
  args = /etc/dovecot/dovecot-sql.conf.ext
  driver = sql
}
plugin {
  recipient_delimiter = +
  sieve = ~/.dovecot.sieve
  sieve_dir = ~/sieve
  sieve_extensions = +notify +imapflags
}
postmaster_address = postmaster@domain.tld
protocols = imap pop3 sieve
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
  }
  unix_listener auth-userdb {
    group = vmail
    mode = 0600
    user = vmail
  }
}
service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
    port = 993
    ssl = yes
  }
}
service imap {
  process_limit = 1024
}
service managesieve-login {
  inet_listener sieve {
    port = 4190
  }
}
service pop3-login {
  inet_listener pop3 {
    port = 0
  }
  inet_listener pop3s {
    port = 995
    ssl = yes
  }
}
service pop3 {
  process_limit = 256
}
ssl_cert = </etc/pki/dovecot/certs/dovecot.pem
ssl_key = </etc/pki/dovecot/private/dovecot.pem
userdb {
  args = /etc/dovecot/dovecot-sql.conf.ext
  driver = sql
}
protocol lda {
  mail_plugins = sieve
}
protocol imap {
  mail_max_userip_connections = 512
}
protocol sieve {
  mail_max_userip_connections = 100
  managesieve_notify_capability = mailto
  managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date
}
protocol pop3 {
  mail_max_userip_connections = 5
  pop3_enable_last = yes
  pop3_reuse_xuidl = yes
}

Pokud jste postupovali podle článku, tak byste měli mít funkční SMTP a IMAP/POP3 server. Zbývající služby mailserveru popíšu v dalším dílu článku. V dalším dílu bude:

  • Amavis
    • Antivir
    • Antispam
  • Roundcube
    • Změna hesla
  • Konfigurace tlustého klienta

Jako jeden z dalších dílů lze považovat i článek o Dovecotu, Sieve a Roundcube, který jsem zde publikoval již dřív.

 

6 komentářů u „Mailserver – Postfix, Dovecot a MySQL

  1. Ceka me prechod z dovecot 1.2.15 na 2.0.13 nebo uvidime, jestli se vyplati pockat na 2.1. Jediny problem mam s automatickou odpovedi, kterou resim pres sieve – odpovida to obcas, velice nespolehlive (cekam na rozsireni sieve, kde povoli :addresses ["*"] – tj vsechny adresy)

  2. Zaujimalo by ma to pokracovanie s nasadenim amavis, spamassassin. Je realne ze by v blizkej dobe vyslo pokracovanie
    clanku ? Ide o to, ci mam pockat, alebo to skusit vyriesit vlastnymi silami + google.

    Vdaka

  3. Funguje ale Thunderbird selže autentifikace. Nastavil jsem v rozšířených spojení SSL a pasword plain over SSL transport.
    Kde je chyba?