OAuth2 в SMTP давно не новость, но именно в 2024–2025 он стал «новой нормой»: крупные провайдеры ограничивают базовую аутентификацию, продавливая токены доступа и делегирование. Если вы отправляете почту из приложений, бэкендов, CI/CD или внутренних сервисов, пора понимать, как работает smtp oauth2/xoauth2, где это реально нужно, и как это внедрить без боли.
Что такое SMTP OAuth2 и XOAUTH2 в двух словах
SMTP OAuth2 — это метод аутентификации клиента к SMTP-серверу с помощью токенов, полученных по протоколу OAuth 2.0. На уровне SASL используются механизмы OAUTHBEARER (стандартизован в RFC 7628) и де-факто популярный XOAUTH2 (исторически применялся в экосистемах Google и Microsoft). Смысл один: вместо пароля клиент предъявляет короткоживущий access token, иногда сопровождаемый процессом обновления через refresh token.
Важно различать сценарии:
- Порт 587 (
submission, STARTTLS) или 465 (implicit TLS) — клиентская отправка с аутентификацией. Здесь и применяется OAuth2. - Порт 25 — межсерверная доставка (MTA-to-MTA), аутентификация обычно не используется. OAuth2 не нужен.
OAuth2 не меняет SMTP как протокол доставки; он меняет только этап аутентификации на submission.
Зачем это нужно в 2025
Три причины:
- Безопасность. Токены короткоживущие, их проще отозвать и ограничить по областям доступа (scope), чем пароли.
- Политики провайдеров. У крупных поставщиков почты базовая аутентификация все чаще выключается. Для части аккаунтов остаются «пароли приложений», но это исключение, а не правило.
- Аудит и комплаенс. OAuth2 лучше вписывается в современные требования IAM: делегированные доступы, ротация, least privilege.
Если ваш код или сервер до сих пор «логинится» на SMTP с логином/паролем — закладывайте время на миграцию. Даже если все работает сегодня, завтра может перестать.

Термины и механизмы
Короткий словарик:
- SASL — прослойка аутентификации, которую использует SMTP (команда
AUTH). - XOAUTH2 — SASL-механизм, отправляющий токен в виде «user=…^Aauth=Bearer <token>^A^A» (где ^A — байт 0x01).
- OAUTHBEARER — стандартизованный механизм (RFC 7628), похожий на XOAUTH2, с формализованными error-response.
- Authorization Code, Device Code, Client Credentials — типы OAuth2-потоков. Для SMTP чаще всего применяют делегированный доступ (пользователь, refresh token) или сервисные схемы (делегирование от имени пользователя в домене).
Токены:
- Access token — живет обычно 1 час. Им мы и логинимся в SMTP.
- Refresh token — живет долго, хранится на сервере и меняется на новый access token при необходимости.
Архитектуры интеграции: что выбрать
1) Самый практичный путь: локальный SMTP-прокси на msmtp
Суть: поднимаем локальный мини-SMTP (msmtpd) на 127.0.0.1:2525, который принимает сообщения от вашего MTA/приложений и отправляет их во внешний SMTP-провайдер по OAuth2 с помощью msmtp. Токены обновляем скриптом. Плюсы — минимум боли, прозрачная интеграция с Postfix/Exim/скриптами, четкий контроль над токенами. Удобно запускать такой прокси на своем сервере или на выделенном VDS, чтобы изолировать секреты и логи.
2) Прямая интеграция MTA с OAuth2 (через SASL)
Теоретически Postfix/Exim могут аутентифицироваться через SASL-модуль с механизмами OAUTHBEARER/XOAUTH2. Практически это сложнее: нужны свежие версии SASL-библиотек и аккуратная прокладка токенов из внешнего помощника в MTA. В продакшене проще и надежнее выбрать msmtp-прокси.
Практика: минимальный стек на msmtp
Ниже — рабочая схема, которую можно внедрить за полдня.
Шаг 1. Получить OAuth2-креды и refresh token
Алгоритм универсален:
- Зарегистрировать приложение в вашей IAM/консоли провайдера почты. Получить
client_idиclient_secret. - Выбрать подходящий flow: для серверов обычно Device Code или Authorization Code со statically provisioned refresh token; для организационных доменов иногда доступна сервисная делегация.
- Получить
refresh_tokenс нужным scope отправки почты (например, «SMTP.Send» или «полные права на почту» — формулировки зависят от провайдера).
Дальше серверу потребуется уметь по refresh_token получать короткоживущий access_token.
Шаг 2. Скрипт, меняющий refresh token на access token
Сделаем простой помощник. Он читает параметры из файла, дергает токен-эндпоинт и печатает access_token в stdout. Путь к файлам и команды — пример, подправьте под свой дистрибутив и провайдера.
#!/usr/bin/env bash
set -euo pipefail
CONF=/etc/msmtp-oauth.env
. "$CONF"
# Переменные в файле:
# OAUTH_TOKEN_ENDPOINT=<token-endpoint>
# OAUTH_CLIENT_ID=<client_id>
# OAUTH_CLIENT_SECRET=<client_secret>
# OAUTH_REFRESH_TOKEN=<refresh_token>
# OAUTH_SCOPE=<optional-scope-if-required>
# OAUTH_AUDIENCE=<optional-audience-if-required>
# Вызов токен-эндпоинта. Важно: не логируйте секреты.
RESP=$(curl -sS -X POST -H "Content-Type: application/x-www-form-urlencoded" --data "grant_type=refresh_token" --data "refresh_token=${OAUTH_REFRESH_TOKEN}" --data "client_id=${OAUTH_CLIENT_ID}" --data "client_secret=${OAUTH_CLIENT_SECRET}" --data "scope=${OAUTH_SCOPE:-}" --data "audience=${OAUTH_AUDIENCE:-}" "${OAUTH_TOKEN_ENDPOINT}")
# Извлечем access_token (jq удобен, но можно и awk/grep):
ACCESS=$(printf '%s' "$RESP" | jq -r '.access_token')
if [ -z "$ACCESS" ] || [ "$ACCESS" = "null" ]; then
echo "Failed to get access_token" 1>&2
echo "$RESP" 1>&2
exit 1
fi
# msmtp ожидает сам токен без префикса Bearer
printf '%s' "$ACCESS"
Права и файлы:
install -m 700 -o root -g root /root/get-smtp-access-token.sh /usr/local/bin/get-smtp-access-token
install -m 600 -o root -g root /dev/stdin /etc/msmtp-oauth.env
# В /etc/msmtp-oauth.env положите client_id, client_secret, refresh_token (секреты!)
Шаг 3. Конфигурация msmtp
Создадим /etc/msmtprc с использованием XOAUTH2 и скрипта:
# /etc/msmtprc
# Общие настройки
defaults
logfile /var/log/msmtp.log
syslog on
# Аккаунт для отправки через внешний SMTP
account outbound
host smtp.mail-provider.example
port 587
tls on
tls_starttls on
auth xoauth2
user sender@example.com
passwordeval /usr/local/bin/get-smtp-access-token
from sender@example.com
auto_from on
account default: outbound
Пояснения:
auth xoauth2— msmtp сформирует правильную SASL-строку. Скрипт должен печатать только access token.passwordeval— безопаснее, чем хранить токен в файле. Каждый запуск делает обмен refresh→access.tls_starttls on— на 587 нужен STARTTLS.
Шаг 4. Локальный SMTP-приемник (msmtpd)
Чтобы ваш MTA или приложение говорили с msmtp через привычный SMTP, поднимем msmtpd на 127.0.0.1:2525. Пример systemd-unit:
# /etc/systemd/system/msmtpd.service
[Unit]
Description=Local SMTP proxy to msmtp (XOAUTH2)
After=network.target
[Service]
ExecStart=/usr/bin/msmtpd --listen=127.0.0.1 --port=2525 --background=0 --syslog=on --maillog=on -- /usr/bin/msmtp -t
User=nobody
Group=nogroup
Restart=always
RestartSec=2s
[Install]
WantedBy=multi-user.target
Запуск:
systemctl daemon-reload
systemctl enable --now msmtpd.service
Шаг 5. Подключаем Postfix к локальному смарт-хосту
В Postfix достаточно отправлять все наружу через 127.0.0.1:2525; никакой SASL в самом Postfix не нужен. Если вы только настраиваете submission и TLS в самом Postfix, смотрите материал про безопасный submission: submission и SMTP AUTH/TLS в Postfix.
# /etc/postfix/main.cf (фрагменты)
relayhost = [127.0.0.1]:2525
smtp_tls_security_level = may
smtp_tls_loglevel = 1
# Отключаем клиентский SASL в Postfix, он здесь не используется
smtp_sasl_auth_enable = no
Перезапуск:
postfix reload
Тест письма:
sendmail -bv root
swaks --to you@example.com --server 127.0.0.1:2525 --header "Subject: XOAUTH2 test" --body "hello"
Шаг 6. Подключаем Exim к локальному смарт-хосту
В Exim используйте существующий «smarthost» роутер или добавьте отправку через 127.0.0.1:2525. Суть та же: Exim не аутентифицируется сам, он просто кладет письмо на локальный msmtpd.
Отладка XOAUTH2 и что смотреть в логах
Классический способ — посмотреть рукопожатие через TLS и пробную аутентификацию. Пример ручного AUTH XOAUTH2 с произвольным токеном:
# Подключиться к внешнему SMTP
openssl s_client -starttls smtp -crlf -connect smtp.mail-provider.example:587
# Затем диалог:
EHLO test
# Сформировать строку для XOAUTH2: base64("user=user@example.com^Aauth=Bearer ACCESS_TOKEN^A^A")
AUTH XOAUTH2 dXNlcj11c2VyQGV4YW1wbGUuY29tAWF1dGg9QmVhcmVyIHlhMjkuLi5hYmMxMgEB
Типичные ответы сервера:
235 2.7.0 Authentication successful— успех.334с JSON об ошибке — уOAUTHBEARERдетализированные коды; уXOAUTH2часто «invalid_token»/«expired».535 5.7.3 Authentication unsuccessful— токен не принят. Проверяйте срок жизни, scope, включенность SMTP в настройках аккаунта.

Безопасность: хранение и ротация токенов
Рекомендации для продакшена:
- Не храните access token на диске. Он короткоживущий — лучше получайте при каждом запуске отправки (через
passwordeval). - Refresh token и секреты сложите в
/etcс правами 600 и владельцемroot. Не добавляйте в репозитории. - Журналируйте минимум. Никогда не пишите токены в лог.
- Ограничьте сетевые ACL: доступ к msmtpd — только с localhost.
- Обновляйте CA-траст, следите за TLS-версиями и алгоритмами.
Частные случаи провайдеров
Без ссылок на документацию, но важно понимать тренды:
- Рабочие домены. Для корпоративных почтовых систем часто доступны сервисные сценарии: приложение получает токен «от имени пользователя» на основании админской делегации. Это избавляет от интерактива и подходит для серверов.
- Пользовательские аккаунты. Обычно используют Device Code или Authorization Code, чтобы однократно получить
refresh_token, далее все работает без участия пользователя. - SMTP AUTH в Microsoft 365. Включается на уровне организации и/или почтового ящика. OAuth2 поддерживается, но активация SMTP AUTH в тенанте и права приложения — обязательные шаги.
А если очень хочется «напрямую» через SASL?
Краткая дорожная карта для Postfix:
- Убедитесь, что используете свежий стек SASL (Cyrus SASL с модулями
OAUTHBEARER/XOAUTH2). - В
/usr/lib/sasl2/smtp.conf(или каталоге дистрибутива) включите механизмы, например:mech_list: OAUTHBEARER XOAUTH2 PLAIN. - Организуйте способ передать в SASL актуальный access token для нужного пользователя. В простом случае — через внешний помощник, к которому Postfix обращается за токеном перед аутентификацией (подробности зависят от сборки SASL и дистрибутива).
- В
main.cfограничьте механизмы черезsmtp_sasl_mechanism_filter, чтобы предпочесть OAuth2.
Но даже при таком подходе точка отказа та же: выдача токенов. Поэтому в реальной жизни схема с msmtpd оказывается проще и предсказуемее.
Диагностика проблем
- invalid_grant при обмене refresh→access — refresh токен отозван, истек или не соответствует клиенту. Перевыпустите.
- invalid_scope — приложение не имеет права на SMTP/отправку. Проверьте включенные области доступа.
- SMTP AUTH disabled — в настройках ящика/тенанта выключена клиентская отправка. Включите.
- Clock skew — неверное время на сервере ломает валидацию JWT. Синхронизируйте NTP.
- Сбой TLS — проверьте STARTTLS, версии TLS, цепочку сертификатов, SNI.
Эксплуатация и мониторинг
Несколько практических советов:
- Логируйте в msmtp минимум: факты отправки, коды ответов, не содержимое токенов.
- В метриках выделите ошибки 4xx/5xx на этапе AUTH отдельно от ошибок передачи.
- Добавьте alert на рост доли авторизационных ошибок за интервал (например, >2% в 15 минут).
- Если у провайдера есть лимиты на частоту обмена refresh→access, внедрите кэширование access token на 5–10 минут, чтобы не дергать эндпоинт на каждое письмо при больших потоках. Для высокой производительности см. рекомендации по TLS и параллелизму: ускорение Postfix с кэшированием и TLS.
FAQ: коротко о главном
Нужно ли мигрировать с паролей на OAuth2 прямо сейчас? Если вы пользуетесь крупными почтовыми серверами — да, это самый безопасный путь на 2025 год.
Можно ли по-прежнему использовать «пароли приложений»? Местами — да, но это компромисс и зона риска. При возможности переходите на OAuth2.
Как быть с несколькими отправителями/ящиками? В /etc/msmtprc заведите несколько аккаунтов и используйте msmtpd с выбором аккаунта по From/route, либо поднимите несколько инстансов на разных портах.
Что с входящей почтой? OAuth2 относится к аутентификации клиента на этапе отправки. Доставка на ваш домен по 25 порту не меняется.
Итоги
Переход на smtp oauth2/xoauth2 — уже не «опция», а базовая гигиена почтовой инфраструктуры в 2025. Самый бесшовный путь для серверов и приложений — локальный прокси на msmtpd с выдачей токенов через простой скрипт, а MTA (Postfix/Exim) работает с ним как со смарт-хостом. Такой дизайн минимизирует изменения, не требует глубоких модификаций SASL в MTA и позволяет централизованно контролировать секреты и ротацию токенов. Если же вам нужен «нативный» SASL OAuth в самом MTA, планируйте время на совместимость библиотек и тесты. В обоих случаях ключ к успеху — аккуратное хранение секретов, стабильная синхронизация времени и наблюдаемость ошибок AUTH.


