Authentifizierung in Kubernetes mit Dex: LDAP befestigen

Heute werde ich die Details der Konfiguration der Authentifizierung in Kubernetes mit Dex in Verbindung mit LDAP erläutern und zeigen, wie Sie Dex statische Benutzer hinzufügen können. 

In diesem Artikel werde ich nicht auf die Grundprinzipien von Dex eingehen, sondern sofort mit der Installation und Konfiguration von LDAP fortfahren. In diesem Artikel können Sie sich mit den Prinzipien von Dex vertraut machen .

Was werden wir machen:

  1. Installieren Sie OpenLDAP und konfigurieren Sie die STARTTLS-Unterstützung darauf. 
  2. Wir beschreiben die Struktur des LDAP-Verzeichnisses unserer Organisation .
  3. Aktivieren Sie die OIDC-Unterstützung (OpenID Connect) auf kube-api-Servern .
  4. Holen Sie sich das SAN-Zertifikat für die Domänen, die Dex verwenden wird .
  5. Installieren Sie Dex und Dex-auth, wo wir das LDAP-Verzeichnis und die statischen Benutzer beschreiben
  6. Wir werden kubeconfig unseres Benutzers generieren, um mit dem Cluster zu arbeiten .
  7. Richten Sie die RBAC-Authentifizierung für Gruppen und Benutzer im Cluster ein .

So lass uns gehen.



Ich zeige Ihnen ein Beispiel eines vorgefertigten Kubernetes-Clusters mit Helm Version 3 und Ingress sowie drei Domainnamen.

Installieren und konfigurieren Sie den OpenLDAP-Server


Wir werden OpenLDAP als LDAP für die Ubuntu 18.04-Distribution verwenden. 
Unser Servername: openldap.dtln.cloud. 

  1. Wir sind mit dem Server verbunden und beginnen mit der Installation von OpenLDAP. Während der Installation werden wir aufgefordert, ein Passwort festzulegen:

    sudo apt update 
    sudo apt install slapd ldap-utils
    

  2. OpenLDAP für unsere Domain neu konfigurieren:

    sudo dpkg-reconfigure slapd 
    

  3. Wählen Sie Nein :


  4. Geben Sie den Domainnamen ein:


  5. Geben Sie den Namen der Organisation ein:


  6. Passworteingabe wiederholen:


  7. Wir bieten Unterstützung für STARTTLS. Wir stellen die notwendigen Pakete zusammen:

    sudo apt install gnutls-bin ssl-cert
    

  8. CA-:

    sudo sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem"
    

  9. /etc/ssl/ca.info:

    cn = DTLN Company
    ca
    cert_signing_key
    

  10. CA-a , :

    sudo certtool --generate-self-signed --load-privkey /etc/ssl/private/cakey.pem --template /etc/ssl/ca.info --outfile /etc/ssl/certs/cacert.pem
    sudo certtool --generate-privkey --bits 1024 --outfile /etc/ssl/private/openldap_key.pem
    

  11. /etc/ssl/openldap.info:

    organization = DTLN Company
    cn = openldap.dtln.cloud
    tls_www_server
    encryption_key
    signing_key
    expiration_days = 3650
    

  12. :

    sudo certtool --generate-certificate --load-privkey /etc/ssl/private/openldap_key.pem --load-ca-certificate /etc/ssl/certs/cacert.pem --load-ca-privkey /etc/ssl/private/cakey.pem --template /etc/ssl/openldap.info --outfile /etc/ssl/certs/openldap.pem
    

  13. OpenLDAP STARTTLS. certinfo.dif:

    dn: cn=config
    add: olcTLSCACertificateFile
    olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
    -
    add: olcTLSCertificateFile
    olcTLSCertificateFile: /etc/ssl/certs/openldap.pem
    -
    add: olcTLSCertificateKeyFile
    olcTLSCertificateKeyFile: /etc/ssl/private/openldap_key.pem
    

  14. :

    sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.dif
    

  15. :

    sudo chgrp openldap /etc/ssl/private/openldap_key.pem
    sudo chmod 0640 /etc/ssl/private/openldap_key.pem
    sudo gpasswd -a openldap ssl-cert
    sudo systemctl restart slapd.service
    

  16. , /etc/ldap/ldap.conf :

    TLS_CACERT /etc/ssl/certs/cacert.pem
    

  17. STARTTLS:

    ldapwhoami -H ldap://openldap.dtln.cloud -x -ZZ
    

    :



    :


LDAP-


  1. , x , Kubernetes. content.ldif:

    dn: ou=People,dc=openldap,dc=dtln,dc=cloud
    objectClass: organizationalUnit
    ou: People
    dn: cn=jane,ou=People,dc=openldap,dc=dtln,dc=cloud
    objectClass: person
    objectClass: inetOrgPerson
    sn: doe
    cn: jane
    mail: janedoe@openldap.dtln.cloud
    userpassword: foo_password
    
    dn: cn=john,ou=People,dc=openldap,dc=dtln,dc=cloud
    objectClass: person
    objectClass: inetOrgPerson
    sn: doe
    cn: john
    mail: johndoe@openldap.dtln.cloud
    userpassword: bar_password
    
    # Group definitions.
    
    dn: ou=Groups,dc=openldap,dc=dtln,dc=cloud
    objectClass: organizationalUnit
    ou: Groups
    
    dn: cn=admins,ou=Groups,dc=openldap,dc=dtln,dc=cloud
    objectClass: groupOfNames
    cn: admins
    member: cn=jane,ou=People,dc=openldap,dc=dtln,dc=cloud
    
    dn: cn=developers,ou=Groups,dc=openldap,dc=dtln,dc=cloud
    objectClass: groupOfNames
    cn: developers
    member: cn=jane,ou=People,dc=openldap,dc=dtln,dc=cloud
    member: cn=john,ou=People,dc=openldap,dc=dtln,dc=cloud
    

  2. Erweitern Sie die beschriebene Struktur mit dem Befehl:

    ldapadd -x -D cn=admin,dc=openldap,dc=dtln,dc=cloud -W -f content.ldif
    

  3. Stellen Sie sicher, dass sich unsere Benutzer im Verzeichnis befinden:

    ldapwhoami -vvv -h openldap.dtln.cloud -p 389 -D cn=john,ou=People,dc=openldap,dc=dtln,dc=cloud -x -w bar_password -ZZ
    ldapwhoami -vvv -h openldap.dtln.cloud -p 389 -D cn=jane,ou=People,dc=openldap,dc=dtln,dc=cloud -x -w foo_password -ZZ
    

Wir verbinden die Unterstützung für OpenID Connect


Fahren wir mit dem Kubernetes-Cluster-Setup fort. 

Wir verwenden die Domäne dex.ash.dtln.cloud, um auf den Dex-API-Server zuzugreifen, und login.ash.dtln.cloud, um auf den Cluster zuzugreifen.

Wir haben den Cluster ohne die Installationsprogramme kubeadm oder kops bereitgestellt, sodass die OIDC-Konfiguration sofort zur systemd-Einheit hinzugefügt werden kann. In anderen Fällen erfolgt die Konfiguration am besten mit diesen Dienstprogrammen.

  1. Wir bearbeiten die Einheit /etc/systemd/system/kube-apiserver.service und fügen die Startparameter zum Abschnitt ExecStart hinzu :

    --oidc-client-id=dex-k8s-authenticator \
    --oidc-groups-claim=groups \
    --oidc-username-claim=email \
    --oidc-issuer-url=https://dex.ash.dtln.cloud/ \
    
  2. Wir starten unsere APIs neu und überprüfen, ob sie gestiegen sind:

    sudo systemctl daemon-reload
    sudo systemctl restart kube-apiserver
    sudo systemctl status kube-apiserver
    

Erstellen Sie ein Zertifikat für mehrere Domänen


Gehen Sie nun zum Kubernetes-Cluster. 

  1. Wir installieren den Cert-Manager mit Helm: 

    helm repo add jetstack https://charts.jetstack.io
    helm repo update
    helm install cert-manager --namespace kube-system jetstack/cert-manager --version v0.13.0
    

  2. Wir beschreiben die Anforderung eines SAN-Zertifikats für unsere Domänen in cert.yml:

    ---
    apiVersion: cert-manager.io/v1alpha2
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-dex
    spec:
      acme:
        email: kubernetes@dataline.ru
        server: https://acme-v02.api.letsencrypt.org/directory
        privateKeySecretRef:
          name: letsencrypt-key-dex
        solvers:
        - http01:
            ingress:
              class: nginx
    ---
    apiVersion: cert-manager.io/v1alpha2
    kind: Certificate
    metadata:
      name: auth-dex
      namespace: kube-system
    spec:
      secretName: cert-auth-dex
      issuerRef:
        kind: ClusterIssuer
        name: letsencrypt-dex
      commonName: dex.ash.dtln.cloud
      dnsNames:
      - dex.ash.dtln.cloud
      - login.ash.dtln.cloud
    

  3. Wir führen den Befehl aus:

    kubectl apply -f cert.yaml
    

  4. Jetzt sehen wir uns den Status unserer Zertifikatanforderung mit den folgenden Befehlen an: 

    kubectl get certificates --all-namespaces
    kubectl get challenges --all-namespaces
    

  5. Wir warten auf Bestätigung, der Vorgang kann einige Zeit dauern:



Installieren Sie Dex


Für Dex benötigen wir ca.crt, ca.key vom Master-Server. Normalerweise befinden sie sich im Verzeichnis / etc / kubernetes / pki /.
Wir benötigen auch das frühere CA-Zertifikat mit OpenLDAP, das wir generiert haben und das sich im Pfad /etc/ssl/certs/cacert.pem befindet

  1. Laden Sie die Dex-Authenticator-Quellen herunter und wechseln Sie in das Verzeichnis:

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

  2. Wir bereiten die Konfiguration für Dex-auth vor, fügen den Inhalt des zuvor kopierten ca.crt ein, es ist wichtig, den Einzug zu beachten:

    ---
    global:
      deployEnv: prod
    dexK8sAuthenticator:
      clusters:
        - name: 'ash.dtln.cloud'
          short_description: "k8s cluster"
          description: "Kubernetes cluster"
          issuer: https://dex.ash.dtln.cloud/
          k8s_master_uri: https://kubernetes.dtln.cloud:6443 # url or ip
          client_id: dex-k8s-authenticator
          static_context_name: false
          client_secret: acDEgDEcIg7RX0U7A9hlW2pGGraHDuMAZ4qFEKg2fUHHxr8
          redirect_uri: https://login.ash.dtln.cloud/callback
          k8s_ca_pem: |
            -----BEGIN CERTIFICATE-----
            #   ca.crt
            -----END CERTIFICATE-----
    ingress:
      enabled: true
      annotations:
        kubernetes.io/ingress.class: nginx
        kubernetes.io/tls-acme: "true"
      path: /
      hosts:
        - login.ash.dtln.cloud
      tls:
        - secretName: cert-auth-dex
          hosts:
            - login.ash.dtln.cloud
    
    

  3. Wir übersetzen den Inhalt von cacert.pem in base64, um ihn der Konfiguration hinzuzufügen:

    cacert.pem | base64
    

  4. Dex, . staticPasswords bcrypt:

    ---
    global:
      deployEnv: prod
    tls:
      certificate: |-
        -----BEGIN CERTIFICATE-----
        # ca.crt
        -----END CERTIFICATE-----
      key: |-
        -----BEGIN RSA PRIVATE KEY-----
        # ca.key
        -----END RSA PRIVATE KEY-----
    ingress:
      enabled: true
      annotations:
        kubernetes.io/ingress.class: nginx
        kubernetes.io/tls-acme: "true"
      path: /
      hosts:
        - dex.ash.dtln.cloud
      tls:
        - secretName: cert-auth-dex
          hosts:
            - dex.ash.dtln.cloud
    serviceAccount:
      create: true
      name: dex-auth-sa
    config:
      issuer: https://dex.ash.dtln.cloud/
      storage:
        type: kubernetes
        config:
          inCluster: true
      web:
        http: 0.0.0.0:5556
      frontend:
        theme: "coreos"
        issuer: "kube-dtln"
        issuerUrl: "https://login.ash.dtln.cloud"
      expiry:
        signingKeys: "6h"
        idTokens: "24h"
      logger:
        level: debug
        format: json
      oauth2:
        responseTypes: ["code", "token", "id_token"]
        skipApprovalScreen: true
    
      connectors:
      - type: ldap
        id: ldap
        name: LDAP
        config:
          insecureNoSSL: false
          insecureSkipVerify: false
          startTLS: true #   
          rootCAData: |-
            # cacert.pem  base64 
            # 
         
          host: openldap.dtln.cloud:389
          usernamePrompt: Email Address
          userSearch:
            baseDN: ou=People,dc=openldap,dc=dtln,dc=cloud
            filter: "(objectClass=person)"
            username: mail
            idAttr: DN
            emailAttr: mail
            nameAttr: cn
          groupSearch:
            baseDN: ou=Groups,dc=openldap,dc=dtln,dc=cloud
            filter: "(objectClass=groupOfNames)"
    
            userMatchers:
            - userAttr: DN
              groupAttr: member
    
            nameAttr: cn
    
      staticClients:
      - id: dex-k8s-authenticator
        name: Kubernetes Dev Cluster
        secret: 'acDEgDEcIg7RX0U7A9hlW2pGGraHDuMAZ4qFEKg2fUHHxr8'
        redirectURIs:
          - https://login.ash.dtln.cloud/callback
    
      enablePasswordDB: True
    
      staticPasswords:
        #       base64
      - email: "admin@dtln.cloud"
        # bcrypt hash of the string "password"
        hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"
        username: "admin"
        userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
    
    

  5. dex dex-auth- :

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


kubeconfig


  1. , pod’. login.ash.dtln.cloud. , mail- . 

    static- mail:


  2.  Dex-auth. C kubeconfig-. :


  3. Versuchen Sie nun, auf den Cluster zuzugreifen und eine Fehlermeldung zu erhalten. Richtig, unser Benutzer hat keine Rechte. Fahren wir also mit der Einrichtung von RBAC fort.



Wir konfigurieren die RBAC-Autorisierung


  1. Beispielsweise weisen wir den statischen Benutzer der Cluster-Administrator-Systemrolle und die Benutzer der Entwicklergruppe der Ansichtsrolle zu, sodass nur Ressourcen angezeigt werden können. Dann sollte der Inhalt der Datei crb.yml folgendermaßen aussehen:

    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: dex-admin
      namespace: kube-system
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
    - kind: User
      name: "admin@dtln.cloud"
    
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: dex-developers
      namespace: kube-system
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: view
    subjects:
    - kind: Group
      name: "developers"
    

  2. Wechseln Sie zum Hauptkontext und wenden Sie die erstellte yaml-Datei auf den Cluster an:

    kubectl config set-context default
    kubectl apply -f crb.yml
    

  3. Wir schauen uns die verfügbaren Kontexte an und wechseln zurück zu unserem Benutzer:

    kubectl config get-contexts
    kubectl config set-context johndoe-ash.dtln.cloud
    

Damit ist die Einrichtung von Dex in Verbindung mit OpenLDAP abgeschlossen.

Ein paar Tipps zum Schluss:

  • Wenn Probleme auftreten, müssen Sie zunächst die Formatierung der Yaml-Dateien überprüfen und auf die Einrückung achten. 
  • Schrägstriche in Adressen müssen mit den Beispielen übereinstimmen. 
  • pod’ Dex, Dex-auth, kube-api .

All Articles