Если ваш сервис или ПО связаны с пользователями, рано или поздно встаёт вопрос авторизации, аутентификации и хранения этих чувствительных данных. Кто-то изобретает велосипед сам, кто-то использует многолетние enterprise-решения, ну а мы решили изучить вопрос и найти наиболее удобный, экономичный и гибкий вариант для своих задач. Расскажем, как мы это делали, какие были трудности и удалось ли их решить. Да, если вы DevOps-инженер или занимаетесь инфраструктурой в своей компании, в конце поста есть приглашение на наш ближайший митап, где можно будет послушать про другие решения Сбера, да и просто поговорить.  Передаю слово моему коллеге, Виталию Смирнову, руководителю DevOps-направления в SberDevices B2B. Привет, Хабр, я — Виталий Смирнов. Уже несколько лет я занимаюсь разработкой B2B продуктов в Сбере, а точнее в SberDevices. У нас много решений, про которые вы слышали, и одно из них — SberJazz (подробно рассказали тут, почему мы выбрали такое название). Если вкратце, это сервис для видеоконференций, который для многих стал альтернативой популярным зарубежным решениям. Причём у него есть как публичная версия (работает без регистрации и смс), так и корпоративная, предназначенная для рабочих встреч. И, разумеется, для бизнес-коммуникаций, конфиденциальность данных пользователей является первостепенной задачей, поэтому мы внедрили систему идентификации и управления доступом пользователей — IAM (Identity and Access management), которая включает в себя несколько функций, необходимых для работы:  Регистрация — это способ создания учётной записи. Он может быть разным. Например, пользователь заходит на сайт и создаёт себе аккаунт. Или в компании есть логин-пароль; Аутентификация — это способ идентифицировать себя в нашем сервисе, подтвердить личность и получить соответствующий доступ;  Авторизация — это разграничение прав доступа. Сервис проверяет, если аутентификацию прошёл тот человек, что регистрировался, есть ли у него какие-то права, чтобы осуществлять те или иные действия;  Аудит доступа — это контроль и наблюдение за тем, что сейчас происходит с сервисом. Кто вошел в систему, кто зарегистрировался, в какой момент это сделал, какие права были добавлены и т.п.  Управление пользователями — возможность добавить, удалить пользователей, сделать какие-то изменения в их ролевой модели и их доступах.  Благодаря этой системе пользователи могут получить учётную запись в SberJazz с персональными данными для входа, а также безопасно идентифицироваться на сайте и получать доступ к необходимым функциям. Кроме того, система Identity and Access management позволяет контролировать и наблюдать за тем, что происходит на сайте, и управлять доступами пользователей.  В прошлом, перед появлением систем IAM, организации часто использовали системы, основанные на протоколе LDAP (Lightweight Directory Access Protocol). Например, Microsoft Active Directory была самым популярным решением в таких случаях. Она точечно интегрировалась с различными службами организации, такими как портал, офис, почта, сервис конференции. Однако этот подход имел свои недостатки. Каждая из бизнес-систем должна была иметь свою внутреннюю функцию, которая обеспечивала вход и смену пароля для пользователей. То есть, каждый сервис должен был иметь свою web-страницу или интерфейс для авторизации пользователей.  Кроме того, система должна была иметь механизм интеграции с Active Directory, чтобы проверить учётные данные и подтвердить, что пользователь является действительным участником организации. Таким образом, паттерн интеграции требовал значительных усилий для каждого компонента.  После внедрения IAM систем, процесс авторизации и аутентификации пользователей изменился. Теперь все операции, связанные со входом, пользователями и проверкой паролей, осуществляются через IAM. В свою очередь, все бизнес-системы, такие как офис и почта, уже общаются с ним, и им требуется лишь небольшой компонент, который проверяет, что пользователь имеет правильные учётные данные и имеет необходимые права доступа.  Системы IAM могут быть интегрированы и с централизованными директориями, например, с Microsoft Active Directory, и организовать единую службу входа для любых бизнес-систем с минимальными затратами. В результате, преимущества IAM включают улучшенную безопасность, удобство использования и снижение затрат на разработку и интеграцию различных компонентов.  При выборе IAM-системы для организации есть много вариантов на рынке. В частности, у крупных компаний — это Oracle Access Management, IBM Security Verify Access, Microfocus NetIQ Access Manager и ForgeRock Access Management. Эти продукты давно на рынке, у них есть хороший уровень поддержки, но из минусов — отсутствие гибкости под конкретный продукт и высокая стоимость. Если и выбирать из них, то только если у вас уже есть другие решения этого вендора, а деньги и время на разработку не важны.  В остальных случаях лучше обратить внимание на другие решения — например, Gluu, WSO, Zitadel или CAS, каждая из которых имеет свои особенности и историю развития. Gluu основана в 1999 году и стала open-source в 2009. WSO появилась в 2005 году. Обе системы являются мощными и проверенными временем решениями. Однако стоит учесть, что они предоставляют оперативные исправления безопасности только для премиальных подписчиков, что может быть критичным для крупных и сложных продуктов.  Ещё одно решение, Zitadel — относительно новый проект, запущенный в 2020 году, который может стать стандартом для cloud-native IAM систем. Однако его молодость и отсутствие полноценной интеграции с LDAP делают его менее предпочтительным для некоторых организаций. CAS (Central Authentication Service) был разработан Йельским университетом в начале 2000-х годов. Это зрелый и функциональный проект, но с относительно сложным процессом установки, что может затруднить его использование.  1) WSO2 Carbon, по-видимому, основан на Tomcat  2) Gluu 4.0 поставляется в комплекте с Amazon Corretto, дистрибутивом OpenJDK. Вероятно, это связано с тем, что он построен на базе Shibboleth, который поддерживает только определенные дистрибутивы OpenJDK.  Источник: GitHub В итоге при выборе IAM системы мы столкнулись с тем, что по большому счёту они не слишком сильно отличаются друг от друга. Большинство продуктов, так или иначе, но поддерживают основную функциональность. А вот там, где начинаются различия, как раз и происходит выбор в пользу того или иного варианта. В вышеперечисленных решениях нас не устраивал уровень поддержки и закрытия тикетов, а также сложность интеграции. Перебрав известные нам решения мы выбрали KeyCloak, причём сразу по нескольким причинам.  Keycloak, разработанный компанией Red Hat/IBM в 2014 году, представляет собой уникальное решение в области управления аутентификацией и авторизацией. Его разработка была в период, когда уже существовали значительные альтернативные решения с известными недостатками и проблемами. Основная цель компании Red Hat при создании Keycloak заключалась в создании надёжного фундамента для своей системы Red Hat SSO. Компания понимала, что разработка открытого исходного кода станет ключевым фактором для привлечения внимания и активного участия сообщества разработчиков. Подход компании заключался не в создании продукта, сопровождение которого принесло бы значительные доходы, а в разработке высококлассного открытого решения, которое станет неотъемлемой частью их предлагаемого премиум-продукта для предприятий. Целью Red Hat не является максимизация прибыли от поддержки Keycloak, а скорее продажа и монетизация своей системы SSO, при этом Keycloak выступает в качестве важного компонента данной системы. Мы же выбрали Keycloak как решение для управления идентификацией и авторизацией пользователей по нескольким причинам:  1. Активность и поддержка: Keycloak имеет огромное сообщество разработчиков, множество открытых и закрытых issues, что свидетельствует о постоянной разработке и улучшении продукта.  2. Богатая функциональность: Keycloak предоставляет широкий набор функций, таких как поддержка OpenID Connect, SSO, MFA и других протоколов аутентификации. Это делает его гибким и универсальным решением для различных сценариев использования.  3. Простота интеграции: Keycloak легко интегрировать с различными приложениями и платформами, что существенно упрощает задачу разработчиков. Базовые паттерны интеграции, такие как использование OpenID Connect-провайдера, позволяют быстро и безболезненно внедрить управление идентификацией и авторизацией в существующие системы.  4. Кастомизация и масштабируемость: Keycloak предоставляет возможность настройки и масштабирования в соответствии с потребностями бизнеса и требованиями безопасности. Можно легко настроить параметры, такие как срок жизни сессии, правила аудита и взаимодействие с внешними системами.  5. Использование в крупных компаниях: Keycloak разработан в Red Hat и используется в крупных проектах и компаниях, что подтверждает его надёжность и готовность к промышленному использованию.  6. Open source: возможность быстрее и проще адаптировать и запустить проект, чем с закрытым корпоративным продуктом. А нам важно быть гибкими и оптимизировать всё, что возможно.  При анализе активности разработки двух решений — Keycloak и CAS (Central Authentication Service), становится очевидным, что Keycloak привлекает значительное количество разработчиков. Это видно по непрерывному прогрессу в разработке. В случае с CAS мы наблюдаем, что разработкой занимается только один человек, выполняющий значительное количество коммитов. Это указывает на то, что, вероятно, существует закрытый репозиторий CAS, где реально ведется разработка, а некоторые обновления периодически выкладываются на GitHub.  Рассмотрим базовые паттерны интеграции, коих существует великое множество. Самым популярным и широко принятым в наши дни является OpenID Connect. Этот паттерн интеграции представляет собой следующую схему: у нас есть отдельный компонент — провайдер OpenID Connect, который представлен Keycloak, и наше приложение, которое существует отдельно.  Допустим, справа у нас находится Keycloak, слева – почтовое или офисное приложение, а в центре – пользователь. При пользовательском входе в приложение оно запросит «дай мне токен». Если у пользователя отсутствует токен, приложение автоматически перенаправит его на Keycloak. В Keycloak пользователь может ввести свои учётные данные (логин и пароль), получить токен, и затем использовать этот токен для взаимодействия с приложением. Таким образом, с использованием паттерна OpenID Connect, Keycloak выступает в роли провайдера аутентификации и авторизации, обеспечивая безопасный доступ пользователя к приложению. Этот паттерн является одним из наиболее эффективных и распространенных решений для интеграции систем.  Интеграция Keycloak в приложение предоставляет прозрачный пользовательский опыт. Допустим, пользователь заходит на страницу банка и происходит автоматическое перенаправление — если он не вошел в систему, его перенаправляют на форму ввода логина/пароля в Keycloak, и после успешного ввода данных он перенаправляется обратно на страницу. При необходимости приложение может отправить запрос в провайдер OpenID Connect и получить дополнительные сведения о пользователе, такие как пол, возраст, профиль и права доступа. Так выглядит этот поток информации.  Теперь обратимся к паттернам интеграции. При внедрении Keycloak в продукт возникает вопрос о том, как проверять аутентификацию пользователей — чтобы убедиться, что пользователь вошел в систему и у него есть корректный токен. Самым простым и популярным методом является использование OAuth2Proxy — это дополнительное приложение, которое может быть интегрировано в NGINX или поддерживается в Istio. Оно выполняет работу интеграции за нас. Мы можем настроить OAuth2Proxy таким образом, чтобы пользователь ввел свои учётные данные, и если они корректны, мы пропускаем его через прокси в наше приложение.  Прокси — это компонент, который позволяет перенаправлять запросы на аутентификацию и авторизацию через внешние системы аутентификации или сервисы авторизации, такие как SSO или OAuth в KeyCloak. Прокси обычно устанавливается между клиентским приложением и KeyCloak сервером, и может использоваться для обеспечения дополнительного уровня безопасности, например, для фильтрации трафика или скрытия IP-адресов клиентов.  Есть также другой паттерн, когда логика нашего прокси встраивается непосредственно в приложение, и само приложение может проверить токен и сделать выводы на основе этой информации. Выбор между паттернами зависит от разработчиков и конкретных деталей реализации, а также от того, насколько глубоко они хотят интегрировать систему. Например, в Red Hat широко используется Keycloak, и в их предложении Kubernetes OpenShift они используют Keycloak. Они даже не интегрируют проверку токенов в приложении, а просто устанавливают прокси и выполняют проверку, что является самым простым, эффективным и быстрым паттерном.  Наша задача заключается в создании продуктов для бизнеса и предоставлении их заказчикам для развертывания в их собственных средах. Например, у нас есть продукт для видеоконференций SberJazz, который имеет собственную систему управления идентификацией (Identity Management). Мы используем Keycloak внутри SberJazz для предоставить наш продукт вместе с Keycloak. Мы пакуем Keycloak в контейнер Docker и разворачиваем его в среде Kubernetes. Поскольку Keycloak является одним из компонентов нашего продукта, мы не требуем от заказчика его настройки или интеграции. У нас есть система управления жизненным циклом нашего продукта, и пользователь может даже не знать, что внутри используется Keycloak. Если пользователь заинтересован, мы можем помочь ему получить доступ к Keycloak, но в большинстве случаев они даже не осознают его наличия. При этом регистрация, авторизация и аутентификация работают и обеспечивают безопасность.  Однако есть несколько нюансов, связанных с тем, что пользователь не знает о наличии Keycloak внутри продукта. Вот основные задачи, которые мы выделили:  Изменение пароля администратора: в Keycloak можно установить первоначальный пароль администратора. Если впоследствии требуется изменить этот пароль, это может быть сложной задачей, которая требует знания предыдущего пароля и выполнения нескольких действий. Но решение есть. Изменение настроек подключения к внешним системам: Keycloak может отправлять письма пользователям о смене пароля, сбросе пароля или для регистрации. Также он может интегрироваться с Active Directory. В случае изменения настроек этих внешних систем, таких как почта или Active Directory, поменяются и учётные данные для подключения. Изменение конфигурации продукта: например, время жизни сессии пользователя, и тогда ему приходится снова вводить логин-пароль.  Изменение настроек аудита: то есть, если мы хотим как-то расширить аудит, что происходит в системе и изменить эти данные.  И в итоге всего две основные проблемы, которые мешают нам решить эти задачи:  Keycloak не может быть просто настроен с помощью конфигурационного файла.  Невозможность изменить пароль администратора после установки.  Проблема с простой конфигурацией решаема. У Keycloak есть альтернатива: конфиг может быть экспортирован и загружен обратно с помощью файла REALM (содержит настройки и параметры для определенной реальности — realm). Такой файл — это логическое разделение KeyCloak, которое может содержать набор пользователей, ролей, групп и других объектов, необходимых для аутентификации и авторизации пользователей в пределах конкретного приложения или группы приложений. Этот файл содержит полную конфигурацию Keycloak в виде большого и сложного текста JSON. Однако предоставление этого файла пользователям и просьба внести в него изменения может вызвать путаницу и сложности.  Поэтому мы создаём шаблон из этого файла REALM, в котором мы определяем нужные нам конфигурационные параметры. На основе простого и понятного пользовательского ввода, например, через 10 вопросов, мы формируем целевой конфигурационный файл.  Что касается загрузки этого файла, мы предоставляем два варианта: можно попросить пользователя загрузить его через графический интерфейс, но в настоящее время это уже непрактично. Поэтому мы используем автоматизацию на основе утилиты Keycloak-config- cli, которая позволяет гарантированно загрузить файл REALM в Keycloak. Мы включаем эту утилиту вместе с файлом конфигурации REALM в задачу Kubernetes, запускаем её и дожидаемся успешного завершения операции KeyCloak. Keycloak не хранит пароли пользователей в открытом виде, а хэширует их в своей БД с помощью функции формирования ключа pbkdf2-sha256. Поэтому для изменения пароля администратора и обеспечения его соответствия глобальному паролю администратора продукта, в момент смены пароля администратора через установщик продукта запускается разработанный нами скрипт смены пароля с помощью Job в Kubernetes. Этот скрипт вычисляет значение функции формирования ключа pbkdf2-sha256 для нового пароля администратора, и загружает его значение в базу keycloak. Но обратите внимание, чтобы успешно реализовать это, необходимо знать алгоритм хэширования и предварительно сгенерировать соответствующий хэш. В противном случае, если не удастся выполнить эти действия, потребуется полная переустановка Keycloak с нуля.  pwd_hash = hashlib.pbkdf2_hmac('sha256', sys.argv[1], b'mysalt', 180000)  print('update credential set secret_data=\'{"salt": "bОlzYАx0", "value": "' + b64encode(pwd_hash) + '"}\', credential_data=\'{"hashIterations": 180000, "algorithm": "pbkdf2-sha256"}\' where user_id = (select id from user_entity where realm_id=(select id from realm where name=\'master\') and username=\'admin\')');  Здесь формируется значение хэша и запрос в БД для выполнения UPDATE с новым значением. PBKDF2-sha256 (Password-Based Key Derivation Function 2 with SHA-256) — это алгоритм, используемый для создания ключей на основе пароля. Он является стандартом, определённым в документе PKCS#5 (Public-Key Cryptography Standards).  PBKDF2-sha256 использует SHA-256 (Secure Hash Algorithm 256) в качестве функции хеширования. Он работает путем применения SHA-256 многократно к исходному паролю с использованием случайного значения, называемого «солью». Это обеспечивает устойчивость к атакам на словарь и предотвращает возможность использования «рэйнбоу-таблиц» (таблиц, содержащих уже рассчитанные хэши паролей), чтобы быстро получить исходный пароль.  PBKDF2-sha256 также имеет параметры, определяющие количество итераций, которые должны быть выполнены при производстве ключей, и длину производимого ключа. Чем больше итераций, тем безопаснее ключ, но тем дольше время производства ключа. Использование PBKDF2-sha256 рекомендуется для хранения паролей в зашифрованном виде в базах данных и других местах, где пароли должны быть сохранены в безопасном виде.  В итоге использование Keycloak в нашей инфраструктуре предоставляет нам гибкость и надёжность в управлении аутентификацией и авторизацией пользователей. Несмотря на некоторые нюансы, связанные с настройкой и изменениями в Keycloak, мы разработали описанные выше варианты решения, которые помогают нам интегрировать и управлять Keycloak в рамках наших продуктов и систем. Надеемся, что наш опыт окажется полезным и другим DevOps-инженерам.  На текущий момент мы разработали, протестировали и предлагаем всем нашим клиентам интеграцию SberJazz с встроенным KeyCloak. Причем пользователь может даже не знать, что внутри у приложения и системы, т.к. мы максимально упростили для него этот процесс. Вообще при работе с KeyCloak есть много интересных нюансов, помимо тех, что я затронул в этой статье. В других материалах планирую рассказать, например, как сделать отказоустойчивый сетап в Kubernetes из нескольких реплик и другие особенности разработки для высоконагруженных корпоративных систем. Как видите, KeyCloak позволяет нам быть гибкими и даже если где-то есть ограничения, с ними можно справиться и оптимизировать продукт так, чтобы он был максимально удобным, простым и выгодным для бизнеса.  Ещё больше про разработку мы рассказывали на нашем майском митапе, где обсудили принципы DevOPS-культуры, использование Terraform и Terragrunt, демонстрировали разворачивание on-prem SberJazz с нуля. Ну и просто очень лампово потусили. Посмотреть как это было, а также послушать доклады спикеров можно тут.