Настройка 2FA в Keycloak через Telegram-бота
Граница. Keycloak из коробки поддерживает TOTP, WebAuthn, SMS-шлюзы и email-OTP. Telegram в этом списке нет. Чтобы бот доставлял одноразовые коды, требуется собственный Authentication SPI-провайдер, JAR-артефакт и сборка дистрибутива.

Лид: почему это не из коробки
Решение — неофициальное, community-уровня, с разной степенью поддержки. Это первое, что нужно зафиксировать до старта работ.
Telegram — не гарантированный канал. Доставка зависит от региона, нагрузки на Bot API и политики платформы. Для критичных контуров такой 2FA — точка отказа, а не усиление.
Кастомный код исполняется в адресном пространстве Keycloak. Уязвимость в плагине — уязвимость в аутентификации. Аудит JAR-файла обязателен.
Далее — разбор архитектуры, требований и пошаговый алгоритм развёртывания.
Архитектура: где в Keycloak живёт 2FA
Keycloak построен поверх JBoss/WildFly (до версии 17) и Quarkus (v17+). Аутентификация — набор потоков (Flows), состоящих из Execution-шагов. Каждый шаг — реализация интерфейса Authenticator. Внутренний SPI открыт для расширений: подключение нового метода равно регистрации собственного AuthenticatorFactory в виде JAR-файла, который Keycloak загружает из директории провайдеров.
Telegram-2FA в этой модели — ещё один Authenticator. На входе он получает учётные данные пользователя, на выходе проверяет одноразовый код, отправленный ботом. Логика:
1. После успешной проверки пароля Keycloak смотрит атрибут telegramId в профиле.
2. Если атрибут существует — провайдер вызывает Telegram Bot API и отправляет 6-значный OTP в личный чат с пользователем.
3. Код валидируется в течение TTL (по умолчанию 30–60 секунд).
4. При совпадении — сессия открывается.
Стандартная длина OTP — 6 цифр. Это компромисс между энтропией и удобством ввода. Более длинные коды поддерживаются спецификацией TOTP RFC 6238, но в Telegram-реализациях обычно фиксированы.
Коробочного Telegram-провайдера в Keycloak нет. Любой плагин — сторонний код с неопределённым уровнем поддержки.
Требования к инфраструктуре
Перед развёртыванием — три контрольных точки.
1. Telegram-бот. Регистрируется через @BotFather в клиенте Telegram. Команда /newbot возвращает API Token — уникальный идентификатор бота. Токен хранится в переменных окружения Keycloak, не в открытом конфиге. Формат хранения — секрет в vault (HashiCorp Vault, Kubernetes Secrets, AWS Secrets Manager), не plaintext в keycloak.conf.
2. Атрибут telegramId в профиле пользователя. Keycloak должен знать, какому chat_id отправлять сообщение. Варианты:
- ручное добавление атрибута через админ-консоль;
- импорт через LDAP/AD-mapper;
- самостоятельная регистрация через кастомную тему (требует фронтенд-разработки).
Без атрибута провайдер не работает. Это деградация, не отказ — пользователь не сможет пройти 2FA.
3. Совместимость версий. Начиная с v17 Keycloak перешёл на Quarkus, и структура дистрибутива изменилась. JAR-файлы провайдеров теперь размещаются в /opt/keycloak/providers/. До v17 — /standalone/deployments/. Команда сборки дистрибутива — kc.sh build (Quarkus) вместо --auto-config (WildFly).
| Параметр | Keycloak до v17 (WildFly) | Keycloak v17+ (Quarkus) |
|---|---|---|
| Директория для JAR | /standalone/deployments/ | /opt/keycloak/providers/ |
| Команда сборки | --auto-config или standalone.sh | kc.sh build |
| Время холодного старта | 30–60 секунд | 5–15 секунд |
| Потребление памяти (базовое) | ~512 MB | ~256 MB |
| Способ конфигурации | XML + properties | Env vars + properties |
Инструкции от 2021 года и ранее к актуальным версиям (24.x, 25.x) не применимы. Это первый источник ошибок при миграции.
Алгоритм развёртывания
Шесть шагов от нулевого состояния до работающего потока.
1. Получить токен бота через @BotFather в Telegram. Сохранить токен в защищённое хранилище.
2. Собрать или загрузить JAR-провайдер. Варианты: open-source проекты (проверить дату последнего коммита, количество открытых issues, наличие тестов) или собственная разработка на Java с использованием org.keycloak.authentication.Authenticator и org.keycloak.authentication.AuthenticatorFactory. В обоих случаях — code review. JAR загружается в доверенную среду.
3. Разместить JAR в директории провайдеров. Для Quarkus-версии: cp keycloak-telegram-authenticator.jar /opt/keycloak/providers/.
4. Пересобрать дистрибутив: ./bin/kc.sh build. Команда индексирует новые провайдеры и регистрирует их в classpath.
5. Настроить переменные окружения:
Порт для взаимодействия с Telegram Bot API — 443 (HTTPS). Самоподписанные сертификаты исключены.
6. Сконфигурировать поток аутентификации. В админ-консоли: Authentication → Flows → дублировать стандартный Browser Flow → переименовать копию (например, Browser with Telegram 2FA) → добавить Execution шаг типа Telegram OTP с уровнем Required → привязать поток к realm.
После сохранения — рестарт Keycloak. Без рестарта новые AuthenticatorFactory не зарегистрируются.
Проверка работоспособности
Два слоя контроля.
Серверный. Лог Keycloak (/opt/keycloak/data/log/keycloak.log или stdout в контейнере). Искать строки инициализации провайдера:
Отсутствие этих строк — признак того, что JAR не подхвачен. Проверить путь, пересобрать (kc.sh build), рестартовать.
Пользовательский. Тестовый вход: ввести логин/пароль → Keycloak запрашивает OTP → в Telegram приходит сообщение с кодом → ввод кода → сессия открыта. Если код не приходит — проверить:
- наличие атрибута
telegramIdу пользователя; - сетевую доступность до
api.telegram.org:443из контейнера Keycloak; - валидность токена через
curl https://api.telegram.org/bot<TOKEN>/getMe; - отсутствие блокировки Telegram на уровне провайдера/региона.
Тестовая проверка занимает 5 минут. Пропуск этого этапа — основная причина «не работает» в логах поддержки.
Сравнение методов 2FA в Keycloak
Прежде чем вводить Telegram как второй фактор, — матрица альтернатив.
| Метод | Уровень защиты | Зависимость от внешних систем | Стоимость | Совместимость с Keycloak |
|---|---|---|---|---|
| TOTP (Google Authenticator, FreeOTP) | Высокий | Нет | Бесплатно | Из коробки |
| WebAuthn (YubiKey, Touch ID) | Криптографический | Нет | $20–50 за устройство | Из коробки |
| Email OTP | Средний | SMTP-сервер | Бесплатно | Из коробки |
| SMS OTP | Низкий (SIM-swap) | SMS-шлюз | $0.01–0.05 за сообщение | Через провайдер |
| Telegram OTP (кастомный SPI) | Средний | Telegram Bot API | Бесплатно | Через сторонний JAR |
Telegram-2FA проигрывает WebAuthn по криптографической стойкости, TOTP — по автономности, но выигрывает по UX в тех организациях, где Telegram — рабочий мессенджер. Bot API как канал доставки используется далеко за пределами ИБ: от интернет-магазинов до медиа-порталов со спортивными рассылками.
Ограничения и риски
Пять технических угроз, которые нужно учитывать до утверждения метода.
- Отсутствие официального плагина. Red Hat не выпускает Telegram-провайдер. Все реализации — community-проекты. Поддержка ограничена issues на GitHub, SLA отсутствует. Точные лимиты Telegram API на отправку сообщений могут варьироваться в зависимости от нагрузки на бота.
- Зависимость от Telegram. Доставка сообщений в Telegram не гарантирована. Возможны блокировки или сбои API. Регионы с ограничениями (Китай, Иран, отдельные провайдеры в РФ) — постоянный риск отказа второго фактора. Совместимость конкретных open-source плагинов с самыми последними минорными версиями Keycloak требует индивидуальной проверки.
- Аудит стороннего кода. JAR из непроверенного источника без аудита — уязвимость нулевого дня в аутентификации. Минимум: проверка зависимостей (
mvn dependency:tree), статанализ (SpotBugs, SonarQube), контрольные суммы в CI. - Утечка токена бота. Токен в открытом конфиге — компрометация бота. Злоумышленник получает возможность рассылать сообщения от имени сервиса. Хранение — только в vault.
- Атрибут
telegramIdкак атака. Если атрибут редактируется пользователем (через self-service), злоумышленник подменяет chat_id и перехватывает OTP. Решение — read-only атрибут, редактирование только администратором.
Сторонний JAR без аудита — это не «удобное расширение». Это потенциальная уязвимость в аутентификации.
Чек-лист перед выводом в продакшн
1. JAR-провайдер получен из проверенного источника, выполнен code review.
2. Токен бота хранится в vault, не в keycloak.conf.
3. Атрибут telegramId заполнен у всех пользователей потока.
4. Сетевая связность keycloak → api.telegram.org:443 подтверждена.
5. Тестовый вход выполнен с верификацией кода в Telegram.
6. Логи Keycloak содержат строки инициализации провайдера.
7. В Fallback-потоке (Browser Flow) настроен альтернативный метод 2FA на случай недоступности Telegram.
8. SLA на поддержку плагина зафиксирован: кто реагирует на CVE, кто обновляет.
Итоги
Telegram-2FA в Keycloak — рабочая, но нишевая конфигурация. Применима там, где Telegram — рабочий стандарт коммуникации, а TOTP/WebAuthn по каким-то причинам не подходят: например, при массовом онбординге сотрудников без смартфонов с приложениями-аутентификаторами.
Коробочного решения нет. Каждый этап — разработка или установка стороннего кода, аудит, контроль токенов, проверка fallback-сценариев. Без выполнения этих шагов Telegram-2FA — это не второй фактор, а иллюзия защиты.
Где Telegram-2FA не нужен — везде, где есть WebAuthn. Аппаратный ключ дешевле, безопаснее и не зависит от сторонних сервисов. Всё остальное — компромисс.