SSO и 2FA пускают в веб-почту mailcow, а Thunderbird отвергает пароль: где взять пароль приложения
SSO и двухфакторная аутентификация в mailcow защищают вход в SOGo, но ничего не знают о протоколах IMAP, SMTP, POP3 и SIEVE — там нужен отдельный пароль приложения. Разбираю, почему это не баг, чем Generic OIDC отличается от Mailpassword Flow Keycloak и как настроить оба варианта на конкретном кейсе с 50 рабочими местами.
Симптом: в браузере всё работает, а в Thunderbird — Login failed
После того как я настраиваю единый вход для корпоративной почты на mailcow — через Keycloak или любой другой Generic OIDC-провайдер — почти всегда следующим шагом идёт один и тот же вопрос от клиента: «в SOGo и веб-почте вход работает, а Thunderbird и Outlook на компьютерах сотрудников ругаются на неверный пароль». Иногда та же картина возникает и без SSO — просто после включения двухфакторной аутентификации: вход в браузер требует TOTP-код и проходит, а IMAP-клиент на телефоне отваливается с ошибкой авторизации.
Это не сбой и не недоделанная интеграция — у mailcow сознательно разделены два уровня аутентификации. Веб-вход в SOGo/Roundcube проходит через SSO или пароль плюс второй фактор. А протоколы для почтовых клиентов — IMAP, SMTP, POP3, SIEVE — работают по логину и паролю без интерактивного второго фактора, потому что сам протокол не предусматривает диалоговое окно для TOTP-кода или редиректа в браузер провайдера. Поэтому для них у mailcow есть отдельная сущность — пароль приложения.
Отдельно уточню терминологию, чтобы не путаться дальше в статье: под «SSO» я имею в виду именно вход через внешний Identity Provider (Keycloak, Generic OIDC), а под «2FA» — встроенную двухфакторку mailcow (WebAuthn, TOTP, Yubi OTP). Это два разных механизма, но правило для протоколов у них одинаковое: обоим нужен пароль приложения, потому что дело не в конкретном провайдере, а в самой природе IMAP/SMTP.
Почему протокольный доступ не наследует веб-аутентификацию
App Passwords — не костыль, а осознанная архитектура. Причина такая же, как в Google, Microsoft 365 и любом другом сервисе с 2FA: у IMAP/SMTP/POP3/SIEVE нет штатного места, куда встроить второй фактор или редирект на страницу провайдера SSO — это простые протоколы логин+пароль, придуманные задолго до OAuth2 и WebAuthn. Требование создавать пароль приложения для ящиков с включённой 2FA в mailcow формализовано релизом 2025-03 (25 марта 2025 года): «2FA protected mailboxes will need an app password for authentication with mail protocols» — цитата из официальных release notes, и разработчики отдельно предупредили о критичности изменения аутентификации в этом обновлении.
Создаётся пароль приложения в самом mailcow UI — после входа в личный кабинет ящика, в разделе настроек App Passwords, отдельно для каждого клиента или сценария (Thunderbird, телефон, скрипт). Это касается любого ящика с 2FA независимо от того, подключён SSO или нет: сначала обычный вход в mailcow UI по паролю или SSO, затем — создание отдельного пароля именно для протокольного доступа.
На практике это значит, что каждому почтовому клиенту — Thunderbird на ноутбуке, встроенной почте на телефоне, скрипту рассылки — стоит выдавать свой отдельный пароль приложения, а не один общий на все устройства. Тогда при компрометации или утере телефона можно отозвать ровно один пароль, не трогая остальные подключения того же человека — это тот же принцип, что с токенами API, только применённый к почтовым протоколам.
Generic OIDC и Mailpassword Flow — два разных способа подружить Keycloak с mailcow
Если единый вход настроен через Generic OIDC, документация mailcow прямо описывает Authorization Code Flow: браузер редиректит пользователя на Keycloak, тот возвращает токен, mailcow проверяет атрибуты вроде mailcow_template. Для внешних почтовых клиентов правило то же самое, что и с обычной 2FA — сначала войти в mailcow UI, затем создать пароль в Mailbox Settings → App Passwords, и именно этот пароль использовать в Thunderbird или на телефоне. Ограничение, о котором разработчики предупреждают отдельно: при таком подходе mailcow не может автоматически отозвать доступ у пользователя, деактивированного в Keycloak, если у него остался живой пароль приложения — синхронизация статуса идёт только через сам OIDC-вход.
У Keycloak есть и второй, более глубокий вариант интеграции — Mailpassword Flow. Это не OIDC-поток вообще, а прямое обращение mailcow к Keycloak Admin REST API за атрибутами пользователя. Для него у клиента Keycloak должен быть настроен Service Account с ролью view-users, а у самого пользователя — атрибут mailcow_password с совместимым хешем пароля. Ключевое отличие от Generic OIDC: Mailpassword Flow поддерживает автоматическое создание пользователя и почтового ящика прямо при первом обращении по почтовому протоколу — то есть человек может ни разу не зайти в веб-интерфейс, а сразу подключить Thunderbird, и ящик заведётся сам.
Как настроить Mailpassword Flow: bcrypt-хеш и атрибут в Keycloak
Практическая настройка Mailpassword Flow начинается в Keycloak, а не в mailcow. Клиенту mailcow в Keycloak нужен включённый Service Account с ролью view-users — без неё mailcow не сможет прочитать нужные атрибуты через Admin REST API. Дальше каждому пользователю, который должен получить протокольный доступ этим способом, заводится атрибут mailcow_password со значением совместимого хеша.
Хеш генерируется командой из документации mailcow: mkpasswd -m bcrypt | sed 's/^/{BLF-CRYPT}/' — утилита mkpasswd в Debian и Ubuntu ставится пакетом whois (apt install whois), по умолчанию её в системе может не быть; префикс {BLF-CRYPT} обязателен, потому что по нему mailcow определяет схему хеша при проверке пароля (формат тот же, что понимает Dovecot). Готовое значение атрибута выглядит как {BLF-CRYPT}$2b$... и вставляется в поле mailcow_password в консоли Keycloak. Важный практический момент: при переключении существующего ящика на любой из двух режимов SSO прежний SQL-пароль mailcow не удаляется, а просто временно не используется — если позже вернуть ящик на обычную mailcow-аутентификацию, старый пароль снова заработает без пересоздания.
Ещё одна деталь, которую стоит проверить сразу после первого теста: если Service Account потерял роль view-users после обновления Keycloak или её случайно отозвали при пересборке клиента, mailcow не выдаст явную ошибку конфигурации — просто перестанет находить атрибут и будет вести себя так, будто у пользователя нет ни ящика, ни пароля. Поэтому первый шаг диагностики при жалобе «Mailpassword Flow перестал работать у всех» — не mailcow, а права Service Account в консоли Keycloak.
Кейс «ГикХаус»: 50 рабочих мест, Keycloak и почта на телефонах резидентов
У клиента — хакерспейса «ГикХаус», 50 рабочих мест — уже был развёрнут Keycloak как единая точка входа для внутренних сервисов, и почту на mailcow сначала подключили туда же через провайдера типа Generic-OIDC. Вход в SOGo и веб-почту заработал сразу. Но примерно у трети резидентов, которые настраивали почту на личных телефонах через стандартный протокол IMAP, начались стабильные отказы авторизации — сообщение об ошибке в Mail на iOS ничего не объясняло, просто «не удаётся войти».
Решили так: поскольку большинство резидентов уже заведены в Keycloak и IT-администратор хакерспейса ведёт их атрибуты централизованно, в System → Configuration → Access → Identity Provider переключили тип провайдера с Generic-OIDC на Keycloak (Mailpassword Flow есть только у него), включили флажок Mailpassword Flow и завели атрибут mailcow_password новым и переносимым резидентам вместо ручной раздачи паролей приложений — так почтовый ящик и учётная запись создаются одновременно при первом входе, без отдельного шага «зайти в mailcow UI и сгенерировать пароль». Для уже существующих активных ящиков, где это выглядело избыточным ради полутора десятков человек, остались на связке SSO + App Passwords, создав пароль каждому вручную. Вся миграция заняла два вечера, из них час ушёл на то, чтобы у клиента Keycloak в mailcow точно оказалась включена роль view-users — без неё Mailpassword Flow тихо не находит атрибут и откатывается к отказу.
Отдельно проговорили с администратором хакерспейса важный нюанс: ящик создаётся автоматически при первом входе человека — в mailcow UI или, с Mailpassword Flow, по почтовому протоколу — либо кроном Import Users, если этот флажок включён. Мы импорт не включали, поэтому сама по себе регистрация в Keycloak ящик не создавала. Для части новых резидентов это означало, что администратору всё равно нужно было один раз показать, как подключить телефон, — автоматизация убрала шаг «создать ящик вручную в mailcow UI», но не убрала первое подключение клиента полностью.
Грабли: авто-деактивация, кэш аутентификации Dovecot и EAS
Перед любыми экспериментами с аутентификацией — сменой SSO, включением Mailpassword Flow, массовой генерацией паролей приложений — стоит на всякий случай проверить, что бэкап mailcow действительно рабочий, а не просто выполняется по расписанию: изменения аутентификации — тот редкий случай, когда откат вручную может занять часы. Первая грабля — деактивация. Если пользователь заблокирован или удалён в Keycloak, а у него остался действующий пароль приложения, при Generic OIDC доступ по IMAP/SMTP не исчезнет автоматически: это ограничение, о котором разработчики писали в посте о состоянии LDAP/OIDC в nightly-ветке: mailcow не связывает статус деактивации в IdP с уже выданными паролями приложений. Практический вывод — при увольнении сотрудника недостаточно заблокировать его в Keycloak, нужно отдельно отозвать пароли приложений в mailcow UI или полностью деактивировать ящик. Разработчики в разборе состояния LDAP/OIDC прямо пишут, что деактивированный в IdP пользователь теряет вход в mailcow UI, но ящик продолжает принимать почту, и предлагают шаблон ящика с деактивацией через атрибут mailcow_template.
Вторая — кэш аутентификации Dovecot и мобильные клиенты по протоколу Exchange ActiveSync (EAS). В релизе 2025-05 (13 мая 2025 года) разработчики отдельно чинили PR #6488 — «Fix EAS login issue with app passwords and improve auth cache handling in Dovecot»: до этого исправления пароли приложений могли не приниматься именно у клиентов на EAS из-за особенностей кэширования сессии в Dovecot. Если у вас телефон на встроенном Exchange-клиенте всё ещё отказывается принимать свежесозданный пароль приложения, первое, что стоит проверить, — версия mailcow: на версиях до 2025-05 (исправление вошло именно в этот релиз) баг мог быть на стороне платформы, а не в настройках.
Что выбрать: App Passwords вручную или Mailpassword Flow
Для небольшой команды до десятка почтовых ящиков разумнее оставаться на ручных App Passwords — это два клика в интерфейсе mailcow, не требует прав Service Account в Keycloak и не создаёт лишней зависимости от Admin REST API. Такой же подход стоит выбирать, если вы уже подключали ящики через миграцию на mailcow и большинство сотрудников появились в системе не через Keycloak.
Mailpassword Flow оправдан там, где организация массово заводит и удаляет учётные записи через Keycloak — коворкинги, учебные центры, компании с высокой текучкой временного персонала — и где важно, чтобы почтовый ящик создавался автоматически в момент первого подключения клиента, а не требовал ручного шага в веб-интерфейсе mailcow от каждого нового человека. Обратная сторона — дополнительная точка отказа: если Service Account потеряет роль view-users или атрибут mailcow_password не совпадёт форматом, вся протокольная аутентификация для таких пользователей откажет разом, и разбираться придётся уже не в mailcow, а в логах Keycloak.
Есть и промежуточный вариант, который я иногда предлагаю клиентам с 15–30 ящиками: держать Mailpassword Flow выключенным по умолчанию, но включать его точечно для отделов с высокой текучкой — стажёров, сезонных сотрудников, временных резидентов, — оставляя постоянный костяк команды на обычных App Passwords. Это чуть усложняет документацию для администратора, зато не создаёт лишней зависимости от Keycloak Admin API там, где в ней нет практической необходимости.
Частые вопросы
У меня включена обычная 2FA без SSO — тоже нужен пароль приложения?
Да. Требование не привязано к SSO — оно действует для любого ящика с включённой двухфакторной аутентификацией. Правило из релиза mailcow 2025-03: 2FA-защищённые ящики нуждаются в пароле приложения для почтовых протоколов независимо от способа входа в веб-интерфейс.
Чем Mailpassword Flow отличается от обычного Generic OIDC?
Generic OIDC — это Authorization Code Flow, работает только для входа в веб-интерфейс, а для IMAP/SMTP всё равно нужен пароль приложения. Mailpassword Flow — отдельный механизм через Keycloak Admin REST API с атрибутом mailcow_password, который умеет сам создавать ящик и работает непосредственно с протокольным доступом.
Можно ли одновременно использовать оба варианта в одном mailcow?
Да, ничего не мешает часть ящиков вести через ручные App Passwords, а часть — через Mailpassword Flow, как мы сделали в кейсе с «ГикХаус». Сам флажок Mailpassword Flow глобальный, в настройках провайдера Keycloak, а работает он для тех, у кого заведён атрибут mailcow_password. Остальные продолжают ходить по паролям приложений.
Как сгенерировать хеш для mailcow_password в Keycloak?
Командой `mkpasswd -m bcrypt | sed 's/^/{BLF-CRYPT}/'` на любой Linux-машине с установленным пакетом whois. Префикс {BLF-CRYPT} обязателен — по нему Dovecot распознаёт формат хеша.
Почему у сотрудника на iPhone почта через EAS не принимает свежий пароль приложения?
Проверьте версию mailcow: до релиза 2025-05 (13.05.2025) был баг взаимодействия паролей приложений с кэшем аутентификации Dovecot именно на EAS-клиентах, исправленный в PR #6488. На актуальной версии проблема обычно в том, что пароль приложения создан не для того ящика, под которым настраивается EAS.
Если уволить сотрудника в Keycloak, у него сразу пропадёт доступ по IMAP?
Нет, если он подключён через Generic OIDC и у него остался действующий пароль приложения — mailcow не связывает статус деактивации в IdP с уже выданными паролями протоколов. Доступ нужно отзывать отдельно: удалить пароли приложений или деактивировать ящик в mailcow.
Источники
- mailcow docs — Generic-OIDC: Authentication for External Mail Clients — Authorization Code Flow, требование App Passwords для IMAP/SIEVE/POP3/SMTP, ограничение по авто-деактивации. https://docs.mailcow.email/manual-guides/mailcow-UI/u_e-mailcow_ui-generic-oidc/
- mailcow docs — Keycloak — Mailpassword Flow через Keycloak Admin REST API, атрибут mailcow_password, Service Account с ролью view-users, команда mkpasswd -m bcrypt с префиксом {BLF-CRYPT}, автосоздание ящика. https://docs.mailcow.email/manual-guides/mailcow-UI/u_e-mailcow_ui-keycloak/
- mailcow docs — Two-Factor Authentication — Требование App Passwords для внешних почтовых клиентов у ящиков с включённой 2FA. https://docs.mailcow.email/manual-guides/mailcow-UI/u_e-mailcow_ui-tfa/
- mailcow.email — 2025-03 Release notes — Дата 25.03.2025, формулировка «2FA protected mailboxes will need an app password for authentication with mail protocols», предупреждение о критичности изменения аутентификации. https://mailcow.email/posts/2025/release-2025-03/
- mailcow.email — 2025-05 Release notes — Дата 13.05.2025, PR #6488 «Fix EAS login issue with app passwords and improve auth cache handling in Dovecot», identity_provider опция отключения авто-создания пользователей. https://mailcow.email/posts/2025/release-2025-05/
