Keycloak
Установка и запуск
После перебора различных вариантов установки и запуска Keycloak самым комфортным оказался 'docker-compose'.
Пример конфигурации Keycloak с letsencrypt, базой данных PostgreSQL и автоматическим бекапированием на S3:
--- services: proxy: image: traefik:v3.3 command: - "--entrypoints.web.address=:80" - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--entrypoints.web.http.redirections.entrypoint.scheme=https" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.myresolver.acme.tlschallenge=true" - "--certificatesresolvers.myresolver.acme.email=mail@example.com" # <--------------------------- - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" ports: - target: 80 published: 80 protocol: tcp mode: host - target: 443 published: 443 protocol: tcp mode: host volumes: - /var/run/docker.sock:/var/run/docker.sock - ./letsencrypt:/letsencrypt keycloak: image: quay.io/keycloak/keycloak:26.0.1 restart: unless-stopped command: start ports: - "127.0.0.1:8080:8080" environment: KC_PROXY_ADDRESS_FORWARDING: "true" KC_HOSTNAME_STRICT: "false" KC_HOSTNAME_STRICT_HTTPS: "false" KC_HOSTNAME: keycloak.example.com # <--------------------------- KC_HTTP_ENABLED: "true" KC_PROXY_HEADERS: xforwarded KEYCLOAK_ADMIN: tmpadmin KEYCLOAK_ADMIN_PASSWORD: secret # <--------------------------- # --- KC_DB: postgres KC_DB_URL: jdbc:postgresql://postgres:5432/kc KC_DB_USERNAME: db_username # <--------------------------- KC_DB_PASSWORD: db_secret # <--------------------------- # --- labels: - "traefik.http.routers.kc.rule=Host(`keycloak.example.com`)" # <--------------------------- - "traefik.http.routers.kc.service=kc" - "traefik.http.routers.kc.entrypoints=websecure" - "traefik.http.routers.kc.tls.certresolver=myresolver" - "traefik.http.services.kc.loadbalancer.server.port=8080" postgres: image: postgres:16 environment: POSTGRES_USER: db_username # <--------------------------- POSTGRES_PASSWORD: db_password # <--------------------------- POSTGRES_DB: kc PGDATA: /var/lib/postgresql/data/pgdata ports: - "127.0.0.1:5432:5432" volumes: - postgresql_data:/var/lib/postgresql/data/pgdata deploy: resources: limits: cpus: '0.50' memory: 512M reservations: cpus: '0.25' memory: 256M command: > postgres -c max_connections=1000 -c shared_buffers=256MB -c effective_cache_size=768MB -c maintenance_work_mem=64MB -c checkpoint_completion_target=0.7 -c wal_buffers=16MB -c default_statistics_target=100 healthcheck: test: [ "CMD-SHELL", "pg_isready -U db_username -d kc" ] # <--------------------------- interval: 30s timeout: 10s retries: 5 restart: unless-stopped tty: true stdin_open: true backup: image: eeshugerman/postgres-backup-s3:16 environment: SCHEDULE: '@daily' BACKUP_KEEP_DAYS: 14 S3_ENDPOINT: https://s3.endpoint.com # <--------------------------- S3_REGION: my-region # <--------------------------- S3_ACCESS_KEY_ID: access_key # <--------------------------- S3_SECRET_ACCESS_KEY: secret_key # <--------------------------- S3_BUCKET: bucket_name # <--------------------------- S3_PREFIX: backups # <--------------------------- POSTGRES_HOST: postgres POSTGRES_DATABASE: kc POSTGRES_USER: db_username # <--------------------------- POSTGRES_PASSWORD: db_password # <--------------------------- volumes: postgresql_data: {}
Интеграция
Grafana
Источники:
- https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/
- https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/keycloak/
- https://stackoverflow.com/questions/68741412/grafana-generic-oauth-role-assignment
Интеграция с Grafana осуществляется в соответствии с документацией. Однако, необходимо учитывать особенность: Grafana осуществляет поиск ролей в 'id_token', а не 'access_token'. По умолчанию, роли пользователя не попадают в id_token, поэтому надо подкрутить конфигурацию клиента - https://stackoverflow.com/questions/68741412/grafana-generic-oauth-role-assignment.
SSH
Пример конфигурации, которая позволяет предоставлять административный доступ к серверу через ssh
путем назначения роли пользователю или группе.
План:
- настраиваем сервер
- устанавливаем расширение в Keycloak
На этапе настройки сервера устанавливаем kc-ssh-pam. В процессе установки можно внести ряд дополнений:
Запрещаем дальнейшие действия в случае неудачной проверки пользователя в Keycloak. Это может быть полезным, если локальный пользователь с таким же именем уже существует на сервере или в Keycloak такого пользователя. В таком случае, пользователь сможет зайти под локальной учетной записью, что не является предпочтительным.
# --- вместо auth sufficient pam_exec.so expose_authtok log=/var/log/kc-ssh-pam.log /opt/kc-ssh-pam/kc-ssh-pam auth optional pam_script.so # --- использовать auth [success=2 default=ignore] pam_exec.so expose_authtok log=/var/log/kc-ssh-pam.log /opt/kc-ssh-pam/kc-ssh-pam auth optional pam_script.so auth requisite pam_deny.so
В скрипте /usr/share/libpam-script/pam_script_auth
добавляем строку
adduser $PAM_USER sudo
чтобы новый пользователь сразу добавлялся в группу sudo
.
Также, здесь необходимо отключить пароль для sudo
.
sudo visudo # --- вместо %sudo ALL=(ALL:ALL) ALL # --- используем %sudo ALL=NOPASSWD: ALL
На втором этапе устанавливаем расширение keycloak-restrict-client-auth для Keycloak. Это расширение нам требуется для ограничение доступа к Realm клиенту, созданному на предыдущем этапе. "Из коробки" (на сколько понимаю) Keycloak не предоставляет такую возможность.
Установку выполняем по README.md для Client Role based режима. Здесь можно использовать более простой вариант аутентификации
Кроме того, требуется указать новый способ аутентификации в настройках клиента ssh-login: Clients > ssh-login > Advanced > Authentication flow overrides > Direct Grant Flow
По итогу получаем, что при назначении роли restricted-access
пользователю или группе предоставляется ssh
доступ с sudo к преднастроенным серверам.
Рецепты
Восстанавливаем доступ администратора
Для восстановления пароля требуется доступ к серверу, на котором установлен Keycloak.
Создаем временного администратора
bin/kc.sh bootstrap-admin user
Далее:
- заходим под временным администратором,
- сбрасываем пароль,
- заходим под администратором,
- удаляем временного администратора.
Как получить токен
В целях отладки можно выполнить curl
запрос к Keycloak и получить токен
curl -d "grant_type=password" \ -d "scope=openid" \ -d "client_id=client_id" \ -d "client_secret=client_secret" \ -d "username=username" \ -d "password=secret" \ https://keycloak.example.com/realms/REALM_NAME/protocol/openid-connect/token | jq .