28 Jan. 5, 2025, 7:23 p.m.

Установка KEYCLOAK (для 24 и 26+) + TRAEFIK-AUTH + Traefik в k8s

Задача: настроить связку KEYCLOAK + TRAEFIK-AUTH и закрыть свободный доступ к dashboard Traefik в среде kubernetes.

Введение

Архитектура

Keycloak выступает в роли провайдера аутентификации (OIDC);

traefik-forward-auth «сидит» между Traefik и Keycloak: он перенаправляет неавторизованные запросы к Keycloak, а после успешной аутентификации передаёт обратно требуемые заголовки (e-mail/username/etc.) в Traefik;

Traefik (Reverse Proxy):

  • отдаёт Dashboard на каком-нибудь поддомене (например, traefik.example.com);
  • все запросы на traefik.example.com пропускает через middleware типа ForwardAuth, который указывает на контейнер с traefik-forward-auth;
  • если пользователь не аутентифицирован, его перенаправляют в Keycloak. Если аутентифицирован — пускают дальше к Dashboard.

Установка KEYCLOAK

Данные для создания манифестов

Образ:

quay.io/keycloak/keycloak:24.0.0
ИЛИ разница в переменных среды
quay.io/keycloak/keycloak:26.0.0

Аргументы запуска:

start
--optimized # после окончательной отладки

Переменные среды для 24 версии:

KC_PROXY_ADDRESS_FORWARDING=true
KC_HOSTNAME_STRICT=false
KC_HOSTNAME=<внешнее DNS имя по которому будут приходить запросы>
KC_PROXY=edge
KC_HTTP_ENABLED=true
KC_DB=postgres # тип базы данных
KC_DB_USERNAME=<USER>
KC_DB_PASSWORD<PASS>
KC_DB_URL_HOST=<путь к базе данных>
KC_DB_URL_PORT=<порт базы данных>
KC_DB_URL_DATABASE=<имя базы данных>
KEYCLOAK_ADMIN=<логин администратора>
KEYCLOAK_ADMIN_PASSWORD=<пароль администратора>

Переменные среды для 26 версии:

KC_HTTP_ENABLED=true
KC_PROXY_HEADERS=xforwarded
KC_HOSTNAME=<внешнее DNS имя по которому будут приходить запросы>
KC_DB=postgres # тип базы данных
KC_DB_USERNAME=<USER>
KC_DB_PASSWORD<PASS>
KC_DB_URL_HOST=<путь к базе данных>
KC_DB_URL_PORT=<порт базы данных>
KC_DB_URL_DATABASE=<имя базы данных> 
KC_BOOTSTRAP_ADMIN_USERNAME=<ВРМЕННЫЙ АККАУНТ администратора>
KC_BOOTSTRAP_ADMIN_PASSWORD=<ВРМЕННЫЙ ПАРОЛЬ АККАУНТА администратора>

Порт, который слушает контейнер: 8080

Настройка MIDDLEWARES и INGRESS:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: keycloak-8080-ingress
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`keycloak.example.com`)
    kind: Rule
    services:
    - name: keycloak-svc
      port: 8080
    middlewares:
    - name: keycloak-https-redirect
  tls: {}
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: keycloak-https-redirect
spec:
  redirectScheme:
    scheme: https
    permanent: true

Настройка

По умолчанию в Keycloak есть master realm. Рекомендуется создать отдельный realm (скажем, myrealm), чтобы не хранить производственные настройки в master.

Зайдите в админку Keycloak под admin/admin. Выберите пункт «Create Realm» и назовите его myrealm (или как удобно).

Создание клиента (Client) для Traefik Forward Auth

  • В разделе Clients → Create client.
  • Client Type = OpenID Connect.
  • Client ID = traefik-forward-auth (можете выбрать другое имя).
  • Нажимаем «Next» и настраиваем Client authentication = ON, Standard flow = ON (остальное — по необходимости).

В блоке Settings (на вкладке этого клиента):

  • Root URL: (можно оставить пустым или указать URL вашего фронтенда).
  • Redirect URIs: обязательно добавить адрес, на который traefik-forward-auth слушает callbacks, например: https://auth.example.com/_oauth

  • Или, если у вас всё запущено в Docker-сети и вы тестируете локально: http://traefik-forward-auth:4181/_oauth (укажите тот протокол/домен и путь, куда будут приходить ответы от Keycloak).

  • Valid redirect URIs: здесь тоже надо явно указать callback-URL (аналогично пункту выше).
  • Web origins: + укажите * или точный домен, если Keycloak будет кидать CORS-запросы.
  • Не забудьте сохранить.

Client Secret Во вкладке Credentials клиента Keycloak вы найдёте Client Secret, который понадобится нам при настройке traefik-forward-auth.

В этом же интерфесе нужно создать пользователей и пароли к ним.


Установка TRAEFIK-FORWARD-AUTH

Образ:

thomseddon/traefik-forward-auth:2.2.0-arm

Переменные среды:

DEFAULT_PROVIDER=oidc
PROVIDERS_OIDC_ISSUER_URL=https://keycloak.example.com/realms/<ВАШ REALMS>
PROVIDERS_OIDC_CLIENT_ID=<НАЗВАНИЕ КЛИЕНТА В REALMS>
PROVIDERS_OIDC_CLIENT_SECRET=<секрет клиента>
SECRET=<любая строка>
URL=<адрес самого traefik-forward-auth, если все компоненты в одном NAMESPACE можно использовать внутренние адреса>
INSECURE_OIDC_SKIP_VERIFY_TLS=true
LOG_LEVEL=info

Порт, который слушает контейнер: 4181


Конфигурация MIDDLEWARES для ресурса, который нужно ограничить

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: keycloak-auth
spec:
  forwardAuth:
    address: "http://traefik-forward-auth-svc:4181"
    trustForwardHeader: true
    authResponseHeaders:
      - "Authorization"
      - "X-Forwarded-User"

Заключение

После проделанных действий при входе на сайт, который ограничен, будет “выпадать” форма авторизации в KEYCLOAK. Путём манипуляций с Authentication > Flows > browser (его клоном так как оригинал нельзя менять, не забудьте сделать ему BIND FLOW) можно определять этапы авторизации. Например, Логин/пароль + OTP. Или paswordless.