Как защитить мое приложение?
Чтобы включить аутентификацию через Dex для приложения, выполните следующие шаги:
-
Создайте custom resource DexAuthenticator.
Создание
DexAuthenticator
в кластере приводит к созданию экземпляра oauth2-proxy, подключенного к Dex. После появления custom resourceDexAuthenticator
в указанном namespace появятся необходимые объекты Deployment, Service, Ingress, Secret.Пример custom resource
DexAuthenticator
:1apiVersion: deckhouse.io/v1 2kind: DexAuthenticator 3metadata: 4 # Префикс имени подов Dex authenticator. 5 # Например, если префикс имени `app-name`, то поды Dex authenticator будут вида `app-name-dex-authenticator-7f698684c8-c5cjg`. 6 name: app-name 7 # Namespace, в котором будет развернут Dex authenticator. 8 namespace: app-ns 9spec: 10 # Домен вашего приложения. Запросы на него будут перенаправляться для прохождения аутентификацию в Dex. 11 applicationDomain: "app-name.kube.my-domain.com" 12 # Отправлять ли `Authorization: Bearer` header приложению. Полезно в связке с auth_request в NGINX. 13 sendAuthorizationHeader: false 14 # Имя Secret'а с SSL-сертификатом. 15 applicationIngressCertificateSecretName: "ingress-tls" 16 # Название Ingress-класса, которое будет использоваться в создаваемом для Dex authenticator Ingress-ресурсе. 17 applicationIngressClassName: "nginx" 18 # Время, на протяжении которого пользовательская сессия будет считаться активной. 19 keepUsersLoggedInFor: "720h" 20 # Список групп, пользователям которых разрешено проходить аутентификацию. 21 allowedGroups: 22 - everyone 23 - admins 24 # Список адресов и сетей, с которых разрешено проходить аутентификацию. 25 whitelistSourceRanges: 26 - 1.1.1.1/32 27 - 192.168.0.0/24
-
Подключите приложение к Dex.
Для этого добавьте в Ingress-ресурс приложения следующие аннотации:
nginx.ingress.kubernetes.io/auth-signin: https://$host/dex-authenticator/sign_in
nginx.ingress.kubernetes.io/auth-response-headers: X-Auth-Request-User,X-Auth-Request-Email
nginx.ingress.kubernetes.io/auth-url: https://<NAME>-dex-authenticator.<NS>.svc.{{ C_DOMAIN }}/dex-authenticator/auth
, где:NAME
— значение параметраmetadata.name
ресурсаDexAuthenticator
;NS
— значение параметраmetadata.namespace
ресурсаDexAuthenticator
;C_DOMAIN
— домен кластера (параметр clusterDomain ресурсаClusterConfiguration
).
Ниже представлен пример аннотаций на Ingress-ресурсе приложения, для подключения его к Dex:
1annotations: 2 nginx.ingress.kubernetes.io/auth-signin: https://$host/dex-authenticator/sign_in 3 nginx.ingress.kubernetes.io/auth-url: https://app-name-dex-authenticator.app-ns.svc.cluster.local/dex-authenticator/auth 4 nginx.ingress.kubernetes.io/auth-response-headers: X-Auth-Request-User,X-Auth-Request-Email
Настройка ограничений на основе CIDR
В DexAuthenticator нет встроенной системы управления разрешением аутентификации на основе IP-адреса пользователя. Вместо этого вы можете воспользоваться аннотациями для Ingress-ресурсов:
-
Если нужно ограничить доступ по IP и оставить прохождение аутентификации в Dex, добавьте аннотацию с указанием разрешенных CIDR через запятую:
1nginx.ingress.kubernetes.io/whitelist-source-range: 192.168.0.0/32,1.1.1.1
-
Если необходимо, чтобы пользователи из указанных сетей освобождались от прохождения аутентификации в Dex, а пользователи из остальных сетей обязательно аутентифицировались в Dex, добавьте следующую аннотацию:
1nginx.ingress.kubernetes.io/satisfy: "any"
Как работает аутентификация с помощью DexAuthenticator
-
Dex в большинстве случаев перенаправляет пользователя на страницу входа провайдера и ожидает, что пользователь будет перенаправлен на его
/callback
URL. Однако такие провайдеры, как LDAP или Atlassian Crowd, не поддерживают этот вариант. Вместо этого пользователь должен ввести свои логин и пароль в форму входа в Dex, и Dex сам проверит их верность, сделав запрос к API провайдера. -
DexAuthenticator устанавливает cookie с целым refresh token (вместо того чтобы выдать тикет, как для ID token) потому что Redis не сохраняет данные на диск. Если по тикету в Redis не найден ID token, пользователь сможет запросить новый ID token, предоставив refresh token из cookie.
-
DexAuthenticator выставляет HTTP-заголовок
Authorization
, равный значению ID token из Redis. Это необязательно для сервисов по типу Upmeter, потому что права доступа к Upmeter не такие проработанные. С другой стороны, для Kubernetes Dashboard это критичный функционал, потому что она отправляет ID token дальше для доступа к Kubernetes API.
Как сгенерировать kubeconfig для доступа к Kubernetes API?
Сгенерировать kubeconfig
для удаленного доступа к кластеру через kubectl
можно через веб-интерфейс kubeconfigurator
.
Настройте параметр publishAPI:
-
Откройте настройки модуля
user-authn
(создайте ресурс moduleConfiguser-authn
, если его нет):1kubectl edit mc user-authn
-
Добавьте следующую секцию в блок
settings
и сохраните изменения:1publishAPI: 2 enabled: true
Для доступа к веб-интерфейсу, позволяющему сгенерировать kubeconfig
, зарезервировано имя kubeconfig
. URL для доступа зависит от значения параметра publicDomainTemplate (например, для publicDomainTemplate: %s.kube.my
это будет kubeconfig.kube.my
, а для publicDomainTemplate: %s-kube.company.my
— kubeconfig-kube.company.my
)
Настройка kube-apiserver
С помощью функций модуля control-plane-manager Deckhouse автоматически настраивает kube-apiserver, выставляя следующие флаги так, чтобы модули dashboard
и kubeconfig-generator
могли работать в кластере.
Как работает подключение к Kubernetes API с помощью сгенерированного kubeconfig
-
До начала работы kube-apiserver необходимо запросить конфигурационный endpoint OIDC провайдера (в нашем случае — Dex), чтобы получить issuer и настройки JWKS endpoint.
-
Kubeconfig generator сохраняет ID token и refresh token в файл kubeconfig.
-
После получения запроса с ID token kube-apiserver идет проверять, что token подписан провайдером, который мы настроили на первом шаге, с помощью ключей, полученных с точки доступа JWKS. В качестве следующего шага он сравнивает значения claim’ов
iss
иaud
из token’а со значениями из конфигурации.
Как Dex защищен от подбора логина и пароля?
Одному пользователю разрешено только 20 попыток входа. Если указанный лимит израсходован, одна дополнительная попытка будет добавляться каждые 6 секунд.