Postfix relay для нескольких доменов: маршрутизация почты

Архитектура почтового relay для нескольких доменов

Задача, с которой мы сталкиваемся регулярно: один почтовый шлюз принимает письма сразу для нескольких доменов и раскидывает их по разным бэкенд-серверам. Звучит просто, но нюансов хватает. Вот самые частые сценарии:

  • Компания держит несколько доменов (company.ru, brand.ru, support.ru), и за каждым стоит свой почтовый сервер
  • Гибридная инфраструктура — часть ящиков на Exchange, часть на Dovecot, часть вообще в облаке
  • Единый relay для исходящей почты: один IP, DKIM-подпись для всех доменов сразу

Postfix для этой роли подходит лучше всего — и вот почему. Его transport maps позволяют точно указать, на какой сервер отправить письмо в зависимости от домена получателя. Никакой магии, просто таблица маршрутизации. В этой статье мы поднимем полноценный relay-шлюз с аутентификацией, TLS и DKIM-подписью.

Установка и базовая конфигурация Postfix

Ставим Postfix на Ubuntu 22.04. Ничего лишнего:

sudo apt update
sudo apt install -y postfix postfix-pcre libsasl2-modules

# При установке выбираем "Internet Site"
# System mail name: mail.company.ru

Теперь базовая конфигурация /etc/postfix/main.cf. Её придётся подогнать под себя, но точка отсчёта такая:

# Основные параметры
myhostname = mail.company.ru
mydomain = company.ru
myorigin = $mydomain
mydestination = $myhostname, localhost

# Relay для указанных доменов
relay_domains = company.ru, brand.ru, support.ru

# TLS для входящих
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.company.ru/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.company.ru/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

# TLS для исходящих
smtp_tls_security_level = may
smtp_tls_loglevel = 1

# Ограничения
smtpd_relay_restrictions = permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination

# Transport map
transport_maps = hash:/etc/postfix/transport

Transport maps: маршрутизация по доменам

Файл /etc/postfix/transport — это и есть сердце маршрутизации. Именно здесь прописываем, куда летят письма для каждого домена:

# /etc/postfix/transport
# Домен           Транспорт:Назначение
company.ru        smtp:[10.0.1.10]:25
brand.ru          smtp:[10.0.1.20]:25
support.ru        smtp:[exchange.company.ru]:25
marketing.ru      smtp:[smtp.yandex.ru]:465

Квадратные скобки вокруг адреса — не украшение. Они отключают MX-lookup, и Postfix идёт напрямую к указанному хосту. После любых правок в файле пересоздаём хеш-таблицу, иначе изменения не применятся:

sudo postmap /etc/postfix/transport
sudo systemctl reload postfix

Когда доменов становится много или логика усложняется — переходим на регулярные выражения (pcre):

# /etc/postfix/transport_pcre
# Все субдомены company.ru → один сервер
/^.+\.company\.ru$/    smtp:[10.0.1.10]:25

# Конкретный адрес → специальный сервер
/^ceo@company\.ru$/    smtp:[secure.company.ru]:25

В main.cf подключаем pcre-таблицу вот так:

transport_maps = pcre:/etc/postfix/transport_pcre, hash:/etc/postfix/transport

Relay для исходящей почты

Relay отправляет исходящую почту от имени нескольких доменов? Тогда настройте sender_dependent_default_transport_maps — это отдельная история, но очень полезная:

# /etc/postfix/sender_transport
@company.ru     smtp:[smtp-out-1.company.ru]:587
@brand.ru       smtp:[smtp-out-2.company.ru]:587

С этой настройкой исходящая почта уходит через разные серверы в зависимости от того, с какого домена отправляется письмо. Удобно, когда у каждого домена свой smarthost или выходной IP.

SASL-аутентификация для relay-клиентов

Бэкенд-серверы должны аутентифицироваться при отправке через relay? Настраиваем SASL. На практике это нужно почти всегда:

# /etc/postfix/main.cf
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname

Если используете Dovecot SASL, добавьте в /etc/dovecot/conf.d/10-master.conf следующий блок:

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

Relay сам подключается к внешнему серверу, который требует логин и пароль? Тогда вот конфиг для этого случая:

# /etc/postfix/sasl_passwd
[smtp.yandex.ru]:465    user@company.ru:SecretPassword
[smtp.gmail.com]:587    relay@company.ru:AppPassword

# Создаём хеш и устанавливаем права
sudo postmap /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db

# В main.cf
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous

DKIM-подпись для всех доменов

Ставим OpenDKIM — он будет подписывать всю исходящую почту:

sudo apt install -y opendkim opendkim-tools

Генерируем ключи для каждого домена отдельно. Один ключ на все домены — плохая идея:

sudo mkdir -p /etc/opendkim/keys/{company.ru,brand.ru,support.ru}

for domain in company.ru brand.ru support.ru; do
    sudo opendkim-genkey -b 2048 -d $domain -D /etc/opendkim/keys/$domain -s mail
    sudo chown -R opendkim:opendkim /etc/opendkim/keys/$domain
done

Настраиваем /etc/opendkim.conf:

Syslog          yes
Mode            sv
Canonicalization relaxed/simple
Domain          company.ru,brand.ru,support.ru
KeyTable        /etc/opendkim/key.table
SigningTable    refile:/etc/opendkim/signing.table
Socket          local:/var/spool/postfix/opendkim/opendkim.sock
PidFile         /run/opendkim/opendkim.pid
TrustAnchorFile /usr/share/dns/root.key
UserID          opendkim

Таблица ключей /etc/opendkim/key.table — здесь связываем домен с файлом приватного ключа:

mail._domainkey.company.ru company.ru:mail:/etc/opendkim/keys/company.ru/mail.private
mail._domainkey.brand.ru brand.ru:mail:/etc/opendkim/keys/brand.ru/mail.private
mail._domainkey.support.ru support.ru:mail:/etc/opendkim/keys/support.ru/mail.private

Таблица подписей /etc/opendkim/signing.table — указываем, какие домены подписываем:

*@company.ru    mail._domainkey.company.ru
*@brand.ru      mail._domainkey.brand.ru
*@support.ru    mail._domainkey.support.ru

Подключение OpenDKIM к Postfix

В /etc/postfix/main.cf подключаем milter — именно через него Postfix будет передавать письма в OpenDKIM:

milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

Создаём директорию для сокета и перезапускаем оба сервиса:

sudo mkdir -p /var/spool/postfix/opendkim
sudo chown opendkim:postfix /var/spool/postfix/opendkim
sudo systemctl restart opendkim postfix

И не забудьте про DNS. Для каждого домена нужна TXT-запись с публичным ключом DKIM. Содержимое берётся из файла /etc/opendkim/keys/company.ru/mail.txt — он генерируется автоматически и содержит всё нужное.

Защита от спама и ограничение потока

Открытый relay без ограничений — это подарок спамерам. Добавляем защитные ограничения в main.cf:

# Проверки при подключении
smtpd_client_restrictions =
    permit_mynetworks,
    reject_rbl_client zen.spamhaus.org,
    reject_rbl_client bl.spamcop.net

# Проверки отправителя
smtpd_sender_restrictions =
    reject_non_fqdn_sender,
    reject_unknown_sender_domain

# Проверки получателя
smtpd_recipient_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination,
    reject_non_fqdn_recipient,
    reject_unknown_recipient_domain

# Rate limiting
smtpd_client_message_rate_limit = 100
smtpd_client_recipient_rate_limit = 500
anvil_rate_time_unit = 3600s

Дополнительно можно фильтровать письма по заголовкам через header_checks:

# /etc/postfix/header_checks
/^Subject:.*\bviagra\b/i    REJECT Spam detected
/^X-Mailer:.*PHPMailer/     WARN Possible spam from PHPMailer

Мониторинг и отладка relay-сервера

Когда что-то идёт не так — вот инструменты, которые реально помогают:

# Очередь писем
postqueue -p

# Подробная информация о письме
postcat -q <queue_id>

# Логи
journalctl -u postfix -f
tail -f /var/log/mail.log

# Статистика
qshape deferred
qshape active

Для мониторинга размера очереди удобно держать простой скрипт. Если очередь растёт — значит что-то сломалось, и лучше узнать об этом раньше пользователей:

#!/bin/bash
# /usr/local/bin/check_postfix_queue.sh
QUEUE_SIZE=$(postqueue -p | tail -1 | grep -oP '\d+(?= Request)')
THRESHOLD=500

if [ "${QUEUE_SIZE:-0}" -gt "$THRESHOLD" ]; then
    echo "CRITICAL: Postfix queue has $QUEUE_SIZE messages" | \
    mail -s "Postfix Queue Alert" admin@company.ru
fi

Чтобы проверить, куда Postfix реально маршрутизирует письмо, используйте:

# Проверяем, куда будет отправлено письмо
postmap -q "user@brand.ru" hash:/etc/postfix/transport
# Ожидаемый вывод: smtp:[10.0.1.20]:25

# Тестовая отправка
echo "Test" | mail -s "Relay test" user@brand.ru

Часто задаваемые вопросы

Добавьте домен в relay_domains и запись в /etc/postfix/transport, затем выполните postmap /etc/postfix/transport и postfix reload. Reload применяет изменения на лету — без прерывания работы и без потери писем в очереди.

Первым делом смотрим очередь командой qshape deferred — она сразу покажет, к какому домену накопились недоставленные письма. Дальше проверяем доступность целевого сервера: telnet 10.0.1.20 25. Если сервер не отвечает, письма зависнут в deferred-очереди и будут повторяться автоматически — Postfix не выбросит их сразу.

Да, начиная с Postfix 3.4 SNI поддерживается. Создайте файл /etc/postfix/sni_map с записями вида mail.brand.ru /etc/letsencrypt/live/mail.brand.ru/privkey.pem /etc/letsencrypt/live/mail.brand.ru/fullchain.pem и пропишите tls_server_sni_maps = hash:/etc/postfix/sni_map в main.cf. Мы проверяли — работает корректно.

В DNS создайте две MX-записи с разным приоритетом: company.ru MX 10 mail1.company.ru и company.ru MX 20 mail2.company.ru. Оба сервера конфигурируются одинаково. Если mail1 упал — внешние отправители автоматически пойдут на mail2. Простая и надёжная схема.

Обязательно, и это частая ошибка. Для каждого домена добавьте IP relay-сервера в SPF-запись: v=spf1 ip4:1.2.3.4 include:_spf.company.ru -all. Если relay отправляет почту от имени нескольких доменов — IP должен быть прописан в SPF каждого из них. Иначе письма будут падать в спам или отклоняться.

Нужна помощь с настройкой?

Если не хочется разбираться со всем этим самостоятельно — команда АйТи Фреш настроит relay-шлюз под вашу инфраструктуру. Более 15 лет опыта, обслуживание от 15 000 ₽/мес.

📞 Связаться с нами
#postfix relay#маршрутизация почты#postfix несколько доменов#transport maps postfix#relay host postfix#postfix dkim#почтовый сервер linux#postfix sasl
Комментарии 0

Оставить комментарий

загрузка...