Привет, Хабр и его жители! Я, Максим Санджиев, представляю отдел, занимающийся развитием, поддержкой и безопасностью инфраструктуры в департаменте Security Services компании «Лаборатории Касперского». У нас в отделе накопилась «нестандартная» экспертиза по работе с vault, IAM (keycloak), rook-ceph, minio s3, prometheus, k8s и многими другими инструментами OPS/SecOps/SRE. Хотели бы с вами поделиться нашими ресерчами, идеями, самописными разработками и получить фидбэк на наши реализации. Начнем с кейсов по работе с IAM.
![](https://habrastorage.org/webt/hc/ib/th/hcibthuwthvg64rtbikegyw05e4.png)
Эта статья рассчитана на людей, которые ранее были знакомы с IAM и, в частности, с keycloak-ом. Поэтому в этой части не будет «базы» по SAML2, OAuth2/OIDC и в целом по IAM (на Хабре есть хорошие статьи на эту тему).
Рассмотрим два кейса:
Представим, что у нас уже настроен стандартный браузерный поток на keycloak с проверкой клиентских сертификатов и маппингом этих сертификатов с УЗ в keycloak (при необходимости могу сделать отдельный раздел по данной тематике, здесь это как вводная информация). Нам требуется, чтобы у админских УЗ после проверки пароля от клиентского сертификата и его валидации появлялось окно ввода OTP-пароля. Обычных пользователей нагружать OTP нет необходимости, так как мы считаем сочетание «пароль + проверка клиентского сертификата» достаточно безопасным. Исключение — когда есть подозрение, что у пользователя скомпрометирован сертификат, тогда данный кейс тоже будет применим к этому пользователю. В этом случае последовательность решения данного кейса такая:
1) Создаем client в keycloak и настраиваем взаимодействие между необходимым нам веб-ресурсом (в нашем кейсе можно как по протоколу SAML2, так и по OAuth2/OIDC). Также настраиваем авторизацию посредством custom client scopes, если такой функционал заложен у необходимого нам веб-ресурса. Описывать этот процесс не буду, он присутствует в других статьях про keycloak.
2) Создаем Realm role, к которой мы будем привязывать группы наших админов, в разделе Manage → Realm Roles.
![](https://habrastorage.org/webt/01/0h/ef/010hefiz_ul4a_jz67lvl7bz4se.png)
3) Создаем группу пользователей и связываем созданную ранее роль на эту группу пользователей (Role mapping) в разделе Manage → Groups.
![](https://habrastorage.org/webt/ih/vx/ow/ihvxowljetkujgedl71i1gc1fok.png)
![](https://habrastorage.org/webt/kv/dw/zh/kvdwzhge2sdqezjtpyiowiya6fq.png)
![](https://habrastorage.org/webt/cs/kz/kk/cskzkky-a7m3irix4-hqv9mtyfi.png)
4) Добавляем админские учетные записи в созданную ранее группу.
5) Переходим в раздел Configure → Authentication → Flow. Дублируем текущий браузерный поток.
![](https://habrastorage.org/webt/qg/x8/aw/qgx8awnuwehemr1lzqfu5dqx3jg.png)
6) Добавляем в текущий поток step под названием «Conditional OTP Form».
![](https://habrastorage.org/webt/sw/hm/ew/swhmewjz3a5oobq5csstx5nu864.png)
![](https://habrastorage.org/webt/us/r9/qd/usr9qdtirtuum60pq5hggqwyvre.png)
7) Настраиваем добавленный ранее step «Conditional OTP Form», указав, что для роли с админами обязательным условием будет дополнительная проверка OTP.
![](https://habrastorage.org/webt/cm/hd/-f/cmhd-fjjheyv0n6uin8hwx9kc9e.png)
8) Делаем проверку OTP обязательной.
![](https://habrastorage.org/webt/o1/dj/ew/o1djewljnkhxphvjipslkrgbnqs.png)
9) Заходим в Manage → Clients и выбираем созданного в пункте 1 клиента. Далее переходим в Advanced → переходим в самый низ и ищем настройку «Authentication flow overrides». Выбираем созданный ранее нами flow.
![](https://habrastorage.org/webt/fl/aa/dq/flaadq0dur6tsi2qvuy8eekegsy.png)
10) Проверяем, что все работает. Заходим на нужный нам веб-ресурс с пользовательской УЗ и с админской УЗ. И видим, что при входе с админской УЗ нам требуется ввести OTP.
![](https://habrastorage.org/webt/zo/4v/ko/zo4vkoiyf1a4eox1wegc7tujdlw.png)
![](https://habrastorage.org/webt/h7/6k/eh/h76kehlgt1uc8mxsimawvjppjkk.png)
Первый кейс решен! Переходим ко второму.
В некоторых сервисах, которые мы связываем с keycloak, есть встроенный функционал/маппинг групп пользователей, которым разрешен доступ на веб-морду, но как показывает практика, далеко не все разработчики этот функционал добавляют. Представим, что у нас есть веб-ресурс, доступ к которому мы хотим определенной группе пользователей дать или, наоборот, запретить. Этот веб-ресурс уже соединен/настроен с keycloak. Тогда последовательность решения данного кейса такая:
1) Создаем Realm role, к которой мы будем привязывать группы пользователей с разрешенным доступом к веб-ресурсу, в разделе Manage → Realm Roles (смотрим, как это делалось в первом кейсе, пункт 2).
2) Создаем группу пользователей и связываем созданную ранее роль на эту группу пользователей (Role mapping) в разделе Manage → Groups (смотрим, как это делалось в первом кейсе, пункт 3).
3) Добавляем пользовательские учетные записи в созданную ранее группу.
4) Переходим в раздел Configure → Authentication → Flow. Дублируем текущий браузерный поток (смотрим, как это делалось в первом кейсе, пункт 5).
5) Создаем дополнительный sub-flow (к примеру, RBAC).
![](https://habrastorage.org/webt/tj/mj/i1/tjmji1rjxndr2ylc83d3mv1v0ou.png)
6) Добавляем в этот sub-flow condition «user role» и step «Deny access».
![](https://habrastorage.org/webt/ze/mc/qw/zemcqw3xknrgeia7gee9w7drofm.png)
![](https://habrastorage.org/webt/qa/ed/0s/qaed0sbytpr57sj0inw8w5devrq.png)
![](https://habrastorage.org/webt/dq/tr/8i/dqtr8i00mrnwpib8rpu-nhdk6bs.png)
7) Настраиваем condition «user role» — указав созданную ранее роль и передвинув ползунок на «Negative output».
![](https://habrastorage.org/webt/w2/-q/0y/w2-q0ykgkaeopqg8lwjgebqiqks.png)
8) Настраиваем step «Deny access». Alias и сообщение вводим по желанию.
![](https://habrastorage.org/webt/iq/gl/tr/iqgltroh-x7ulioli9trnbemf34.png)
9) Заходим в Manage → Clients и выбираем нужного клиента. Далее переходим в Advanced → переходим в самый низ и ищем настройку «Authentication flow overrides». Выбираем созданный ранее нами flow (смотрим, как это делалось в первом кейсе, пункт 9).
10) Проверяем, что все работает. Заходим на нужный нам веб-ресурс с УЗ, входящей «в группу разрешенных», и видим, что ничего не изменилось, но если попытаться аутентифицироваться с УЗ, не входящей «в группу разрешенных», то мы увидим окно:
![](https://habrastorage.org/webt/nx/75/ev/nx75eveqhhup8lh8h4tntfnuq5s.png)
Второй кейс решен! При необходимости логику flow можно поменять.
Если вам было интересно и вы сами хотите работать с инфраструктурой на предмет исследования уязвимостей и защиты от вторжений, то приходите к нам в «Лабораторию Касперского». Сейчас у коллег по команде открыты вакансии пентестера (Penetration Testing Specialist) и аппсекера (Application Security Specialist). У нас одна из самых сильных White Hat-команд в России, и процесс найма в нее максимально облегчен: попасть к нам можно всего за одно техническое собеседование!
А здесь можно проверить свои знания по offensive и defensive в нашей игре про умный город.
![](https://habrastorage.org/webt/hc/ib/th/hcibthuwthvg64rtbikegyw05e4.png)
Эта статья рассчитана на людей, которые ранее были знакомы с IAM и, в частности, с keycloak-ом. Поэтому в этой части не будет «базы» по SAML2, OAuth2/OIDC и в целом по IAM (на Хабре есть хорошие статьи на эту тему).
Рассмотрим два кейса:
- Есть учетная запись (УЗ) в keycloak с правами админа на какой-то веб-ресурс. Как, используя keycloak, сделать так, чтобы для входа админу требовался дополнительный фактор аутентификации?
- Есть веб-ресурс (client в терминологии keycloak). Как дать доступ к этому веб-ресурсу средствами keycloak на этапе аутентификации определенной группе пользователей (в ситуации, когда это не реализовано самим приложением)?
Первый кейс. Админский фактор
Представим, что у нас уже настроен стандартный браузерный поток на keycloak с проверкой клиентских сертификатов и маппингом этих сертификатов с УЗ в keycloak (при необходимости могу сделать отдельный раздел по данной тематике, здесь это как вводная информация). Нам требуется, чтобы у админских УЗ после проверки пароля от клиентского сертификата и его валидации появлялось окно ввода OTP-пароля. Обычных пользователей нагружать OTP нет необходимости, так как мы считаем сочетание «пароль + проверка клиентского сертификата» достаточно безопасным. Исключение — когда есть подозрение, что у пользователя скомпрометирован сертификат, тогда данный кейс тоже будет применим к этому пользователю. В этом случае последовательность решения данного кейса такая:
1) Создаем client в keycloak и настраиваем взаимодействие между необходимым нам веб-ресурсом (в нашем кейсе можно как по протоколу SAML2, так и по OAuth2/OIDC). Также настраиваем авторизацию посредством custom client scopes, если такой функционал заложен у необходимого нам веб-ресурса. Описывать этот процесс не буду, он присутствует в других статьях про keycloak.
2) Создаем Realm role, к которой мы будем привязывать группы наших админов, в разделе Manage → Realm Roles.
![](https://habrastorage.org/webt/01/0h/ef/010hefiz_ul4a_jz67lvl7bz4se.png)
3) Создаем группу пользователей и связываем созданную ранее роль на эту группу пользователей (Role mapping) в разделе Manage → Groups.
![](https://habrastorage.org/webt/ih/vx/ow/ihvxowljetkujgedl71i1gc1fok.png)
![](https://habrastorage.org/webt/kv/dw/zh/kvdwzhge2sdqezjtpyiowiya6fq.png)
![](https://habrastorage.org/webt/cs/kz/kk/cskzkky-a7m3irix4-hqv9mtyfi.png)
4) Добавляем админские учетные записи в созданную ранее группу.
5) Переходим в раздел Configure → Authentication → Flow. Дублируем текущий браузерный поток.
![](https://habrastorage.org/webt/qg/x8/aw/qgx8awnuwehemr1lzqfu5dqx3jg.png)
6) Добавляем в текущий поток step под названием «Conditional OTP Form».
![](https://habrastorage.org/webt/sw/hm/ew/swhmewjz3a5oobq5csstx5nu864.png)
![](https://habrastorage.org/webt/us/r9/qd/usr9qdtirtuum60pq5hggqwyvre.png)
7) Настраиваем добавленный ранее step «Conditional OTP Form», указав, что для роли с админами обязательным условием будет дополнительная проверка OTP.
![](https://habrastorage.org/webt/cm/hd/-f/cmhd-fjjheyv0n6uin8hwx9kc9e.png)
8) Делаем проверку OTP обязательной.
![](https://habrastorage.org/webt/o1/dj/ew/o1djewljnkhxphvjipslkrgbnqs.png)
9) Заходим в Manage → Clients и выбираем созданного в пункте 1 клиента. Далее переходим в Advanced → переходим в самый низ и ищем настройку «Authentication flow overrides». Выбираем созданный ранее нами flow.
![](https://habrastorage.org/webt/fl/aa/dq/flaadq0dur6tsi2qvuy8eekegsy.png)
10) Проверяем, что все работает. Заходим на нужный нам веб-ресурс с пользовательской УЗ и с админской УЗ. И видим, что при входе с админской УЗ нам требуется ввести OTP.
![](https://habrastorage.org/webt/zo/4v/ko/zo4vkoiyf1a4eox1wegc7tujdlw.png)
![](https://habrastorage.org/webt/h7/6k/eh/h76kehlgt1uc8mxsimawvjppjkk.png)
Первый кейс решен! Переходим ко второму.
Второй кейс. Запрет аутентификации средствами самого keycloak
В некоторых сервисах, которые мы связываем с keycloak, есть встроенный функционал/маппинг групп пользователей, которым разрешен доступ на веб-морду, но как показывает практика, далеко не все разработчики этот функционал добавляют. Представим, что у нас есть веб-ресурс, доступ к которому мы хотим определенной группе пользователей дать или, наоборот, запретить. Этот веб-ресурс уже соединен/настроен с keycloak. Тогда последовательность решения данного кейса такая:
1) Создаем Realm role, к которой мы будем привязывать группы пользователей с разрешенным доступом к веб-ресурсу, в разделе Manage → Realm Roles (смотрим, как это делалось в первом кейсе, пункт 2).
2) Создаем группу пользователей и связываем созданную ранее роль на эту группу пользователей (Role mapping) в разделе Manage → Groups (смотрим, как это делалось в первом кейсе, пункт 3).
3) Добавляем пользовательские учетные записи в созданную ранее группу.
4) Переходим в раздел Configure → Authentication → Flow. Дублируем текущий браузерный поток (смотрим, как это делалось в первом кейсе, пункт 5).
5) Создаем дополнительный sub-flow (к примеру, RBAC).
![](https://habrastorage.org/webt/tj/mj/i1/tjmji1rjxndr2ylc83d3mv1v0ou.png)
6) Добавляем в этот sub-flow condition «user role» и step «Deny access».
![](https://habrastorage.org/webt/ze/mc/qw/zemcqw3xknrgeia7gee9w7drofm.png)
![](https://habrastorage.org/webt/qa/ed/0s/qaed0sbytpr57sj0inw8w5devrq.png)
![](https://habrastorage.org/webt/dq/tr/8i/dqtr8i00mrnwpib8rpu-nhdk6bs.png)
7) Настраиваем condition «user role» — указав созданную ранее роль и передвинув ползунок на «Negative output».
![](https://habrastorage.org/webt/w2/-q/0y/w2-q0ykgkaeopqg8lwjgebqiqks.png)
8) Настраиваем step «Deny access». Alias и сообщение вводим по желанию.
![](https://habrastorage.org/webt/iq/gl/tr/iqgltroh-x7ulioli9trnbemf34.png)
9) Заходим в Manage → Clients и выбираем нужного клиента. Далее переходим в Advanced → переходим в самый низ и ищем настройку «Authentication flow overrides». Выбираем созданный ранее нами flow (смотрим, как это делалось в первом кейсе, пункт 9).
10) Проверяем, что все работает. Заходим на нужный нам веб-ресурс с УЗ, входящей «в группу разрешенных», и видим, что ничего не изменилось, но если попытаться аутентифицироваться с УЗ, не входящей «в группу разрешенных», то мы увидим окно:
![](https://habrastorage.org/webt/nx/75/ev/nx75eveqhhup8lh8h4tntfnuq5s.png)
Второй кейс решен! При необходимости логику flow можно поменять.
Если вам было интересно и вы сами хотите работать с инфраструктурой на предмет исследования уязвимостей и защиты от вторжений, то приходите к нам в «Лабораторию Касперского». Сейчас у коллег по команде открыты вакансии пентестера (Penetration Testing Specialist) и аппсекера (Application Security Specialist). У нас одна из самых сильных White Hat-команд в России, и процесс найма в нее максимально облегчен: попасть к нам можно всего за одно техническое собеседование!
А здесь можно проверить свои знания по offensive и defensive в нашей игре про умный город.
toxella
Спасибо за статью! У меня вопрос касаемо клиентских сертификатов. Сертификаты пользователи как предъявляют? Файлами загружают или токены используются физические?
panablack Автор
Клиентские сертификаты хранятся на внешних токенах (но при желании, можно хранить и на обычной флешке в шифрованном виде). Сертификат проверяется в двух местах: на балансировщике/ingress-ноде и в самом keycloak.
Для пользователя это обычное окно в браузере с выбором сертификата.
Как это всё настроить расскажу в будущей статье.
alexkuzko
Если будет такая возможность, дополнительно укажите какие кросс-платформенные решения/подходы есть.
Потому что Windows only это боль и чаще всего крест на внедрении...
panablack Автор
Когда внедряли клиентские сертификаты (mTLS), то действительно на винде сходу не работало. Только указав версию TLS на реверс-прокси, браузеры на винде стали выдавать заветное окно запроса клиентского серта. Таких проблем на линуксе и маке не было.