У каждого сервера есть собственная почта: отчёты задач по расписанию, предупреждения смарт-мониторинга диска, уведомления служб наблюдения. Доставить её напрямую с обычного VPS удаётся редко: исходящий порт у многих хостеров закрыт, репутация свежего адреса нулевая, и письма тихо оседают в спаме у получателей. Relay решает вопрос архитектурно: локальный Postfix принимает письма приложений и передаёт их проверенному провайдеру доставки, а дальше работает его репутация и его каналы. Ниже настройка связки, пароли трёх провайдеров, системные письма и разбор типичных отказов.

Почему прямая отправка писем с VPS работает через раз

История с портом 25 стара как сама виртуализация: хостеры закрывают его по умолчанию, потому что через него в разные годы лились реки спама с заражённых машин. В итоге честный сервер с честными письмами получает закрытую дверь и молча копит сообщения в очереди, а владелец узнаёт о проблеме через неделю по отсутствию отчётов.

Вторая причина репутационная. Свежий адрес сервера не имеет истории, и крупные провайдеры относятся к таким отправителям по умолчанию холодно: обратной записи нет, истории нет, объёмов нет. Письма формально уходят, но оседают в папке со спамом, и мониторинг, который должен будить ночью, будит уже утром в лучшем случае.

Теоретически прямой отправке можно помочь: прописать обратную зону, настроить подписи и правила, прогревать адрес неделями. Практически у большинства серверов нет столько писем для прогрева, и проще взять готовую репутацию у того, кто занимается доставкой профессионально.

Именно это и делает relay. Локальный Postfix остаётся интерфейсом для приложений: они отдают письма на локальный порт и не знают ничего о внешнем мире. Дальше письма уходят по шифрованному каналу с аутентификацией провайдеру доставки, и во внешний мир они приезжают с его репутацией, его подписями и его обработанными обратными связями.

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

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

Параметры relayhost и шифрование в main.cf

Настройка живёт в нескольких строках main.cf:

relayhost = [smtp.sendgrid.net]:587
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_loglevel = 1

Строка relayhost задаёт точный адрес и порт провайдера. Квадратные скобки вокруг имени принципиальны: без них Postfix полезет искать MX-записи для домена провайдера, а провайдеру доставки это не нужно. Порт 587 выбран не из красоты: он для авторизованной отправки и почти всегда открыт даже там, где классический 25 закрыт правилами сети.

Пара строк про аутентификацию включает её и указывает, где лежат пароли. Опция noanonymous запрещает анонимную сессию, а encrypt требует шифрования канала: без него Postfix откажется отправлять пароль в открытом виде, и это правильная упрямость. Строка smtp_tls_loglevel поднимает детализацию защищённого соединения в журнале на время отладки, и после настройки её возвращают к нулю.

Применяется конфигурация перечитыванием:

sudo systemctl reload postfix

Reload не рвёт текущие сессии, и с этого момента вся исходящая почта сервера, которой он сам не является получателем, едет на провайдера.

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

Проверить активный relay можно не выходя из консоли: команда postconf relayhost отвечает текущим значением, и по ней сверяется, что нужная строка действительно в конфигурации, а не в черновике редактора. Мелочь, которая однажды сэкономит полчаса недоумения.

Файл паролей sasl passwd и команда postmap

Пароли живут в отдельном файле:

[smtp.sendgrid.net]:587 apikey:SG.длинный-сгенерированный-ключ

Левая часть обязана совпадать со строкой relayhost символ в символ, включая квадратные скобки и порт. Расхождение хотя бы в двоеточии приводит к тому, что Postfix не находит пароль для нужного узла, и аутентификация тихо проваливается. Это первая причина, по которой связка не работает у внимательных людей.

Файл превращается в свою хэш-копию командой postmap:

sudo postmap /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd*

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

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

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

Параметры конкретных провайдеров SendGrid, SES и Яндекса

SendGrid различает имя и пароль своеобразно: именем выступает слово apikey, паролем сгенерированный в панели ключ. Формат строки паролей показан выше, а сам ключ создаётся один раз и хранится как настоящий секрет: утечка ключа означает чужие письма от вашего имени и потраченный лимит.

Amazon SES выдаёт SMTP-учётные данные отдельной парой в своей консоли, и адрес узла зависит от региона:

relayhost = [email-smtp.eu-central-1.amazonaws.com]:587

Молодая учётная запись живёт в песочнице: письма уходят только на подтверждённые адреса, пока домен не пройдёт проверку и не выйдет в производственный режим. Порядок входа честный: подтвердить домен, дождаться снятия ограничений, потом переключать сервер.

Яндекс принимает SMTP на собственном узле, а пароль заводится не основной, а в виде пароля приложения:

relayhost = [smtp.yandex.ru]:465

Для доменной почты рабочая схема строится на сервисе Яндекс 360, и адрес отправителя обязан совпадать с учётной записью, от которой ходит пароль: письмо от произвольного имени relay-канал не пропустит.

Общее правило для всех троих: провайдер шлёт письма от подтверждённых отправителей. Письмо с чужим полем From будет отклонено самим провайдером, поэтому адрес в письмах приложений настраивается осознанно и закрепляется в конфигурации.

Выбор между тройкой уместно свести к бытовой логике: SendGrid удобен простым ключом и внятной панелью, SES ближе тем, у кого инфраструктура уже живёт в облаке Amazon, Яндекс короткий путь для команды с почтой на собственном домене. Технически все трое делают одно и то же: принимают письмо по шифрованному каналу и доставляют его репутацией своих адресов.

Системные письма cron и мониторинга уходят через relay

Сервер разговаривает сам с собой чаще, чем кажется. Задачи по расписанию отправляют вывод на локальную почту, смарт-мониторинг диска шлёт предупреждения, службы наблюдения будят письмами.

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

root: Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.

Строка вписывается в /etc/aliases, после чего команда newaliases пересобирает базу, и системные письма начинают уходить на настоящий адрес через настроенный канал.

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

Приложения в контейнерах пользуются тем же каналом: достаточно отдать им localhost и порт 25 в качестве почтового узла, и дальше вся их почта уезжает тем же relay. Настройка, единожды сделанная в Postfix, покрывает и системные письма, и всё, что крутится рядом.

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

Тест отправки и чтение журналов при проблемах

Проверка канала делается одним письмом из консоли:

echo "тело тестового письма" | mail -s "relay test" Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.

Через пару секунд очередь обязана опустеть, а в журнале появиться строка о доставке. Журнал живёт в /var/log/mail.log, и в нём видна вся дорога письма: приём локально, соединение с провайдером, аутентификация, ответ его серверов.

Проверка настроенного канала выглядит так:

  1. тестовое письмо уходит из очереди за пару секунд;
  2. журнал показывает соединение с провайдером и статус sent;
  3. письмо приезжает во входящие без пометки спама;
  4. утренний отчёт задачи по расписанию оказывается на месте.

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

Полезная привычка при первом запуске: включить подробный уровень журнала соединений, отправить три-четыре письма и прочитать, как Postfix договаривается с сервером провайдера. Увидеть успешное согласование шифрования и приём пароля один раз полезнее десяти прочитанных инструкций, а потом уровень журналирования возвращается к скромному.

Типичные ошибки аутентификации и отказов релея

Отказ SASL authentication failed означает неверный пароль, несовпадение строк relayhost и файла паролей или забытую команду postmap. Первым делом сверяются скобки и порт в обоих местах, вторым сам пароль, третьим наличие свежего файла .db рядом с исходником.

Ответ провайдера Relay access denied обычно связан не с паролем, а с отправителем: домен письма не подтверждён у провайдера, либо учётная запись ещё в песочнице. Лечится проверкой домена в панели провайдера и совпадением поля From с подтверждённым адресом.

Таймауты соединения живут своей жизнью: если порт 587 не отвечает, проверяется исходящий канал вообще, а заодно настройка сетевых протоколов. Нерабочий IPv6-туннель способен молча ронять исходящие соединения, и строка inet_protocols = ipv4 в main.cf на время диагностики быстро закрывает вопрос.

Ещё один молчаливый кандидат на подозрения это DNS: узел провайдера обязан резолвиться с сервера, и экзотическая настройка локального резолвера иногда подкладывает сюрпризы. Проверка одной командой dig по адресу провайдера экономит вечер, потому что ошибка выглядит в журнале точно так же, как сетевая.

Готовый канал из нескольких строк конфигурации работает годами без внимания, а его журнал при разборе инцидентов ценнее любых предположений о том, куда делись письма. Тридцать секунд раз в неделю на просмотр пустой очереди и свежих строк доставки, и системная почта перестаёт быть лотереей, превратившись в скучную и надёжную службу.

А начинается всё с пяти строк main.cf, одного файла паролей и тестового письма: двадцать минут работы, после которых системная почта сервера просто существует и не требует к себе внимания.