Если вы администрируете собственный почтовый сервер на Postfix, то milter — ваш главный инструмент для расширения проверки и модификации писем. В этой статье мы настраиваем и увязываем три ключевых компонента:
- OpenDKIM — подписание исходящих и верификация входящих DKIM-писем.
- OpenDMARC — проверка политики DMARC и выработка решения для входящей почты.
- Rspamd — антиспам, SPF/DKIM/DMARC-оценка, заголовки и карантин.
Покажу, как выбрать порядок milters, какие сокеты использовать с учётом chroot в Postfix, как развести правила для входящего трафика (порт 25) и исходящего (submission 587/465), а также как тестировать и отлаживать.
Зачем milter и как он работает в Postfix
Milter (Mail Filter) — это стандартный способ сторонним сервисам получать события SMTP-сеанса и влиять на письмо до его очереди (pre-queue) или при обработке локальной почты (через non_smtpd_milters). Postfix передаёт milter-модулям ключевые атрибуты: IP отправителя, HELO, MAIL FROM, RCPT TO, заголовки и тело. В ответ milter может добавить/изменить заголовки, запросить временный откат (4xx), окончательный отказ (5xx) или пропустить сообщение.
Почему это важно:
- DKIM-подпись исходящих должна выполняться до постановки в очередь и до фильтрации, чтобы downstream-системы получили неизменённое тело и корректный DKIM.
- DMARC-оценка опирается на результаты SPF/DKIM. Корректный порядок milters гарантирует, что DMARC увидит уже готовые
Authentication-Results. - Антиспам (Rspamd) имеет смысл запускать после криптографической верификации и DMARC, чтобы скоринг учитывал эти итоги.
Схема потока и рекомендуемый порядок milters
Классическая и предсказуемая цепочка для входящей почты на порт 25:
- OpenDKIM — проверяет подписи и при необходимости помечает результат в
Authentication-Results. - OpenDMARC — оценивает политику домена, видит итоги DKIM/SPF и принимает решение (pass/none/quarantine/reject).
- Rspamd — выполняет антиспам-скоринг, использует результаты валидации, добавляет итоговые заголовки и может поместить в карантин или пометить как спам.
Для исходящей почты (submission 587/465) обычно достаточно OpenDKIM (подписать) и Rspamd (минимальная проверка и заголовки). OpenDMARC на исходящем трафике не нужен: DMARC — это политика домена для входящей проверки на стороне получателя.
Главный принцип: на входе — проверяем (DKIM, DMARC, антиспам), на выходе — подписываем и не мешаем доставке. Разделение конфигурации для 25 и 587/465 в Postfix делается через переопределения в
master.cf.

Сокеты: unix vs inet и chroot Postfix
Postfix по умолчанию в Debian/Ubuntu запускает smtpd в chroot (/var/spool/postfix). Из-за этого рекомендуется использовать unix-сокеты, размещённые внутри /var/spool/postfix, чтобы демон имел к ним доступ.
- Безопаснее: unix-сокет не торчит в сеть.
- Прозрачнее для chroot: указываем путь относительно каталога chroot в Postfix, например
unix:/opendkim/opendkim.sock.
Иногда для упрощения используют inet:127.0.0.1:port. Это тоже рабочий вариант, но следите за фаерволом и не слушайте 0.0.0.0.
Подготовка системы
Предположим Debian/Ubuntu. Установим пакеты:
apt update
apt install postfix opendkim opendkim-tools opendmarc rspamd
Добавьте postfix в группы milters (чтобы сокеты были доступны):
usermod -aG opendkim postfix
usermod -aG opendmarc postfix
usermod -aG _rspamd postfix
Имена пользователей/групп могут отличаться в зависимости от дистрибутива (rspamd или _rspamd). Проверьте getent passwd и getent group.
Если вы поднимаете почтовик на отдельном сервере, удобнее делать это на управляемом облачном VDS с предсказуемыми IOPS и резервным копированием.
OpenDKIM: генерация ключей и базовая конфигурация
Создадим каталоги и ключ для домена example.com. В проде используйте собственный домен:
mkdir -p /etc/opendkim/keys/example.com
opendkim-genkey -b 2048 -s mail -d example.com -D /etc/opendkim/keys/example.com
chown -R opendkim:opendkim /etc/opendkim/keys
chmod 0700 /etc/opendkim/keys
chmod 0600 /etc/opendkim/keys/example.com/mail.private
Файлы:
mail.private— закрытый ключ (секрет).mail.txt— TXT-запись для DNS (публичный ключ).
Пример /etc/opendkim.conf:
Syslog yes
UMask 002
Mode sv
Canonicalization relaxed/simple
Selector mail
KeyTable /etc/opendkim/key.table
SigningTable /etc/opendkim/signing.table
ExternalIgnoreList refile:/etc/opendkim/trusted.hosts
InternalHosts refile:/etc/opendkim/trusted.hosts
Socket local:/var/spool/postfix/opendkim/opendkim.sock
UserID opendkim
PidFile /run/opendkim/opendkim.pid
AutoRestart yes
LogWhy yes
SoftwareHeader yes
Таблицы:
# /etc/opendkim/key.table
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private
# /etc/opendkim/signing.table
*@example.com mail._domainkey.example.com
# /etc/opendkim/trusted.hosts
127.0.0.1
::1
localhost
Создадим каталог для сокета внутри chroot Postfix:
mkdir -p /var/spool/postfix/opendkim
chown opendkim:opendkim /var/spool/postfix/opendkim
chmod 0755 /var/spool/postfix/opendkim
Перезапускаем:
systemctl enable opendkim
systemctl restart opendkim
Проверьте, что сокет существует и доступен группе postfix:
ls -l /var/spool/postfix/opendkim/opendkim.sock
Не забудьте опубликовать TXT-запись DKIM из файла mail.txt в DNS домена (селектор mail). После репликации проверьте, что публичный ключ читается. Если оформляете новый домен под почту, воспользуйтесь удобной страницей регистрации доменов.
OpenDMARC: политика и интеграция
OpenDMARC оценивает соответствие домена-отправителя политике DMARC (none/quarantine/reject), используя результаты SPF и DKIM. На старте безопаснее не блокировать письма, а только метить и логировать.
Пример /etc/opendmarc.conf:
Syslog true
UMask 007
Socket local:/var/spool/postfix/opendmarc/opendmarc.sock
UserID opendmarc
PidFile /run/opendmarc/opendmarc.pid
AuthservID mail.example.com
TrustedAuthservIDs mail.example.com
IgnoreAuthenticatedClients true
SPFIgnoreResults false
FailureReports false
RejectFailures false
Создаём каталог под сокет и запускаем:
mkdir -p /var/spool/postfix/opendmarc
chown opendmarc:opendmarc /var/spool/postfix/opendmarc
chmod 0755 /var/spool/postfix/opendmarc
systemctl enable opendmarc
systemctl restart opendmarc
RejectFailures false на этапе обкатки позволит не ломать доставку. Когда уровень уверенности будет достаточным, можно перевести в true или оставлять решение Rspamd. IgnoreAuthenticatedClients true отключает DMARC-проверку для авторизованных исходящих (submission).
Rspamd: worker-proxy в режиме milter
Rspamd — высокопроизводительный антиспам с поддержкой SPF/DKIM/DMARC, fuzzy, байесом, символами скоринга и карантином. Для Postfix рекомендуется включить worker-proxy в режиме milter и слушать unix-сокет в chroot.
Пример /etc/rspamd/local.d/worker-proxy.inc:
type = "proxy";
milter = yes;
bind_socket = "unix:/var/spool/postfix/rspamd/rspamd.sock mode=660 owner=_rspamd group=postfix";
upstream "local" {
default = yes;
self_scan = yes;
}
Убедимся, что каталог существует и доступен:
mkdir -p /var/spool/postfix/rspamd
chown _rspamd:postfix /var/spool/postfix/rspamd
chmod 0770 /var/spool/postfix/rspamd
systemctl enable rspamd
systemctl restart rspamd
Если вы используете OpenDKIM для подписи исходящих, чтобы избежать двойного DKIM, отключите модуль DKIM-подписи в Rspamd:
# /etc/rspamd/local.d/dkim_signing.conf
enabled = false;
Аналогично можно настроить, будет ли Rspamd добавлять собственные заголовки Authentication-Results. Если у вас их уже ставят OpenDKIM/OpenDMARC и вы хотите единообразия, ограничьте дублирование в milter_headers.conf (по ситуации в вашей инсталляции).
Postfix: включаем milters и разделяем входящий/исходящий поток
Базовые параметры в /etc/postfix/main.cf:
milter_protocol = 6
milter_default_action = accept
smtpd_milters = unix:/opendkim/opendkim.sock, unix:/opendmarc/opendmarc.sock, unix:/rspamd/rspamd.sock
non_smtpd_milters = $smtpd_milters
milter_mail_macros = i {mail_addr} {rcpt_addr} {client_addr} {client_name} {auth_type} {auth_authen} {tls_version} {cipher}
milter_default_action = accept на этапе обкатки защищает от ложных отказов, если какой-то milter внезапно недоступен. После стабилизации можно ужесточить поведение по политике вашей организации.
Разделим набор milters для входящего (25) и исходящего (587/465), чтобы на исходящем не выполнять DMARC:
# /etc/postfix/master.cf
smtp inet n - y - - smtpd
-o smtpd_milters=unix:/opendkim/opendkim.sock,unix:/opendmarc/opendmarc.sock,unix:/rspamd/rspamd.sock
-o milter_macro_daemon_name=INBOUND
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o milter_macro_daemon_name=ORIGINATING
-o smtpd_milters=unix:/opendkim/opendkim.sock,unix:/rspamd/rspamd.sock
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o milter_macro_daemon_name=ORIGINATING
-o smtpd_milters=unix:/opendkim/opendkim.sock,unix:/rspamd/rspamd.sock
После правок перезагрузите Postfix:
postfix reload
Для submission/smtps вам нужен актуальный сертификат сервера. Если требуется корпоративный валидированный сертификат, можно приобрести надёжные SSL-сертификаты и установить их в Postfix.
Тестирование и отладка
Отправим тестовое письмо через локальный порт 25 (эмулируя входящее):
swaks --to you@example.com --from test@external.tld --server 127.0.0.1:25 --data <<EOF
Subject: milter inbound test
Hello
EOF
И через submission, как аутентифицированный пользователь (исходящее):
swaks --to someone@remote.tld --server 127.0.0.1:587 --auth LOGIN --auth-user user --auth-password pass --tls
Проверьте логи:
journalctl -u opendkim -u opendmarc -u rspamd -e
journalctl -u postfix -e | tail -n 200
Ищите в заголовках доставленного письма:
DKIM-Signature(на исходящем).Authentication-Resultsс DKIM/SPF/DMARC.- Заголовки Rspamd (
X-Spamили расширенные, в зависимости от профиляmilter_headers).

Типичные проблемы и как их решать
1) Postfix не может подключиться к сокету milter
Проверьте, что путь сокета находится внутри /var/spool/postfix, права группы включают postfix, и smtpd работает в chroot. Популярная ошибка — указать путь вне chroot или забыть добавить пользователя postfix в группу сервиса.
2) Дублирующиеся заголовки Authentication-Results
Если и OpenDKIM/OpenDMARC, и Rspamd добавляют Authentication-Results, появятся дубликаты. Определите «единственный достоверный источник» и отключите дублирование в другом компоненте. На практике часто оставляют заголовки от Rspamd, а в OpenDMARC ориентируются на результаты, но это зависит от вашей политики и удобства отладки.
3) Письма срываются из-за RejectFailures
Не включайте RejectFailures true в OpenDMARC, пока вы не убедились, что легитимный трафик не страдает от переадресаций и «сломанных» отправителей. Начните с логирования и пометки, а затем постепенно ужесточайте политику (или поручите финальное решение Rspamd).
4) DKIM-подпись слетает
Любые модификации тела/заголовков после подписи приведут к body hash mismatch. Убедитесь, что цепочка milters не меняет письмо после OpenDKIM. Если используете Rspamd для подписи, отключите подпись в OpenDKIM (или наоборот).
5) DNS и ключи
Проверьте, что TXT-запись селектора доступна авторитетно, TTL умеренный, ключ 2048 бит и не утёк в репозитории. Для ротации используйте новые селекторы и перекатывайте записи без простоя. Подробно — в материале Ротация DKIM-селекторов и настройка TTL.
6) SELinux/AppArmor
На системах с SELinux/AppArmor проверьте профили. Ограничения могут блокировать создание сокетов в /var/spool/postfix или доступ Postfix к ним. Решение — корректные политики и контексты.
Про DMARC и роль каждого компонента
DMARC оценивает alignment домена из From: с результатами SPF/DKIM. В связке из статьи есть две рабочие модели:
- Классика: OpenDKIM проверяет DKIM, OpenDMARC выносит DMARC-решение, Rspamd учитывает результат в скоринге. Плюс — прозрачная трассировка: кто проверил, кто решил. Минус — потенциально два источника AR-заголовков.
- Единый центр: Rspamd проверяет SPF/DKIM/DMARC, а OpenDKIM только подписывает исходящие. Плюс — единообразные заголовки и отчётность в одном месте. Минус — меньше изоляции ролей, придётся аккуратнее настраивать Rspamd.
Какой вариант выбрать — зависит от ваших процедур и опыта команды. В инфраструктурах с большим количеством переадресаций пригодится ARC; подробнее о его внедрении — в статье ARC в Postfix и Rspamd для корректной переадресации.
Практические рекомендации по эксплуатации
- Логи: централизуйте и метите префиксы сервисов; так вы быстрее поймёте, где именно «упало» — в OpenDKIM, OpenDMARC или Rspamd.
- Оценка риска: сначала «метки и обучение», затем «отклонение». Rspamd позволяет завести карантин и проверять жалобы.
- Ротация DKIM: используйте селекторы вида
2025q1, меняйте ключи раз в 6–12 месяцев. - Предсказуемость: фиксируйте порядок milters. Любая перестановка может поменять заголовки и итоги проверки.
- Тестовые домены: держите пару внешних ящиков на разных провайдерах, чтобы видеть реальную доставляемость.
- Переадресации: DMARC ломается на простых форвардах без ARC — учитывайте это в скоринге.
Чек-лист внедрения
- Установить пакеты, добавить пользователя
postfixв группы milters. - OpenDKIM: ключи, таблицы, сокет в chroot, публикация TXT, рестарт.
- OpenDMARC: базовый конфиг, мягкий режим, сокет в chroot, рестарт.
- Rspamd:
worker-proxyв milter, сокет в chroot, рестарт. - Postfix:
smtpd_miltersиnon_smtpd_miltersвmain.cf, разделение для 25 и 587/465 вmaster.cf. - Тесты swaks для входящего и исходящего, проверка заголовков и логов.
- Наблюдение и метрики, постепенное ужесточение политики.
Итоги
Связка Postfix + OpenDKIM + OpenDMARC + Rspamd даёт предсказуемую и управляемую доставляемость: исходящие письма стабильно подписываются, входящие проходят криптографическую проверку и DMARC-политику, а Rspamd обеспечивает высокоточную фильтрацию спама. Ключевые моменты успеха — корректный порядок milters, аккуратная работа с сокетами в chroot, раздельная конфигурация для входящего/исходящего, постепенная политика отказов и тщательная отладка. Если всё сделать по чек-листу, получится устойчивая и хорошо диагностируемая почтовая инфраструктура.


