Fixamos a autorização do ActiveDirectory ao Kubernetes usando o Keycloak

Este artigo foi escrito para expandir o já o existente, mas fala sobre os recursos do pacote com o Microsoft ActiveDirectory e também o complementa.

Neste artigo, vou dizer-lhe como instalar e configurar:

  • Manto-chave é um projeto de código aberto. O que fornece um único ponto de entrada para aplicativos. Funciona com uma variedade de protocolos, incluindo LDAP e OpenID nos quais estamos interessados.
  • porteiro keycloak - aplicativo de proxy reverso que permite integrar a autorização através do Keycloak.
  • Passadiço - um aplicativo que gera uma configuração para kubectl com a qual você pode fazer login e conectar-se à API do Kubernetes por meio do OpenID.

Como as permissões funcionam no Kubernetes.

Podemos gerenciar direitos de usuário / grupo usando RBAC, vários artigos já foram criados sobre isso, não vou me alongar sobre isso em detalhes. O problema é que você pode usar o RBAC para restringir os direitos do usuário, mas o Kubernetes não sabe nada sobre os usuários. Acontece que precisamos de um mecanismo de entrega de usuário no Kubernetes. Para fazer isso, adicionaremos um provedor ao Kuberntes OpenID, que dirá que tal usuário realmente existe, e o próprio Kubernetes lhe dará os direitos.

Treinamento

  • Você precisará de um cluster Kubernetes ou minikube
  • Active Directory
  • Domínios:
    keycloak.exemplo.org
    kubernetes-dashboard.example.org
    gangway.exemplo.org
  • Certificado para domínios ou certificado autoassinado

Não vou me alongar sobre como criar um certificado autoassinado, você precisa criar 2 certificados, esta é a raiz (autoridade de certificação) e o cliente curinga para o domínio *.example.org

Após receber/emitir certificados, o cliente deve ser adicionado ao Kubernetes, para isso criamos um secret para ele:

kubectl create secret tls tls-keycloak --cert=example.org.crt --key=example.org.pem

Em seguida, vamos usá-lo para nosso controlador Ingress.

Instalação do Keycloak

Decidi que a maneira mais fácil é usar soluções prontas para isso, ou seja, gráficos de leme.

Instale o repositório e atualize-o:

helm repo add codecentric https://codecentric.github.io/helm-charts
helm repo update

Crie um arquivo keycloak.yml com o seguinte conteúdo:

keycloak.yml

keycloak:
  # Имя администратора
  username: "test_admin"
  # Пароль администратор  
  password: "admin"
  # Эти флаги нужны что бы позволить загружать в Keycloak скрипты прямо через web морду. Это нам 
  понадобиться что бы починить один баг, о котором ниже.
  extraArgs: "-Dkeycloak.profile.feature.script=enabled -Dkeycloak.profile.feature.upload_scripts=enabled" 
  # Включаем ingress, указываем имя хоста и сертификат который мы предварительно сохранили в 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 для своей работы требует базу данных, в тестовых целях я разворачиваю Postgresql прямо в Kuberntes, в продакшене так лучше не делать!
  persistence:
    deployPostgres: true
    dbVendor: postgres

postgresql:
  postgresUser: keycloak
  postgresPassword: ""
  postgresDatabase: keycloak
  persistence:
    enabled: true

Configuração da federação

Em seguida, vá para a interface da web keycloak.exemplo.org

Clique no canto esquerdo Adicionar reino

Chave
Valor

Nome
kubernetes

Nome visível
Kubernetes

Desative a verificação de e-mail do usuário:
Escopos do cliente —> E-mail —> Mapeadores —> E-mail verificado (Excluir)

Montamos federação para importar usuários do ActiveDirectory, vou deixar screenshots abaixo, acho que vai ficar mais claro.

Federação de usuários —> Adicionar provedor… —> ldap

Configuração da federaçãoFixamos a autorização do ActiveDirectory ao Kubernetes usando o Keycloak
Fixamos a autorização do ActiveDirectory ao Kubernetes usando o Keycloak

Se tudo estiver bem, depois de pressionar o botão Sincronizar todos os usuários você verá uma mensagem sobre a importação bem-sucedida de usuários.

Em seguida, precisamos mapear nossos grupos

Federação de usuários --> ldap_localhost --> Mapeadores --> Criar

Criando um mapeadorFixamos a autorização do ActiveDirectory ao Kubernetes usando o Keycloak

Configuração do cliente

É necessário criar um cliente, em termos de Keycloak, este é um aplicativo que será autorizado por ele. Vou destacar os pontos importantes na captura de tela em vermelho.

Clientes —> Criar

Configuração do clienteFixamos a autorização do ActiveDirectory ao Kubernetes usando o Keycloak

Vamos criar scoupe para grupos:

Escopos do Cliente —> Criar

Criar escopoFixamos a autorização do ActiveDirectory ao Kubernetes usando o Keycloak

E configure um mapeador para eles:

Escopos do cliente —> grupos —> Mapeadores —> Criar

mapeadorFixamos a autorização do ActiveDirectory ao Kubernetes usando o Keycloak

Adicione o mapeamento de nossos grupos aos escopos de cliente padrão:

Clientes —> kubernetes —> Escopos do cliente —> Escopos do cliente padrão
selecionar grupos в Escopos de cliente disponíveisempurrar Adicionar selecionado

Obtemos o segredo (e o escrevemos no thread) que usaremos para autorização no Keycloak:

Clientes —> kubernetes —> Credenciais —> Segredo
Isso conclui a configuração, mas ocorreu um erro quando, após a autorização bem-sucedida, recebi um erro 403. Relatório de erro.

Consertar:

Escopos do cliente —> funções —> Mapeadores —> Criar

MapperFixamos a autorização do ActiveDirectory ao Kubernetes usando o Keycloak

Código do script

// add current client-id to token audience
token.addAudience(token.getIssuedFor());

// return token issuer as dummy result assigned to iss again
token.getIssuer();

Configurando o Kubernetes

Precisamos especificar onde está nosso certificado raiz do site e onde o provedor OIDC está localizado.
Para fazer isso, edite o arquivo /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
...

Atualize a configuração kubeadm no cluster:

kubeadmconfig

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
...

Configurando o proxy de autenticação

Você pode usar o gatekeeper keycloak para proteger seu aplicativo da web. Além de esse proxy reverso autorizar o usuário antes de mostrar a página, ele também passará informações sobre você para o aplicativo final nos cabeçalhos. Assim, se o seu aplicativo for compatível com OpenID, o usuário será imediatamente autorizado. Considere o exemplo do painel do Kubernetes

Instalando o painel do Kubernetes


helm install stable/kubernetes-dashboard --name dashboard -f values_dashboard.yaml

valores_dashboard.yaml

enableInsecureLogin: true
service:
  externalPort: 80
rbac:
  clusterAdminRole: true
  create: true
serviceAccount:
  create: true
  name: 'dashboard-test'

Definir direitos de acesso:

Vamos criar um ClusterRoleBinding que concederá direitos de administrador de cluster (cluster-admin ClusterRole padrão) para usuários no grupo 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

Instale o gatekeeper keycloak:


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

valores_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"

Depois disso, quando você tentar ir para kubernetes-dashboard.example.org, seremos redirecionados para o Keycloak e em caso de autorização bem-sucedida chegaremos ao Dashboard já logado.

instalação de passarela

Por conveniência, você pode adicionar um corredor que gerará um arquivo de configuração para kubectl, com a ajuda do qual entraremos no Kubernetes sob nosso usuário.


helm install --name gangway stable/gangway -f values_gangway.yaml

valores_gangway.yaml


gangway:
  # Произвольное имя кластера
  clusterName: "my-k8s"
  # Где у нас 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"
  # Теоритически сюда можно добавить groups которые мы замапили
  scopes: ["openid", "profile", "email", "offline_access"]
  redirectURL: "https://gangway.example.org/callback"
  # Имя клиента
  clientID: "kubernetes"
  # Секрет
  clientSecret: "c6ec03b8-d0b8-4cb6-97a0-03becba1d727"
  # Если оставить дефолтное значние, то за имя пользователя будет братья <b>Frist name</b> <b>Second name</b>, а при "sub" его логин
  usernameClaim: "sub"
  # Доменное имя или IP адресс API сервера
  apiServerURL: "https://192.168.99.111:8443"

# Включаем 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

# Если используем самоподписанный сертификат, то его(открытый корневой сертификат) надо указать.
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-----

Se parece com isso. Permite baixar imediatamente o arquivo de configuração e gerá-lo usando um conjunto de comandos:

Fixamos a autorização do ActiveDirectory ao Kubernetes usando o Keycloak

Fonte: habr.com

Adicionar um comentário