HimeraSearchDB
Carding_EbayThief
triada
CrackerTuch
d-shop

НОВОСТИ Аутентификация в Kubernetes с помощью Dex: прикручиваем LDAP

BDFpromo
Оффлайн

BDFpromo

.
.
Регистрация
23.09.18
Сообщения
12.347
Реакции
176
Репутация
0
Сегодня я подробно разберу настройку аутентификации в Kubernetes с помощью Dex в связке с LDAP, а также покажу, как можно добавлять статических пользователей в Dex.

В статье не буду останавливаться на основных принципах работы Dex, а сразу перейду к установке и настройке LDAP. Познакомиться с принципами работы Dex можно .

Что будем делать:
  1. .
  2. .
  3. .
  4. .
  5. .
  6. .

Итак, поехали.
wsgg8p0mpws1v3lyysdrmrqrebm.png


Показывать буду на примере уже с Helm версии 3 и Ingress, а также тремя доменными именами.


Устанавливаем и настраиваем OpenLDAP-сервер


В качестве LDAP будем использовать OpenLDAP на дистрибутиве ubuntu 18.04.
Имя нашего сервера: openldap.dtln.cloud.
  1. Подключаемся к серверу и приступаем к установке OpenLDAP. В процессе установки нам предложат установить пароль:

    sudo apt update
    sudo apt install slapd ldap-utils


  2. Переконфигурируем OpenLDAP для нашего домена:

    sudo dpkg-reconfigure slapd


  3. Выбираем No:
    fhqq1tkbajxlbsb_dm99rfvsnme.png

  4. Вводим доменное имя:
    7awvcbbuj2wcoiq0m0lnl39lms8.png

  5. Вводим имя организации:
    3lw2wcds6l3z9ygwhqhjget7eag.png

  6. Повторяем ввод пароля:
    hgkwa0bqtheyjgngubxoged7_zu.png

  7. Включаем поддержку STARTTLS. Ставим необходимые пакеты:

    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



    В случае успеха получаем:
    memvkzuygkpfn371n9ssmkfmsfc.png


    В случае проблемы проверяем еще раз пути до сертификатов и выполнение команд:
    hrq50fdpfscjrjku2innzthxkd4.png


Описываем структуру 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: [email protected]
    userpassword: foo_password

    dn: cn=john,ou=People,dc=openldap,dc=dtln,dc=cloud
    objectClass: person
    objectClass: inetOrgPerson
    sn: doe
    cn: john
    mail: [email protected]
    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. Разворачиваем описанную структуру командой:

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


  3. Удостоверимся в наличии наших пользователей в каталоге:

    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



Подключаем поддержку OpenID Connect


Переходим к настройке кластера Kubernetes.

Домен dex.ash.dtln.cloud используем для обращения Dex к API-серверу, а login.ash.dtln.cloud – для получения доступа к кластеру.

Мы разворачивали кластер без установщиков kubeadm или kops, так что OIDC-конфигурацию можно сразу добавлять в systemd-юнит. В остальных случаях настройку лучше сделать с помощью этих утилит.
  1. Редактируем юнит /etc/systemd/system/kube-apiserver.service и добавляем параметры запуска в секцию ExecStart:

    --oidc-client-id=dex-k8s-authenticator \
    --oidc-groups-claim=groups \
    --oidc-username-claim=email \
    --oidc-issuer-url= \
  2. Рестартуем наши API, проверяем, что они поднялись:

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


Создаем мультидоменный сертификат


Теперь переходим в кластер Kubernetes.

  1. Ставим cert-manager, используя Helm:

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


  2. Описываем запрос на получение SAN-сертификата для наших доменов в cert.yml:

    ---
    apiVersion: cert-manager.io/v1alpha2
    kind: ClusterIssuer
    metadata:
    name: letsencrypt-dex
    spec:
    acme:
    email: [email protected]
    server:
    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. Выполняем команду:

    kubectl apply -f cert.yaml


  4. Теперь смотрим состояние нашего запроса на получение сертификата следующими командами:

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


  5. Ждем подтверждения, процесс может занять некоторое время:
    qv-tdn_lae9i9ztr5vixcbqg_yq.png


Устанавливаем Dex


Для Dex нам понадобятся ca.crt, ca.key c мастер-сервера. Обычно они лежат в каталоге /etc/kubernetes/pki/
Также нужен сгенерированный нами раннее CA-сертификат с OpenLDAP, расположенный по пути /etc/ssl/certs/cacert.pem

  1. Скачиваем исходники dex-authenticator и переходим в каталог:

    git clone [email protected]:mintel/dex-k8s-authenticator.git
    cd dex-k8s-authenticator/


  2. Готовим конфиг для Dex-auth, вставляем содержимое ранее скопированного ca.crt, важно соблюдать отступы:

    ---
    global:
    deployEnv: prod
    dexK8sAuthenticator:
    clusters:
    - name: 'ash.dtln.cloud'
    short_description: "k8s cluster"
    description: "Kubernetes cluster"
    issuer:
    k8s_master_uri: # url or ip
    client_id: dex-k8s-authenticator
    static_context_name: false
    client_secret: acDEgDEcIg7RX0U7A9hlW2pGGraHDuMAZ4qFEKg2fUHHxr8
    redirect_uri:
    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. Переводим содержимое cacert.pem в base64, чтобы добавить его в конфиг:

    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:
    storage:
    type: kubernetes
    config:
    inCluster: true
    web:
    http: 0.0.0.0:5556
    frontend:
    theme: "coreos"
    issuer: "kube-dtln"
    issuerUrl: " "
    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:
    -

    enablePasswordDB: True

    staticPasswords:
    # Создаем статического пользователя с паролем в base64
    - email: "[email protected]"
    # 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’ы. Смотрим их логи и идем по адресу . Логинимся под созданной нами учеткой, для авторизации мы использовали mail-формат логина.

    Для static-записи выбираем вход через mail:
    9wkicxu8omkz-nzcni_ntpap82m.png

  2. После успешной аутентификации нас перенаправляют на страницу с инструкцией Dex-auth. C ее помощью мы генерируем kubeconfig-файл. В дальнейшем с ним мы будем подключаться к нашему кластеру:
    hihsvaodu4rk0jfyomuackhfczw.png

  3. Теперь попытаемся получить доступ к кластеру и получаем ошибку. Все верно, наш пользователь не имеет прав, так что переходим к настройке RBAC.
    bupzl3l0wuq9gjp88yws0mi7pvi.png


Настраиваем RBAC-авторизацию


  1. Для примера привяжем статического пользователя к системной роли cluster-admin, а пользователей группы developers – к роли view, позволяющей только просматривать ресурсы. Тогда содержимое файла crb.yml должно быть таким:

    ---
    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: "[email protected]"

    ---
    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. Переключаемся на основной контекст и применяем созданный yaml-файл на кластер:

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


  3. Смотрим доступные контексты и переключаемся обратно на нашего пользователя:

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

На этом настройка Dex в связке с OpenLDAP закончена.

Пара советов напоследок:
  • Если возникают проблемы, первым делом нужно проверить форматирование yaml-файлов и обратить внимание на отступы.
  • Слэши в адресах должны соответствовать примерам.
  • Не забудьте посмотреть логи pod’ов Dex, Dex-auth, а также журналы юнитов kube-api на мастерах.
 
Сверху Снизу