Для чего нужна маршрутизация исходящей почты? По разным причинам необходимо рассылать сообщения либо с разных IP-адресов, либо через другие хосты. Штатными средствами postfix это можно сделать при помощи sender_dependent_default_transport_maps (пример настройки). Данный параметр работает на основе разных From:. Очень просто на практике — информационные сообщения шлем From: info@domain.tld через один адрес, счета From: billing@domain.tld через другой и т.д.
Но что делать, если ранее настроенная система на сегодняшний день рассылает информационные сообщения и счета From: info@domain.tld через один адрес, а в будущем эти потоки нужно разделить с сохранением From: info@domain.tld в заголовках?
Это возможно при помощи разных message-id. Вот часть лога
postfix/cleanup[4430]: 2387B61F71: message-id=<mailing-35823-756154-ZYPihdIFmGUv@domain.tld>
postfix/cleanup[3240]: EBBCA6531C: message-id=<template-1572491-ZYQOVxW8_8_C@domain.tld>
В первой строке для рассылки информационных сообщений используется message-id mailing, во второй для рассылки счетов — message-id template. По этим именам настроим маршрутизацию
Реализация
Для этого воспользуемся возможностями header_checks. В main.cf указываем
header_checks = pcre:/etc/postfix/header_checks
В файле header_checks пишем регулярное выражение
/^Message-id:.*template-([A-Za-z0-9]+(-[A-Za-z0-9_-]+)+)@domain\.tld/ FILTER smtp80:
А в master.cf добавляем сервис smtp80
smtp80 unix - - n - - smtp -o syslog_name=smtp80 -o smtp_bind_address=x.x.x.80 -o smtp_helo_name=i80.domain.tld
Перечитаем конфиги
postfix reload
и посмотрим в логи
postfix/cleanup[3240]: EBBCA6531C: filter: header Message-ID: <template-1572491-ZYQOVxW8_8_C@domain.tld> from domain.local[192.168.5.1]; from=<info@domain.tld> to=<2@gmail.com> proto=ESMTP helo=<[127.0.0.1]>: smtp80:
…
postfix/cleanup[3240]: EBBCA6531C: message-id=<template-1572491-ZYQOVxW8_8_C@domain.tld>
…
smtp80/smtp[3115]: EBBCA6531C: to=<2@gmail.com>, relay=gmail-smtp-in.l.google.com[142.250.147.26]:25, delay=10, delays=0.08/0/0.77/9.3, dsn=2.0.0, status=sent (250 2.0.0 OK 1703153250 k12-20020a1709063e0c00b00a2692bf2087si723992eji.473 — gsmtp)
Как видим, почта с message-id template ушла через smtp80, который висит на адресе x.x.x.80 (можно проверить выполнив ip addr). Вся остальная почта уходит стандартно — через интерфейс по-умолчанию
Почти все
И все было бы хорошо, но когда почта идет внутри domain.tld с заголовками
From: info@domain.tld To: feedback@domain.tld
то происходит зацикливание, о чем читаем в логах
smtp80/smtp[7028]: B3C41616A7: to=<feedback@domain.tld>, relay=none, delay=0.03, delays=0.02/0/0.01/0, dsn=5.4.6, status=bounced (mail for domain.tld loops back to myself)
Для решения вносим изменения в header_checks, добавив нужное правило перед правилом с message-id. Обновленный файл выглядит так
/^To:.*feedback@domain.tld/ PASS /^Message-id:.*template-([A-Za-z0-9]+(-[A-Za-z0-9_-]+)+)@domain\.tld/ FILTER smtp80:
Правила из header_checks читаются по порядку сверху вниз. Если найдено совпадение для feedback@domain.tld выполняется деректива PASS, что значит прекратить дальнейшую проверку и продолжить отправку почтового сообщения
Вариант для нескольких To: домена domain.tld одной строкой
/^To:.*(feedback|manager|techsupport)@domain.tld/ PASS /^Message-id:.*template-([A-Za-z0-9]+(-[A-Za-z0-9_-]+)+)@domain\.tld/ FILTER smtp80:
Все

Системный администратор с 2000 года
Участник Freelancehunt, Хабр Q&A
Кейсы