Как выполнить операцию соединения в LDAP без явного использования учетных данных (анонимное соединение не допускается)

Вопрос или проблема

Я создал портал для своей компании, и из-за некоторых требований нам нужно запрашивать сервер LDAP для получения некоторых данных. Однако мне не разрешается использовать/хранить какие-либо учетные данные для запроса ldap. Кроме того, сервер ldap не позволяет анонимное подключение. Есть ли способ выполнить операцию подключения и запросить сервер ldap? Мой веб-сервер работает на системе Linux и подключен к домену. В бэкенде я использую Python.

Мне не разрешается использовать/хранить какие-либо учетные данные для запроса ldap. Кроме того, сервер ldap не позволяет анонимное подключение.

Ваши требования противоречивы. Либо вы подключаетесь с учетными данными, либо без – третьего варианта нет.

Можно использовать gss-proxy для хранения учетных данных (Kerberos keytab) таким образом, чтобы приложение могло их использовать, но не могло извлечь – то есть файл ключа доступен только пользователю root, а демон gss-proxy действует как агент, аналогичный LSASS в Windows. Это был бы самый безопасный вариант; однако, учетные данные все равно нужно хранить где-то в системе.

(К слову: gss-proxy не является тем же, что и KCM от sssd. Последний только предоставляет хранилище, но не обеспечивает изоляцию учетных данных.)

Можно достичь чего-то подобного без gss-proxy, используя задачу cron с kinit (или инструмент k5start – который работает под другой учетной записью, получает TGT для веб-приложения и переносит кэш тикетов. Таким образом, веб-приложение может использовать свой 10-часовой Kerberos тикет для запроса LDAP, но не имеет доступа к долгосрочным учетным данным.

(На машине уже хранятся свои “учетные данные машины” на диске, т.е. machine keytab, которые могли бы в теории быть использованы для этой цели; но это было бы менее безопасно, поскольку это позволило бы веб-приложению выдавать себя за машину, поэтому это определенно не то, что вы хотите. Приложение действительно должно иметь свой набор учетных данных.)

Также можно использовать аутентификацию Kerberos для самого веб-приложения (т.е. SPNEGO от веб-браузера к приложению) и настроить его на делегирование учетных данных пользователя веб-приложению, чтобы запрос LDAP мог быть выполнен с использованием делегированных учетных данных пользователя (которые временно хранятся на диске). Но делегирование само по себе небезопасно – это означает, что вместо того, чтобы хранить только один набор учетных данных постоянно, приложение теперь хранит много наборов временно и может выдавать себя за каждого пользователя, так что риск выше.


Для использования gss-proxy:

  1. Создайте учетную запись службы AD для веб-приложения.

  2. Создайте keytab для учетной записи службы.

  3. Убедитесь, что вы можете kinit с помощью keytab, и что приложение может аутентифицироваться на LDAP, используя Kerberos (SASL GSSAPI bind); используйте kdestroy после тестирования.

    >>> import gssapi
    >>> import os
    
    # Учетных данных пока нет
    >>> gssapi.Credentials(usage="initiate").name
    gssapi.raw.exceptions.MissingCredentialsError
    
    # Проверьте, что keytab корректен
    >>> os.system("kinit -k -t app.keytab")
    >>> os.system("klist")
    Кэш тикетов: FILE:/tmp/krb5cc_2001
    Основной принцип: [email protected]
    
    >>> gssapi.Credentials(usage="initiate").name
    Name(b'[email protected]', <OID 1.2.840.113554.1.2.2.1>)
    
    >>> os.system("kdestroy")
    

    Чтобы использовать Kerberos с LDAP:

    serv = ldap3.Server("ldap://dc01.example.com")
    conn = ldap3.Connection(serv,
                            authentication=ldap3.SASL,
                            sasl_mechanism="GSSAPI")
    conn.bind()
    

    Сервер LDAP должен указываться по имени, а не по IP-адресу.

  4. Установите gss-proxy.

  5. Настройте gss-proxy, чтобы ваш системный UID приложения использовал keytab как в примере httpd. Убедитесь, что вы chown keytab на другую учетную запись пользователя (например, root), чтобы приложение больше не могло читать его напрямую.

    [service/myapp]
        mechs = krb5
        cred_store = ccache:/var/lib/gssproxy/clients/krb5cc_%U
        cred_store = client_keytab:/etc/gssproxy/myapp.keytab
        euid = myapp
    
  6. Запустите ваше приложение с GSS_USE_PROXY=1 в окружении. Библиотека GSSAPI автоматически будет общаться с gss-proxy вместо поиска локального тикета.

    >>> import gssapi
    >>> import os
    
    # Учетных данных пока нет
    >>> gssapi.Credentials(usage="initiate").name
    gssapi.raw.exceptions.MissingCredentialsError
    
    # Скажем libgssapi говорить с прокси
    >>> os.environ["GSS_USE_PROXY"] = "1"
    
    # Теперь он может видеть тикеты, полученные gss-proxy
    >>> gssapi.Credentials(usage="initiate").name
    Name(b'[email protected]', <OID 1.2.840.113554.1.2.2.1>)
    

Ответ или решение

Как выполнить операцию привязки в LDAP без явного использования учетных данных: Подробное руководство

Ваша задача – осуществить привязку к LDAP серверу для выполнения запросов без хранения учетных данных. Поскольку анонимная привязка недоступна и хранение учетных данных запрещено, необходимо адаптировать подход с использованием Kerberos и gss-proxy. В данном руководстве мы изучим, как это сделать, исходя из вашего окружения (Linux и Python).

1. Использование Kerberos для аутентификации

Kerberos позволяет безопасно аутентифицировать пользователей и сервисы без необходимости передавать пароли по сети. В вашем случае необходимо выполнить следующие шаги:

  • Создание учетной записи сервиса: Создайте учетную запись в Active Directory (AD) для вашего веб-приложения.

  • Генерация ключевого файла (keytab): С помощью утилиты ktutil или kadmin создайте ключевой файл, который будет использоваться для аутентификации.

2. Проверка и тестирование Kerberos

Проверьте корректность созданного keytab-файла. Используйте команды kinit и klist для получения TGT (Ticket Granting Ticket) и отображения существующих билетов:

kinit -k -t app.keytab
klist

Вы должны увидеть свой TGT, подтверждающий успешную аутентификацию.

3. Установка gss-proxy

Поскольку вам необходимо изолировать учетные данные, установите и настройте gss-proxy. Это позволяет вашему приложению безопасно использовать учетные данные Kerberos:

  1. Установка gss-proxy:

    sudo apt-get install gssproxy
  2. Конфигурация gss-proxy:

    • Создайте конфигурационный файл, например, /etc/gssproxy/gssproxy.conf:
      [service/myapp]
      mechs = krb5
      cred_store = ccache:/var/lib/gssproxy/clients/krb5cc_%U
      cred_store = client_keytab:/etc/gssproxy/myapp.keytab
      euid = myapp
    • Замените myapp на имя пользователя, под которым запускается ваше приложение.
  3. Изменение разрешений на keytab: Убедитесь, что только нужные пользователи могут получить доступ к keytab:

sudo chown root:root /etc/gssproxy/myapp.keytab
sudo chmod 400 /etc/gssproxy/myapp.keytab

4. Настройка вашего Python приложении

В вашем Python приложении установите переменную окружения GSS_USE_PROXY, чтобы использовать gss-proxy для получения билетов Kerberos:

import os
import gssapi
import ldap3

os.environ["GSS_USE_PROXY"] = "1"

# Убедитесь в наличии билета
try:
    gssapi.Credentials(usage="initiate").name
except gssapi.raw.exceptions.MissingCredentialsError:
    print("Билеты отсутствуют. Проверьте конфигурацию GSS-Proxy.")

# Подключение к LDAP
server = ldap3.Server("ldap://dc01.example.com")
conn = ldap3.Connection(server, authentication=ldap3.SASL, sasl_mechanism="GSSAPI")
if conn.bind():
    print("Успешная привязка к LDAP!")
else:
    print("Не удалось выполнить привязку: ", conn.result)

Заключение

Используя комбинацию Kerberos и gss-proxy, вы можете безопасно выполнять операции привязки к LDAP без необходимости явного хранения учетных данных. Этот метод обеспечивает высокий уровень безопасности и изоляции учетных данных, что соответствует требованиям вашей организации. Помните, что адекватная настройка и тестирование системы являются ключевыми моментами для успешной реализации.

Оцените материал
Добавить комментарий

Капча загружается...