Postfix relay для нескольких доменов: один сервер, много брендов
Семёнов Евгений Сергеевич, директор АйТи Фреш. 15+ лет в корпоративных почтовых системах. Всё чаще встречается сценарий: у клиента 2–7 доменов разных брендов или юрлиц, каждый со своим SMTP-провайдером и требованиями к аутентификации. Разворачивать на каждом сервере свой relay — дорого и неудобно. Гораздо практичнее собрать один умный Postfix, который сам знает, куда маршрутизировать исходящую почту. Расскажу, как я разворачиваю такие relay-узлы у нас на практике.
Архитектура задачи
Допустим, у клиента три домена:
- brand1.ru — основной бренд, маркетинговые рассылки через Unisender SMTP.
- brand2.ru — B2B-продажи, CRM отправляет через собственный MX напрямую.
- brand3.ru — техническая почта (алерты, отчёты), идёт через Mailgun.
Все внутренние приложения (1С, CRM, Bitrix, самописный бэкенд) отправляют на единую точку — внутренний relay. Relay смотрит на домен отправителя и перенаправляет письмо в нужный upstream. В каждом случае применяется свой DKIM-ключ и свои учётные данные.
Железо и ОС
Для relay-сервера обычно достаточно минимальных ресурсов: 2 vCPU, 2 ГБ RAM, 40 ГБ SSD. Relay не хранит почту, а только пересылает — нагрузка низкая. У нас на практике такие relay работают на виртуалках в кластере Proxmox на Dell Xeon Platinum 8280 с 40G Mellanox — там одна VM обрабатывает до 50 писем/сек без заметной нагрузки.
ОС — Debian 12 или Ubuntu 22.04 LTS. Устанавливаем Postfix и OpenDKIM:
apt update
apt install -y postfix postfix-pcre opendkim opendkim-tools
При первой установке Postfix выбираем тип «Satellite system» — он специально для relay.
Основной конфиг Postfix
# /etc/postfix/main.cf
myhostname = relay.example.ru
mydomain = example.ru
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
# Relay не хранит локальную почту
mydestination =
local_transport = error:local mail disabled
alias_maps =
alias_database =
# Только доверенные клиенты (локальная сеть приложений)
mynetworks = 127.0.0.0/8 10.10.0.0/16 192.168.0.0/24
smtpd_relay_restrictions = permit_mynetworks reject_unauth_destination
# Шифрование и аутентификация upstream
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
# Главное — sender-based маршрутизация
sender_dependent_default_transport_maps = hash:/etc/postfix/sender_transport
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
smtp_sender_dependent_authentication = yes
# Канонические адреса (на случай если local уходит иначе)
sender_canonical_maps = hash:/etc/postfix/sender_canonical
# DKIM через milter
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
# Без local delivery и без receive
recipient_delimiter =
smtpd_banner = $myhostname ESMTP relay
smtp_helo_name = relay.example.ru
Маппинг домен → transport
Главная магия — три файла маппинга. В /etc/postfix/sender_transport прописываем, через какой «transport» идти каждому домену:
# /etc/postfix/sender_transport
@brand1.ru smtp-unisender:
@brand2.ru smtp-brand2mx:
@brand3.ru smtp-mailgun:
@example.ru smtp:
А в /etc/postfix/sender_relay — куда именно отправлять по каждому transport:
# /etc/postfix/sender_relay
@brand1.ru [smtp.unisender.com]:587
@brand2.ru [mx.brand2.ru]:25
@brand3.ru [smtp.mailgun.org]:587
@example.ru [smtp.external-relay.ru]:587
И учётки в /etc/postfix/sasl_passwd:
# /etc/postfix/sasl_passwd
[smtp.unisender.com]:587 postmaster@brand1.ru:UniSenderPass123!
[smtp.mailgun.org]:587 postmaster@brand3.ru:MailgunPass456!
[smtp.external-relay.ru]:587 info@example.ru:RelayPass789!
После редактирования всех трёх файлов — строим хэш-базы и рестартуем Postfix:
postmap /etc/postfix/sender_transport
postmap /etc/postfix/sender_relay
postmap /etc/postfix/sasl_passwd
chmod 600 /etc/postfix/sasl_passwd*
systemctl restart postfix
Описание дополнительных transport
Transport — это описание способа доставки. По умолчанию есть smtp: (стандартный), lmtp: (локальный для доставки в мейлбоксы) и error: (отвергнуть). Для наших целей добавляем свои с разными именами в /etc/postfix/master.cf:
# /etc/postfix/master.cf (в конец файла)
smtp-unisender unix - - - - - smtp
-o syslog_name=postfix/unisender
-o smtp_tls_wrappermode=no
-o smtp_tls_security_level=encrypt
-o smtp_helo_name=relay.brand1.ru
smtp-mailgun unix - - - - - smtp
-o syslog_name=postfix/mailgun
-o smtp_tls_wrappermode=no
-o smtp_tls_security_level=encrypt
-o smtp_helo_name=relay.brand3.ru
smtp-brand2mx unix - - - - - smtp
-o syslog_name=postfix/brand2mx
-o smtp_tls_security_level=may
Для каждого transport можно задать свои параметры: TLS-строгость, HELO-имя, лимиты, логирование. Особенно важен smtp_helo_name — он должен совпадать с PTR и SPF записями.
OpenDKIM для нескольких доменов
Для каждого домена — свой ключ с уникальным селектором. Генерим:
mkdir -p /etc/opendkim/keys/{brand1.ru,brand2.ru,brand3.ru}
for d in brand1.ru brand2.ru brand3.ru; do
cd /etc/opendkim/keys/$d
opendkim-genkey -s mail -d $d -b 2048
chown opendkim:opendkim mail.private
done
В /etc/opendkim/KeyTable:
mail._domainkey.brand1.ru brand1.ru:mail:/etc/opendkim/keys/brand1.ru/mail.private
mail._domainkey.brand2.ru brand2.ru:mail:/etc/opendkim/keys/brand2.ru/mail.private
mail._domainkey.brand3.ru brand3.ru:mail:/etc/opendkim/keys/brand3.ru/mail.private
В /etc/opendkim/SigningTable:
*@brand1.ru mail._domainkey.brand1.ru
*@brand2.ru mail._domainkey.brand2.ru
*@brand3.ru mail._domainkey.brand3.ru
В DNS каждого домена публикуем публичный ключ из соответствующего mail.txt. После чего проверяем подписи:
for d in brand1.ru brand2.ru brand3.ru; do
opendkim-testkey -d $d -s mail -vvv
done
systemctl restart opendkim postfix
Тестирование маршрутизации
| Сценарий | Команда |
|---|---|
| Отправка с brand1.ru | echo "test" | mail -s "Test brand1" -r no-reply@brand1.ru test@mail.ru |
| Проверка пути в логах | tail -f /var/log/mail.log | grep brand1 |
| Проверка DKIM | grep dkim /var/log/mail.log | tail -20 |
| Проверка upstream | grep "status=sent" /var/log/mail.log |
Критерий успеха — письмо с brand1.ru уходит в Unisender SMTP, с brand2.ru — напрямую в MX brand2.ru, с brand3.ru — через Mailgun. Каждое письмо подписано соответствующим DKIM-ключом.
Мини-кейс: строительный холдинг, 4 бренда
В октябре 2025 к нам обратился строительный холдинг — 4 юрлица с разными доменами и брендами, 280 сотрудников. Проблема: у каждого юрлица свой почтовый сервер (старые Exchange и кривые Postfix), многочисленные жалобы «письма не доходят». Задача — свести всё на единый relay и навести порядок с DKIM/SPF.
Работа за 3 недели:
- Неделя 1: аудит — обнаружено, что на 2 доменах вообще нет DKIM, у одного SPF с 12 lookups, у одного MX смотрит на IP, давно не существующий.
- Неделя 2: развернули центральный relay на Debian 12 в нашем дата-центре МТС, настроили sender-based routing на 4 upstream (2 своих сервера, Mail.ru Бизнес, UniOne).
- Неделя 3: миграция приложений (1С, CRM, планировщики, самописные cron-ы) на relay, вывели из продакшена старые серверы, починили DNS на всех 4 доменах.
Итог: рассылки холдинга попадают в inbox 96% у Mail.ru (было 54%), 98% у Yandex. Стоимость работ — 280 000 руб. за всё включая аудит и миграцию. Сопровождение — 12 000 руб./мес.
Лимиты и защита от abuse
Relay, открытый в корпоративной сети — лакомая цель. Если приложение скомпрометировали, через relay можно разослать спам или фишинг. Защита:
# /etc/postfix/main.cf — дополнительные ограничения
smtpd_client_restrictions =
permit_mynetworks
reject_unknown_client_hostname
# Лимиты по rate
smtpd_client_message_rate_limit = 100
smtpd_client_recipient_rate_limit = 500
smtpd_client_event_limit_exceptions = $mynetworks
# anvil процесс уже работает по умолчанию
# Логи лимитов можно увидеть в anvil reports
grep anvil /var/log/mail.log
Для более сложной политики (разные лимиты для разных приложений) я использую policyd-weight или postfwd с правилами «приложение X имеет право слать 1000 писем/час с brand1.ru, приложение Y — только 100 с brand3.ru».
Мониторинг и алерты
Ключевые метрики relay-сервера:
- Размер очереди (postqueue -p | tail -1) — должен быть минимальным, обычно <20.
- Количество sent/deferred/bounce за последние минуты.
- Среднее время обработки письма.
- Статус соединений с upstream SMTP.
- DKIM signing success/failure.
# Prometheus postfix-exporter
docker run -d --name postfix-exporter \
--network host \
-v /var/log/mail.log:/var/log/mail.log:ro \
kumina/postfix-exporter \
--postfix.logfile_path=/var/log/mail.log \
--postfix.showq_path=/var/spool/postfix/public/showq
В Grafana собираем дашборд с графиками per-sender-domain: если у brand2.ru вдруг вырос bounce rate — знаем, что пора разбираться. Алерты в Telegram через alertmanager.
Типовые ошибки при настройке
- Забыли `postmap` после правки. Postfix работает со скомпилированными файлами, а не с текстовыми. Правка без postmap не применится.
- Неправильный HELO. Если relay шлёт с HELO, не совпадающим с PTR, upstream считает это подозрительным.
- TLS wrappermode для 587 порта. На 587 — STARTTLS, без wrappermode. На 465 — wrappermode yes.
- SASL пароли в ротированных логах. Проверьте, что
smtp_sasl_mechanism_filterне выдаёт лишнего. - Отсутствие reject_unknown_client_hostname. Open-relay уязвимость, если приложения смогли подключаться снаружи.
- Разный selector для одного домена. Если вы меняете DKIM-ключ — меняйте и selector, публикуйте параллельно, и только через 48 часов удаляйте старый.
Построим единый почтовый relay для ваших брендов
Развёртывание Postfix-relay с sender-based маршрутизацией для 2–20 доменов, настройка DKIM/SPF/DMARC на каждом, миграция приложений, мониторинг. 15+ лет опыта с корпоративной почтой, работаем с Unisender, Mailgun, SendGrid, Mail.ru Бизнес.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
FAQ — частые вопросы про Postfix multi-domain relay
- Зачем нужен relay для нескольких доменов?
- Когда в компании несколько брендов или юридических лиц с разными доменами, и каждый требует отправки писем через свой SMTP-провайдер с корректными SPF/DKIM/DMARC. Relay принимает весь исходящий трафик от приложений и сам выбирает, через какой канал отправить.
- Чем отличается от обычного SMTP relay?
- Обычный relay отправляет всё в один upstream. Sender-based relay в Postfix смотрит на заголовок From (или envelope sender) и направляет письмо в тот SMTP, который правильный для этого домена. Для разных доменов — разные DKIM-ключи, разные учётки на upstream.
- Как это работает с DKIM?
- OpenDKIM имеет SigningTable, где для каждого домена своя пара ключ-селектор. Письмо от brand1.ru подписывается ключом brand1, письмо от brand2.ru — ключом brand2. Публичные ключи публикуются в DNS каждого домена.
- Нужен ли свой белый IP?
- Если вы relay-ите через чужой SMTP (sendgrid, mailgun, yandex.ru) — ваш IP не важен. Если отправляете напрямую в MX получателей — нужен белый IP с правильным PTR, SPF и DKIM, иначе почта не дойдёт.
- Как ограничить rate для разных доменов?
- Через anvil и smtpd_client_message_rate_limit с разделением по transport. Более гибкий вариант — через policyd (cluebringer) или postfwd с правилами на основе sender-домена.