Authentification dans Kubernetes avec GitHub OAuth et Dex

Je vous présente le tutoriel pour générer l'accès au cluster Kubernetes à l'aide de Dex, dex-k8s-authentificator et GitHub.

image

Mème local du chat en langue russe Kubernetes sur Telegram

Présentation


Nous utilisons Kubernetes pour créer des environnements dynamiques pour l'équipe de développement et le contrôle qualité. Ainsi, nous voulons leur donner accès au cluster pour les tableaux de bord et kubectl. Contrairement à OpenShift, vanilla Kubernetes n'a pas d'authentification native, nous utilisons donc des outils tiers pour cela.

Dans cette configuration, nous utilisons:

  • dex-k8s-authentificator - application web pour gĂ©nĂ©rer la configuration de kubectl
  • Dex - Fournisseur OpenID Connect
  • GitHub - simplement parce que nous utilisons GitHub dans notre entreprise

Nous avons essayé d'utiliser Google OIDC, mais malheureusement nous n'avons pas pu les obtenir avec des groupes, donc l'intégration avec GitHub nous convenait très bien. Sans mappage de groupe, vous ne pouvez pas créer de stratégies RBAC basées sur un groupe.

Alors, comment fonctionne notre processus d'autorisation dans Kubernetes dans une représentation visuelle:

image
Processus d'autorisation

Un peu plus de détails et de points:

  1. L'utilisateur se connecte Ă  dex-k8s-authentifier ( login.k8s.example.com )
  2. dex-k8s-authentator redirige la demande vers Dex ( dex.k8s.example.com )
  3. Dex redirige vers la page de connexion GitHub
  4. GitHub génère les informations d'autorisation nécessaires et les renvoie à Dex
  5. Dex transmet les informations reçues à l'authentification dex-k8s
  6. L'utilisateur obtient le jeton OIDC de GitHub
  7. dex-k8s-authentifier ajoute un jeton Ă  kubeconfig
  8. kubectl passe le jeton Ă  KubeAPIServer
  9. KubeAPIServer basé sur le jeton transféré renvoie les accès dans kubectl
  10. L'utilisateur obtient l'accès à partir de kubectl

Activités préparatoires


Bien sûr, nous avons déjà un cluster k8s.example.com ( k8s.example.com ) installé, ainsi que HELM. Nous avons également une organisation sur GitHub (super-org).
Si vous n'avez pas de HELM, il est très facile à installer.

Nous devons d'abord configurer GitHub.

Accédez à la page des paramètres de l'organisation ( https://github.com/organizations/super-org/settings/applications ) et créez une nouvelle application (application OAuth autorisée):
image
Créer une nouvelle application sur GitHub

Remplissez les champs avec les URL nécessaires, par exemple:

  • URL de la page d'accueil: https://dex.k8s.example.com
  • URL de rappel d'autorisation: https://dex.k8s.example.com/callback

Attention aux liens, il est important de ne pas perdre de barres obliques.

En réponse au formulaire rempli, GitHub va générer l' Client ID et le Client secret , les enregistrer dans un endroit sûr, ils nous seront utiles (par exemple, nous utilisons Vault pour stocker des secrets):

 Client ID: 1ab2c3d4e5f6g7h8 Client secret: 98z76y54x32w1 

Préparez les enregistrements DNS pour les sous-domaines login.k8s.example.com et dex.k8s.example.com , ainsi que les certificats SSL pour les entrées.

Créez des certificats SSL:

 cat <<EOF | kubectl create -f - apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: cert-auth-dex namespace: kube-system spec: secretName: cert-auth-dex dnsNames: - dex.k8s.example.com acme: config: - http01: ingressClass: nginx domains: - dex.k8s.example.com issuerRef: name: le-clusterissuer kind: ClusterIssuer --- apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: cert-auth-login namespace: kube-system spec: secretName: cert-auth-login dnsNames: - login.k8s.example.com acme: config: - http01: ingressClass: nginx domains: - login.k8s.example.com issuerRef: name: le-clusterissuer kind: ClusterIssuer EOF kubectl describe certificates cert-auth-dex -n kube-system kubectl describe certificates cert-auth-login -n kube-system 

Un ClusterIssuer avec le nom le-clusterissuer devrait déjà exister, sinon, créez-le en utilisant HELM:

 helm install --namespace kube-system -n cert-manager stable/cert-manager cat << EOF | kubectl create -f - apiVersion: certmanager.k8s.io/v1alpha1 kind: ClusterIssuer metadata: name: le-clusterissuer namespace: kube-system spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: k8s-admin@example.com privateKeySecretRef: name: le-clusterissuer http01: {} EOF 

Configuration de KubeAPIServer


Pour que kubeAPIServer fonctionne, vous devez configurer OIDC et mettre Ă  jour le cluster:

 kops edit cluster ... kubeAPIServer: anonymousAuth: false authorizationMode: RBAC oidcClientID: dex-k8s-authenticator oidcGroupsClaim: groups oidcIssuerURL: https://dex.k8s.example.com/ oidcUsernameClaim: email kops update cluster --yes kops rolling-update cluster --yes 

Nous utilisons kops pour déployer des clusters, mais cela fonctionne de la même manière pour les autres gestionnaires de clusters .

Configuration des authentificateurs Dex et dex-k8s


Pour que Dex fonctionne, vous devez avoir un certificat et une clé du maître Kubernetes, en les tirant de là:

 sudo cat /srv/kubernetes/ca.{crt,key} -----BEGIN CERTIFICATE----- AAAAAAAAAAABBBBBBBBBBCCCCCC -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- DDDDDDDDDDDEEEEEEEEEEFFFFFF -----END RSA PRIVATE KEY----- 

Clonez le référentiel dex-k8s-authentifier:

 git clone git@github.com:mintel/dex-k8s-authenticator.git cd dex-k8s-authenticator/ 

En utilisant des fichiers de valeurs, nous pouvons définir de manière flexible des variables pour nos graphiques HELM .

Décrivons la configuration de Dex:

 cat << \EOF > values-dex.yml global: deployEnv: prod tls: certificate: |- -----BEGIN CERTIFICATE----- AAAAAAAAAAABBBBBBBBBBCCCCCC -----END CERTIFICATE----- key: |- -----BEGIN RSA PRIVATE KEY----- DDDDDDDDDDDEEEEEEEEEEFFFFFF -----END RSA PRIVATE KEY----- ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" path: / hosts: - dex.k8s.example.com tls: - secretName: cert-auth-dex hosts: - dex.k8s.example.com serviceAccount: create: true name: dex-auth-sa config: | issuer: https://dex.k8s.example.com/ storage: # https://github.com/dexidp/dex/issues/798 type: sqlite3 config: file: /var/dex.db web: http: 0.0.0.0:5556 frontend: theme: "coreos" issuer: "Example Co" issuerUrl: "https://example.com" logoUrl: https://example.com/images/logo-250x25.png expiry: signingKeys: "6h" idTokens: "24h" logger: level: debug format: json oauth2: responseTypes: ["code", "token", "id_token"] skipApprovalScreen: true connectors: - type: github id: github name: GitHub config: clientID: $GITHUB_CLIENT_ID clientSecret: $GITHUB_CLIENT_SECRET redirectURI: https://dex.k8s.example.com/callback orgs: - name: super-org teams: - team-red staticClients: - id: dex-k8s-authenticator name: dex-k8s-authenticator secret: generatedLongRandomPhrase redirectURIs: - https://login.k8s.example.com/callback/ envSecrets: GITHUB_CLIENT_ID: "1ab2c3d4e5f6g7h8" GITHUB_CLIENT_SECRET: "98z76y54x32w1" EOF 

Et pour l'authentificateur dex-k8s:
 cat << EOF > values-auth.yml global: deployEnv: prod dexK8sAuthenticator: clusters: - name: k8s.example.com short_description: "k8s cluster" description: "Kubernetes cluster" issuer: https://dex.k8s.example.com/ k8s_master_uri: https://api.k8s.example.com client_id: dex-k8s-authenticator client_secret: generatedLongRandomPhrase redirect_uri: https://login.k8s.example.com/callback/ k8s_ca_pem: | -----BEGIN CERTIFICATE----- AAAAAAAAAAABBBBBBBBBBCCCCCC -----END CERTIFICATE----- ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" path: / hosts: - login.k8s.example.com tls: - secretName: cert-auth-login hosts: - login.k8s.example.com EOF 

Installez Dex et dex-k8s-authentifier:

 helm install -n dex --namespace kube-system --values values-dex.yml charts/dex helm install -n dex-auth --namespace kube-system --values values-auth.yml charts/dex-k8s-authenticator 

Vérifions la facilité de service des services (Dex devrait retourner le code 400, et dex-k8s-authentifier - le code 200):

 curl -sI https://dex.k8s.example.com/callback | head -1 HTTP/2 400 curl -sI https://login.k8s.example.com/ | head -1 HTTP/2 200 

Configuration RBAC


Nous créons ClusterRole pour le groupe, dans notre cas avec des accès en lecture seule:

 cat << EOF | kubectl create -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster-read-all rules: - apiGroups: - "" - apps - autoscaling - batch - extensions - policy - rbac.authorization.k8s.io - storage.k8s.io resources: - componentstatuses - configmaps - cronjobs - daemonsets - deployments - events - endpoints - horizontalpodautoscalers - ingress - ingresses - jobs - limitranges - namespaces - nodes - pods - pods/log - pods/exec - persistentvolumes - persistentvolumeclaims - resourcequotas - replicasets - replicationcontrollers - serviceaccounts - services - statefulsets - storageclasses - clusterroles - roles verbs: - get - watch - list - nonResourceURLs: ["*"] verbs: - get - watch - list - apiGroups: [""] resources: ["pods/exec"] verbs: ["create"] EOF 

Créez une configuration pour ClusterRoleBinding:

 cat <<EOF | kubectl create -f - apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: dex-cluster-auth namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-read-all subjects: kind: Group name: "super-org:team-red" EOF 

Nous sommes maintenant prĂŞts pour les tests.

Les tests


Nous allons sur la page de connexion ( https://login.k8s.example.com ) et nous connectons en utilisant le compte GitHub:

image
Page de connexion

image
Page de connexion redirigée vers GitHub

image
Suivez les instructions générées pour l'accès

Après un copier-coller à partir de la page Web, nous pouvons utiliser kubectl pour gérer les ressources de notre cluster:

 kubectl get po NAME READY STATUS RESTARTS AGE mypod 1/1 Running 0 3d kubectl delete po mypod Error from server (Forbidden): pods "mypod" is forbidden: User "amet@example.com" cannot delete pods in the namespace "default" 

Et cela fonctionne, tous les utilisateurs de GitHub de notre organisation peuvent voir les ressources et entrer dans les pods, mais ils n'ont pas le droit de les modifier.

Source: https://habr.com/ru/post/fr436238/


All Articles