Postfix - выбор сервера для отправки в зависимости от получателя

На веб сервере бывает так, что локальный почтовый сервер не занимается сам отправкой почты, а пересылает ее на другие smtp сервера. Мне часто бывает нужно выбирать сервер отправки в зависимости от адреса получателя. Я расскажу, как это сделать на примере почтового сервера postfix. В зависимости от домена получателя, он будет выбирать внешний smtp сервер, на который будет пересылать сообщение.

Онлайн-курс по устройству компьютерных сетей

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Зачем нужен postfix на web сервере

Расскажу для начала, зачем вообще в данном случае нужен postfix. Почему не отправлять почту напрямую с сайта через smtp с авторизаций на удаленном сервере. Сейчас все современные движки это поддерживают. Причин тут может быть много. Вот основные из них:

  1. У postfix хорошее логирование. Если вы отправляете через него, у вас будет вся аналитика по отправке. Вы можете проверить статус доставки каждого письма. Если вам нужны логи, то их ведение нужно будет реализовывать либо в самом движке сайта, либо их должен поддерживать удаленный smtp сервер. Но, к примеру, если с сайта письмо ушло, а на удаленный smtp не попало по какой-то причине, у вас не останется информации об этом событии, если сам сайт не ведет логов.
  2. Postfix может быть гибко настроен на отправку почты. Можно выбирать, как будет отправляться почта для каждого исходящего домена, для разного домена или даже адреса получателя. Можно на ходу подменять адрес отправителя или изменять тему письма. И все это делается достаточно просто. Реализовывать тот же функционал через движок сайта значительно труднее.
  3. Вы можете всю отправленную почту пересылать куда-то на отдельный ящик для различных нужд - аналитика, контроль и т.д. Это тоже гибко настраивается. Для каждого сайта может быть свой почтовый ящик для сбора. Их может быть несколько, для каждого адреса отправителя свой дублирующий ящик и т.д. В общем, это все тоже очень гибко настраивается.
  4. Так как есть подробное логирование отправки, легко настроить мониторинг postfix и получить аналитику и контроль отправленных сообщений. Если кто-то сломает ваш сайт и начнет рассылать через него спам, вы это сразу заметите. К примеру, я настраивал почтовый сервер для одной нишевой соц. сети. Когда кто-то начал массово спамить через личные сообщения, это сразу стало видно на мониторинге почты, так как количество отправленных сообщений через почтовый сервер резко возросло. На каждое личное сообщение отправлялось уведомление по почте.

Это несколько примеров, которые сходу пришли в голову. В целом, никакого уникального функционала postfix не представляет, но все описанное выше очень легко и быстро реализовывается штатными средствами почтового сервера. Просто бери и настраивай, как тебе надо. Нет нужды это реализовывать самому в самом движке. Накодить весь этот функционал трудозатратно.

Выбор сервера отправки в зависимости от адреса получателя

Теперь история, зачем мне это нужно было. Локальный почтовый сервер postfix отправлял всю почту сайта через внешний smtp сервер. Это настроено глобально для всего postfix через параметр relayhost в main.cf. Подробное описание того, как это сделать, по ссылке. Я захотел оставлять копию всех отправленных сообщений на сервере. Для этого настроил sender_bcc_maps для сбора всей исходящей почты. Как это сделать, я подробно рассказываю в своей статье про настройку postfix.

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

Итак, в sender_bcc_map всю локальную почту я оставляю локально, просто указывая адрес отправителя (каждый сайт шлет почту от своего ящика) и локального пользователя, к которому она будет складываться. Если у вас много сайтов, то для каждого сайта будет свой локальный пользователь. Чаще всего это так, потому что разные сайты лучше всего запускать под разными пользователями, от которых работает веб сервер. Файл с записями для sender_bcc_map выглядит так:

user1@site1.ru user1
user2@site2.ru user2

Если у вас использует разные ящики для отправки, то можете настроить правило для всего домена сразу:

*@site1.ru user1
*@site2.ru user2

Дальше вам нужно выяснить, как выглядит полностью адрес домена для локальной доставки почты. Это имя задается в параметре mydomain в конфиге postfix main.cf. Допустим, там указано имя сервера - websrv.site.ru. Это не принципиально, в нашем случае там можно написать все, что угодно, но лучше использовать полное доменное имя (fqdn) самого веб сервера, которое указано в DNS записи типа А.

Теперь создаем файл transport_map, в котором пишем следующее:

websrv.site.ru local

Мы явно указываем, что всю почту для домена websrv.site.ru отправлять локально. Не забываем построить индексированный файл:

# postmap /etc/postfix/transport_map

Отправляемся в конфиг main.cf и добавляем туда параметр:

transport_maps = hash:/etc/postfix/transport_map

Перезапускаем postfix и проверяем работу. При отправке почтового сообщения от имени пользователя user1@site1.ru там должно быть примерно следующее:

websrv postfix/smtpd[3604343]: CC8F0602E205: client=localhost[127.0.0.1]
websrv postfix/cleanup[3604346]: CC8F0602E205: message-id=<DNCl5UdUPH7JG8sqfGbn9dobkStUcQ3l5IjwA8iMxDY@site.ru>
websrv postfix/qmgr[3452705]: CC8F0602E205: from=<user1@site1.ru>, size=874, nrcpt=2 (queue active)
websrv postfix/smtpd[3604343]: disconnect from localhost[127.0.0.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
websrv postfix/local[3604348]: CC8F0602E205: to=<user1@websrv.site.ru>, relay=local, delay=0.07, delays=0.06/0.01/0/0.01, dsn=2.0.0, status=sent (delivered to mailbox)
websrv postfix/smtp[3604347]: CC8F0602E205: to=<mail@mail.ru>, relay=smtp.yandex.ru[77.88.21.158]:465, delay=0.93, delays=0.06/0.01/0.23/0.63, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued on myt6-9bdf92ffd111.qloud-c.yandex.net as 1608951012-xOUj8gBhbE-oCJSqvIX)
websrv postfix/qmgr[3452705]: CC8F0602E205: removed
user1@site1.ru адрес, с которого сайт ведет отправку почты
user1@websrv.site.ru итоговый локальный адрес, куда идет пересылка почты
mail@mail.ru внешний почтовый адрес, куда идет отправление через внешний smtp
smtp.yandex.ru адрес внешнего smtp сервера

Получили в итоге то, что хотели. Внешняя почта отправляется через внешний smtp адрес, указанный в relayhost, а копии сообщений падают в локальный ящик, который находится в файле /var/mail/user1. Конкретно мне это нужно было для отладки, чтобы понять, что именно отправляет сайт.

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

sender_bcc_maps:

*@site1.ru fwd_site1@backupmail.ru 
*@site2.ru fwd_site2@backupmail.ru

transport_map:

backupmail.ru relay:[backupmail.ru]:25

В данном случае backupmail.ru это отдельный почтовый домен и почтовый сервер для него для сбора всей вашей почты. Это не обязательно может быть собственноручно настроенный почтовый сервер. Можете использовать ящик в какой-то готовой службе почты. Но имейте ввиду, если это будет какой-то бесплатный сервис, то он вас быстро заблокирует, если будете слать слишком много почты на этот ящик.

Transport Map и Relayhost Map

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

  • relayhost - общий параметр, который задает адрес smtp сервера, использующийся для отправки всей почты;
  • transport_maps - позволяет управлять серверами для отправки в зависимости от адреса или домена получателя почты;
  • sender_dependent_relayhost_maps - позволяет управлять серверами для отправки в зависимости от адреса или домена отправителя почты.

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

Онлайн-курс по устройству компьютерных сетей.

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Помогла статья? Подписывайся на telegram канал автора

Анонсы всех статей, плюс много другой полезной и интересной информации, которая не попадает на сайт.

Автор Zerox

Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству. Если вам интересно узнать обо мне побольше, то можете послушать интервью. Запись на моем канале - https://t.me/srv_admin/425 или на сайте в контактах.

10 комментариев

  1. Спасибо Мастеру за отличный материал.
    Мне надо было сделать "простую подмену" в postfix.
    https://lan-meister.blogspot.com/2021/05/blog-post.html#more

    Просто и быстро.

  2. Postfix не надо ПЕРЕЗАПУСКАТЬ. Достаточно заставить перечитать его конфиги - postfix reload.

  3. postfixadmin в помощь. Умеет mysql, postgre. Рулится из вебки.

  4. Добрый день. Сможет кто подсказать варианты реализации кластера почтовых серверов у разных хостеров?
    Например есть по 1 ноде ву разных хостеров, не связанных между собой. Как-то можно на базе этого сделать кластер почтовых серверов?

    Заранее благодарю за ответы!

    • Вот один из платных вариантов - https://habr.com/ru/company/zimbra/blog/432782/
      Колхозить самостоятельно такое решение - непростая задача. Да и вряд ли это будет надежно работать. Варианты исполнения - Heartbeat + DRBD, Corosync и Pacemaker. Это то, что сходу приходит в голову.

  5. Александр

    Владимир добрый вечер, мне кажется что для sender_bcc_maps и transport_maps лучше использовать mysql table, так автоматизировать удобнее.

    • Это уже выбор каждого, как делать. Перенести эти файлы в mysql не проблема. Но вот писать обвязку для управления мне лично сложно, а готовых бесплатных панелей с таким функционалом не знаю. Можно, конечно, в mysql напрямую запросы писать для изменения, но мне так не хочется делать. Одно время через phpmyadmin таблицы редактировал. Мне проще для небольших проектов в файлах все держать. Это же не полноценный почтовый сервер с кучей клиентов, а просто рассыльщик сообщений. Он редко меняет конфигурацию. Обычно один раз настроишь отправку и больше не трогаешь.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.
Используешь Telegram? Подпишись на канал автора →
This is default text for notification bar