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

Лид: почему это не из коробки
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_TOKEN=<token>
TELEGRAM_CODE_TTL=60
TELEGRAM_API_URL=https://api.telegram.orgПорт для взаимодействия с 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 в контейнере). Искать строки инициализации провайдера:
AuthenticatorFactory provider-telegram-otp loaded
TelegramOTPProvider initializedОтсутствие этих строк — признак того, что 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 без аудита — это не «удобное расширение». Это потенциальная уязвимость в аутентификации.
Итоги
Telegram-2FA в Keycloak — рабочая, но нишевая конфигурация. Применима там, где Telegram — рабочий стандарт коммуникации, а TOTP/WebAuthn по каким-то причинам не подходят: например, при массовом онбординге сотрудников без смартфонов с приложениями-аутентификаторами.
Коробочного решения нет. Каждый этап — разработка или установка стороннего кода, аудит, контроль токенов, проверка fallback-сценариев. Без выполнения этих шагов Telegram-2FA — это не второй фактор, а иллюзия защиты.
Где Telegram-2FA не нужен — везде, где есть WebAuthn. Аппаратный ключ дешевле, безопаснее и не зависит от сторонних сервисов. Всё остальное — компромисс.