Опис
В цьому дописі налаштуємо інтеграцію з freeipa(LDAP). Надалі орієнтуючись на ldap групи будемо нарізати доступи розробникам до їхніх проєктів. Варто згадати що є декілька варіантів аутентифікації в кластері кубернетес і одним з надійних та перевірених є використання OIDC провайдерів, а саме популярний провайдер DEX.
OIDC(OpenID Connect) – це механізм автентифікації який базується на OAuth 2.0(протокол авторизації). Він дозволяє перевіряти ідентичність користувача на основі аутентифікованого сеансу, проведеного провайдером автентифікації. Основними компонентами є
- ID Token: це JSON Web Token, який містить відомості про користувача;
- UserInfo Endpoint: кінцева точка, де клієнт може отримати дані користувача за умови, що у нього є дійсний access token;
- Discovery: механізм, дозволяє клієнтам дізнаватися про конфігурацію провайдера;
Dex – популярний OIDC провайдер для аутентифікації користувачів. Він дозволяє налаштовувати аутентифікацію користувачів через зовнішні служби LDAP, SAML. Kubernetes буде комунікувати з Dex через OIDC для аутентифікації.
За допомогою Dex ми:
- Підвищуємо безпеку.
(використовувати політики автентифікації й не тільки) - Отримуємо гнучкість.
(Кожна організація має унікальні вимоги, і Dex досить гнучкий, щоб дозволити використовувати майже будь-якого постачальника ідентифікаційної інформації). - Забезпечуємо централізовану систему автентифікації.
Перед початком налаштування у повинно бути:
- розгорнутий argoсd;
- встановлена утиліта argocd-cli;
- створений системний користувач у freeipa для інтеграції;
Налаштування
Щоб не виникало проблем з групами та налаштуванням ldap переглянемо доступні атрибути для тестового користувача. Для цього скористаємось командою ldapsearch, запустимо її на сервері freeipa:
ldapsearch -W -D uid=<USER>,cn=users,cn=accounts,dc=example,dc=com -b "uid=<USER>,cn=users,cn=accounts,dc=example,dc=com" '(memberof=cn=ipausers,cn=groups,cn=accounts,dc=example,dc=com)'
Отримали вивід, в якому є необхідна інформація. Щоб не було проблем з пошуком груп в ldap варто звернути увагу на доступні objectClass оскільки вони можуть бути в кожного свої:
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <uid=test_user,cn=users,cn=accounts,dc=example,dc=com> with scope subtree
# filter: (memberof=cn=ipausers,cn=groups,cn=accounts,dc=example,dc=com)
# requesting: ALL
#
# test_user, users, accounts, example.com
dn: uid=test_user,cn=users,cn=accounts,dc=example,dc=com
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=example,dc=com
krbExtraData:: ********************
krbPasswordExpiration: *************
krbLastPwdChange: *************
krbLoginFailedCount: 0
krbLastFailedAuth: *************
gidNumber: *********
uidNumber: ***********
ipaUniqueID: *******8-6***-***c-8***-1**2****7**4b
ou: EC
givenName: Test
krbPrincipalName: [email protected]
mail: [email protected]
uid: test_user
homeDirectory: /home/test_user
sn: User
gecos: Test User
initials: TU
loginShell: /bin/bash
objectClass: posixaccount
objectClass: ipaobject
title: TEST
krbCanonicalName: [email protected]
cn: Test User
displayName: Test User
mepManagedEntry: cn=test_user,cn=groups,cn=accounts,dc=example,dc=com
krbLastAdminUnlock: ************
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
також опції для користувачів та груп можемо отримати через UI, для цього в freeipa потрібно перейти в IPA Server > Configuration:
Створимо файл patch-dex.yaml в якому опишемо необхідні параметри для configmap argocd:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://<YOUR_ARGOCD_URL>
dex.config: |
connectors:
- type: ldap
id: ldap
name: LDAP
config:
host: <YOUR_IPA_SERVER_URL>:636
bindDN: uid=<INTEGRATION_IPA_USER>,cn=users,cn=accounts,dc=example,dc=com
bindPW: <INTEGRATION_IPA_PASS>
insecureNoSSL: false
insecureSkipVerify: true
usernamePrompt: Username
# Ldap user serch attributes
userSearch:
baseDN: "cn=users,cn=accounts,dc=example,dc=com"
filter: "(objectClass=posixAccount)"
username: uid
idAttr: DN
emailAttr: mail
nameAttr: cn
# Ldap group serch attributes
groupSearch:
baseDN: "cn=groups,cn=accounts,dc=example,dc=com"
filter: "(objectClass=ipaobject)"
userMatchers:
- userAttr: DN
groupAttr: member
nameAttr: cn
Звертаємо увагу на filter: “(objectClass=ipaobject)” тут потрібно вказати той об’єкт який описаний у Вашій ipa(ми переглядали вище використовуючи ldapsearch), якщо він не вірний – dex не зможе отримати ldap групи.
Також є змога дуже чуттєві дані передавати через secrets, для цього потрібно:
kubectl -n argocd patch secrets argocd-secret --patch "{\"data\":{\"dex.ldap.bindPW\":\"$(echo IPA_INT_USER_PASS | base64 -w 0)\"}}"
kubectl -n argocd patch secrets argocd-secret --patch "{\"data\":{\"dex.ldap.bindDN\":\"$(echo uid=<INTEGRATION_IPA_USER>,cn=users,cn=accounts,dc=example,dc=com | base64 -w 0)\"}}"
та в configmap вказати:
bindDN: "$dex.ldap.bindDN" bindPW: "$dex.ldap.bindPW"
Скажу відразу, варіант з використанням secrets не розглядав (поки що), проте гадаю комусь буде корисним.
Що ж застосовуємо описані нами зміни:
kubectl apply -f patch-dex.yaml
Взагалі argocd вміє в реальному часі перечитувати конфігураційні файли, тому видаляти або скейлити поди з dex та argo-server не обов’язково.
Далі пробуємо виконати вхід до argo за допомогою argocd-cli:
argocd login <YOUR_ARGOCD_URL> --sso
або через UI, де у Вас з’явиться кнопка “LOG IN VIA ...”(якщо кнопка не з’явилася — перегляньте ще раз configmap та усуньте помилки):
після чого відкривається нова сторінка в браузері де потрібно вказати логін та пароль від ldap, вводимо дані та тиснемо Login:
перевіряємо логи argocd-dex-server:
│ time="2023-08-16T10:56:12Z" level=info msg="performing ldap search cn=users,cn=accounts,dc=example,dc=com sub (&(objectClass=posixAccount)(uid=test_user))"
│ time="2023-08-16T10:56:12Z" level=info msg="username \"test_user\" mapped to entry uid=test_user,cn=users,cn=accounts,dc=example,dc=com"
│ time="2023-08-16T10:56:12Z" level=info msg="performing ldap search cn=groups,cn=accounts,dc=example,dc=com sub (&(objectClass=ipaobject)(member=uid=test_user,cn=users,cn=accounts,dc=example,dc=com))"
│ time="2023-08-16T10:56:12Z" level=info msg="login successful: connector \"ldap\", username=\"Test User\", preferred_username=\"\", email=\"[email protected]\", groups=[\"ipausers\"]
Як бачимо, логін пройшов успішно, ldap групи відображаються. Якщо в рядку groups=[] порожньо, не лякайтесь, варто погратися з filter: “(objectClass=””)” та додати Ваш об’єкт групи. Загалом інтеграцію налаштовано. Залишається розібратися з правами, на основі ldap груп нарізати відповідні доступи в argo. Даний процес розглянемо в окремій публікації.
Оскільки для розгортання використовувався helm, всі описані зміни додамо в custom-values.yaml знайшовши відповідні опції в файлі чарту valeus.yaml:
configs: cm: url: https://<YOUR_ARGOCD_URL> dex.config: | connectors: - type: ldap id: ldap name: LDAP config: # host and port of the LDAP server in form "host:port". host: <YOUR_FREEIPA_SERVER_URL>:636 bindDN: uid=<FREEIPA_INT_USER>,cn=users,cn=accounts,dc=example,dc=com bindPW: <FREEIPA_INT_PASS> insecureNoSSL: false insecureSkipVerify: true usernamePrompt: Username # Ldap user serch attributes userSearch: baseDN: "cn=users,cn=accounts,dc=example,dc=com" filter: "(objectClass=posixAccount)" username: uid idAttr: DN emailAttr: mail nameAttr: cn # Ldap group serch attributes groupSearch: baseDN: "cn=groups,cn=accounts,dc=example,dc=com" filter: "(objectClass=ipaobject)" userMatchers: - userAttr: DN groupAttr: member nameAttr: cn
Корисні посилання
- https://dexidp.io/docs/connectors/ldap
- https://www.freeipa.org
- https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/values.yaml
- https://argo-cd.readthedocs.io/en/stable