Внедрение MTA-STS: как заставить входящую почту шифроваться, а не «по возможности»
Оппортунистический TLS в SMTP обходится одной downgrade-атакой: посредник вырезает STARTTLS, и письмо уходит в открытом виде. Разбираем рабочий рантбук по MTA-STS — публикация политики, HTTPS-хостинг policy-файла, TLS-RPT и безопасный переход testing → enforce без потери писем.
EvilMail Team17 июля 2026 г.13 мин чтения
STARTTLS в SMTP — это вежливое предложение, а не требование. Отправляющий сервер спрашивает «умеешь TLS?», принимающий отвечает «умею», и они шифруются. Проблема в том, что весь этот диалог идёт открытым текстом до момента согласования шифрования. Активный посредник на пути письма просто вычёркивает строку 250-STARTTLS из ответа на EHLO — и отправитель, не увидев поддержки TLS, спокойно доставляет письмо по 25-му порту в чистом виде. Ни ошибки, ни предупреждения, ни следа в логах получателя. Классическая downgrade-атака, и оппортунистический TLS против неё бессилен по определению: он не проверяет ни сертификат, ни сам факт, что шифрование вообще предлагалось.
MTA-STS (RFC 8461) закрывает эту дыру. Он превращает «зашифруем, если получится» в «доставляй только по TLS с валидным сертификатом, иначе не доставляй вообще». Ниже — не пересказ RFC, а рантбук: как за один вечер поднять политику, захостить policy-файл, безопасно пройти путь testing → enforce и не потерять ни одного письма.
MTA-STS: внедрение политики и принудительное шифрование входящей почты — EvilMail Blog
Почему не DANE
У downgrade-атаки два ответа: DANE и MTA-STS. DANE публикует отпечаток сертификата в DNS-записи TLSA и криптографически привязывает его к DNSSEC. Это сильнее: никакого TOFU, доверие построено на цепочке подписей от корня зоны. Но у DANE жёсткое требование — работающий DNSSEC на всей зоне, включая делегирование от регистратора. Если его нет (а у большинства доменов в 2026-м его нет), DANE недоступен в принципе.
MTA-STS не требует DNSSEC. Он опирается на WebPKI — тот же публичный CA, что и для HTTPS-сайта — плюс TOFU (trust on first use): отправитель один раз забирает политику по HTTPS, проверяет сертификат обычными средствами и кэширует на max_age. Слабое место проговорим честно: самое первое соединение, до кэширования политики, теоретически уязвимо к MITM. DANE этой дыры лишён. Но если выбор стоит между «MTA-STS сегодня» и «DANE когда-нибудь после внедрения DNSSEC» — ставьте MTA-STS сегодня. Для 95% доменов это правильный компромисс.
Три компонента
MTA-STS — это три независимые части, которые мы настроим по очереди:
DNS TXT `_mta-sts` — сигнал «политика существует» с версионным id. Отправитель читает эту короткую запись при каждой доставке.
HTTPS policy-файл на поддомене mta-sts.<domain> — сам контракт: режим, список MX, время жизни. Отправитель тянет его по HTTPS, только когда id в TXT сменился.
TLS-RPT TXT `_smtp._tls` (RFC 8460) — обратный канал: суточные JSON-отчёты о том, сколько сессий зашифровалось, а сколько сломалось и почему.
MTA-STS и TLS-RPT — парные стандарты. Внедрять enforce без TLS-RPT — значит выкатывать блокирующую политику вслепую, не имея данных о том, кто и как к вам не смог подключиться.
Шаг 1: DNS-запись политики
Запись _mta-sts.evilmail.pro типа TXT:
_mta-sts.evilmail.pro. IN TXT "v=STSv1; id=20260704120000"
id — единственное, что здесь несёт нагрузку. Отправитель сравнивает его со своим кэшем: совпадает — политика не менялась, файл перечитывать не нужно; изменился — идёт за свежим policy-файлом. Отсюда железное правило: любое изменение policy-файла требует нового `id`. Иначе отправители будут держать в кэше старую версию до истечения max_age. Конвенция — timestamp YYYYMMDDHHMMSS: он монотонно растёт и не даёт перепутать порядок версий.
Шаг 2: HTTPS-хостинг policy-файла
Здесь ломается чаще всего. Файл обязан лежать строго по адресу https://mta-sts.evilmail.pro/.well-known/mta-sts.txt. Требования, каждое из которых критично:
отдаётся с Content-Type: text/plain;
сертификат валиден именно для mta-sts.evilmail.pro (wildcard основного домена не покроет поддомен, если не выписан явно);
никаких кросс-хостовых редиректов — отправитель не пойдёт за Location на другой хост;
перевод строки LF или CRLF, обязательно с завершающим переводом строки в конце файла.
Построчно: version всегда STSv1. mode — testing, enforce или none. mx — по одной строке на MX-хост; допускается wildcard уровня одного лейбла, например mx: *.mx.provider.net (полезно, если вы за внешним провайдером с пулом MX). max_age — время кэширования в секундах, потолок 31557600 (около года). Список `mx` в файле обязан совпадать с реальными MX-записями в DNS — любой хост, куда реально доставляется почта, должен быть в списке, иначе enforce его зарежет.
Шаг 3: TLS-RPT до перехода в enforce
Публикуем канал отчётов:
_smtp._tls.evilmail.pro. IN TXT "v=TLSRPTv1; rua=mailto:[email protected]"
Через сутки на этот адрес начнут падать JSON-агрегаты от Google, Microsoft и Yahoo. Каждый отчёт содержит по каждой политике агрегированные счётчики total-successful-session-count и total-failure-session-count, а для сбоев — тип: certificate-expired, starttls-not-supported, validation-failure, tlsa-invalid. Именно эти цифры отвечают на вопрос «безопасно ли включать enforce». Фрагмент отчёта:
Три сбоя из почти шести тысяч сессий, все — certificate-expired на одном стороннем отправителе. Это не повод откладывать enforce. А вот сотни validation-failure означали бы, что ваш собственный сертификат или список mx не в порядке — сначала чините, потом enforce.
mode: testing → enforce без потери почты
Стратегия выката держится на одном принципе: в testing сбои TLS не блокируют доставку, только репортятся. Это ваша страховочная сетка.
Неделя в testing с max_age: 86400. Сутки кэша означают, что откатиться можно быстро — старая политика протухнет за день.
Читаем TLS-RPT всю неделю. Убеждаемся, что total-failure-session-count держится около нуля, а validation-failure отсутствует. Сверяем список mx в файле с фактическим выводом dig MX.
Переходим в enforce: меняем mode на enforce, поднимаем max_age до 604800–2592000 (неделя–месяц) и обязательно ставим новый `id` в TXT — иначе отправители не перечитают файл.
Главные грабли enforce — тот самый длинный max_age. Он же и защита (отправители держат политику в кэше), и мина: если вы смените MX, у отправителей ещё сутками-неделями будет висеть старая enforce-политика, которая зарежет доставку на новые хосты. Поэтому перед сменой MX заранее снижайте `max_age` до 86400, дайте старому значению истечь у отправителей, поменяйте MX и файл (с новым id), убедитесь по TLS-RPT, что всё зелёное, и только потом снова поднимайте max_age.
Отправляющая сторона: Postfix и чужой MTA-STS
Симметрия: ваша политика защищает входящую почту, но чтобы защитить исходящую, ваш MTA должен читать чужие политики. Postfix из коробки MTA-STS не понимает. Ставится демон postfix-mta-sts-resolver, который отвечает Postfix через socketmap:
curl -sv заодно покажет цепочку сертификата — убедитесь, что CN/SAN содержит mta-sts.evilmail.pro и цепочка полная. Из внешних валидаторов рабочие в 2026-м: hardenize.com (комплексно по всему домену), MTA-STS-тестер от aykevl, checktls.com.
Отдельный, самый важный алерт — истечение сертификата на `mta-sts.`. В режиме enforce протухший сертификат policy-эндпоинта означает, что отправители не смогут провалидировать политику и начнут откладывать вашу входящую почту. Certbot с автообновлением этого не гарантирует, если nginx после обновления не перезагрузился. Мониторьте срок так же, как мониторите основной MX.
Чеклист внедрения
Поддомен mta-sts.evilmail.pro заведён, DNS указывает на веб-сервер.
Сертификат Let's Encrypt для mta-sts. выпущен, автообновление проверено.
Policy-файл по /.well-known/mta-sts.txt отдаётся с Content-Type: text/plain, без редиректов.
Список mx в файле сверен с фактическим dig MX.
TXT _mta-sts с id в формате timestamp опубликована.
TXT _smtp._tls (TLS-RPT) с рабочим rua-ящиком опубликована.
Прожита неделя в mode: testing, TLS-RPT прочитан, total-failure-session-count ≈ 0.
Переход в enforce со сменой id и подъёмом max_age.
Настроен алерт на истечение сертификата mta-sts..
Перед любой сменой MX — заранее снижаем max_age, ждём истечения кэша, потом меняем.
На исходящей стороне поднят postfix-mta-sts-resolver, чтобы читать чужие политики.
MTA-STS не заменяет DKIM, SPF и DMARC — те про подлинность отправителя, а MTA-STS про конфиденциальность транспорта. Но именно он закрывает единственную дыру, которую не закрывает ничто другое: тихий откат вашей входящей почты в открытый текст. Один вечер работы, и downgrade-атака на транспорт к вашему домену перестаёт быть возможной.