Привет! Я занимаюсь сопровождением реализации внутренних и внешних технических задач. В статье расскажу, как организовать централизованную аутентификацию через Identity Provider Keycloak. Сотрудники не будут мучаться с кучей паролей от БД, систем аналитики, таск-менеджеров, почты и других программ. На выходе получится готовый сервис аутентификации, который изолирован в своей VPC и доступен из интернета. Поехали ;)

Почему именно Identity Provider Keycloak?

Это уже готовая надежная система, которая поддерживает OAuth 2.0, OpenID Connect, SAML. Ничего не придется писать с нуля, у Keycloak нет дорогущих лицензий и привязки к одному вендору. Можно настроить кучу гибких сложных сценариев, например прикрутить 2FA, разграничить права доступа, заделать полностью изолированное окружение для конкретного проекта и не только. В общем, удобная вещь!

С чего начнем и что вам понадобится

Какие инструменты нужны

В моем сценарии развернем Keycloak в облаке. Все будет сделано на мощностях и с сервисами Cloud.ru, но можно развернуть везде, где захотите, в том числе локально. Плюс развертывания в облаке — обслуживание всей инфраструктуры лежит на провайдере, вы не тратите на это свое время. Еще развертывание БД и ВМ в облаке куда быстрее и проще: есть готовые конфигурации на все случаи жизни, а если что непонятно, приходите в техподдержку — и вам помогут.

Перечислю, какие инструменты будем использовать:

  • Виртуальные машины — сервис, в рамках которого вы получите ВМ, на которой и развернете Keycloak.

  • Публичный IP-адрес, чтобы ваш сервис аутентификации был доступен через интернет.

  • Managed PostgreSQL — управляемая БД PostgreSQL. Там разместятся, например, логины, хеши паролей, профили, настройки ролей и прав доступа, информация об активных сессиях и токенах.

  • VPC — изолированная виртуальная сеть, создаст безопасное изолированное пространство для всей инфраструктуры Keycloak.

  • nip.io — бесплатный DNS-сервис для тестирования, предоставляет временные доменные имена и сертификаты. В продакшене же лучше использовать зарегистрированные домены и SSL-сертификаты.

  • Nginx — веб-сервер, который берет на себя роль обратного прокси и обеспечивает HTTPS-шифрование трафика.

  • Let’s Encrypt — центр сертификации, дает бесплатные SSL/TLS-сертификаты.

Перед тем, как приступить, нужно сделать еще вот что:

  1. Зарегистрироваться в личном кабинете Cloud.ru или войти под своей учетной записью, если аккаунт уже есть.

  2. Сгенерировать пару SSH-ключей, публичный ключ загрузить в облако Cloud.ru Evolution.

Кратко опишу шаги, которые предстоит сделать, чтобы запустить Keycloak:

  1. Развернуть ресурсы в облаке.

  2. Настроить окружение ВМ.

  3. Настроить защищенный доступ через Nginx.

  4. Установить и запустить Keycloak.

  5. Отключить доступ по SSH.

Шаг 1. Разверните ресурсы в облаке

На этом этапе мы создадим все что нужно для работы Keycloak: виртуальную сеть, группу безопасности, саму виртуальную машину и кластер Managed PostgreSQL®. Все компоненты будут в одной VPC, что даст нам сетевую изоляцию и, соответственно, безопасность.

  • Создайте VPC, назовите ее identity-provider-VPC.

  • Создайте подсеть и задайте ей такие параметры:
    Название — identity-provider-subnet.
    VPC — identity-provider-VPC.
    Адрес — 10.10.1.0/24.
    DNS-серверы — 8.8.8.8.

  • Создайте новую группу безопасности.
    Из параметров:
    а) укажите Название, например, identity-provider-sg,
    б) добавьте правила для разных типов трафика, детали показал в таблице ниже:

Трафик

Протокол

Порт

Тип источника/адресата

Источник/адресат

Входящий

TCP

443

IP-адрес

0.0.0.0/0

Входящий

TCP

80

IP-адрес

0.0.0.0/0

Исходящий

Любой

Оставьте пустым

IP-адрес

0.0.0.0/0

Тут не спешите. После того как создали группу безопасности и привязали ее к виртуалке, проверьте, что доступ по SSH все еще работает. Подключитесь к серверу заново в отдельном окне терминала. Только убедившись, что соединение стабильно, переходите к следующему шагу.

  • Создайте виртуальную машину и задайте ей параметры:
    Название — identity-provider.
    Образ — публичный образ Ubuntu 22.04.
    Сетевой интерфейс — кликните на тип Подсеть с публичным IP.
    VPC — identity-provider-VPC.
    Подсеть — identity-provider-subnet.
    Публичный IP — оставьте Арендовать новый или выберите IP-адрес из списка арендованных.
    Группы безопасности — добавьте группу identity-provider-sg.
    Логин — keycloak.
    Метод аутентификации — Публичный ключ и Пароль.
    Публичный ключ — укажите ключ, который создали.
    Пароль — собственно, пароль.

  • Создайте кластер Managed PostgreSQL с параметрами:
    Имя кластера — identity-provider.
    Название базы данных — identity_provider_database.
    Версия PostgreSQL — 16.
    Режим — Стандарт.
    Тип — Single.
    Подсеть — identity-provider-subnet.

После того, как все создали, осталось убедиться, что все точно создалось. Проверьте это в личном кабинете:

  1. На странице Сети → VPC должна быть сеть identity-provider-VPC, в списке ее подсетей — identity-provider-subnet.

  2. В Сети → Группы безопасности отображена группа безопасности identity-provider-sg со статусом Создана.

  3. В Инфраструктура → Виртуальные машины есть ВМ identity-provider в статусе Запущена.

  4. В Базы данных → Managed PostgreSQL® отображан кластер identity-provider в статусе Доступен.

Шаг 2. Настройте окружение виртуальной машины

Теперь подготовим среду для Keycloak: загрузим нужные плагины и утилиты, обновим компоненты. Итак, что нужно сделать:

sudo apt update && sudo apt upgrade -y
  • Установить Nginx, настроить автозапуск и запустить веб-сервер без перезагрузки:

sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
  • Установить Java 17:

sudo apt install openjdk-17-jdk -y
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> ~/.bashrc
  • Загрузить Let’s Encrypt и плагин для Nginx:

sudo apt install certbot python3-certbot-nginx -y

Шаг 3. Настройте защищенный доступ через Nginx

На этом шаге вы зарегистрируете доменное имя, настроите Nginx в качестве защищенного прокси, получите SSL-сертификат и ограничите доступ через межсетевой экран.

Опишу, как зарегистрировать домен, настроить Nginx в качестве прокси, получить SSL-сертификат и ограничить доступ через файервол.

  • Создать конфиг Nginx:

sudo nano /etc/nginx/sites-available/identity-provider.conf
  • Вставить вот этот код, где <ip_address> заменить на публичный IP виртуалки:

server {
    listen 80;
    server_name <ip_address>.nip.io www.<ip_address>.nip.io;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port 443;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;

        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

Когда я настраивал в первый раз, админ-консоль Keycloak иногда висла или через прокси работала нестабильно. Убедитесь, что в вашей конфигурации Nginx есть proxy_set_header Upgrade $http_upgrade; и proxy_set_header Connection "upgrade"; — эти строки как раз для этого.

  • Сконфигурировать файервол:

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
  • Активировать конфигурацию и перезапустить Nginx:

sudo ln -sf /etc/nginx/sites-available/identity-provider.conf /etc/nginx/sites-enabled/identity-provider.conf
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
  • Выпустить SSL-сертификат:

sudo certbot --nginx -d <ip_address>.nip.io --redirect --agree-tos -m <email>

Где:

<ip_address> — публичный IP-адрес виртуальной машины,

<email> — email для регистрации сертификата.

  • Перейти по адресу https://<ip\_address>.nip.io и проверить, что браузер отмечает соединение как защищенное. Это можно посмотреть в поисковой строке, там должен быть замок и пометка вроде «Подключение защищено».

Шаг 4. Установите и запустите Keycloak

Почти добрались до конца. Теперь надо установить сам Keycloak, ради которого мы тут сегодня собрались, подключить сервис к базе данных и запустить Keycloak как systemd-службу.

Итак, для этого надо:

  • Скачать и распаковать Keycloak:

cd /opt
sudo wget https://github.com/keycloak/keycloak/releases/download/26.0.2/keycloak-26.0.2.tar.gz
sudo tar -xzf keycloak-26.0.2.tar.gz
sudo mv keycloak-26.0.2 keycloak
sudo chown -R keycloak:keycloak /opt/keycloak
sudo chmod o+x /opt/keycloak/bin/
  • Создать конфигурационный файл Keycloak:

sudo nano /opt/keycloak/conf/keycloak.conf
  • Вставить в терминал этот код, значения параметров подставить свои:

db=postgres
db-username=<postgres_admin_user>
db-password=<postgres_admin_password>
db-url=jdbc:postgresql://<postgres_ip>:5432/identity_provider_database

proxy=edge
hostname=https://<ip_address>.nip.io
http-enabled=true
proxy-headers=xforwarded
hostname-strict=false
hostname-admin=https://<ip_address>.nip.io

health-enabled=true
metrics-enabled=true

Где:

<postgres_admin_user> — имя пользователя кластера Managed PostgreSQL®,

<postgres_admin_password> — пароль этого пользователя,

<postgres_ip> — приватный IP кластера,

<ip_address> — публичный IP виртуалки.

  • Собрать конфигурацию Keycloak:

sudo -u keycloak /opt/keycloak/bin/kc.sh build
  • Создать и открыть в nano файл службы systemd:

sudo nano /etc/systemd/system/keycloak.service
  • После того, как откроется текстовый редактор, настроить содержимое файла:

[Unit]
Description=Keycloak Identity Provider
After=network.target
Wants=network.target

[Service]
Type=simple
User=keycloak
Group=keycloak
Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
Environment=KC_LOG_LEVEL=INFO
WorkingDirectory=/opt/keycloak
ExecStart=/opt/keycloak/bin/kc.sh start
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutStopSec=30
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Я специально добавил Environment=JAVA_HOME... и Environment=KC_LOG_LEVEL=INFO. Первое гарантирует, что Keycloak точно найдет Java. Второе — что в журналах (sudo journalctl -u keycloak) будет полезная информация для отладки, а не тонны отладочных сообщений. Параметры KillSignal=SIGINT и TimeoutStopSec=30 помогут сервису корректно завершить работу при перезагрузке, а не быть принудительно убитым.

  • Создать временного администратора:

sudo -u keycloak /opt/keycloak/bin/kc.sh bootstrap-admin user

Придумайте действительно сложный пароль и сохраните его в надежном месте, например, в менеджере паролей. После первого входа в админ-консоль рекомендую либо создать нового администратора с другим логином в только что созданном realm, либо хотя бы сменить пароль для этого временного пользователя user.

  • Запустить сервис: перезагрузить конфигурацию, включить автозапуск и, собственно, запустить:

sudo systemctl daemon-reload
sudo systemctl enable keycloak
sudo systemctl start keycloak
  • Перейти по https://<ip\_address>.nip.io, войти в администраторскую консоль Keycloak по логину и паролю, которые вы создали.

Шаг 5. Отключите доступ по SSH

Ура-ура, почти закончили J Сервис развернут и настроен, осталось только запретить доступ по SSH-ключам для большей безопасности. Но перед этим финально проверьте, что можете зайти в админ-консоль, создать тестового пользователя и realm. Также советую сделать резервную копию конфигурации Keycloak и БД. Если после отключения SSH что-то пойдет не так, у вас будет точка восстановления, и не придется настраивать все заново через серийную консоль.

И, собственно, как запретить доступ по SSH-ключам:

  1. В личном кабинете наверху слева найдите иконку с девятью точками, нажмите на нее. Перейдите в раздел Инфраструктура → Виртуальные машины.

  2. В списке ВМ кликните на identity-provider.

  3. Зайдите в Сетевые параметры.

  4. В блоке сетевого интерфейса нажмите на три точки и выберите Изменить группы безопасности.

  5. Удалите группу SSH-access_ru и сохраните изменения.

  6. Убедитесь, что доступа не осталось. Для проверки покдлючитесь к виртуальной машине по SSH. Если доступ по SSH и правда отключился, администрирование будет доступно только через серийную консоль виртуальной машины.

Подытожим

Итак, мы развернули Keycloak, настроили его взаимодействие БД Managed PostgreSQL®, безопасное подключение через Nginx и отключили ненужный доступ по SSH, чем повысили безопасность. Дальше Keycloak можно внедрить в корпоративные сервисы и завести туда пользователей, чтобы организовать централизованный вход.

Как вы сами оцениваете Keycloak? Как пользуетесь, какие настройки задаете? Готов обсудить это в комментариях.