Otentikasi di Kubernetes dengan Dex: kencangkan LDAP

Hari ini saya akan membahas rincian konfigurasi otentikasi di Kubernetes menggunakan Dex bersama dengan LDAP, dan juga menunjukkan bagaimana Anda dapat menambahkan pengguna statis ke Dex. 

Pada artikel ini saya tidak akan membahas prinsip-prinsip dasar Dex, tetapi segera melanjutkan untuk menginstal dan mengkonfigurasi LDAP. Anda bisa berkenalan dengan prinsip-prinsip Dex dalam artikel ini .

Apa yang kita lakukan:

  1. Instal OpenLDAP dan konfigurasikan dukungan STARTTLS di atasnya. 
  2. Kami menggambarkan struktur direktori LDAP organisasi kami .
  3. Aktifkan dukungan OIDC (OpenID Connect) pada server kube-api .
  4. Dapatkan sertifikat SAN untuk domain yang akan digunakan Dex .
  5. Instal Dex dan Dex-auth, tempat kami menggambarkan direktori LDAP dan pengguna statis
  6. Kami akan menghasilkan kubeconfig dari pengguna kami untuk bekerja dengan cluster .
  7. Menyiapkan otentikasi RBAC untuk grup dan pengguna di kluster .

Jadi ayo pergi.



Saya akan menunjukkan kepada Anda dengan contoh kluster Kubernet yang sudah jadi dengan Helm versi 3 dan Ingress, serta tiga nama domain.

Instal dan konfigurasikan server OpenLDAP


Kami akan menggunakan OpenLDAP sebagai LDAP pada distribusi ubuntu 18.04. 
Nama server kami: openldap.dtln.cloud. 

  1. Kami terhubung ke server dan kami memulai instalasi OpenLDAP. Selama instalasi, kami akan diminta untuk mengatur kata sandi:

    sudo apt update 
    sudo apt install slapd ldap-utils
    

  2. Mengkonfigurasi ulang OpenLDAP untuk domain kami:

    sudo dpkg-reconfigure slapd 
    

  3. Pilih Tidak :


  4. Masukkan nama domain:


  5. Masukkan nama organisasi:


  6. Ulangi entri kata sandi:


  7. Kami menyertakan dukungan untuk STARTTLS. Kami menempatkan paket yang diperlukan:

    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. Perluas struktur yang dijelaskan dengan perintah:

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

  3. Pastikan pengguna kami ada di direktori:

    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
    

Kami menghubungkan dukungan untuk OpenID Connect


Mari beralih ke pengaturan kluster Kubernetes. 

Kami menggunakan domain dex.ash.dtln.cloud untuk mengakses server Dex API, dan login.ash.dtln.cloud untuk mengakses cluster.

Kami menyebarkan cluster tanpa penginstal kubeadm atau kops, sehingga konfigurasi OIDC dapat segera ditambahkan ke unit systemd. Dalam kasus lain, konfigurasi paling baik dilakukan menggunakan utilitas ini.

  1. Kami mengedit unit /etc/systemd/system/kube-apiserver.service dan menambahkan parameter startup ke bagian ExecStart :

    --oidc-client-id=dex-k8s-authenticator \
    --oidc-groups-claim=groups \
    --oidc-username-claim=email \
    --oidc-issuer-url=https://dex.ash.dtln.cloud/ \
    
  2. Kami memulai kembali API kami, memeriksa apakah API telah meningkat:

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

Buat sertifikat multi-domain


Sekarang pergi ke kluster Kubernetes. 

  1. Kami memasang cert-manager menggunakan 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. Kami menjelaskan permintaan untuk sertifikat SAN untuk domain kami di 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. Kami menjalankan perintah:

    kubectl apply -f cert.yaml
    

  4. Sekarang kita melihat status permintaan sertifikat kami dengan perintah berikut: 

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

  5. Kami sedang menunggu konfirmasi, prosesnya mungkin memakan waktu:



Instal Dex


Untuk Dex, kita perlu ca.crt, ca.key dari server master. Biasanya mereka berada di direktori / etc / kubernetes / pki /.
Kami juga membutuhkan sertifikat CA sebelumnya dengan OpenLDAP yang kami buat, terletak di jalur /etc/ssl/certs/cacert.pem

  1. Unduh sumber dex-authenticator dan buka direktori:

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

  2. Kami menyiapkan konfigurasi untuk Dex-auth, menempel konten ca.crt yang sebelumnya disalin, penting untuk mengamati lekukan:

    ---
    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. Kami menerjemahkan konten cacert.pem ke base64 untuk menambahkannya ke konfigurasi:

    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. Sekarang coba akses cluster dan dapatkan kesalahan. Itu benar, pengguna kami tidak memiliki hak, jadi mari beralih ke pengaturan RBAC.



Kami mengkonfigurasi otorisasi RBAC


  1. Sebagai contoh, kami menetapkan pengguna statis ke peran sistem cluster-admin , dan pengguna grup pengembang ke peran tampilan, yang memungkinkan hanya melihat sumber daya. Maka isi file crb.yml harus seperti ini:

    ---
    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. Beralih ke konteks utama dan terapkan file yaml yang dibuat ke kluster:

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

  3. Kami melihat konteks yang tersedia dan kembali ke pengguna kami:

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

Ini melengkapi pengaturan Dex bersama dengan OpenLDAP.

Beberapa tips untuk yang terakhir:

  • Jika masalah muncul, hal pertama yang perlu diperiksa adalah memformat file yaml dan memperhatikan indentasi. 
  • Garis miring pada alamat harus cocok dengan contoh. 
  • pod’ Dex, Dex-auth, kube-api .

All Articles