> For the complete documentation index, see [llms.txt](https://book.konstantinsecurity.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.konstantinsecurity.com/readme/architect/kubernetes/frameworks/deckhouse/ldap-authentification.md).

# LDAP authentification

<https://habr.com/ru/companies/flant/articles/710010/>

[Deckhouse](https://deckhouse.ru/) — Kubernetes-платформа с открытым кодом, с помощью которой можно создавать идентичные Kubernetes-кластеры в любой инфраструктуре и автоматически управлять ими. Для проверки подлинности в Deckhouse используется модуль [user-authn](https://deckhouse.ru/documentation/v1/modules/150-user-authn/). Он настраивает единую систему аутентификации, интегрированную с Kubernetes и веб-интерфейсами других модулей — например, с Grafana.

user-authn поддерживает несколько внешних провайдеров и протоколов аутентификации: GitHub, GitLab, Bitbucket Cloud, Crowd, LDAP и OIDC. В статье расскажу, как развернуть сервер LDAP и настроить через него доступ к приложению.

![](/files/53mOBwCON4V8PYtVrNpv)

## Подготовка

Нам потребуется кластер Kubernetes с установленной платформой Deckhouse. Кластер [можно развернуть](https://deckhouse.ru/gs/) в облаке или локально (на kind). Установка занимает от 15 до 30 минут.

[В конфигурации](https://deckhouse.ru/documentation/v1/deckhouse-configure-global.html) Deckhouse в параметре [publicDomainTemplate](https://deckhouse.ru/documentation/v1/deckhouse-configure-global.html#parameters-modules-publicdomaintemplate) должен быть корректный шаблон DNS-имен, который указывает на IP-адреса Ingress-контроллеров кластера. Также можно воспользоваться сервисом типа [sslip.io](https://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.<ВАШ_ДОМЕН>` без авторизации.

## Настройка аутентификации

Приступим к самому интересному: закроем доступ к приложению.

Чтобы включить аутентификацию, нужно:

* включить аутентификацию через развернутый экземпляр 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](https://deckhouse.ru/documentation/v1/modules/150-user-authn/cr.html#dexauthenticator-v1-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'
```

Обновим страницу приложения в браузере — сработает переадресация на страницу входа:

![](/files/LrUMap4DrwtYHzoC5I6j)

Выберем способ входа через 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](https://deckhouse.ru/documentation/v1/modules/150-user-authn/cr.html#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](https://deckhouse.ru/documentation/v1/modules/150-user-authn/). Также в документации есть [готовые примеры](https://deckhouse.ru/documentation/v1/modules/150-user-authn/usage.html) использования модуля.

## Убираем за собой

Для удаления созданных выше ресурсов выполним:

```
kubectl delete dexprovider openldap-demo
kubectl delete user openldap-demo
kubectl delete ns openldap-demo
```
