К основному контенту

Superset: Интеграция Apache Superset с Active Directory

 


Ниже — подробная, практическая статья по интеграции Superset с Microsoft Active Directory.

Примечание: инструкция рассчитана на запуск Superset в Kubernetes с помощью Helm. Так же это применимо и для minikube


Краткий обзор (TL;DR)

  1. Создать сервисный аккаунт в AD (bind user) — не использовать личный аккаунт администратора.

  2. В Kubernetes хранить секреты (bind DN, пароль) в k8s Secret.

  3. Обновить values.yml Helm-чарта: поменять образ на partonen/superset, передать переменные окружения / секреты и маунт superset_config.py.

  4. В superset_config.py настроить Flask-AppBuilder LDAP (AUTH_LDAP), сопоставление полей пользователей и маппинг AD-групп → роли Superset.

  5. Развернуть Helm, проверить логи, протестировать вход LDAP-пользователем.

  6. Включить безопасное соединение (TLS/LDAPS) в проде; отладку — только временно.


Требования и предпосылки

  • Kubernetes-кластер с доступом kubectl и права на создание Secrets/ConfigMaps.

  • Helm-чарт для Superset (вы используете Helm + values.yml).

  • Доступ к Active Directory (адрес AD/LDAPS, порт, базовый DN).

  • Созданный сервисный аккаунт в AD (bind user) с правом поиска в нужной OU.

  • SSL-сертификаты для LDAPS (если используете TLS/LDAPS).


Шаг 1 — Подготовка Active Directory (анонимно)

  1. Создайте в AD аккаунт типа служебного svc_superset (не админ), и поместите его в OU, где он может читать атрибуты пользователей и группы.
    Плейсхолдеры:

    • Bind DN: CN=svc_superset,OU=svc,OU=users,DC=corp,DC=example,DC=com → замените на ваш DN.

    • Bind password: никогда не храните в репозитории — используйте Kubernetes Secret.

  2. Определите OU/users search base и формат UID для пользователей (обычно sAMAccountName для AD).

    • Search base: OU=People,DC=corp,DC=example,DC=com (пример).

  3. Решите, как будете маппить AD-группы на роли Superset (например AD_Group_Superset_Admins → роль Admin в Superset).


Шаг 2 — Создание Kubernetes Secret (без паролей в репозитории)

Создайте Secret, где хранится BIND_DN и BIND_PASSWORD. Ниже — пример команды (замените значения на реальные при выполнении):

kubectl create secret generic superset-ldap \ --from-literal=LDAP_BIND_DN='CN=svc_superset,OU=svc,OU=users,DC=corp,DC=example,DC=com' \ --from-literal=LDAP_BIND_PASSWORD='REPLACE_WITH_BIND_PASSWORD' \ --namespace superset

Важно: REPLACE_WITH_BIND_PASSWORD — замените командой на реальный пароль только в момент создания. Не сохраняйте пароль в коде.


Шаг 3 — Настройка Helm values.yml (замена образа)

В вашем values.yml Helm-чарта замените образ Superset на нужный:

image: repository: partonen/superset tag: "latest" # или конкретная версия, например "2.1.0" pullPolicy: IfNotPresent # Пример передачи env из Secret extraEnv: - name: LDAP_BIND_DN valueFrom: secretKeyRef: name: superset-ldap key: LDAP_BIND_DN - name: LDAP_BIND_PASSWORD valueFrom: secretKeyRef: name: superset-ldap key: LDAP_BIND_PASSWORD - name: LDAP_SERVER_URI value: "ldaps://ad.corp.example.com:636" # или ldap:// если без TLS # Маунт конфигурации superset_config.py (через ConfigMap или Secret) extraVolumes: - name: superset-config configMap: name: superset-configmap extraVolumeMounts: - name: superset-config mountPath: /app/pythonpath/superset_config.py subPath: superset_config.py

Если ваш чарт отличается по структуре — адаптируйте. Главное: image.repository: partonen/superset.


Шаг 4 — Подготовка superset_config.py 

Поместите superset_config.py в ConfigMap (или в образ, если билдите собственный). Ниже — подробный пример конфигурации LDAP для Flask-AppBuilder / Superset. Пароли/секреты заменены на чтение из переменных окружения.

# superset_config.py (анонимизированный пример) import os from flask_appbuilder.security.manager import AUTH_LDAP # --- Общие настройки аутентификации --- AUTH_TYPE = AUTH_LDAP AUTH_ROLE_ADMIN = "Admin" # роль Superset для админов AUTH_USER_REGISTRATION = True # авт. регистрация при первом входе (опционально) AUTH_USER_REGISTRATION_ROLE = "Gamma" # роль по умолчанию для новых пользователей AUTH_ROLES_SYNC_AT_LOGIN = True # --- Параметры LDAP/AD --- # Сервер LDAP/LDAPS (читается из env) AUTH_LDAP_SERVER = os.environ.get("LDAP_SERVER_URI", "ldap://REPLACE_WITH_AD:389") AUTH_LDAP_USE_TLS = os.environ.get("LDAP_USE_TLS", "False") == "True" # Bind DN и пароль (берём из env, которые мы передали из k8s Secret) AUTH_LDAP_BIND_USER = os.environ.get("LDAP_BIND_DN", "") AUTH_LDAP_BIND_PASSWORD = os.environ.get("LDAP_BIND_PASSWORD", "") # Где искать пользователей (search base) AUTH_LDAP_SEARCH = os.environ.get("LDAP_SEARCH_BASE", "OU=People,DC=corp,DC=example,DC=com") # Поле, соответствующее логину пользователя в AD AUTH_LDAP_UID_FIELD = os.environ.get("LDAP_UID_FIELD", "sAMAccountName") # Маппинг атрибутов (при необходимости) AUTH_LDAP_FIRSTNAME_FIELD = "givenName" AUTH_LDAP_LASTNAME_FIELD = "sn" AUTH_LDAP_EMAIL_FIELD = "mail" # Если требуется — поле с членством в группах (AD обычно использует memberOf) AUTH_LDAP_GROUP_FIELD = "memberOf" # --- Маппинг AD-групп -> ролям Superset --- # Формат ключей зависит от того, как AD возвращает memberOf (обычно полные DN групп). # Здесь перечислены примеры, замените на свои DN групп. AUTH_ROLES_MAPPING = { "CN=SUPSET_AD_ADMINS,OU=Groups,DC=corp,DC=example,DC=com": ["Admin"], "CN=SUPSET_AD_PUBLISHERS,OU=Groups,DC=corp,DC=example,DC=com": ["Alpha"], # Новые пользователи по умолчанию получат роль из AUTH_USER_REGISTRATION_ROLE } # --- Доп. настройки логирования/отладки (временно) --- # WARNING: включайте только для отладки, не в проде if os.environ.get("LDAP_DEBUG", "False") == "True": import logging logging.getLogger("flask_appbuilder.security.manager").setLevel(logging.DEBUG) try: import ldap ldap.set_option(ldap.OPT_DEBUG_LEVEL, 255) except Exception: pass # --- Остальные настройки Superset по желанию ---

Пояснения:

  • AUTH_ROLES_MAPPING — сопоставляет AD-группы (DN) ролям Superset. Подставьте те DN, которые возвращает memberOf в вашем AD.

  • AUTH_USER_REGISTRATION: если True, то при первом логине пользователя он будет автоматически создан в Superset. Если вы хотите ручную проверку — ставьте False.

  • Все секреты читаются из переменных окружения, поэтому в Helm/values нужно пробросить их из Kubernetes Secret (см. предыдущий раздел).


Шаг 5 — Развёртывание (примерная последовательность)

  1. Создайте ConfigMap с superset_config.py:

kubectl create configmap superset-configmap \ --from-file=superset_config.py=./superset_config.py \ -n superset
  1. Убедитесь, что Secret superset-ldap создан (см. Шаг 2).

  2. Подкорректируйте values.yml (см. Шаг 3), затем примените Helm:

helm upgrade --install superset ./superset-chart -f values.yml --namespace superset

(замените ./superset-chart на реальный путь/имя чарта)

  1. Просмотрите логи пода:

kubectl -n superset logs -l app=superset --tail=200

Или конкретного пода:

kubectl -n superset get pods kubectl -n superset logs superset-xxxxx

Шаг 6 — Тестирование входа и валидация

  1. Попробуйте войти в Superset через веб-интерфейс с AD-пользователем (sAMAccountName).

  2. Проверьте, создался ли пользователь в Superset и была ли назначена ожидаемая роль.

  3. Если пользователь не создаётся — проверьте логи (Flask-AppBuilder, Superset) — обычно там видно ошибку поиска/bind.

  4. Для отладки LDAP отдельно можно использовать ldapsearch или ldap3 скрипт из-под того же сервера/пода, где запускается Superset, чтобы убедиться, что bind и поиск работают.

Примеры команд (запускать на машине, имеющей доступ к AD; при использовании LDAPS указывайте порт 636 и TLS):

# Проверка доступности LDAPS nc -vz ad.corp.example.com 636 # ldapsearch (пример) ldapsearch -H ldaps://ad.corp.example.com -D "CN=svc_superset,OU=svc,DC=corp,DC=example,DC=com" -w 'REPLACE_PASSWORD' -b "OU=People,DC=corp,DC=example,DC=com" "(sAMAccountName=jdoe)"

(в Kubernetes можно запустить временный debug-pod и выполнить аналогичную проверку внутри кластера)


Шаг 7 — Безопасность и рекомендации

  1. LDAPS/TLS: в проде используйте ldaps:// (порт 636) или StartTLS, валидируйте сертификат AD. Не используйте plaintext LDAP через интернет.

  2. Секреты: храните пароли в Kubernetes Secret, можно дополнительно зашифровать через External Secrets/SealedSecrets/Vault.

  3. Минимальные привилегии: сервисный аккаунт должен иметь только права на поиск (read) и доступ к атрибутам.

  4. Логирование: временно включайте LDAP debug (см. LDAP_DEBUG), но отключайте в проде, т.к. логи могут содержать чувствительную информацию.

  5. RBAC: стройте маппинг AD-групп → ролям Superset заранее и документируйте его.

  6. Мониторинг: контролируйте неудачные входы, количество созданных пользователей и аудит.


Частые ошибки и диагностика

  • Bind failed / invalid credentials: проверьте LDAP_BIND_DN и пароль в Secret; проверьте, может ли данный DN логиниться снаружи (ldapsearch).

  • Search base неверен: проверьте AUTH_LDAP_SEARCH — если он слишком узкий, нужные пользователи не найдутся.

  • memberOf пуст / нет групп: некоторые AD конфигурации не возвращают memberOf в результатах. Проверьте, какие атрибуты возвращает сервер — возможно, придётся делать дополнительный поиск групп по membership.

  • TLS/сертификаты: при LDAPS ошибка валидации сертификата — добавьте CA в доверенные сертификаты внутри контейнера или используйте verified chain.

  • Пользователь застрял в «машинном» статусе: убедитесь, что AUTH_USER_REGISTRATION и AUTH_USER_REGISTRATION_ROLE выставлены так, как вы хотите.


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

  • Создан сервисный AD-аккаунт (bind DN) с правами поиска.

  • Secret в k8s содержит LDAP_BIND_DN и LDAP_BIND_PASSWORD.

  • ConfigMap с superset_config.py добавлен и монтируется в контейнер.

  • values.yml обновлён — image.repository: partonen/superset.

  • Helm-релиз обновлён и поды поднялись (kubectl get pods).

  • Логи проверены на ошибки bind/search.

  • Тестовый пользователь из AD успешно логинится и получает нужную роль.


Пример анонимизированных фрагментов (подытог)

Пример команды создания Secret (замените значения):

kubectl create secret generic superset-ldap \ --from-literal=LDAP_BIND_DN='CN=svc_superset,OU=svc,OU=users,DC=corp,DC=example,DC=com' \ --from-literal=LDAP_BIND_PASSWORD='REPLACE_BIND_PASSWORD' \ -n superset

Ключевая часть values.yml:

image: repository: partonen/superset tag: "latest" extraEnv: - name: LDAP_BIND_DN valueFrom: secretKeyRef: name: superset-ldap key: LDAP_BIND_DN - name: LDAP_BIND_PASSWORD valueFrom: secretKeyRef: name: superset-ldap key: LDAP_BIND_PASSWORD - name: LDAP_SERVER_URI value: "ldaps://ad.corp.example.com:636" - name: LDAP_SEARCH_BASE value: "OU=People,DC=corp,DC=example,DC=com" - name: LDAP_UID_FIELD value: "sAMAccountName"

Ключевые настройки в superset_config.py (коротко):

AUTH_TYPE = AUTH_LDAP AUTH_LDAP_SERVER = os.environ.get("LDAP_SERVER_URI") AUTH_LDAP_BIND_USER = os.environ.get("LDAP_BIND_DN") AUTH_LDAP_BIND_PASSWORD = os.environ.get("LDAP_BIND_PASSWORD") AUTH_LDAP_SEARCH = os.environ.get("LDAP_SEARCH_BASE") AUTH_LDAP_UID_FIELD = os.environ.get("LDAP_UID_FIELD", "sAMAccountName") AUTH_ROLES_MAPPING = { "CN=SUPSET_AD_ADMINS,OU=Groups,DC=corp,DC=example,DC=com": ["Admin"] }

Комментарии

Популярные сообщения из этого блога

Настройка и подключение IPSec в Windows

Настройка IPSec на Windows включает в себя создание правил безопасности и фильтров для защиты сетевого трафика. Ниже — пошаговое руководство. Включение службы IPSec Перед настройкой убедитесь, что служба IPSec Policy Agent запущена: Нажмите Win + R , введите services.msc и нажмите Enter . Найдите IPsec Policy Agent . Если она не работает, нажмите ПКМ → Свойства . Установите Тип запуска: Автоматически , затем нажмите Запустить . Настройка политики IPSec через «Локальную политику безопасности» Нажмите Win + R , введите secpol.msc , нажмите Enter . Перейдите в Политики IP-безопасности в локальном компьютере . В правом окне нажмите Создать политику IP-безопасности → Далее . Укажите имя политики (например, "IPSec VPN"), снимите флажок Активировать правило по умолчанию , нажмите Далее . Нажмите Добавить , чтобы создать правило. Транспортный или туннельный режим : Если IPSec для защищенной локальной сети – выберите Транспортный режим . Если IPSec для VPN – выберите Туннельн...

Как найти и изменить репозитарии для CentOS 8

В CentOS 8 официальные репозитории (BaseOS, AppStream и Extras) управляются с помощью dnf и файлов конфигурации в /etc/yum.repos.d/ . Вот как их найти и изменить: 1. Просмотр текущих репозиториев dnf repolist Если нужно увидеть подробную информацию: dnf repolist all 2. Изменение репозиториев Файлы конфигурации репозиториев находятся в /etc/yum.repos.d/ . Например, основной репозиторий может быть в файле CentOS-AppStream.repo . Открыть его можно так: nano /etc/yum.repos.d/CentOS-AppStream.repo Внутри можно изменить: enabled=1 → включает репозиторий enabled=0 → отключает репозиторий baseurl= или mirrorlist= → задать новый источник пакетов 3. Замена недоступных репозиториев CentOS 8 достиг конца поддержки , и официальные зеркала больше не работают. Вместо них можно подключить Vault или AlmaLinux/Rocky Linux : Использование архивного репозитория CentOS Vault Создайте резервную копию старых .repo файлов: mkdir /root/repo-backup && mv /etc/yum.repos.d/*.repo /root/repo-backu...

Debian 11: настройка сети и имени хоста /etc/network/interfaces, NetworkManager и systemd-networkd

Как настроить сеть в Debian 11? 🔹 1. Настройка через /etc/network/interfaces (Традиционный способ) Этот метод удобен для серверов и минималистичных систем без NetworkManager . Открываем конфигурационный файл: sudo nano /etc/network/interfaces 🔹 DHCP (Автоматическое получение IP) auto eth0 iface eth0 inet dhcp 🔹 Статический IP auto eth0 iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameservers 8.8.8.8 8.8.4.4 🔹 Wi-Fi (WPA2) auto wlan0 iface wlan0 inet dhcp wpa-ssid "Название_сети" wpa-psk "Пароль" 📌 Применение изменений: sudo systemctl restart networking 🔹 2. Настройка через NetworkManager (Удобно для десктопов) Проверяем статус: systemctl status NetworkManager Если не установлен, ставим: sudo apt install network-manager sudo systemctl enable --now NetworkManager 🔹 Графический интерфейс (TUI) nmtui Выберите Edit a connection , настройте параметры и сохраните. 🔹 Консольный способ ( nmcli ...