После обновления mailcow пропал mta-sts.txt: куда переехала публикация политики и как её вернуть
Вчера mta-sts.txt открывался, сегодня отдаёт 404, а DNS-записи никто не трогал — так выглядит типичная жалоба после обновления mailcow до 2025-09 или новее. Разгадка не в поломке, а в том, что публикация политики MTA-STS переехала из статического файла в интерфейс mailcow. Разбираю, что изменилось, как перенести старую политику и на что теперь смотреть при диагностике.
Почему mta-sts.txt вдруг стал возвращать 404
MTA-STS — механизм, который заставляет отправляющий сервер проверять действующую TLS-политику домена перед доставкой письма, чтобы почта к вашему домену не могла быть тихо понижена до незашифрованного соединения атакой на уровне сети. До версии mailcow 2025-09 администраторы вручную клали статический файл по пути /.well-known/mta-sts.txt на веб-сервере поддомена mta-sts.example.org и обновляли его руками при каждом изменении политики. Начиная с релиза 2025-09 mailcow, вышедшего 10 сентября 2025 года, MTA-STS стал штатной функцией, и документация прямо говорит: mailcow отдаёт содержимое политики динамически, генерируя его из настроек домена в интерфейсе, а не читает файл на диске.
Из-за этого перехода те файлы .well-known/mta-sts.txt, что администраторы создавали вручную до обновления, mailcow больше не обслуживает — маршрут теперь ведёт на PHP-обработчик, который формирует ответ из базы данных, и старый файл на диске просто перестаёт участвовать в выдаче. Внешне это выглядит как поломка после обновления mailcow: корень поддомена mta-sts может отдавать 200, а сам путь /.well-known/mta-sts.txt — 404, потому что маршрутизация для конкретно этого пути изменилась, а остальной веб-сервер работает как прежде.
Отдельная ловушка в том, что симптом проявляется не сразу и не для всех отправителей одинаково: получающие серверы кешируют MTA-STS-политику на срок max_age, и пока старая политика не устарела в чужом кеше, письма продолжают доставляться так, будто ничего не изменилось. Проблема всплывает волнами — то один внешний партнёр сообщает о странностях с TLS, то другой, по мере того как их кеш политики истекает и они пытаются перечитать её заново, натыкаясь на 404 вместо актуального документа.
Что подтверждает GitHub Issue #6734
В Issue #6734 репозитория mailcow-dockerized администратор описал ровно эту ситуацию: после обновления до версии 2025-09a политика MTA-STS перестала быть доступна, хотя раньше всё работало штатно. В логах приложенного отчёта виден запуск нового контейнера postfix-tlspol-mailcow, добавленного как раз этим релизом, а ниже — строка php-fpm-mailcow с ответом 404 на GET /.well-known/mta-sts.txt. То есть обновление прошло, контейнеры поднялись, запрос за политикой доходит до PHP — и проблема не в самом апдейте, а именно в новой модели публикации политики.
Issue закрыт мейнтейнерами со статусом not planned, что в терминах GitHub означает: это не признанный баг, а ожидаемое поведение новой версии. На форуме сообщества mailcow есть отдельная ветка «Update 2025-09 MTA-STS Configuration» с тем же вопросом «куда делся мой файл», а ответ дан в самой документации: с 2025-09 ранее созданные вручную файлы .well-known/mta-sts.txt больше недоступны, политикой управляют через UI.
Для меня статус not planned в подобных issue — это не отказ мейнтейнеров признавать проблему, а сигнал, что поведение осознанное и менять его обратно никто не будет. Когда я вижу такой статус на GitHub у mailcow, дальше не трачу время на поиск обходного пути вернуть старое поведение, а сразу иду читать актуальную документацию по новому способу — как в случае с MTA-STS это оказывается быстрее и надёжнее, чем пытаться реанимировать статический файл через кастомные правки веб-сервера поверх контейнеров mailcow.
Как теперь настраивается политика MTA-STS в mailcow
Начиная с 2025-09 настройка живёт во вкладке MTA-STS в свойствах домена в веб-интерфейсе mailcow. Там задаётся статус Active, режим — testing или enforce, и Maximum Age, для которого документация рекомендует значение по умолчанию 86400 секунд, то есть сутки. Режим testing позволяет включить политику и смотреть за отчётами о нарушениях, не блокируя реальную доставку писем, если что-то настроено неправильно — с него я всегда советую начинать после переезда со статического файла, даже если раньше уже был enforce.
DNS-часть при переходе меняется не сильно: по-прежнему нужна TXT-запись _mta-sts.example.org с содержимым вида v=STSv1; id=<идентификатор>, где id нужно обновлять при каждом изменении политики, и CNAME-запись mta-sts.example.org, указывающая на FQDN сервера mailcow — она нужна, чтобы на этот поддомен можно было выпустить корректный TLS-сертификат и получатели могли забрать политику по HTTPS. Разница в том, что теперь новый id mailcow генерирует сам при сохранении настроек в интерфейсе, а в DNS его вносите вы, взяв значение из раздела DNS Check, а не придумывая вручную, как раньше.
Ещё одно изменение из той же ветки обновлений — PR #6759 «Allow wildcard subdomains for MTA-STS», влитый 22 сентября 2025 года, то есть уже после выхода 2025-09 (он упомянут в заметке к релизу). Если у вас много доменов и поддоменов, как в телеком-инфраструктуре, прочитайте описание этого PR и проверьте поведение на своей версии, прежде чем рассчитывать на него: в основном руководстве mailcow по MTA-STS про wildcard ничего не сказано.
Как перенести старую политику без перерыва в защите
Я обычно свожу этот перенос в тот же чек-лист, что использую при миграции компании на mailcow, — там тоже важно не потерять ни одну настройку домена при переходе на новую модель. Перед тем как включать новую настройку, я выгружаю содержимое старого статического mta-sts.txt из бэкапа или репозитория — режим, список mx-хостов и старый max_age, чтобы воссоздать точно такую же политику в интерфейсе, а не придумывать новую с нуля. В свойствах домена включаю MTA-STS, выставляю Active, переношу режим (обычно оставляю testing на первые несколько дней даже если раньше был enforce — так безопаснее при смене механизма публикации), указываю MX-хосты через запятую и Maximum Age.
После сохранения смотрю сгенерированный id в интерфейсе mailcow и обновляю DNS-запись _mta-sts.example.org с этим новым значением — старый id, который раньше вписывали в TXT вручную, заменяю, иначе отправители не поймут, что политика изменилась, и продолжат пользоваться закешированной. Через несколько минут проверяю publish запросом к самому поддомену:
# проверяем, что политика отдаётся динамически из mailcow
curl -sI https://mta-sts.example.org/.well-known/mta-sts.txt
curl -s https://mta-sts.example.org/.well-known/mta-sts.txt
# проверяем актуальный id в DNS
dig +short TXT _mta-sts.example.orgЕсли curl возвращает 200 и корректное содержимое, а id в DNS совпадает с тем, что показывает интерфейс mailcow, значит переход завершён и отправители снова видят действующую политику.
Кейс: провайдер «ГигаКанал» проверял только главную страницу поддомена
У клиента — телекоммуникационного провайдера «ГигаКанал», 33 рабочих места — после планового обновления mailcow служба эксплуатации проверила поддомен mta-sts.gigakanal.example в браузере, увидела, что сайт открывается без ошибок, и закрыла задачу как выполненную. На деле браузер открывал корневую страницу поддомена, которая действительно отдавала 200 благодаря общей публикации mailcow, а конкретно /.well-known/mta-sts.txt при этом возвращал 404 — проверка была неполной, и разрыв обнаружился только когда один из корпоративных клиентов пожаловался, что его сервер при отправке писем к «ГигаКаналу» больше не может получить политику MTA-STS и шлёт почту без строгой проверки TLS.
Мы перенесли политику в интерфейс так, как описано выше: сначала testing на трое суток, чтобы убедиться, что отчёты о нарушениях TLS не сыплются массово из-за побочных проблем инфраструктуры, а затем переключили в enforce. Отдельно завели в регламент клиента правило: после любого крупного обновления mailcow проверять не корневую страницу поддомена, а именно путь /.well-known/mta-sts.txt через curl с явным кодом ответа — за пять секунд это исключает ложное чувство, что «всё работает», основанное на проверке не той страницы.
Разбор задержался ещё и потому, что жалоба от партнёра звучала расплывчато — «у нас участились предупреждения о безопасности при отправке к вам», без конкретной ссылки на MTA-STS. Мы завели для «ГигаКанала» простое правило мониторинга: раз в сутки cron-задача дёргает /.well-known/mta-sts.txt по HTTPS и присылает алерт в мессенджер техподдержки, если код ответа не 200 или содержимое неожиданно изменилось. Стоило это меньше часа настройки, а окупилось уже при следующем крупном обновлении mailcow — алерт сработал до того, как об этом узнал кто-то из клиентов, и разбор занял пятнадцать минут вместо суток разбора по чужой жалобе.
Где здесь появился postfix-tlspol-mailcow и при чём тут исходящая почта
Тем же релизом 2025-09 в mailcow появился отдельный контейнер postfix-tlspol-mailcow — он занимается противоположной стороной MTA-STS: проверяет опубликованные политики чужих доменов, когда ваш mailcow сам выступает отправителем и должен решить, можно ли доставлять письмо получателю с ослабленным шифрованием или нужно отказать. Это разные, хотя и связанные вещи: публикация собственной политики домена решает, как ваш сервер защищён как получатель, а postfix-tlspol-mailcow решает, как ваш сервер ведёт себя как отправитель по отношению к чужим политикам.
Наличие и работоспособность postfix-tlspol-mailcow сама по себе не гарантирует, что публикация вашей собственной политики в порядке — это две независимые проверки, и я вижу, как администраторы иногда путают их: контейнер запущен, логи чистые, значит всё работает. На деле нужно отдельно проверить именно исходящую сторону через postfix-tlspol и отдельно — входящую публикацию политики через прямой запрос к /.well-known/mta-sts.txt, как показано выше.
Тот же 2025-09 не единственный релиз mailcow, где стоит внимательно читать журнал изменений: похожая история была и с шаблоном, который открывал доступ ко всей переписке — тоже казалось, что всё работает, пока не разобрались в деталях конкретного апдейта. Релиз-заметка 2025-09 отдельно предупреждает, что при проблемах с высокой нагрузкой на CPU или повторяющихся рестартах контейнера рекомендуется пересобрать образ вручную — это разовая операция на нестабильных окружениях, и я советую сначала проверить логи postfix-tlspol-mailcow именно на такие симптомы, прежде чем списывать проблему на сеть или на удалённого получателя.
Чек-лист после обновления mailcow, где затронут MTA-STS
Короткий список проверок, который я прохожу после каждого крупного обновления mailcow на клиентах, у которых включён MTA-STS:
1. Проверить именно /.well-known/mta-sts.txt через curl с кодом ответа, а не только открыть страницу в браузере. 2. Сверить содержимое политики (режим, mx, max_age) с тем, что было настроено раньше. 3. Убедиться, что вкладка MTA-STS в свойствах домена в mailcow активна и режим соответствует ожидаемому. 4. Проверить, что id в TXT-записи _mta-sts.example.org совпадает с тем, что генерирует mailcow. 5. Проверить логи postfix-tlspol-mailcow отдельно — это исходящая сторона, не входящая публикация. Этот же набор проверок я закладываю в регламент планового обслуживания клиентов на mailcow: пяти минут хватает, чтобы поймать регресс до того, как его заметит партнёр или клиент.
Частые вопросы
С какой версии mailcow MTA-STS настраивается через UI, а не файлом?
С релиза 2025-09 от 10 сентября 2025 года. Начиная с этой версии mailcow генерирует содержимое политики динамически из настроек домена, а старые статические файлы больше не обслуживаются.
Нужно ли удалять старый файл mta-sts.txt вручную?
Не обязательно технически — mailcow его всё равно не читает, маршрут отдаёт содержимое из UI. Но я рекомендую убрать файл из системы контроля версий или деплоя, чтобы он не вводил в заблуждение при следующем аудите.
Какой режим выбрать сразу после переноса политики в интерфейс — testing или enforce?
Начинайте с testing на несколько дней, даже если раньше был enforce. Это позволит увидеть отчёты о нарушениях TLS до того, как политика начнёт реально блокировать доставку писем.
Что означает id в TXT-записи _mta-sts и когда его нужно менять?
id — версия политики; получающие серверы кешируют политику до истечения max_age и перепроверяют её только при изменении id. Меняйте id при любом изменении режима, списка mx или max_age, иначе получатели могут какое-то время использовать устаревшую версию.
Влияет ли postfix-tlspol-mailcow на публикацию собственной политики домена?
Нет, это разные механизмы. postfix-tlspol-mailcow проверяет чужие политики при исходящей доставке, а публикацию собственной политики нужно проверять отдельно — прямым запросом к /.well-known/mta-sts.txt.
Источники
- docs.mailcow.email: Setting up MTA-STS — Проверено: с 2025-09 политика управляется через UI, DNS-записи TXT _mta-sts с id и CNAME mta-sts на FQDN mailcow, режимы none/testing/enforce, рекомендованный Maximum Age 86400 секунд. https://docs.mailcow.email/post_installation/setup-mta-sts/
- mailcow.email: Update 2025-09 — Проверено: дата релиза 10.09.2025, новый контейнер postfix-tlspol-mailcow добавляет исходящую поддержку MTA-STS, проверка docker compose logs postfix-tlspol-mailcow и ручная пересборка образа при проблемах, PR #6686 (MTA-STS) и PR #6759 (wildcard-поддомены, влит 22.09.2025). https://mailcow.email/posts/2025/release-2025-09/
- GitHub: mailcow/mailcow-dockerized Issue #6734 — Проверено напрямую через GitHub API: заголовок 'The mta-sts policy file is unaccessible after the last update', статус closed / not_planned, в логе виден запуск postfix-tlspol-mailcow сразу после апдейта 2025-09a. https://github.com/mailcow/mailcow-dockerized/issues/6734



