Вопрос или проблема
Я создал портал для своей компании, и из-за некоторых требований нам нужно запрашивать сервер 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:
-
Создайте учетную запись службы AD для веб-приложения.
-
Создайте keytab для учетной записи службы.
-
Убедитесь, что вы можете
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-адресу.
-
Установите gss-proxy.
-
Настройте 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
-
Запустите ваше приложение с
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:
-
Установка gss-proxy:
sudo apt-get install gssproxy
-
Конфигурация 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
на имя пользователя, под которым запускается ваше приложение.
- Создайте конфигурационный файл, например,
-
Изменение разрешений на 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 без необходимости явного хранения учетных данных. Этот метод обеспечивает высокий уровень безопасности и изоляции учетных данных, что соответствует требованиям вашей организации. Помните, что адекватная настройка и тестирование системы являются ключевыми моментами для успешной реализации.