Документация / Postfix

Postfix: отправка почты через SMTP-релей (relayhost)

Postfix на сервере обычно стоит ради почты, которую шлют сами программы: cron, мониторинг, сайт через sendmail. Если он доставляет её напрямую, письма уходят с IP сервера без истории и без DKIM, и крупные почтовые сервисы встречают их фильтром. Параметр relayhost отправляет всю исходящую почту через релей fmailer: релей подписывает её DKIM вашего домена, а Postfix только авторизуется и передаёт письма.

Логин и пароль можно получить на странице токенов домена.

Параметры подключения

ПараметрЗначение
SMTP-хостsmtp.fmailer.ru
Порт587
ШифрованиеSTARTTLS (соединение переводится в TLS до авторизации)
ЛогинЛогин токена вашего домена
ПарольПароль этого токена — показывается один раз, при создании
Каждый режим доступен и на высоком порту: 8465 (SSL/TLS), 8587 (STARTTLS) и 8025 (без шифрования). Многие хостинги и облака блокируют исходящие 25, 465 и 587 — если соединение обрывается по таймауту, используйте соответствующий высокий порт.

Пакеты

Postfix авторизуется через Cyrus SASL, а механизм PLAIN лежит в отдельном пакете. Без него авторизация не начнётся и в журнале появится No worthy mechs found:

bash
# Debian, Ubuntu: модули SASL с механизмом PLAIN
sudo apt install postfix libsasl2-modules

# RHEL, AlmaLinux, Rocky
sudo dnf install postfix cyrus-sasl-plain

Вся почта через релей

Добавьте в /etc/postfix/main.cf:

/etc/postfix/main.cfproperties
# /etc/postfix/main.cf — вся исходящая почта через релей
relayhost = [smtp.fmailer.ru]:587

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
# PLAIN — механизм с открытым паролем; разрешаем его только внутри TLS
smtp_sasl_tls_security_options = noanonymous

smtp_tls_security_level = encrypt
ПараметрЧто делает
relayhost Куда отдавать всю почту для чужих доменов. Скобки отключают поиск MX, :587 — порт отправки со STARTTLS.
smtp_sasl_auth_enableВключает SMTP-авторизацию на стороне клиента.
smtp_sasl_password_mapsТаблица с логином и паролем для каждого релея.
smtp_sasl_tls_security_options Снимает запрет на механизмы с открытым паролем внутри TLS. Без этого Postfix отказывается от PLAIN.
smtp_tls_security_level = encrypt Не отправлять без шифрования: если STARTTLS не удался, письмо остаётся в очереди, а пароль не уходит открытым текстом.

Логин и пароль

Создайте /etc/postfix/sasl_passwd. Ключ в начале строки должен совпадать с relayhost полностью, вместе со скобками и портом:

/etc/postfix/sasl_passwd
# /etc/postfix/sasl_passwd
# ключ должен совпадать с relayhost символ в символ: скобки и порт
[smtp.fmailer.ru]:587    <логин токена>:<пароль токена>

Закройте файл от чтения другими пользователями, соберите индекс и перечитайте конфигурацию. postmap нужно запускать после каждой правки файла, иначе Postfix продолжит читать старый .db:

bash
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd     # создаёт sasl_passwd.db
sudo postfix check
sudo systemctl reload postfix
Тип таблицы в примерах — hash:. Если postconf -m его не показывает, используйте тип из postconf default_database_type, например lmdb:, и в main.cf, и в команде postmap lmdb:/etc/postfix/sasl_passwd.

Порт 465

Для TLS с первого байта на порту 465 нужен smtp_tls_wrappermode (Postfix 3.0 и новее). Без него Postfix ждёт приветствия сервера открытым текстом, не дожидается и отключается по таймауту:

properties
# /etc/postfix/main.cf — порт 465, TLS с первого байта
relayhost = [smtp.fmailer.ru]:465
smtp_tls_wrappermode = yes
smtp_tls_security_level = encrypt

# /etc/postfix/sasl_passwd — ключ тоже с :465
[smtp.fmailer.ru]:465    <логин токена>:<пароль токена>

Через релей только один домен

Если на сервере живёт несколько сайтов или своя почта, а через fmailer должен уходить только подтверждённый домен, оставьте relayhost пустым и выберите релей по адресу отправителя. Postfix ищет отправителя конверта сначала целиком, затем по @домену:

/etc/postfix/main.cfproperties
# /etc/postfix/main.cf — через релей только почта домена mail.example.ru
# relayhost не задан: остальная почта уходит напрямую, как раньше
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_tls_security_options = noanonymous

# TLS обязателен только для релея, остальным серверам — по возможности
smtp_tls_security_level = may
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
# /etc/postfix/sender_relay
@mail.example.ru           [smtp.fmailer.ru]:587

# /etc/postfix/tls_policy
[smtp.fmailer.ru]:587    encrypt

# /etc/postfix/sasl_passwd
[smtp.fmailer.ru]:587    <логин токена>:<пароль токена>
bash
sudo postmap /etc/postfix/sender_relay
sudo postmap /etc/postfix/tls_policy
sudo postmap /etc/postfix/sasl_passwd
sudo systemctl reload postfix

Логин и пароль по-прежнему ищутся по адресу релея, поэтому smtp_sender_dependent_authentication здесь не нужен: он понадобится, только если разным отправителям нужны разные учётные данные. Если вы уже используете transport_maps для этого домена, учтите, что у них приоритет выше, чем у sender_dependent_relayhost_maps.

Авторизация: только AUTH PLAIN

Релей объявляет единственный механизм — AUTH PLAIN. Postfix выбирает механизм из пересечения того, что умеет сам, что объявил сервер и что пропускает smtp_sasl_mechanism_filter, поэтому дополнительная настройка не нужна. Помешать могут две вещи: значение smtp_sasl_security_options по умолчанию (noplaintext) и старый фильтр smtp_sasl_mechanism_filter = login, оставшийся от другого провайдера.

Проверка

Отправьте письмо с адреса на подтверждённом домене. Адрес в -f становится отправителем конверта, и релей проверяет именно его:

bash
# Тестовое письмо: отправитель — на подтверждённом домене
printf 'From: noreply@mail.example.ru\nTo: you@example.com\nSubject: Postfix relay test\n\nHello from Postfix\n' \
  | sendmail -f noreply@mail.example.ru you@example.com

mailq                                  # пустая очередь — письмо ушло
sudo journalctl -t postfix/smtp -f     # или /var/log/mail.log, /var/log/maillog

В журнале успешная отправка выглядит так: relay= указывает на релей, а status=sent означает, что релей принял письмо. Дальнейшую судьбу письма и ответ сервера получателя показывает журнал доставки в панели.

postfix/smtp[2817]: 4F1A2C0D3E: to=<you@example.com>,
  relay=smtp.fmailer.ru[…]:587, delay=0.8, dsn=2.0.0, status=sent (250 …)

Разбор ошибок

Сообщение в журналеПричина и решение
SASL authentication failure: No worthy mechs found Не задан smtp_sasl_tls_security_options = noanonymous или не установлен libsasl2-modules (cyrus-sasl-plain).
SASL authentication failed; server … said: 535 5.7.8 Неверный логин или пароль токена. Проверьте строку в sasl_passwd и не забудьте postmap. Подробнее об ошибке 535 .
550 relaying denied Postfix подключился без авторизации: ключ в sasl_passwd не совпал с relayhost (скобки, порт) или smtp_sasl_auth_enable выключен. Разбор отказа в пересылке .
550 from must be equal to … Отправитель конверта не на подтверждённом домене, чаще всего root@имя-сервера. Используйте sender_dependent_relayhost_maps или smtp_generic_maps.
550 not relaying to your domain, required until verified Домен ещё не подтверждён: до проверки NS-записей письма уходят только на адреса этого же домена.
timed out while receiving the initial server greeting В relayhost порт 465, а smtp_tls_wrappermode не включён.
connect to smtp.fmailer.ru…: Connection timed out Хостинг закрыл исходящий порт. Используйте 8587 или 8465 и поменяйте порт и в relayhost, и в sasl_passwd.
550 hourly limit exceeded Исчерпан часовой лимит тарифа. Postfix считает ответ 5xx окончательным и вернёт письмо отправителю, поэтому следите за расходом на странице домена.

Частые вопросы

Зачем квадратные скобки вокруг адреса в relayhost?

Скобки запрещают Postfix искать MX-записи для этого имени: он подключается прямо к хосту, указанному в relayhost. Без скобок Postfix запросит MX домена и может уйти не туда. Ключ в sasl_passwd должен быть записан в той же форме, со скобками и портом, иначе логин и пароль не найдутся.

Что значит «SASL authentication failure: No worthy mechs found»?

Postfix не нашёл механизма авторизации, который ему разрешено использовать. Наш релей предлагает только PLAIN, а значение smtp_sasl_security_options по умолчанию запрещает механизмы с открытым паролем. Укажите smtp_sasl_tls_security_options = noanonymous и обязательный TLS. Та же ошибка бывает, если не установлен пакет libsasl2-modules (cyrus-sasl-plain в RHEL).

Нужно ли включать AUTH LOGIN или настраивать smtp_sasl_mechanism_filter?

Нет. Релей принимает только AUTH PLAIN, и Postfix выберет его сам из того, что объявил сервер. Если в конфигурации остался фильтр вроде smtp_sasl_mechanism_filter = login, уберите его или впишите plain: при пустом пересечении списков авторизация не пройдёт.

Как отправлять через релей почту только одного домена?

Не задавайте relayhost, а укажите sender_dependent_relayhost_maps с записью @mail.example.ru → [релей]:587. Через релей пойдут письма с этим доменом в адресе отправителя конверта, остальные Postfix доставит напрямую. Чтобы TLS был обязательным только для релея, используйте smtp_tls_policy_maps.

Нужен ли OpenDKIM или другой milter для подписи?

Для домена, подтверждённого в панели, нет: подпись DKIM ставит релей, а SPF и DMARC публикуются в делегированной зоне. Если OpenDKIM уже подписывает этот домен, письмо придёт с двумя подписями. Ошибкой это не считается, но второй ключ придётся поддерживать без пользы.

Почему письма от cron и root не уходят?

У системной почты адрес отправителя вроде root@имя-сервера. Релей принимает письма только с подтверждённого домена и отвечает «550 from must be equal to …». Направьте через релей только свой домен (sender_dependent_relayhost_maps) или перепишите адреса через smtp_generic_maps.

Что дальше