Deckhouse — Kubernetes-платформа с открытым кодом, с помощью которой можно создавать идентичные Kubernetes-кластеры в любой инфраструктуре и автоматически управлять ими. Для проверки подлинности в Deckhouse используется модуль user-authn. Он настраивает единую систему аутентификации, интегрированную с Kubernetes и веб-интерфейсами других модулей — например, с Grafana.
user-authn поддерживает несколько внешних провайдеров и протоколов аутентификации: GitHub, GitLab, Bitbucket Cloud, Crowd, LDAP и OIDC. В статье расскажу, как развернуть сервер LDAP и настроить через него доступ к приложению.
![](https://habrastorage.org/getpro/habr/upload_files/3ee/be9/8df/3eebe98df5289896b4dad1571e50c67a.png)
Подготовка
Нам потребуется кластер Kubernetes с установленной платформой Deckhouse. Кластер можно развернуть в облаке или локально (на kind). Установка занимает от 15 до 30 минут.
В конфигурации Deckhouse в параметре publicDomainTemplate должен быть корректный шаблон DNS-имен, который указывает на IP-адреса Ingress-контроллеров кластера. Также можно воспользоваться сервисом типа sslip.io; в этом случае в publicDomainTemplate достаточно будет указать шаблон %s.x.x.x.x.sslip.io
, где x.x.x.x
— ваш IP-адрес.
В командах и шаблонах, которые приводятся в статье, будет задействовано пространство имен openldap-demo
. При необходимости его можно изменить.
Настройка LDAP-сервера
Развернем LDAP-сервер:
kubectl create -f https://raw.githubusercontent.com/flant/examples/master/2022/11-d8-user-authn/ldap.yaml
Прежде чем продолжить, убедимся, что Pod сервера запустился, то есть в статусе Running
:
# kubectl -n openldap-demo get pod
NAME READY STATUS RESTARTS AGE
ldap-6c949b6c6d-4zxg7 1/1 Running 0 1m
В конфигурации развернутого LDAP-сервера есть два пользователя:
johndoe@example.com
(парольbar
) — входит в группуadmins
;janedoe@example.com
(парольfoo
) — входит в группыadmins
иdevelopers
.
Далее, для примера, предоставим доступ пользователю janedoe@example.com
из группы developers
.
Создадим в кластере ресурс DexProvider, который «подключит» созданный LDAP-сервер и будет использоваться при аутентификации:
kubectl create -f https://raw.githubusercontent.com/flant/examples/master/2022/11-d8-user-authn/dex-provider.yaml
Настройка веб-приложения
Развернем в качестве приложения простой echo-server, который выводит на страницу информацию об HTTP-запросе.
Выполним команду, указав в переменной DOMAINNAME
используемый вами домен:
DOMAINNAME=<ВАШ_ДОМЕН>
curl https://raw.githubusercontent.com/flant/examples/master/2022/11-d8-user-authn/echo-service.yaml | sed "s/{{ __cluster__domain__ }}/${DOMAINNAME}/" | kubectl create -f -
Приложение будет развернуто в пространстве имен openldap-demo
. Ingress-ресурс приложения будет настроен на поддомен echo
.
Проверим, что Pod echoserver
запустился:
# kubectl -n openldap-demo get pod
NAME READY STATUS RESTARTS AGE
echoserver-6944fb9c86-9flgh 1/1 Running 0 1m
ldap-6c949b6c6d-4zxg7 1/1 Running 0 3m
Откроем браузер и убедимся, что приложение доступно по адресу echo.<ВАШ_ДОМЕН>
без авторизации.
Настройка аутентификации
Приступим к самому интересному: закроем доступ к приложению.
Чтобы включить аутентификацию, нужно:
создать ресурс DexAuthenticator для развертывания OAuth2 Proxy;
включить аутентификацию через развернутый экземпляр OAuth2 Proxy в Ingress-ресурсе приложения.
OAuth2 Proxy будет принимать запросы на аутентификацию от nginx и выполнять аутентификацию в LDAP.
Создадим ресурс DexAuthenticator, указав в переменной DOMAINNAME
используемый вами домен:
DOMAINNAME=<ВАШ_ДОМЕН>
curl https://raw.githubusercontent.com/flant/examples/master/2022/11-d8-user-authn/dex-authenticator.yaml | sed "s/{{ __cluster__domain__ }}/${DOMAINNAME}/" | kubectl create -f -
Убедимся, что в пространстве имен openldap-demo
появился и запустился Pod echoserver-dex-authenticator
:
# kubectl -n openldap-demo get pod
NAME READY STATUS RESTARTS AGE
echoserver-6944fb9c86-9flgh 1/1 Running 0 5m
echoserver-dex-authenticator-6bdd57cc95-wvbgk 2/2 Running 1 2m
ldap-6c949b6c6d-4zxg7 1/1 Running 0 8m
Посмотрим на ресурс DexAuthenticator. Обратите внимание на параметр spec.allowedGroups: он содержит список групп, которым будет разрешен доступ к приложению. В нашем случае это группа developers
, в которую входит пользователь janedoe@example.com
:
# kubectl -n openldap-demo get dexauthenticator echoserver -o yaml
apiVersion: deckhouse.io/v1
kind: DexAuthenticator
...
spec:
allowedGroups:
- developers
...
Теперь настроим Ingess-контроллер так, чтобы он использовал OAuth2 Proxy.
Укажем две аннотации на Ingress-ресурсе приложения, выполнив команды:
kubectl -n openldap-demo annotate ingress echoserver 'nginx.ingress.kubernetes.io/auth-signin=https://$host/dex-authenticator/sign_in'
kubectl -n openldap-demo annotate ingress echoserver 'nginx.ingress.kubernetes.io/auth-url=https://echoserver-dex-authenticator.openldap-demo.svc.cluster.local/dex-authenticator/auth'
Обновим страницу приложения в браузере — сработает переадресация на страницу входа:
![](https://habrastorage.org/getpro/habr/upload_files/be5/e3c/463/be5e3c4635b930e6987bfa508b542ed8.png)
Выберем способ входа через LDAP-сервер: Log in with OpenLDAP Demo. Войдем под пользователем janedoe@example.com
(пароль в LDAP: foo
).
Проверим, что все работает как нужно. Откроем браузер в безопасном режиме и попробуем войти под другим пользователем — johndoe@example.com
(пароль в LDAP: bar
). Получим ошибку User not in allowed groups
, так как пользователь johndoe
не состоит в группе developers
.
Вы можете добавить несколько провайдеров аутентификации, создав несколько ресурсов DexProvider. В этом случае при входе в приложение выбирайте нужного провайдера из списка.
Также можно создать статического пользователя, то есть учетную запись, все данные которой хранятся в кластере Kubernetes. Об этом — дальше.
Добавление статического пользователя
Для аутентификации статического пользователя внешние провайдеры аутентификации не используются. Нужно создать custom resource User.
Создадим пользователя openldap-demo@example.com
, который состоит в группе developers
, с паролем bar
и временем жизни учетной записи — 24 часа:
kubectl create -f - <<"EOF"
apiVersion: deckhouse.io/v1
kind: User
metadata:
name: openldap-demo
spec:
email: openldap-demo@example.com
# echo "bar" | htpasswd -BinC 10 "" | cut -d: -f2
password: '$2a$10$spCnoGzDIRicDfiTmtImwu7sn2Csjj6oWRoLjNs6N/bV3WDsxioui'
groups:
- developers
ttl: 24h
EOF
Обратите внимание: в комментарии к полю
password
приведены команды генерации пароля. Они пригодятся, если вы хотите использовать другой пароль.
После того, как пользователь создан, в приложение можно войти, выбрав Log in with Email.
Более подробную информацию о настройке аутентификации в кластере можно найти в описании модуля user-authn. Также в документации есть готовые примеры использования модуля.
Убираем за собой
Для удаления созданных выше ресурсов выполним:
kubectl delete dexprovider openldap-demo
kubectl delete user openldap-demo
kubectl delete ns openldap-demo
P.S.
Читайте также в нашем блоге: