почтовый сервер на postfix с opendkim и dovecot


Ниже будет описано как настроить почтовый сервер на своем сервере, какие DNS записи ему прописать, как избежать попадания писем в спам у популярных почтовых провайдеров.

И конечно же немного про безопасность всего этого. Хочу обратить ваше внимание, что данная статья не включает описание настроек, настройку высокопроизводительного почтового сервера и пр. глубинных тем. Может, как-нибудь опишу свой опыт в этой теме в других статьях.

Почтовый сервер в примере состоит из:

1. vps: 1 cpu, 1gb ram, 50gb disk, 100Mb/s net 2. OS Debian Wheezy 3. Opendkim 4. Postifx 5. Dovecot

Для наглядности примера, предположим, что наш домен — prolinux.org Его ip 54.201.180.127

Также рекомендую установить пакет bind9utils для удобной работы с DNS.

Для начала, т. к. этот процесс может занять неопределенное время, я рекомендую создать PTR запись.

Потому что бывает, что ее созданием занимается сам провайдер услуг. Это необходимо для борьбы со спамом, точнее, чтоб нас не считали за спамеров.

Проверяем наличие корректной PTR:

dig @8.8.8.8 127.180.201.54.in-addr.arpa -t ptr +short

В выводе вы должны увидеть свой домен.

Теперь можно создать MX запись. Это проще простого:

prolinux.org IN MX 10 mx.prolinux.org

Мы направили нашу MX запись с единственным приоритетом к нам же на сервер, на котором будет стоять Postfix в качестве релея.

Теперь пару слов про SPF.

SPF (Sender Policy Framework) — TXT запись DNS, которая описывает разрешенные для отправки почты сети. Рекомендуется добавить эту запись, во избежание попадания вашей почты в спам.

Но у меня почта настроена на yandex, если же вы хотите разрешить отправку почты со своего сервера, то рекомендуется следующая запись:

prolinux.org. IN TXT "v=spf1 +a +mx ~all"

Таким образом, мы разрешаем отправку писем с ip A и MX записей, с остальных ip подлинность почты ставится под сомнение.

DKIM (DomainKeys Identified Mail) — похожая на SPF технология, созданная для борьбы со спуфингом. Принцип её работы такой: на почтовом сервере стоит программа, которая добавляет специальный заголовок с подписью к легитимным письмам, для домена прописана специальная TXT запись с публичным ключом для проверки подписи в заголовке письма.

Вкупе с SPF и отсутствием IP сервера в черных списках, DKIM позволит пройти вашим письмам мимо спам фильтров прямиком во входящие.

Рассмотрим настройку DKIM на примере opendkim (версия 2.6.8-4) в Debian Wheezy.

Для начала установим необходимые пакеты:

sudo apt-get -y install opendkim opendkim-tools

Теперь приступим к конфигурации.Приведем конфиг /etc/opendkim.conf к следующему виду:

Syslog yes
UMask 002
OversignHeaders From
AutoRestart yes
AutoRestartRate 10/1h
Canonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
LogWhy Yes
Mode sv
PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256
SigningTable refile:/etc/opendkim/SigningTable
Socket inet:8891@localhost
SyslogSuccess Yes
TemporaryDirectory /var/tmp
UserID opendkim:opendkim

Теперь создадим необходимые директории и конфиги в них:

mkdir -p /etc/opendkim/keys

Нашим разделителем будет default, можно выбрать другое слово в качестве разделителя.

/etc/opendkim/KeyTable

default._domainkey.prolinux.org prolinux.org:default:/etc/opendkim/keys/prolinux.org.private

Указание на TXT запись /etc/opendkim/SigningTable

*@prolinux.org default._domainkey.prolinux.org

Список доверенных сетей, с которых разрешено отправлять легитимную почту /etc/opendkim/TrustedHosts

127.0.0.1
prolinux.org
54.201.180.127/24

Теперь создадим ключи

opendkim-genkey -D /etc/opendkim/keys/ -d prolinux.org -s default

Выставим файлам права

chown opendkim: -R /etc/opendkim/
chmod 400 /etc/opendkim/keys/prolinux.org.private

Запустим opendkim и добавим его в автозагрузку

sudo service opendkim start
sudo update-rc.d opendkim enable

Теперь добавьте следующие TXT записи вашему домену:

_domainkey in TXT "t=s\; o=~\;"

Следующую запись подсмотрите в файле: /etc/opendkim/keys/prolinux.org.txt

default._domainkey in TXT "v=DKIM1\; k=rsa\; p=YIGfMB0GCSqGSIb3DQEBAQUAA4GNADCBjQKbgQC/1jSX6xRbfDIuqvV9EsyLS5DGD06xtjh/lTw536eqyZ44REHRTB20I6W5cEUVKoZP9qF5GBgApkzwzqC2zbNxIiTC7P5wNSFLrgTZ//Vxy7zmzRL56Tc20XKI3wxJkYyJpITBrHOrGmtSsLQJI9SUcy5ANdTCKHYAp3PGrGx9HQIDqQAm"

Привязку софта отправки почты к opendkim рассмотрим на этапе настройки Postfix.

Собственно, сама отправка почты. Potsfix выбран за его простоту в настройке и популярность.

Для удобства работы была выбрана интеграция postfix с mysql. Если у вас используется Postgres, то разница в настройке будет небольшая.

Как обычно, сначала установим пакеты

sudo apt-get install postfix-mysql mysql-server

Конфигурацию mysql я пропущу, т. к. это не относится к теме, будем считать, что у вас есть права создавать базы данных, наполнять их и создавать пользователей.

Для начала создадим базу

CREATE DATABASE mailserver;

пользователя

GRANT SELECT ON mailserver.* TO 'mailuser'@'127.0.0.1' IDENTIFIED BY 'mailuser2014';
USE mailserver;

Таблица, в которой будет содержаться информация о доменах

CREATE TABLE `virtual_domains` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Таблица с пользователями

CREATE TABLE `virtual_users` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`password` varchar(128) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Таблица с настройками ящиков-форвардеров

CREATE TABLE `virtual_aliases` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Добавим наш домен в новую таблицу

INSERT INTO `mailserver`.`virtual_domains` ( `id` , `name`)
VALUES ( '1', 'prolinux.org');

Создадим первого пользователя

INSERT INTO `mailserver`.`virtual_users` (`id`, `domain_id`, `password`, `email`)
VALUES ('1', '1', SHA( 'rootpass' ) , 'root@prolinux.org');

Теперь надо сказать Postfix, что он должен получать данные из базы.

Для этого создадим несколько конфигов.

/etc/postfix/mysql-virtual-mailbox-domains.cf

user = mailuser
password = mailuser2014
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'

Замапим postfix на наш конфиг

postconf -e virtual_mailbox_domains=mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf

Проверим, что postfix знает про наш домен

postmap -q prolinux.org mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf

Должны получить в ответ 1

/etc/postfix/mysql-virtual-mailbox-maps.cf

user = mailuser
password = mailuser2014
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'

Повторим процедуру инициализации и проверки конфига

postconf -e virtual_mailbox_maps=mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf

Опять должны получить id нашего пользователя

postmap -q root@prolinux.org mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf

/etc/postfix/mysql-virtual-alias-maps.cf

user = mailuser
password = mailuser2011
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'
postconf -e virtual_alias_maps=mysql:/etc/postfix/mysql-virtual-alias-maps.cf

Т.к. мы алиасы не создавали, то и проверять не будем.

Скроем наши настройки от посторонних глаз

chown postfix:postfix /etc/postfix/mysql-*
chmod o= /etc/postfix/mysql-*

Настроим postfix на использование DKIM ключей. Для этого в /etc/postfix/mail.cf добавим строки

milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Пока не будем перезапускать postfix, потому что нам надо еще настроить dovecot и внести в конфиги postfix информацию о нем.

Пришла пора настроить получение почты и еще пару плюшек.

Для начала установим пакетики

sudo apt-get install dovecot-common dovecot-imapd dovecot-mysql dovecot-sieve

Приступим к настройке. Создадим пользователя и каталог для почты

groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/vmail -m
mkdir /var/vmail
chown -R vmail:vmail /var/vmail
chmod u+w /var/vmail

В /etc/dovecot/dovecot.conf добавим единственную строчку, которая включит простую авторизацию

disable_plaintext_auth = no

В /etc/dovecot/conf.d/10-mail.conf изменим или добавим указание на папку с письмами

mail_location = maildir:/var/vmail/%d/%n/Maildir

Там же приведем секцию inbox к следующему виду

namespace inbox {
    type = private
    separator = .
    inbox = yes
}

Настройки авторизации

/etc/dovecot/conf.d/10-auth.conf

auth_mechanisms = plain login
!include auth-system.conf.ext

Дополнительно изменить

/etc/dovecot/conf.d/auth-system.conf.ext

passdb {
    driver = sql
    args = /etc/dovecot/dovecot-sql.conf
}
userdb {
    driver = passwd
}
userdb {
    driver = static
    args = uid=5000 gid=5000 home=/var/vmail/%d/%n allow_all_users=yes
}

Приведем файл /etc/dovecot/conf.d/15-lda.conf к следующему виду

protocol lda {
    mail_plugins = sieve
}

И в файле /etc/dovecot/conf.d/10-master.conf заменить секцию service auth на такую

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

Dovecot как-то должен узнать про нашу базу данных. Меняем следующий конфиг/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
}
userdb {
    driver = static
    args = uid=5000 gid=5000 home=/var/vmail/%d/%n allow_all_users=yes
}

Создадим /etc/dovecot/dovecot-sql.conf

driver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=mailuser2014
default_pass_scheme = SHA
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';

И скроем его от всех, кому не надо

chown dovecot:root /etc/dovecot/dovecot-sql.conf
chmod 640 /etc/dovecot/dovecot-sql.conf

Можно перезапускать dovecot и добавить его в автозагрузку

sudo service dovecot restart
sudo update-rc.d dovecot enable

Логи можно посмотреть в /var/log/mail.log, /var/log/mail.info, /var/log/mail.err

Вернемся к донастройке Postfix. В /etc/postfix/main.cf изменить

myhostname = prolinux.org
mydestination =

Добавить информацию о мапингах и связке с dovecot

virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

И про авторизацию туда же. Отправлять письма разрешено только из доверенных сетей и авторизованным пользователям. Авторизация проходим через dovecot и базу mysql

smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination

Теперь изменим /etc/postfix/master.cf

Раскомментируем строку

smtp inet n - - - - smtpd

Добавим настройки авторизации

dovecot unix - n n - - pipe
    flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}
submission inet n - n - - smtpd
    -o smtpd_sasl_auth_enable=yes
    -o smtpd_client_restrictions=permit_sasl_authenticated,permit_mynetworks,reject

Привяжем аккаунты dovecot к postfix

sudo postconf -e virtual_transport=dovecot
sudo postconf -e dovecot_destination_recipient_limit=1

По-идее, всё. Рестартуем postfix и проверяем авторизацию.

sudo service postfix restart
sudo update-rc.d postfix enable

Пробуем отправить письмо изнутри:

echo Test | mail -s "test subject" me@gmail.com

Письмо должно попасть в спам, несмотря на все наши старания, т. к. оно написано не с помощью десктопного mail клиента или webmail и в его теле отсутствуют некоторые заголовки.

Но главное, чтоб оно дошло.

Дальше откуда-то снаружи сервера протестируем авторизацию.

Для удобства подготовим закодированные имя пользователя и пароль в base64.

python -c "for i in ('root@prolinux.org','rootpass'): print(i.encode('base64').strip())"
cm9vdEBwcm9saW51eC5vcmc=
cm9vdHBhc3M=

Тестируем postfix

openssl s_client -connect prolinux.org:587 -starttls smtp
CONNECTED(00000003)
–- ssl part goes here –-
250 DSN
helo test
250 prolinux.org
auth login
334 VXNlcm5hbWU6
cm9vdEBwcm9saW51eC5vcmc=
334 UGFzc3dvcmQ6
cm9vdHBhc3M=
235 2.7.0 Authentication successful

Судя по сообщению, мы успешно авторизовались.

Теперь протестируем Dovecot

telnet prolinux.org 143
Trying 54.201.180.127...
Connected to prolinux.org.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS AUTH=PLAIN AUTH=LOGIN] Dovecot ready.
. login root@prolinux.org rootpass
. OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE] Logged in
. list "" "*"
* LIST (\HasNoChildren \Trash) "." "Trash"
* LIST (\HasNoChildren \Sent) "." "Sent"
* LIST (\HasNoChildren) "." "INBOX"
. OK List completed.
. logout
* BYE Logging out
. OK Logout completed.
Connection closed by foreign host.

Всё. Можно идти пить кофе и настраивать почтовый клиент.

Литература: https://workaround.org/ispmail/wheezy http://dev.kafol.net/2013/01/dkim-spf-sendmail-for-multiple-domains.html

comments powered by Disqus