Что мы создаём
Полноценный почтовый сервер для одного домена: Postfix для транспорта, Dovecot для IMAP и локальной доставки, rspamd для фильтрации и подписи DKIM, и три DNS-записи, которые определяют, попадёт ли ваше письмо у крупных получателей во входящие или в папку, которую никто не открывает. Он отправляет, принимает, аутентифицирует и не является открытым релеем.
Совет поднять собственный почтовый сервер немоден, и в основном по делу. Сложность не в программном обеспечении, а в доставляемости. Ошибитесь в DNS — и самый тщательно настроенный Postfix в мире отправит сообщения в пустоту.
Перед началом работы
- Инстанс R-8 или больше. Фильтрация требует много CPU, и rspamd с радостью использует все ядра, которые вы ему дадите, во время спам-волны.
- Домен, DNS которого вы контролируете, и терпение для распространения записей.
- Обратный DNS на адресе инстанса, указывающий на ваш почтовый хостнейм. Он редактируется в панели и обязателен: получатели отклоняют отправителей, чьи адреса не резолвятся.
- Один тикет в поддержку с вопросом, открыт ли исходящий порт 25 на вашем инстансе. Спросите до начала работы, а не после.
mail.example.comповсюду. Подставьте свои значения.
1. Хостнейм и DNS
hostnamectl set-hostname mail.example.com
apt update && apt full-upgrade -yОпубликуйте эти записи сейчас, потому что для шага с сертификатом нужна A-запись, а для шага с подписью нужно куда-то поместить ключ. Значения в таблице — это то, что делает каждая запись, а не то, что вставлять.
| Запись | Имя | Содержимое |
|---|---|---|
| A / AAAA | mail | Адреса инстанса из панели |
| MX | @ | 10 mail.example.com. |
| TXT | @ | v=spf1 mx -all |
| TXT | _dmarc | v=DMARC1; p=none; rua=mailto:[email protected]; adkim=s; aspf=s |
| PTR | адрес инстанса | mail.example.com — задаётся в панели |
Запись SPF говорит: письма отправляет мой MX, всё остальное — подделка. Жёсткий отказ (hard fail), а не мягкий (soft fail), потому что ~all приглашает получателей принять собственное решение, а их решение не будет благосклонным. DMARC начинается с p=none, чтобы вы в течение недели собирали отчёты до того, как что-то начнёт отклоняться от вашего имени.
2. Сертификаты
apt install -y certbot
certbot certonly --standalone -d mail.example.comНа порту 80 ещё ничего не слушает, поэтому автономный режим — самый простой путь. Хуки обновления появятся в конце, когда уже будут существовать демоны для перезагрузки.
3. Postfix
DEBIAN_FRONTEND=noninteractive apt install -y postfix postfix-pcre dovecot-imapd dovecot-lmtpd rspamd redis-serverТеперь задайте конфигурацию транспорта. Каждая строка ниже продумана; postconf записывает их на место, так что редактор не нужен и ошибиться негде:
postconf -e "myhostname = mail.example.com"
postconf -e "mydestination = localhost"
postconf -e "smtpd_banner = \$myhostname ESMTP"
postconf -e "inet_interfaces = all"
postconf -e "smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem"
postconf -e "smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem"
postconf -e "smtpd_tls_security_level = may"
postconf -e "smtp_tls_security_level = dane"
postconf -e "smtpd_tls_mandatory_protocols = >=TLSv1.2"
postconf -e "smtpd_sasl_type = dovecot"
postconf -e "smtpd_sasl_path = private/auth"
postconf -e "smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination"
postconf -e "smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unknown_recipient_domain reject_unauth_destination"
postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"
postconf -e "virtual_mailbox_domains = example.com"
postconf -e "smtpd_milters = inet:127.0.0.1:11332"
postconf -e "non_smtpd_milters = inet:127.0.0.1:11332"
postconf -e "milter_default_action = accept"Самая важная строка — smtpd_relay_restrictions. Она заканчивается на reject_unauth_destination, что не позволяет всему интернету использовать вашу машину для отправки почты. Открытое реле приведёт к внесению в чёрные списки в течение нескольких часов, а также является нарушением правил допустимого использования.
Включите порт отправки, чтобы ваши собственные клиенты могли отправлять письма, с обязательной аутентификацией и без анонимного доступа:
postconf -M submission/inet="submission inet n - y - - smtpd"
postconf -P "submission/inet/syslog_name=postfix/submission"
postconf -P "submission/inet/smtpd_tls_security_level=encrypt"
postconf -P "submission/inet/smtpd_sasl_auth_enable=yes"
postconf -P "submission/inet/smtpd_client_restrictions=permit_sasl_authenticated,reject"4. Dovecot
Почтовые ящики в формате Maildir в домашнем каталоге одного системного пользователя позволяют сохранить эту сборку компактной. Создайте пользователя и хранилище:
groupadd -g 5000 vmail
useradd -g vmail -u 5000 -d /var/vmail -m vmail
install -d -o vmail -g vmail -m 700 /var/vmail/example.comЗапишите /etc/dovecot/conf.d/99-local.conf:
mail_location = maildir:/var/vmail/%d/%n
mail_uid = vmail
mail_gid = vmail
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
ssl_min_protocol = TLSv1.2
auth_mechanisms = plain login
disable_plaintext_auth = yes
passdb {
driver = passwd-file
args = scheme=ARGON2ID username_format=%u /etc/dovecot/users
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/vmail/%d/%n
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}Создайте почтовый ящик. Команда запрашивает пароль дважды и сохраняет хэш, а не сам пароль:
echo -n "[email protected]:" >> /etc/dovecot/users
doveadm pw -s ARGON2ID >> /etc/dovecot/users
chmod 640 /etc/dovecot/users
chgrp dovecot /etc/dovecot/users5. rspamd и DKIM
Сгенерируйте ключ подписи, затем опубликуйте открытую часть:
install -d -o _rspamd -g _rspamd -m 750 /var/lib/rspamd/dkim
rspamadm dkim_keygen -s mail -b 2048 -d example.com -k /var/lib/rspamd/dkim/example.com.mail.key
chown _rspamd:_rspamd /var/lib/rspamd/dkim/example.com.mail.key
chmod 400 /var/lib/rspamd/dkim/example.com.mail.keyЭта команда выводит DNS-запись на стандартный вывод. Опубликуйте её как TXT-запись на mail._domainkey.example.com, точно так, как она выведена, соединив сегменты в кавычках так, как требует ваш DNS-провайдер. Затем сообщите rspamd, где находится ключ, в /etc/rspamd/local.d/dkim_signing.conf:
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
selector = "mail";
allow_username_mismatch = true;
use_domain = "header";
sign_authenticated = true;
sign_local = true;Подключите milter и задайте пароль для веб-интерфейса:
echo "bind_socket = \"127.0.0.1:11332\";" > /etc/rspamd/local.d/worker-proxy.inc
rspamadm pwВставьте полученный хэш в /etc/rspamd/local.d/worker-controller.inc как password = "...". Доступ к интерфейсу — через SSH-туннель, не открывайте порт 11334 наружу.
6. Запуск всего
systemctl enable --now redis-server rspamd dovecot postfix
postfix check
systemctl --no-pager --failedДобавьте хук обновления сертификата, чтобы новый сертификат добрался до обоих демонов:
echo "systemctl reload postfix dovecot" > /etc/letsencrypt/renewal-hooks/deploy/reload-mail.sh
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-mail.shПроверка
Три теста. Первый — локальный, второй — тот, который важен, третий — тот, который уберегает вас от блокировок.
echo | openssl s_client -starttls smtp -connect mail.example.com:25 -servername mail.example.com 2>/dev/null | grep -E "subject=|Verify return"Затем отправьте сообщение с вашего нового сервера на ваш ящик на крупном веб-почтовом провайдере, откройте полученное сообщение и прочитайте его исходные заголовки. Ищите одну строку:
Authentication-Results: mx.receiver.example;
dkim=pass [email protected];
spf=pass smtp.mailfrom=example.com;
dmarc=pass (p=NONE) header.from=example.comТри успешных проверки — и готово. dkim=none означает, что rspamd не подписывает, поэтому проверьте rspamadm configdump dkim_signing. spf=fail почти всегда означает, что сообщение ушло через IPv6, в то время как ваша запись SPF покрывает только адрес MX версии 4.
Наконец, докажите, что вы не реле. С любой другой машины подключитесь и попробуйте отправить письмо между двумя доменами, которые вам не принадлежат:
apt install -y swaks
swaks --to [email protected] --from [email protected] --server mail.example.comПравильный результат — отказ на этапе получателя: 554 5.7.1 Relay access denied. Всё остальное означает, что вы настроили машину, которую будут использовать в злонамеренных целях уже в течение дня; остановитесь и перечитайте шаг три.
Дальнейшие шаги
Оставьте DMARC на p=none на неделю и читайте агрегированные отчёты. Как только они покажут, что только ваш сервер подписывает вашу почту, переходите на p=quarantine, а через две недели — на p=reject. Попутно настройте резервное копирование за пределами узла для /var/vmail, потому что почта — это то, второй копии чего у пользователей никогда нет, а наш аддон резервного копирования записывает данные на другой сайт, нежели инстанс.