Autentisering i Kubernetes med GitHub OAuth og Dex

Jeg presenterer en veiledning for å generere tilgang til Kubernetes-klyngen ved hjelp av Dex, dex-k8s-authenticator og GitHub.

Autentisering i Kubernetes med GitHub OAuth og Dex
Et lokalt meme fra den russisktalende Kubernetes-chatten i Telegram

Innledning

Vi bruker Kubernetes til å opprette dynamiske miljøer for utviklingsteamet og QA. Dermed ønsker vi å gi dem tilgang til klyngen både for dashbordet og for kubectl. I motsetning til OpenShift, har den vanlige Kubernetes ingen innebygd autentisering, så vi bruker tredjepartsverktøy for dette.

I denne konfigurasjonen bruker vi:

  • dex-k8s-authenticator — en webapp for å generere kubectl-konfigurasjoner
  • Dex — en OpenID Connect-leverandør
  • GitHub — bare fordi vi bruker GitHub i selskapet vårt

Vi prøvde å bruke Google OIDC, men dessverre fikk vi ikke til å etablere dem med grupper, så integrasjonen med GitHub passet oss godt. Uten gruppering vil ikke RBAC-politikker basert på grupper kunne opprettes.

Så, hvordan fungerer autoriseringsprosessen vår i Kubernetes i visuell fremstilling:

Autentisering i Kubernetes med GitHub OAuth og Dex
Autoriseringsprosessen

Litt mer detaljert og punktvis:

  1. Brukeren logger inn på dex-k8s-authenticator (login.k8s.example.com)
  2. dex-k8s-authenticator omdirigerer forespørselen til Dex (dex.k8s.example.com)
  3. Dex omdirigerer til GitHubs påloggingsside
  4. GitHub genererer nødvendig informasjon om autoriseringen og sender den tilbake til Dex
  5. Dex overfører den innhentede informasjonen til dex-k8s-authenticator
  6. Brukeren får OIDC-token fra GitHub
  7. dex-k8s-authenticator legger til tokenet i kubeconfig
  8. kubectl sender tokenet til KubeAPIServer
  9. KubeAPIServer returnerer tilgang til kubectl basert på det sendte tokenet
  10. Brukeren får tilgang fra kubectl

Forberedende tiltak

Vi har allerede en installert Kubernetes-klynge (k8s.example.com), samt forhåndsinstallert HELM. Vi har også en organisasjon på GitHub (super-org).
Hvis du ikke har HELM, handler det om å installere det veldig enkelt.

Først må vi konfigurere GitHub.

Gå til innstillingssiden til organisasjonen, (https://github.com/organizations/super-org/settings/applications) og opprett en ny app (Authorized OAuth App):
Autentisering i Kubernetes med GitHub OAuth og Dex
Oppretting av ny app i GitHub

Fyll ut feltene med nødvendige URL-er, for eksempel:

  • Hjemmeside-URL: https://dex.k8s.example.com
  • Autorisasjonscallback-URL: https://dex.k8s.example.com/callback

Vær oppmerksom på lenkene, det er viktig å ikke miste skråstrekene.

Som svar på det utfylte skjemaet vil GitHub generere Client ID og Klient hemmelighet, lagre dem på et sikkert sted, vi vil trenge dem (vi bruker for eksempel Vault til lagring av hemmeligheter):

Klient-ID: 1ab2c3d4e5f6g7h8
Klient hemmelighet: 98z76y54x32w1

Forbered DNS-poster for subdomener login.k8s.example.com og dex.k8s.example.com, samt SSL-sertifikater for innganger.

Vi oppretter SSL-sertifikater:

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

ClusterIssuer med navnet le-clusterissuer bør allerede eksistere, hvis ikke, la oss opprette det med 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

KubeAPIServer-konfigurasjon

For at kubeAPIServer skal fungere, må OIDC konfigureres og klyngen oppdateres:

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

Vi bruker kops for å distribuere klynger, men dette fungerer på lignende måte for andre klyngeadministratorer.

Konfigurasjon av Dex og dex-k8s-authenticator

For at Dex skal fungere, må vi ha et sertifikat og en nøkkel fra Kubernetes-masteren, vi henter det derfra:

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

Vi kloner repositoriet dex-k8s-authenticator:

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

Ved hjelp av values-filer kan vi fleksibelt konfigurere variabler for våre HELM-diagrammer.

La oss beskrive konfigurasjonen for Dex:

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

Og for dex-k8s-authenticator:

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

La Dex og dex-k8s-authenticator:

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

La oss sjekke om tjenestene fungerer (Dex skal returnere kode 400, mens dex-k8s-authenticator skal returnere kode 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

RBAC-konfigurasjon

Vi oppretter ClusterRole for gruppen, i vårt tilfelle med read-only tilgang:

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

Vi lager en konfigurasjon for 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

Nå er vi klare for testing.

Tester

Gå til påloggingssiden (https://login.k8s.example.com) og logg inn med GitHub-kontoen din:

Autentisering i Kubernetes med GitHub OAuth og Dex
Påloggingsside

Autentisering i Kubernetes med GitHub OAuth og Dex
Påloggingsside omdirigert til GitHub

Autentisering i Kubernetes med GitHub OAuth og Dex
 Følg de genererte instruksjonene for å få tilgang

Etter å ha kopiert og limt inn fra nettsiden kan vi bruke kubectl for å administrere ressursene i klyngen vår:

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"

Og det fungerer, alle GitHub-brukere i organisasjonen vår kan se ressurser og logge inn på podene, men de har ikke rettigheter til å endre dem.

Kilde: habr.com

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster