mailcow wildcard-сертификат не выпускается: баг 2026-03
АйТи Фреш
Linux, Docker и DevOps

Почему wildcard-сертификат не выпускался в mailcow 2026-03 и что именно исправили в 2026-03a

Автор: , директор ООО «АйТи-Фреш» · · ~13 мин чтения
Wildcard-сертификат mailcow не выпускается из-за конфликта MAILCOW_HOSTNAME с wildcard-доменом в релизе 2026-03
Сертификат застрял не из-за DNS, а из-за избыточного запроса — Let's Encrypt сам отказался его подписывать.

Если сразу после перехода на mailcow 2026-03 wildcard-сертификат по DNS-01 не выпускается, а в логе acme-mailcow ошибка «is redundant with a wildcard domain in the same request» — дело не в DNS-записях. Это баг первой версии DNS-01 в mailcow: MAILCOW_HOSTNAME попадал в запрос вместе с покрывающим его wildcard. Исправлен в 2026-03a через три дня. Разбираю ошибку, патч и чистую настройку.

Кейс: «Цветной оттиск» переходит на встроенный DNS-01 — и получает отказ

Типография «Цветной оттиск» — 41 рабочее место, у них mailcow работает третий год: заказы на печать приходят по почте, часть — с приложенными макетами по 40–60 МБ, и любой сбой почты сразу бьёт по производству, потому что менеджер не увидит новый заказ в очереди на печать вовремя. Мы ведём для них корпоративную почту на собственном сервере. Wildcard на домен у них был и раньше, но выпускался он в обход mailcow: на хосте жил certbot с DNS-плагином и самописным хуком, который копировал сертификат в data/assets/ssl и перезапускал контейнеры.

До релиза 2026-03 другого пути и не было: встроенный acme-mailcow умел только HTTP-01, а wildcard без DNS-01 не выпустить. В 2026-03 (10 марта 2026) разработчики добавили DNS-01 прямо в acme-mailcow (PR #6912 «acme: add DNS challenges»), и я решил убрать самописную связку — чем меньше внешних скриптов вокруг почтового сервера, тем меньше сюрпризов. 11 марта обновили mailcow, включили DNS-01, перечислили wildcard в ADDITIONAL_SAN — и acme-mailcow вместо сертификата выдал ошибку. Старый сертификат от certbot действовал ещё около трёх недель, так что паники не было, но и откладывать не хотелось.

Первое подозрение у коллеги, который делал переключение, было «мы что-то не так настроили в DNS или в токене API». На деле токен работал: TXT-записи в зоне создавались. Отказывал сам Let's Encrypt — на этапе, когда заказ сертификата ещё только формируется. Это важная подсказка: если ошибка приходит до проверки DNS, копать надо в список имён, а не в DNS-зону.

Если wildcard не выпускается сразу после включения DNS-01 в mailcow 2026-03 (релиз от 10 марта 2026), в первую очередь проверьте версию: это может быть известный баг первой версии DNS-01, исправленный в 2026-03a, а не ошибка вашей конфигурации.

Почему wildcard сам по себе не покрывает всё — apex-домен и ADDITIONAL_SAN

Прежде чем разбирать баг, важно закрыть базовую вещь, которую путают чаще всего: сертификат на *.example.com не покрывает сам example.com — это прямо написано в документации mailcow про первые шаги с SSL и DNS. Домен без поддомена (апекс, он же корневой домен) — это отдельное имя с точки зрения TLS, и wildcard его не защищает, сколько бы поддоменов ни было закрыто.

Поэтому если вам нужен сертификат и на mail.tsvetnoy-ottisk.example, и на голый tsvetnoy-ottisk.example (например, для веб-морды на корневом домене), документация требует явно перечислить оба имени в переменной ADDITIONAL_SAN в mailcow.conf:

# mailcow.conf
ADDITIONAL_SAN=*.tsvetnoy-ottisk.example,tsvetnoy-ottisk.example

Для DNS-01 в mailcow отвечает набор переменных в mailcow.conf: ACME_DNS_CHALLENGE=y включает проверку через DNS вместо HTTP, ACME_DNS_PROVIDER указывает плагин провайдера (в документации пример — dns_servercow, для DNS-хостинга Servercow; в шаблоне конфига стоит заглушка dns_xxx), ACME_ACCOUNT_EMAIL — адрес ACME-аккаунта. Учётные данные API провайдера кладутся отдельно в data/conf/acme/dns-01.conf. Именно в этой новой связке и сидел баг, который поймала типография.

Сравнение сертификата только с wildcard и сертификата с wildcard плюс апекс-домен через ADDITIONAL_SAN в mailcow
Апекс-домен нужно добавлять отдельно — wildcard его не подразумевает, каким бы очевидным это ни казалось.

Баг 2026-03: когда MAILCOW_HOSTNAME конфликтует с wildcard в одном запросе

В issue #7112 трекера mailcow-dockerized, открытом 10 марта 2026 года — в день выхода 2026-03, — описан ровно этот сценарий: MAILCOW_HOSTNAME=mail.example.com, а ADDITIONAL_SAN=*.example.com,example.com,*.example.email,example.email. Имя хоста — поддомен, покрытый wildcard из того же списка, и запрос сертификата у Let's Encrypt отваливается с ошибкой.

Ошибка, которую видит администратор в логе acme-mailcow, дословно звучит так: «Domain name "mail.example.com" is redundant with a wildcard domain in the same request. Remove one or the other from the certificate request.» — то есть сам сервер Let's Encrypt отказывается принимать запрос, где одновременно перечислены и конкретный поддомен, и wildcard, который его уже покрывает, потому что с точки зрения ACME это избыточность в одном запросе.

Логически это правильное поведение центра сертификации — Let's Encrypt не принимает в одном заказе и mail.example.com, и *.example.com, раз второе покрывает первое. Проблема была в том, что в первой версии DNS-01 генератор списка имён в acme-mailcow всегда добавлял MAILCOW_HOSTNAME в запрос, не проверяя, покрыт ли он wildcard из ADDITIONAL_SAN. Убрать hostname из запроса через настройки было нельзя — он обязателен, это основное имя сервера.

Мы посмотрели логи «Цветного оттиска» — картина совпала один в один с описанием issue #7112, вплоть до формулировки ошибки. Это сняло вопрос «может, я что-то сломал в DNS» и превратило задачу из отладки в ожидание патча или временный обход.

Схема возникновения бага 2026-03 в mailcow: конфликт MAILCOW_HOSTNAME и wildcard в одном запросе сертификата
Проблема была не в DNS-записях клиента, а в том, как mailcow сам формировал список SAN до патча.

Что именно исправили в релизе 2026-03a

Патч вышел быстро — через три дня после открытия issue: релиз 2026-03a (Revision A) датирован 13 марта 2026 года и, по описанию, чинит проблемы с LDAP/Keycloak-входом и с новой функцией DNS-01. В список изменений вошли два ACME-исправления. Первое — PR #7124 «[ACME] Fix wildcard certificate conflict with MAILCOW_HOSTNAME» — прямое исправление конфликта между именем хоста и wildcard в одном запросе.

Второе — PR #7134 «[ACME] Skip autodiscover/mta-sts subdomains covered by wildcard certificates» — соседняя проблема из той же серии: mailcow по умолчанию добавляет в сертификат autodiscover. и autoconfig. для каждого домена (переменная AUTODISCOVER_SAN), а при включённом MTA-STS — и mta-sts.. При wildcard на тот же домен эти имена стали бы такой же избыточностью, и Let's Encrypt отверг бы заказ по той же причине. После патча покрытые wildcard имена из запроса пропускаются.

Для «Цветного оттиска» обновление до 2026-03a стало единственным нормальным решением — оно устранило причину, а не симптом. После ./update.sh и перезапуска сертификат выпустился с первой попытки, без ручной правки ADDITIONAL_SAN. Самописный certbot-хук мы удалили только после того, как убедились, что новый сертификат реально отдаётся на всех портах.

Обходной путь без обновления существовал — временно убрать из ADDITIONAL_SAN wildcard на домен хоста и перечислить нужные имена явно, а после обновления вернуть. Но у нас был запас по старому сертификату, а патч вышел всего через три дня после репорта — возиться с временными полумерами на продакшен-почте типографии в сезон заказов было рискованнее, чем подождать и обновиться один раз.

Хронология mailcow: DNS-01 в релизе 2026-03, issue #7112 о wildcard и исправление в 2026-03a через три дня
От репорта до рабочего патча прошло три дня — обновление до 2026-03a устраняет причину, а не только симптом.

Как настроить DNS-01 и wildcard с нуля, чтобы не повторить чужие грабли

Если вы включаете DNS-01 впервые, порядок такой: сначала решаете, какие имена реально нужны в сертификате — MAILCOW_HOSTNAME (например mail.example.com), wildcard *.example.com для прочих имён домена и сам апекс, если он нужен. Версия mailcow — не ниже 2026-03a: в 2026-03 с hostname под wildcard вы гарантированно получите ошибку из issue #7112.

Дальше включаете саму DNS-проверку и провайдера в mailcow.conf:

# mailcow.conf
ACME_DNS_CHALLENGE=y
ACME_DNS_PROVIDER=dns_servercow
ACME_ACCOUNT_EMAIL=admin@tsvetnoy-ottisk.example
ADDITIONAL_SAN=*.tsvetnoy-ottisk.example,tsvetnoy-ottisk.example

Учётные данные API провайдера прописываются не в mailcow.conf, а в /opt/mailcow-dockerized/data/conf/acme/dns-01.conf — для Servercow это SERVERCOW_API_Username и SERVERCOW_API_Password, для других провайдеров имена переменных берутся из документации соответствующего DNS-плагина. После правки конфигурации применяете изменения через docker compose up -d в каталоге /opt/mailcow-dockerized — пересоздастся контейнер acme-mailcow.

Правило, которое стоит держать в голове: не дублируйте в ADDITIONAL_SAN конкретные поддомены, если они уже покрыты вашим же wildcard. В 2026-03a mailcow сам убирает из запроса hostname и служебные autodiscover/autoconfig/mta-sts имена, но за собственные записи вроде *.example.com,imap.example.com отвечаете вы — Let's Encrypt отклонит такой заказ по той же причине избыточности.

Если вы разворачиваете mailcow с нуля, а не чините существующую установку, всю последовательность действий — от выбора хостинга до первого письма, которое не улетело в спам — я подробно расписывал в пошаговом регламенте развёртывания mailcow; там же DNS-01 и wildcard настраиваются в правильном порядке относительно остальных шагов, а не отдельно от них задним числом.

Как убедиться, что сертификат реально обновился, а не просто «нет ошибки»

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

docker compose logs -f acme-mailcow

В логе должно быть явное подтверждение получения сертификата, а не просто отсутствие новых строк. Дальше я проверяю, что реально отдаёт сервер — это надёжнее, чем верить логам на слово: echo | openssl s_client -connect mail.example.com:443 -servername mail.example.com 2>/dev/null | openssl x509 -noout -dates -ext subjectAltName покажет срок действия и список имён (ключ -ext есть в OpenSSL 1.1.1 и новее). Ту же проверку повторяю на 993 и 465 — IMAP и SMTP берут сертификат из того же каталога, но убедиться стоит.

Для «Цветного оттиска» после обновления мы дождались полного цикла выпуска (несколько минут на проверку TXT-записи центром сертификации) и закрыли задачу только тогда, когда openssl показал в SAN *.tsvetnoy-ottisk.example и tsvetnoy-ottisk.example, а срок действия — свежие 90 дней.

Частые ошибки при диагностике: не путайте баг 2026-03 с обычными проблемами DNS-01

Первая ошибка — сразу переписывать DNS-записи или менять DNS-провайдера, когда сертификат перестал выпускаться. Если ошибка в логе именно про «redundant with a wildcard domain», проблема не в DNS-записях и не в правах API-токена, а в списке SAN, который формирует сам mailcow — здесь версия сервера важнее, чем настройки DNS-зоны.

Вторая ошибка — путать этот баг с закрытым портом 80 при выборе HTTP-01 вместо DNS-01: это разные механизмы проверки, у них разные типовые ошибки, и симптом «сертификат не выпускается» у обеих настолько общий, что администраторы иногда начинают чинить не тот способ верификации. Если у вас порт 80 вообще закрыт на периметре и вы сознательно выбрали DNS-01 именно из-за этого, стоит отдельно свериться с тем, как выпустить сертификат при закрытом порте 80 — там другой набор типичных ошибок, не связанный с багом 2026-03.

Похожая путаница возникает и у администраторов, которые привыкли выпускать сертификаты для веба через certbot или встроенные механизмы Nginx и IIS — там логика продления Let's Encrypt устроена немного иначе, чем встроенный acme-mailcow, и переносить оттуда привычки диагностики один в один не всегда правильно: mailcow сам управляет своим ACME-клиентом внутри контейнера, а не полагается на системный certbot.

Третья ошибка — обновляться на 2026-03a вслепую, не читая release notes, если вы намеренно держите mailcow на старой ветке. Revision A точечная, но 2026-03 в целом — крупный релиз (в заголовке — принудительная 2FA, DNS-01, обновления SOGo и Rspamd), и перед ним я делаю бэкап через helper-scripts/backup_and_restore.sh и выбираю тихий день, а не пиковый день сдачи тиража.

Четвёртая — не проверять реальный результат выпуска, а полагаться на то, что «раз ошибок в логе больше нет, значит всё в порядке». Как я писал выше, отсутствие свежей ошибки не гарантирует новый сертификат, поэтому финальный критерий — вывод openssl s_client с нужными именами и датами, а не молчание лога.

Перед любым обновлением почтового сервера, от которого зависит приём заказов, планируйте окно заранее, а не по факту сбоя — с типографией мы договорились обновлять mailcow только по вторникам утром, когда очередь заказов минимальна.

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

Wildcard-сертификат покрывает корневой домен example.com?

Нет. *.example.com не покрывает сам example.com — документация mailcow прямо указывает на это. Если нужен и апекс-домен, его нужно явно добавить в ADDITIONAL_SAN вторым значением через запятую.

Почему wildcard-сертификат не выпускался в mailcow 2026-03?

Это баг первой версии встроенного DNS-01, появившегося в 2026-03: если MAILCOW_HOSTNAME — поддомен, покрытый wildcard из ADDITIONAL_SAN, mailcow включал в заказ оба имени, и Let's Encrypt отклонял его как избыточный. Описано в issue #7112 от 10 марта 2026 года.

Как исправить эту ошибку прямо сейчас?

Обновиться до 2026-03a от 13 марта 2026 года: там конфликт исправлен (PR #7124), а PR #7134 убирает из запроса autodiscover/mta-sts-имена, покрытые wildcard. Ручная правка ADDITIONAL_SAN нужна, только если вы сами перечислили поддомены под wildcard.

В чём разница между DNS-01 и HTTP-01 верификацией в mailcow?

DNS-01 подтверждает владение доменом через TXT-запись в DNS и включается переменной ACME_DNS_CHALLENGE=y с указанием провайдера в ACME_DNS_PROVIDER; HTTP-01 требует открытого порта 80. Ошибки редундантности SAN из бага 2026-03 относятся именно к DNS-01 и wildcard-доменам, а не к порту 80.

Как проверить, что сертификат реально обновился, а не просто исчезла ошибка из лога?

Смотреть docker compose logs -f acme-mailcow во время выпуска и затем проверить, что отдаёт сервер: openssl s_client -connect mail.example.com:443 с выводом через openssl x509 -noout -dates -ext subjectAltName. Отсутствие новых ошибок само по себе ничего не гарантирует.

Можно ли было выпустить wildcard в mailcow до 2026-03?

Встроенным acme-mailcow — нет: DNS-01 добавили только в релизе 2026-03 (PR #6912), а без DNS-01 Let's Encrypt wildcard не выдаёт. Раньше wildcard получали внешним клиентом и подкладывали как собственный сертификат.

Столкнулись с похожей задачей? Обращайтесь — решим

Если у вас происходит что-то из описанного в этой статье — или любая другая проблема с ИТ-инфраструктурой, — обращайтесь в любое время. Мои специалисты и я лично разберём ситуацию, найдём настоящую причину и доведём до решения.

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи