Artykuł ten został napisany w celu rozszerzenia istniejącej , ale opisuje szczegóły integracji z Microsoft Active Directory oraz ją uzupełnia.
W tym artykule opowiem, jak zainstalować i skonfigurować:
- Keycloak — to projekt o otwartym kodzie źródłowym, który zapewnia jednolity punkt wejścia dla aplikacji. Działa z wieloma protokołami, w tym z LDAP i OpenID, które nas interesują.
- Keycloak gatekeeper — to aplikacja działająca jako reverse proxy, umożliwiająca integrację autoryzacji przez Keycloak.
- Gangway — aplikacja, która generuje konfigurację dla kubectl, dzięki której można się autoryzować przez OpenID i podłączyć do API Kubernetes.
Jak działają uprawnienia w Kubernetes.
Zarządzać uprawnieniami użytkowników/grup możemy za pomocą RBAC; na ten temat istnieje już wiele artykułów, więc nie będę się na tym szczegółowo skupiać. Problem polega na tym, że możemy użyć RBAC do ograniczania uprawnień użytkowników, ale Kubernetes nic nie wie o użytkownikach. W związku z tym potrzebny jest mechanizm dostarczania informacji o użytkownikach do Kubernetes. W tym celu dodamy do Kubernetes dostawcę OpenID, który potwierdzi, że dany użytkownik rzeczywiście istnieje, a uprawnienia przyzna sam Kubernetes.
Przygotowanie
- Będziesz potrzebować klastra Kubernetes lub minikube
- Active Directory
- Domeny:
keycloak.example.org
kubernetes-dashboard.example.org
gangway.example.org - Certyfikat dla domen lub certyfikat samopodpisany
Nie będę szczegółowo omawiać, jak tworzyć certyfikaty samopodpisane; należy stworzyć 2 certyfikaty: główny (Centrum Certyfikacji) oraz wildcard dla domeny *.example.org.
Po uzyskaniu/wypisaniu certyfikatów, certyfikat klienta należy dodać do Kubernetes; w tym celu tworzymy jego secret:
kubectl create secret tls tls-keycloak --cert=example.org.crt --key=example.org.pemNastępnie będziemy go używać dla naszego kontrolera Ingress.
Instalacja Keycloak
Postanowiłem, że najłatwiej będzie wykorzystać gotowe rozwiązania, a dokładniej helm chart-y.
Dodajemy repozytorium i aktualizujemy je:
helm repo add codecentric https://codecentric.github.io/helm-charts
helm repo updateTworzymy plik keycloak.yml z następującą zawartością:
keycloak.yml
keycloak:
# Nazwa administratora
username: "test_admin"
# Hasło administratora
password: "admin"
# Te flagi są potrzebne, aby umożliwić ładowanie skryptów do Keycloak bezpośrednio przez interfejs webowy. Będzie to
potrzebne, aby naprawić pewien błąd, o którym mowa poniżej.
extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled"
# Włączamy ingress, podajemy nazwę hosta i certyfikat, który wcześniej zapisaliśmy w secrets
ingress:
enabled: true
path: \/
annotations:
kubernetes.io\/ingress.class: nginx
ingress.kubernetes.io\/affinity: cookie
hosts:
- keycloak.example.org
tls:
- hosts:
- keycloak.example.org
secretName: tls-keycloak
# Keycloak wymaga bazy danych do swojej pracy, w celach testowych uruchamiam Postgresql bezpośrednio w Kubernets, w produkcji lepiej tego nie robić!
persistence:
deployPostgres: true
dbVendor: postgres
postgresql:
postgresUser: keycloak
postgresPassword: ""
postgresDatabase: keycloak
persistence:
enabled: trueKonfigurowanie federacji
Następnie logujemy się do interfejsu webowego
W lewym rogu klikamy Dodaj realm
Klucz
@Value
Nazwa
kubernetes
Nazwa wyświetlana
Kubernetes
Wyłączamy weryfikację potwierdzenia e-maila użytkownika:
Client scopes —> Email —> Mappers —> Email verified (Usuń)
Konfigurujemy federację do importu użytkowników z Active Directory, poniżej umieszczę zrzuty ekranu, myślę że tak będzie jaśniej.
User federation —> Dodaj dostawcę… —> ldap
Konfigurowanie federacji

Jeśli wszystko pójdzie dobrze, po naciśnięciu przycisku Synchronizuj wszystkich użytkowników zobaczysz komunikat o pomyślnym imporcie użytkowników.
Następnie musimy zamapować nasze grupy
User federation —> ldap_localhost —> Mappers —> Utwórz
Tworzenie mappera
Konfiguracja klienta
Musimy stworzyć klienta, w pojęciu Keycloak to aplikacja, która będzie się w nim autoryzować. Ważne punkty zaznaczę na zrzucie ekranu na czerwono.
Klienci —> Utwórz
Konfiguracja klienta
Stworzymy scoupe dla grup:
Client Scopes —> Utwórz
Tworzenie scoupe
I skonfigurujemy mapper dla nich:
Client Scopes —> groups —> Mappers —> Utwórz
Mapper
Dodajemy mapowanie naszych grup w Default Client Scopes:
Klienci —> kubernetes —> Client Scopes —> Default Client Scopes
Wybieramy groups do Dostępne zakresy klienta, klikamy Dodaj wybrane
Zyskujemy secret (i zapisujemy go gdzieś), który będziemy używać do autoryzacji w Keycloak:
Klienci —> kubernetes —> Credentials —> Secret
Na tym konfiguracja się kończy, ale napotkałem błąd, gdy po pomyślnej autoryzacji otrzymywałem błąd 403. .
Poprawka:
Client Scopes —> roles —> Mappers —> Utwórz
Mapper
Kod skryptu
// add current client-id to token audience
token.addAudience(token.getIssuedFor());
// return token issuer as dummy result assigned to iss again
token.getIssuer();
Konfiguracja Kubernetes
Musimy określić, gdzie znajduje się nasz certyfikat główny od witryny, i gdzie znajduje się dostawca OIDC.
W tym celu edytujemy plik \/etc\/kubernetes\/manifests\/kube-apiserver.yaml
kube-apiserver.yaml
...
spec:
containers:
- command:
- kube-apiserver
...
- --oidc-ca-file=/var/lib/minikube/certs/My_Root.crt
- --oidc-client-id=kubernetes
- --oidc-groups-claim=groups
- --oidc-issuer-url=https://keycloak.example.org/auth/realms/kubernetes
- --oidc-username-claim=email
...
Aktualizujemy konfigurację kubeadm w klastrze:
kubeadm config
kubectl edit -n kube-system configmaps kubeadm-config
...
data:
ClusterConfiguration: |
apiServer:
extraArgs:
oidc-ca-file: /var/lib/minikube/certs/My_Root.crt
oidc-client-id: kubernetes
oidc-groups-claim: groups
oidc-issuer-url: https://keycloak.example.org/auth/realms/kubernetes
oidc-username-claim: email
...
Konfiguracja auth-proxy
Aby zabezpieczyć swoją aplikację internetową, można użyć Keycloak Gatekeeper. Oprócz tego, że ten serwer proxy będzie autoryzował użytkownika przed pokazaniem strony, przekazuje również aplikacji końcowej informacje o użytkowniku w nagłówkach. Dzięki temu, jeśli twoja aplikacja obsługuje OpenID, użytkownik jest natychmiast autoryzowany. Przyjrzyjmy się temu na przykładzie Kubernetes Dashboard.
Instalacja Kubernetes Dashboard
helm install stable/kubernetes-dashboard --name dashboard -f values_dashboard.yaml
values_dashboard.yaml
enableInsecureLogin: true
service:
externalPort: 80
rbac:
clusterAdminRole: true
create: true
serviceAccount:
create: true
name: 'dashboard-test'
Konfiguracja uprawnień:
Stwórzmy ClusterRoleBinding, który nada uprawnienia administratora klastra (standardowa ClusterRole cluster-admin) dla użytkowników należących do grupy DataOPS.
kubectl apply -f rbac.yaml
rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dataops_group
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: DataOPS
Instalacja keycloak gatekeeper:
helm repo add gabibbo97 https://gabibbo97.github.io/charts/
helm repo update
helm install gabibbo97/keycloak-gatekeeper --version 2.1.0 --name keycloak-gatekeeper -f values_proxy.yaml
values_proxy.yaml
# Включаем ingress
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
path: /
hosts:
- kubernetes-dashboard.example.org
tls:
- secretName: tls-keycloak
hosts:
- kubernetes-dashboard.example.org
# Говорим где мы будем авторизовываться у OIDC провайдера
discoveryURL: "https://keycloak.example.org/auth/realms/kubernetes"
# Имя клиента которого мы создали в Keycloak
ClientID: "kubernetes"
# Secret который я просил записать
ClientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
# Куда перенаправить в случае успешной авторизации. Формат <SCHEMA>://<SERVICE_NAME>.><NAMESAPCE>.<CLUSTER_NAME>
upstreamURL: "http://dashboard-kubernetes-dashboard.default.svc.cluster.local"
# Пропускаем проверку сертификата, если у нас самоподписанный
skipOpenidProviderTlsVerify: true
# Настройка прав доступа, пускаем на все path если мы в группе DataOPS
rules:
- "uri=/*|groups=DataOPS"
Po tym, gdy spróbujesz wejść na , nastąpi przekierowanie do Keycloak, a po pomyślnej autoryzacji trafić w Dashboard jako zalogowany.
Instalacja gangway
Dla wygody można dodać gangway, który generuje plik konfiguracyjny dla kubectl, dzięki któremu jako nasz użytkownik wejdziemy do Kubernetes.
helm install --name gangway stable/gangway -f values_gangway.yaml
values_gangway.yaml
gangway:
# Dowolna nazwa klastra
clusterName: "my-k8s"
# Gdzie znajduje się nasz dostawca OIDC
authorizeURL: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/auth"
tokenURL: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/token"
audience: "https://keycloak.example.org/auth/realms/kubernetes/protocol/openid-connect/userinfo"
# Teoretycznie można tutaj dodać grupy, które zmapowaliśmy
scopes: ["openid", "profile", "email", "offline_access"]
redirectURL: "https://gangway.example.org/callback"
# Nazwa klienta
clientID: "kubernetes"
# Sekret
clientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
# Jeśli zostawimy domyślną wartość, to jako nazwę użytkownika weźmie "sub" <b>Imię</b> <b>Nazwisko</b>, a przy "sub" jego login
usernameClaim: "sub"
# Nazwa domeny lub adres IP serwera API
apiServerURL: "https://192.168.99.111:8443"
# Włączamy Ingress
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-buffer-size: "64k"
path: /
hosts:
- gangway.example.org
tls:
- secretName: tls-keycloak
hosts:
- gangway.example.org
# Jeśli używamy certyfikatu samopodpisanego, to należy podać jego (publiczny certyfikat) korzenia.
trustedCACert: |-
-----BEGIN CERTIFICATE-----
MIIDVzCCAj+gAwIBAgIBATANBgkqhkiG9w0BAQsFADA1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRGF0YU9QUzEUMBIGA1UEAxMLbXkgcm9vdCBrZXkwHhcNMjAwMjE0MDkxODAwWhcNMzAwMjE0MDkxODAwWjA1MQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRGF0YU9QUzEUMBIGA1UEAxMLbXkgcm9vdCBrZXkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDyP749PqqIRwNSqaK6qr0Zsi03G4PTCUlgaYTPZuMrwUVPK8xX2dWWs9MPRMOdXpgr8aSTZnVfmelIlVz4D7o2vK5rfmAe9GPcK0WbwKwXyhFU0flS9sU/g46ogHFrk03SZxQAeJhMLfEmAJm8LF5HghtGDs3t4uwGsB95o+lqPLiBvxRB8ZS3jSpYpvPgXAuZWKdZUQ3UUZf0X3hGLp7uIcIwJ7i4MduOGaQEO4cePeEJy9aDAO6qV78YmHbyh9kaW+1DL/Sgq8NmTgHGV6UOnAPKHTnMKXl6KkyUz8uLBGIdVhPxrlzG1EzXresJbJenSZ+FZqm3oLqZbw54Yp5hAgMBAAGjcjBwMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHISTOU/6BQqqnOZj+1xJfxpjiG0MAsGA1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAAcwHgYJYIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAQEAj7HC8ObibwOLT4ZYmISJZwub9lcE0AZ5cWkPW39j/syhdbbqjK/6jy2D3WUEbR+s1Vson5Ov7JhN5In2yfZ/ByDvBnoj7CP8Q/ZMjTJgwN7j0rgmEb3CTZvnDPAz8Ijw3FP0cjxfoZ1Z0V2F44Ry7gtLJWr06+MztXVyto3aIz1/XbMQnXYlzc3c3B5yUQIy44Ce5aLRVsAjmXNqVRmDJ2QPNLicvrhnUJsO0zFWI+zZ2hc4Ge1RotCrjfOc9hQY63jZJ17myCZ6QCD7yzMzAob4vrgmkD4q7tpGrhPY/gDcE+lUNhC7DO3l0oPy2wsnT2TEn87eyWmDiTFG9zWDew==
-----END CERTIFICATE-----
Wygląda to mniej więcej tak. Pozwala od razu pobrać plik konfiguracyjny oraz wygenerować go z zestawem poleceń:

Źródło: habr.com
