Эта статья - кратчайшее введение в LDAP и службы каталогов. Для иллюстрации излагаемого материала я буду пользоваться инструментом Softerra LDAP Browser, который можно свободно скачать с сайта производителя .

Концепцию служб каталогов и требования к их реализации определяет серия стандартов X.500 ITU-T. Здесь каталог - это специализированная база данных, оптимизированная для поиска и извлечения информации, также поддерживающая добавление и изменение данных.

Среди реализаций служб каталогов наиболее известные - OpenLDAP и MS Active Directory. Клиентами каталогов являются адресные книги почтовых клиентов, сетевые службы, такие как DNS, SMTP, корпоративные приложения и информационные системы.

Как правило, служба каталогов

  • реализует протокол для взаимодействия с клиентами,
  • поддерживает разграничение доступа,
  • поддерживает репликацию каталогов,
  • не поддерживает механизм транзакций.

Для взаимодействия со службами каталогов X.500 широко используется протокол LDAP (Lightweight Directory Access Protocol), специфицированный в RFC4510 . LDAP работает поверх TCP/IP и является легковесной альтернативой протокола DAP (Directory Access Protocol), весьма требовательного к вычислительным ресурсам.

LDAP реализует протокол взаимодействия со службой каталогов и задает модель данных, соответствующую X.500. Эта модель данных такова:

  • В каталоге хранятся записи (entry).
  • Запись - это коллекция атрибутов (attribute), имеющая уникальное имя (Distinguished Name, DN).
  • Каждый атрибут имеет тип (type) и одно или несколько значений. Синтаксис значений зависит от типа.
  • Атрибут objectClass позволяет контролировать, какие атрибуты обязательны и какие допустимы в записи. Таким образом, записи, как и атрибуты, имеют тип (object class).
  • Записи в каталоге организованы иерархически в виде дерева.
  • Определения типов записей (object classes) и типов атрибутов сами являются записями в каталоге, в специальном поддереве, известном как schema.

Запустим Softerra LDAP Browser и откроем одну из публичных служб каталогов, параметры соединения с которыми предустановлены по умолчанию. (Настроив соединение с MS Active Directory или OpenLDAP в вашей корпоративной сети, вы можете исследовать структуру и содержимое корпоративного каталога.)

Иерархическая организация данных в каталоге часто отражает географическую или организационную структуру. Записи на верхнем уровне могут представлять страны, на нижних - области стран и организации, еще ниже - отделы внутри организаций, людей, оборудование, ресурсы. А можно построить дерево по доменным именам Internet.

Текущая выбранная запись в каталоге Carnegie Mellon University (см. картинку выше) имеет уникальное имя DN o=CMRI,o=CMU,dc=cmu,dc=edu . Компоненты DN - имена узлов иерархической структуры от корневого до текущего (справа налево). Самый левый компонент DN называется относительным уникальным именем (Relative Distinguished Name, RDN). Таким образом, DN o=CMRI,o=CMU,dc=cmu,dc=edu состоит из RDN o=CMRI и DN родительской записи o=CMU,dc=cmu,dc=edu .

Можно рассматривать DN как абсолютный путь к файлу (по аналогии с файловой системой) или как первичный ключ записи в таблице (по аналогии с реляционной БД).

В рассматриваемом DN o=CMRI,o=CMU,dc=cmu,dc=edu два верхних уровня названы по доменным именам Internet. А уровнем ниже текущей записи располагаются записи, идентифицируемые значением атрибута ou (см. картинку выше). Здесь имена атрибутов, идентифицирующие записи разных уровней, имеют следующие значения:

Dc аббревиатура от domain component o аббревиатура от organization ou аббревиатура от organizational unit

Эти имена, как и десятки других, - имена стандартных атрибутов, специфицированных в RFC 2256 и предназначенных для использования в объектных классах, описывающих людей, организации, их подразделения и т.п. Все реализациии LDAP поддерживают эти стандартные типы атрибутов. Вот еще несколько примеров: telephoneNumber , name , givenName , postalAddress , sn (аббревиатура от surname).

В рассматриваемой записи с DN o=CMRI,o=CMU,dc=cmu,dc=edu имеются три атрибута, objectClass , o и businessCategory , по каждому из которых можно искать эту запись в каталоге.

Для поиска записей в LDAP-каталоге задаются три компонента:

Base DN (базовое уникальное имя) показывает, откуда в иерархии начать поиск scope (область поиска) показывает область поиска, одно из:

  • одна запись, идентифицированная base DN
  • записи уровнем ниже base DN, т.е. дочерние, но не внучатые
  • поддерево с корнем base DN, включая корень
filter (фильтр) задает условие отбора записей

Например, поиск по условию

BaseDN: o=CMU,dc=cmu,dc=edu scope: поддерево filter: objectClass=organizationalUnit & ou=*Student*

вернет все записи из поддерева с корнем o=CMU,dc=cmu,dc=edu , удовлетворяющие фильтру (синтаксис фильтра в этом примере легко читаемый, но неправильный, см. далее).

На заметку: cуществуют специальные базовые DN для запроса информации о возможностях сервера, для доступа к схеме (schema) и данным мониторинга.

В Softerra LDAP Browser по Ctrl+F3 вызывается окно поиска, в котором удобно экспериментировать с параметрами поиска LDAP:

В фильтре можно использовать следующие проверки для атрибутов (атрибут ou взят для примера):

Присутствие атрибута (ou=*) Равенство значения (ou=School) Наличие подстроки (ou=S*) Больше или равно (ou>=School) Меньше или равно (ou

Заметьте, что отсутствуют проверки > и < . Проверка на приближенное равенство ~= использует фонетические сравнение. Расширенная проверка для сравнения образца со значением атрибута использует реализованное LDAP-сервером правило, идентификатор которого указан после двоеточия. Примеры выражений для проверки наличия подстроки (звездочка означает 0 или более символов):

В начале Sch* в середине *oo* в конце *ol в начале и в конце Sc*ol

Проверки в фильтре можно комбинировать при помощи логических операторов:

AND (&(sn=Иванов)(phone=*)(GivenName=И*)) OR (|(cn=Багира)(cn=Балу)) NOT (!(cn=Пикачу))

Внимание! Последний фильтр с NOT вернет также записи, не содержащие атрибута cn .

Формируя запрос, можно указать типы атрибутов, которые должны быть включены сервером каталога в ответ. Если список типов атрибутов пуст, то окно поиска LDAP Browser отображает идентифицирующие атрибуты найденных записей (это RDN) и DN родительских записей - вместе они образуют DN найденных записей. Поиск LDAP всегда возвращает DN найденных записей, помимо и независимо от списка атрибутов. Зададим явно список атрибутов, которые мы хотим видеть и повторим запрос (несуществующие типы атрибутов в списке игнорируются сервером и не приводят к ошибке):

Чтобы хорошо освоить синтаксис фильтра, попробуйте разные проверки и их логические комбинации.

Как уже упоминалось, служба каталогов позволяет не только извлекать, но также добавлять и модифицировать записи. Softerra LDAP Browser поддерживает только просмотр данных в каталоге, поэтому для внесения изменений в каталог необходим другой инструмент (например, платный Softerra LDAP Administrator).

Для работы с LDAP практически из любого языка программирования можно воспользоваться существующими библиотекми для этого языка. В будущих статьях, посвященных LDAP, я рассмотрю работу с MS Active Directory в Oracle PL/SQL и в языке программирования Python.

Эта статья была написана для одного компьютерного журнала довольно давно. Поскольку с тех пор они так и не связались со мной по поводу её дальнейшей судьбы, делаю вывод о том, что она не пригодилась и выкладываю на суд общественности.

Это НЕ руководство по установке и внедрению LDAP. Всего лишь обзор для тех, кто ещё не знает - а что же это за зверь такой...

Комментарии приветствуются.

СЛУЖБЫ КАТАЛОГОВ. что это и для чего они нужны

И что бы люди там ни говорили —
Я доживу, переберу позвездно,
Пересчитаю их по каталогу,
Перечитаю их по книге ночи.

Сети растут. Локальные сети - не исключение. Зачастую сетка, ещё вчера связывавшая три компьютера, сегодня разрослась, заматерела и обросла ресурсами. Как не потеряться в них? Как не запутаться в логинах и паролях? Как быстро найти нужную информацию? Рано или поздно эти вопросы встают практически перед каждым системным администратором.

Многие обходятся самописными скриптами. Это истинные самураи, их воля подобна лезвию катаны, а затраченное время легко компенсируется полученым опытом. Другие же, умудрённые процессом передачи дел и должности в случае смены работы или ухода в отпуск, используют стандартизированные решения. Имя этим решениям - службы каталогов.

В данном обзоре я кратко введу Вас в курс дела. Итак, что же такое службы каталогов?

Очень кратко и очень упрощённо - это своего рода базы данных, хранящие в себе информацию о пользователях, узлах и объектах сети. Цель их создания - упростить администрирование.

Возникает вопрос: отчего же не использовать именно базу данных? Дело в том, что между сервисом каталогов и реляционными базами данных есть довольно существенные различия:

  • модель хранения информации - иерархическая древовидная структура (у БД структура реляционная);
  • LDAP ориентирован на ускорение операции чтения, тогда как в БД приоритетна операция записи;
  • данные в LDAP меняются сравнительно редко;
  • клиенты используют стандартный протокол LDAP, тогда как протокол взаимодействия БД с клиентами не стандартизирован;
  • и наконец, служба каталогов обычно легко масштабируется (реплицируется) на несколько серверов.

Служба каталогов легко интегрируется с множеством сервисов, начиная от web-серверов, заканчивая CMS (content managment system). Загляните в документацию используемого Вами приложения, требующего авторизации и поищите там ключевое слово LDAP. Нашли? Так это оно и есть...

Начиналось всё просто. Сети были маленькими, а компьютеры - большими. И было их не так чтобы очень много. В те полузабытые, практически былинные времена обходились простым копированием файлов конфигурации с одного компьютера на другой.

Но время шло. Сети росли и матерели. Становилось всё очевиднее, что нужны какие-то решения. То, что облегчит и без того нелёгкую жизнь системных и сетевых администраторов.

Одной из первых реализаций сервисов такого рода стала разработка комапании Sun Microsystems, первоначально названная Yellow Pages. Впоследствии, из за юридических трений, название было заменено на Network Information Service (NIS) под которым она до сих пор широко известна (в узких кругах).

В основе разработки лежала простая мысль - у компьютеров работающие в сети многие конфигурационные файлы полностью совпадают. Так отчего бы не сделать так, чтобы компьютеры брали эти файлы с одного сервера. Таким образом экономилось не только дисковое пространство (NIS была разработана давно и этот фактор был довольно актуален), но и время затрачиваемое на синхронизацию этих файлов.

Службой каталогов это назвать было сложно, но первые шаги в нужном направлении были сделаны.

Поскольку идея оказалась востребована, CCITT и ISO пошли дальше и разработали серию стандартов X.500, которые включали в себя следующие протоколы: DAP (Directory Access Protocol), DSP (Directory System Protocol), DISP (Directory Information Shadowing Protocol) и DOP (Directory Operational Bindings Management Protocol). Однако впоследствии выяснилось, что эти протоколы чрезмерно сложны и была проведена работа по разработке замены. Ей стал протокол LDAP (Lightweight Directory Access Protocol), послуживший основой для многих удачных решений.

История наиболее известных, основанных на LDAP продуктов, уходит корнями в далёкий 1995 год, когда сотрудники Мичиганского Университета написали первый LDAP-сервер - slapd. В 1996 году компания Netscape пригласила их на работу. В 1999 году, компания AOL стала собственником Netscape. Для продолжения работ над серверными продуктами был заключён стратегический альянс с компанией Sun. Назвали это iPlanet Alliance. С 1999 по 2001 годы команда Netscape Directory Server работала совместно с командой Sun Directory Server, а впоследствии и с разработчиками Innosoft Directory Server (IDDS). Работы велись как над Directory Server, так и над смежными проектами, такими как Meta Directory и Directory Access Router. В октябре 2001 года iPlanet Alliance распался, а его участники Sun и Netscape начали независимое развитие своих продуктов. С 2001 по 2004 годы разработчики Netscape Directory Server много работали над этим проектом. В декабре 2004 Netscape Directory Server стал собственностью компании Red Hat.

Итак, покончив на этом с историей, посмотрим - какие службы каталогов имеются в наличии и чем они хороши.

NIS (хотя, строго говоря, это и не служба каталогов).

Эта разработка Sun Microsystems оказалась очень живучей и используется до сих пор. Её плюсами являются простота концепции и реализации. Минус - можно использовать только на UNIX-совместимых операционных системах, с совпадающими конфигурационными файлами. Отдадим ей дань уважения и перейдём к полноценным LDAP-продуктам. В данной статье я не буду останавливаться на технических подробностях, скажу лишь, что их базовая функциональность различается незначительно. Различия начинаются на уровне документации и прикладного софта, облегчающего администрирование.

Итак, начнём с открытых и бесплатных. Их немного. Собственно, всего два.

Red Hat Directory Server и Fedora Directory Server

Red Hat Directory Server изначально была куплена у Netscape Security Solutions как коммерческий продукт для Red Hat Enterprise Linux, теперь её выпускает сам Red Hat под названием Red Hat Directory Server. Следуя своей политике, Red Hat выпускает и версию для Fedora Core. Её название - Fedora Directory Server. Red Hat Directory Server работает под управлением Red Hat Enterprise Linux (x86, версии 3 и 4), Solaris 9 (SPARC, как 32-разрядный, так и 64-разрядный), HP-UX 11i для HP-9000, а также для 64-разрядной линейки HP Integrity server. Fedora Directory Server менее привередлива и соглашается работать как под Fedora Core (x86, версии 3 и 4) и Red Hat Enterprise Linux, так и под другими версиями linux - gentoo, debian и т.п. Поддерживаются также и Solaris, Windows 2000 и HP/UX 11i (pa-risc). Вывод: отличный выбор для дистрибутивов на базе RedHat. Хорошо документирован, чем выгодно отличается от OpenLDAP. Код этих проектов во многом совпадает (из-за общего прародителя).

OpenLDAP

OpenLDAP - дальнейшее развитие оригинального slapd. Широко распространён. Используется на множестве платформ, таких как Linux, FreeBSD, Windows и MacOS X. Документацию на сайте хочется назвать спартанской. Впрочем, sapienti sat, да и пошаговых руководств в сети предостаточно. Если по каким-либо причинам Вам претит использование продукта от RedHat, OpenLDAP - отличный выбор, проверенный временем. Функциональность у обоих проектов практически идентичная.

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

Novell eDirectory

Сначала несколько слов о политике лицензирования, поскольку она довольно интересна. Во первых, вся продукция бесплатна для ВУЗов. Во-вторых, Вы можете установить этот продукт и использовать его совершенно бесплатно (годовая лицензия на 100000 пользователей. Тех. поддержка отсутствует. Получить можно запрашивая триальный ключ раз в год). В третьих - а можете купить. Цена - 2$ за одну пользовательскую лицензию без временного ограничения. Работает под следующими операционными системами: Novell Netware, Windows (NT-ветка), Linux (SUSE Enterprise, либо RedHat), Solaris, AIX, HP-UX. Резюме: решение всё в одном - весь комплекс необходимых программ поставляется сразу. Установка и настройка сделаны максимально удобными. Невысокая цена. Отличная документация. Для зарегистрированных пользователей - тех. поддержка. Кроссплатформенность. Минус - закрытые исходники.

Microsoft ActiveDirectory

Входит в состав Windows Server 200x. Идеальное решение для сетей MS. Если планируется использовать линейку продуктов только от MS - стоит задуматься. Если же в качестве сервера, используется что-либо отличное от Windows 200x - рекомендую обратить пристальное внимание на вышеперечисленные продукты. Вывод: Отличная интеграция в систему, высококачественная документация. Недостаток - довольно высокая цена.

Sun Java System Directory Server

В начале 2000-х, Sun слилась с компанией iPlanet и используя её разработки (в частности iPlanet Directory Server) создала свой продукт - Sun ONE, впоследствии переименованный в Sun Java System Directory Server. Это не самостоятельный продукт, а лишь часть Java Enterprise System. Системные требования: Solaris 10, Solaris 9, Solaris 8 (только для SPARC), Red Hat Enterprise Linux 2.1 и 3.1, HP-UX 11i, Microsoft Windows 2000, XP (для разработчиков), 2003. Не продаётся отдельно от Java Enterprise System. Вывод - если Вы решили воспользоваться комплексным решением от Sun, у Вас явно не будет особых проблем. Инженеры Sun помогут Вам установить и настроить его под Ваши нужды. За деньги, разумеется.

IBM Tivoli Directory Server

LDAP-решение от IBM. Работает под следующими ОС: AIX, Solaris, Microsoft Windows 2000, HP-UX, а также Linux для Intel и IBM eServer iSeries, pSeries и zSeries. Цены начинаются от 10000$. Решение явно не для всех. Однако стоит отметить доступную для всех документацию. Крайне рекомендую всем, интересующимся LDAP-тематикой, книгу из серии IBM Red Books Understanding LDAP - Design and Implementation Несмотря на то, что освещается в основном IBM Tivoli Directory Server, в ней содержится очень много качественного теоретического материала о том, что такое LDAP и как лучше спланировать Ваш каталог.

На этом я заканчиваю моё слегка затянувшееся повествование. Надеюсь, я смог заинтересовать Вас. Напоследок скажу следующее. LDAP - это следующий шаг за внедрением DHCP. Удобства, приобретаемые благодаря его использованию, перевешивают трудозатраты на его введение. Если в Вашей локальной сети больше 10 компьютеров - задумайтесь о LDAP.

  1. Войдите в Microsoft Windows как Administrator
  2. Экспортируйте контекст LDAP context в файл, выполнив в консоли команду
ldifde –f ldap.txt
  1. Откройте полученный файл
    ldap.txt . Первая его строка будет содержать DN вашего сервера. Например:
dn: DC=ldap-server,DC=my-company,DC=com

Dn: DC=localhost

Вы можете настроить параметры соединения с LDAP в утилите TrackStudio Server Manager, либо, если ее нет — в любом текстовом редакторе.

Настройка через Server Manager

  1. Выберите параметры авторизации пользователей: какое поле использовать для поиска соответствий в TrackStudio и какое — в LDAP
  2. Нажмите Проверить соединение чтобы проверить соединение с LDAP

Настройка соединения в файлах.properties

Если у вас отсутствует возможность запустить Server Manager, вы можете настроить интеграцию с LDAP в файле trackstudio.security.properties

  1. Включите поддержку LDAP в trackstudio.security.properties:
trackstudio.useLDAP yes
  1. Если требуется, включите опцию "Использовать LDAP поверх SSL "
ldap.useSSL yes
  1. Укажите адрес сервера LDAP и его порт
ldap.host 127.0.0.1 ldap.port 389
  1. Установите Base DN к cn=users для вашего доменного имени. Вы можете указать несколько Base DN в
    настройках LDAP. Используйте точку с запятой в качестве разделителя.
ldap.baseDN = dc=example,dc=com
  1. Укажите учетную запись пользователя, через которую будет осуществляться вход в Active Directory:
ldap.userDN = cn=admin,dc=example,dc=com
  1. Укажите пароль к этой записи:
ldap.userDNpass pass

Для того, чтобы пользователи, зарегистрированные в LDAP, имели доступ к TrackStudio, для них должны быть созданы учетные записи. Эти учетные записи должны совпадать с записями в LDAP по названию аккаунта, либо по имени пользователя.

  1. Чтобы входить по имени и фамилии пользователя установите:
ldap.loginAttrLDAP=displayName ldap.loginAttrTS name
  1. Чтобы входить по названию учетной записи:
ldap.loginAttrTS login ldap.loginAttrLDAP=sAMAccountName

Принцип работы

Если установлено trackstudio.useLDAP yes , TrackStudio будет соединяться с указанным LDAP-сервером при попытке входа пользователя и выполнять авторизацию средствами LDAP, используя учетную запись, указанную в ldap.userDN и ldap.userDNpass . TrackStudio затем выполнит локальный поиск в своей базе данных пользователя, соответствущего указанному логину. После этого TrackStudio будет искать в сервере LDAP пользователя, запись ldap.loginAttrLDAP которого соответствует имени или логину (в зависимости от ldap.loginAttrTS ) найденного пользователя. Затем этот пользователь будет авторизован паролем, указанным в окне входа в систему.
TrackStudio поддерживает работу с фильтрами LDAP. Вы можете вписывать свои фильтры в "Поле поиска в LDAP". Таким образом TrackStudio будет работать только с теми пользователями, которые удовлетворяют условиям указанного фильтра. Подробнее о фильтрах вы можете прочитать в этой статье .

Примечание

  • Для входа в TrackStudio в окне входа вы должны использовать именно логин
  • В любом случае соответствующий пользователь должен иметь учетную запись в TrackStudio
  • Когда вы меняете пароль средствами TrackStudio, на сервере LDAP он не меняется
  • Пользователь может войти либо при совпадении пароля с паролем в LDAP, либо с паролем в локальной базе данных TrackStudio. Чтобы запретить встроенную авторизацию, удалите com.trackstudio.app.adapter.auth.SimpleAuthAdapter из цепочки в файле trackstudio.adapter.properties .

Приветствую, гости и читатели моего . Продолжаем расширять возможности . Сегодня попытаемся реализовать авторизацию доменных учеток Active Directory на основе их членства в группах . В статье будет задействовано новая для меня технология, в которой я пока не очень соображаю - LDAP . Поэтому о ней пока будет рассказано "вскользь". Для того, чтобы у вас заработала данная схема, необходимо ознакомиться со статьями:

Без данных статей и понимания - никак

Что такое LDAP в Active Directory (Введение)

Т.к. LDAP пока для меня - это маленькая тайна. Расскажу, что знаю... Итак, LDAP - это некий каталог (дословно - lightweight directory access protocol , в переводе - облегчённый протокол доступа к каталогам ), который хранит в себе различную информацию в древовидной форме и имеет структуру, на нашем примере (на примере домена AD.LOCAL):

Давайте разберем что к чему... В голове структуры - имя домена (AD.LOCAL) , "в подчинении" у домена - отделы (т.н. организационные единицы), у каждого отдела могут быть в подчинении другие отделы. Кроме того, в любой отдел (в том числе и в корневой контейнер - домен) могут входить некие элементы - группы, пользователи, принтеры и др., которые "в себе" могут хранить некоторые настройки - атрибуты объекта (например, у пользователя - пароль, имя, адрес почты и др.).

У каждой записи в LDAP , будь то объект или контейнер с объектами внутри имеется уникальное для всего каталога LDAP имя (т.н. англ. Distinguished Name (DN) - Отличительное имя ). Это даже не имя, а путь , характеризующий полный путь к этом этой записи во всей иерархии. Уникальный путь может выглядеть (на примере группы squid), следующим образом: «cn=squid , ou=groups, ou=UNIXs , dc=ad, dc=local ». Уникальное имя состоит из одного или нескольких относительных отличительных имен (RDN - англ. Relative Distinguished Name ), разделённых запятой. Относительное уникальное имя имеет вид ИмяАтрибута=значение (например cn=squid ). На одном уровне каталога не может существовать двух записей с одинаковыми относительными уникальными именами (при этом, в Active Directory имеются некоторые дополнительные ограничения, например, не может быть пользователя с одинаковым именем во всем дереве).

Давайте разберем приведенный путь. Данный путь стОит читать с конца. Он начинается с описания домена , в котором расположен каталог и обозначается как dc=ad, dc=local , здесь - имя dc (оно же Domain Component компонент доменного имени ) задает имя домена , то есть если бы у нас был домен, например subdomain.ad.local , то данный кусок отличительного имени выглядел бы как dc=subdomain, dc=ad, dc=local. Далее описывается структура иерархия контейнеров отделов (они же OU, они же Organization Unit - организационная единица или подразделение ), которые представляет собой ou=groups, ou=UNIXs . Это стоит читать так же с конца, то есть в текущем домене есть некий контейнер UNIXs , в котором есть подконтейнер groups . Если бы необходимый нам объект находился в отделе, например, Склады, то текущий кусок DN (Distinguished Name) выглядел бы следующим образом: ou=Склады, ou=groups. Далее мы видим в DN описание конкретной записи (в данном случае - запись - это группа squid ). Кусок, DN пути, описывающий группу представляет собой строку cn=squid , где CN - Common Name - общее (относительное) имя (Пользователь, контакт, группа или другой объект, который как правило не имеет дочерних объектов).

Думаю, что общую структуру объяснил понятно. Этого понимания, думаю, будет достаточно для реализации Kerberos LDAP авторизации на основе группы Active Directory .

Настройка squid на Kerberos аутентификацию

Настройку squid на Kerberos аутентификацию необходимо сделать, согласно статьи . После настройки Kerberos аутентификации у нас начинает работать некий прокси-сервер squid, который аутентифицирует доменных пользователей. Предположим, что он имеет некий конфиг:

Ldap ~ # grep -v ^# /etc/squid3/squid.conf | grep -v ^$ auth_param negotiate program /usr/lib/squid3/squid_kerb_auth auth_param negotiate children 15 auth_param negotiate keep_alive on acl manager proto cache_object acl localhost src 127.0.0.1/32 acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https acl CONNECT method CONNECT acl localnet src 10.0.0.0/16 acl to_localnet dst 10.0.0.0/16 acl allusers proxy_auth REQUIRED http_access allow manager localhost http_access allow localhost http_access deny manager http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow allusers http_access deny !allusers all http_access deny all http_port 10.0.0.10:3129 http_port 127.0.0.1:3129 hierarchy_stoplist cgi-bin ? coredump_dir /var/spool/squid3 refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 20% 4320

Конечно же, кроме squid.conf у нас должен быть настроен /etc/krb5.conf и другие необходимые конфиги и, конечно же, Active Directory согласно .

Исходные данные

Конфигурация сети следующая:

  • Локальная подсеть - 10.0.0.0/16
  • IP контроллера домена - 10.0.0.1
  • Имя домена - ad.local
  • Имя контроллера домена - dc.ad.local
  • IP хоста со squid - 10.0.0.10

Использование LDAP групп из Active Directory

Собственно, для чего нам использовать LDAP группы из Active Directory? Мы же можем просто составить необходимые списки acl с внесением туда пользователей, например

Acl allusers proxy_auth "/etc/squid3/acls/vipusers.acl" cat /etc/squid3/acls/vipusers.acl [email protected] [email protected] ...

Но это приемлемо, когда в сети 10-30 пользователей и не часто приходится их заводить... Если у вас больше пользователей еще и текучка кадров большая, то становится жутко неудобно вручную добавлять имена в acl и помнить, кого нужно удалить/изменить. После чего перезапускать/релоадить squid, что так же доставляет неудобство для работающих в данный момент пользователей. Гораздо проще добавить пользователя в AD и включить его в некую группу, в результате чего он автоматически получает доступ к глобальной сети с заданными для группы параметрами и не трогать squid совсем...

Для обращения к LDAP Active Directory , в squid используется хелпер squid_ldap_group , кроме того, squid должен быть с опцией --enable-external-acl-helpers="ldap_group" . Как узнать с какими опциями собран squid я писал в .

Настройка Active Directory для использования групп

По умолчанию, в AD запрещено анонимным пользователям получать какую-либо информацию из каталога. Для того, чтобы squid хелпер squid_ldap_group имел право обращаться к каталогу Active Directory и извлекать некую информацию из доменной структуры, необходимо хелперу предоставить некие учетные данные для доступа к LDAP. Для этого я в домене создал учетку с минимально необходимыми правами (членство в группе Domain Users - Пользователи домена ) (??? может будет достаточно группы Гости домена...). Имя учетной записи в моем примере будет [email protected] , важно задать настройку запрета смены пароля и отменить ограничение времени действия пароля при создании учетной записи.

Для удобства, все группы и учетные записи пользователей и компьютеров использующиеся для интеграции сервисов на Linux в инфраструктуру Kerberos я создаю в контейнере UNIXs в подконтейнерах groups, users, hosts соответственно.

Конечно же, нам необходимо создать (для примера) 2 группы пользователей . 1 - это группа, имеющая доступ в интернет без ограничения доступа (называется squid ), 2 - группа, имеющая доступ только к списку избранных сайтов (называется squid-list ). Можно создать сколько угодно групп с заданием разных настроек, но для примера будет достаточно 2х.

Связь хелпера squid_ldap_group с Active Directory

Нижеприведенная команда была сгруппирована из различных источников в сети, поэтому некоторые параметры останутся без четкого описания (как это не печально...).

Рассмотрим пример установки тестовой связи хелпера squid_ldap_group с каталогом LDAP AD :

Ldap ~ # /usr/lib/squid3/squid_ldap_group -R -d -b "dc=ad,dc=local" \ -f "(&(objectclass=user)(sAMAccountName=%v)(memberOf=cn=%a,ou=groups,ou=UNIXs,dc=ad,dc=local))" \ -D [email protected] -W /etc/squid3/aduser dc test squid-list Connected OK group filter "(&(objectclass=user)(sAMAccountName=test)(memberOf=cn=squid-list,ou=groups,ou=UNIXs,dc=ad,dc=local))", searchbase "dc=ad,dc=local" OK [email protected] squid-list Connected OK group filter "(&(objectclass=user)([email protected])(memberOf=cn=squid-list,ou=groups,ou=UNIXs,dc=ad,dc=local))", searchbase "dc=ad,dc=local" ERR AD\test squid-list Connected OK group filter "(&(objectclass=user)(sAMAccountName=AD\5ctest)(memberOf=cn=squid-list,ou=groups,ou=UNIXs,dc=ad,dc=local))", searchbase "dc=ad,dc=local" ERR ivanov squid-list Connected OK group filter "(&(objectclass=user)(sAMAccountName=ivanov)(memberOf=cn=squid-list,ou=groups,ou=UNIXs,dc=ad,dc=local))", searchbase "dc=ad,dc=local" ERR

Давайте рассмотрим, что мы накуралесили в данной команде (все параметры описаны из man squid_ldap_group):

дословно - do not follow referrals. Как переводится - не знаю Работает и без нее. Но, говорят снижает нагрузку на AD.

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

это базовое отличительное имя нашего дерева каталогов (т.н. BaseDN ). Базовое, то есть от этой ветки будет производиться поиск пользователей в LDAP. Допустим, если бы все наши авторизуемые пользователи находились бы в контейнере OU Юристы , то можно было бы задать значение этого ключа -b "ou=Юристы, ou=groups,dc=ad,dc=local" , тем самым снизив нагрузку на LDAP. Т.к. авторизуемые пользователи у меня разбросаны по всей структуре дерева, то в примере я указываю производить поиск от корня дерева -b "dc=ad,dc=local"

задает некий фильтр поиска необходимой нам группы (memberOf=cn=%a) , которая расположена по пути ou=groups,ou=UNIXs,dc=ad,dc=local . В данном фильтре переменная %v заменяется именем пользователя (без указания домена @AD.LOCAL или AD\), а переменная %a заменяется запрашиваемой группой. Т.к. в LDAP я почти ноль, поэтому толкового объяснения данному фильтру не даю... Соответственно, если у вас группа (принадлежность к которой необходимо проверять) расположена в каком-нибудь контейнере linux в домене primer.domen.local , то данный фильтр будет иметь вид: -f "(&(objectclass=user)(sAMAccountName=%v)(memberOf=cn=%a,ou=linux,dc=primer,dc=domen,dc=local))" .

задает имя пользователя , от которого происходит подключение к каталогу AD.

указывает путь к файлу, который хранит пароль к учетной записи из параметра -D. На данный файл необходимо - пользователя под которым работает squid (обычно это proxy) и на чтение только для владельца.

задает DNS имя сервера LDAP . Здесь можно указать вместо DNS имени - IP адрес.

Далее в листинге я пытаюсь проверить соответствие доменного пользователя test доменной группе squid-list , в которую он действительно входит. При этом, я пытаюсь указать имя пользователя в различных форматах. Как видно, хелпер squid_ldap_group корректно принимает имя только без указания доменной части. О чем нам говорит строка:

Test squid-list Connected OK group filter "(&(objectclass=user)(sAMAccountName=test)(memberOf=cn=squid-list,ou=groups,ou=UNIXs,dc=ad,dc=local))", searchbase "dc=ad,dc=local" OK

Последней попыткой я пытаюсь проверить принадлежность пользователя ivanov к указанной группе squid-list , при этом, реально ivanov в данную группу не входит. Соответственно, неудачные попытки нам возвращают значение ERR.

Если на данном шаге удалось связать хелпер с AD и при правильном вводе пользователя и группы, в которую он входит, происходит корректный ответ хелпера - ОК, значит дело движется в правильном направлении и можно приступить к настройке squid. В противном же случае - необходимо разобраться в причинах проблем.

Настройка squid для авторизации на основе членства в доменной группе LDAP

Приступаем к финальному шагу. Для реализации авторизации на основе членства в доменной группе в squid используется внешний acl, т.н. параметр external_acl_type . Общая схема работы примерно следующая:

# задаем external_acl_type для взаимодействия с LDAP external_acl_type произвольное_имя_ext_acl %LOGIN /путь/к/хелперу/squid_ldap_group -R \ -b "BaseDN" -f "фильтр с переменной %v и %a " -D пользователь_ad@домен -K -W /файл/с/паролем имя_dc # где переменная %v подставляется за счет указания значения %LOGIN, # которое извлекает имя аутентифицированного пользователя # далее необходимо задать acl, которое будет передавать в переменную %a имя групп acl имя_acl external произволное_имя_ext_acl передаваемое_название_группы # далее необходимо с образовавшимся acl работать как с обычным acl, # то есть задавать какие-то разрешения с помощью соответствующих параметров

Если данную схему наложить на наш домен и нашу задачу, то получится примерно следующий конфиг:

Ldap ~ # grep -v ^# /etc/squid3/squid.conf | grep -v ^$ auth_param negotiate program /usr/lib/squid3/squid_kerb_auth auth_param negotiate children 15 auth_param negotiate keep_alive on external_acl_type ldap_verify %LOGIN /usr/lib/squid3/squid_ldap_group -R \ -b "dc=ad,dc=local" -f "(&(objectclass=user)(sAMAccountName=%v)(memberOf=cn=%a,ou=groups,ou=UNIXs,dc=ad,dc=local))"\ -D [email protected] -K -W /etc/squid3/aduser dc.ad.local. acl manager proto cache_object acl localhost src 127.0.0.1/32 acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https acl CONNECT method CONNECT acl localnet src 10.0.0.0/16 acl to_localnet dst 10.0.0.0/16 acl users external ldap_verify squid acl users-list external ldap_verify squid-list acl whitelist dstdomain "/etc/squid3/acls/whitelist.acl" acl allusers proxy_auth REQUIRED http_access allow manager localhost http_access allow localhost http_access deny manager http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow users http_access allow users-list whitelist http_access deny !allusers all http_access deny all http_port 10.0.0.10:3129 http_port 127.0.0.1:3129 hierarchy_stoplist cgi-bin ? coredump_dir /var/spool/squid3 refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 20% 4320

Давайте разберем получившийся конфиг. Как видно, добавился параметр external_acl_type , заставляющий sqiud обращаться к каталогу LDAP, расположенному на контроллере домена dc.ad.local, через хелпер squid_ldap_group. squid_ldap_group ищет пользователей в каталоге, начиная с пути dc=ad,dc=local , авторизованных пользователей, принадлежащих некоторым группам, имена которых (групп) передаются из acl в переменную %a. Как мы видим, у нас пропал параметр -d за ненадобностью и появился параметр -K. Давайте его разберем. Мы , что при Negotiate Kerberos аутентификации имя пользователя у нас получается в виде пользователь@ДОМЕН , а хелпер squid_ldap_group использует имена в формате пользователь (то есть без доменной части). Так вот, ключ -K заставляет squid_ldap_group "обрезать" часть имени @ДОМЕН и корректно сравнивать имя пользователя и группу.

Далее мы видим, что появилось 3 новых acl - users , users-list и whitelist , которые проверяют принадлежность пользователя к группе с именем squid , к группе с именем squid-list и задает белый список сайтов соответственно. При этом, про первые 2 acl было бы понятней сказать, что они передают в external_acl_type с именем ldap_verify имя группы, которой должен принадлежать аутентифицированный пользователь.

Ну и последнее - это появление двух параметров http_access , которые разрешают доступ acl с именем users и acl с именем users-lis t при доступе этих пользователей к сайтам из acl whitelist . Кроме того, был убран параметр http_access allow allusers , который разрешал доступ всем аутентифицированным пользователям.

На этом в настройке можно поставить точку. Перезапускаем сквид и наши пользователи, которые входят в доменные группы squid и squid-list могут работать в интернете.

Особенности работы squid при авторизации на основе доменных групп LDAP

При реализации данной схемы я столкнулся с некоторыми нюансами, которые не стоит оставлять без внимания:

Резюме

В данной статье нам, надеюсь и вам, удалось заставить squid с помощью хелпера squid_ldap_group извлекать из Active Directory информацию о принадлежности пользователя к заданной группе и на основе данной информации предоставлять или не предоставлять доступ к интернету. При этом, есть возможность так же для групп и многие другие настройки и ограничения для доступа в интернет, основываясь на управлении списками доступа acl. До новых статей!

С Уважением, Mc.Sim!

У LDAP, и особенно у OpenLDAP, есть ряд возможностей обеспечения безопасности, которые на первый (да и на второй и третий) взгляд могут показаться немного сложными. Рисунок 15-1 показывает общую картину проблемы, перед тем как углубиться в детали. Далее демонстрируются различные методы доступа и интерфейсы к LDAP-системе, а затем описываются проблемные вопросы безопасности и доступные методы управления рисками. Цель данного упражнения — либо определиться с набором политик безопасности, либо выделить приоритеты реализации.

Рисунок 15-1. Общая картина вопросов обеспечения безопасности

Все номера, встречающиеся в описании ниже, ссылаются на рисунок 15-1.

    Взаимодействие с удалёнными абонентами (1): Обеспечение безопасности при взаимодействии с удалёнными абонентами может как быть, так и не быть проблемным вопросом. При предоставлении неограниченного (анонимного) доступа к неконфиденциальной LDAP-информации вопросы обеспечения безопасности не ставятся. Внимание: в этих условиях Ваш сервер всё равно становится потенциальным объектом DoS/DDoS-атак посредством нагрузки его вредоносными LDAP-запросами. Таким образом, даже такая на первый взгляд тривиальная реализация может потребовать тщательного проектирования.

    Если все взаимодействия с LDAP гарантированно происходят в доверенной сети, то Вы можете остановить свой выбор на работе с простыми паролями в открытом виде без дополнительных заморочек с безопасностью. Однако, даже в таких случаях, в зависимости от топологии доверенной сети, бывает достаточно просто перехватывать трафик и получать либо конфиденциальные данные (1-2), либо пароли (1-1), посылаемые в открытом виде.

    Когда взаимодействие с LDAP осуществляется через ненадёжные сети, у деструктивных личностей в сети сразу находится, чем заняться: будьте готовы к тому, что перехваты, отслеживания, атаки типа "человек посередине" ("man-in-the-middle") и т.п. будут постоянным явлением. Также имейте в виду, что использование онлайн-конфигурации OLC (cn=config) и функций мониторинга (cn=monitor) может привести к тому, что LDAP-браузеры станут обычным инструментом для удалённого администрирования и управления LDAP-серверами. А этот трафик по своей природе невероятно конфиденциален.

    Если решено, что некоторый уровень обеспечения безопасности всё же необходим, то первый вопрос, возникающий в этом случае: нужно ли нам защищать только пароли (1-1), или нужно защищать и данные (1-2), и пароли (1-1)? В зависимости от ответа на этот вопрос будут определяться наши следующие шаги.

    Пароли (1-1): Не следует путать защиту паролей во время передачи по сети с защитой их в конфигурационных файлах или в DIT. Даже если Вы защитили все пароли в конфигурационных файлах или в DIT с помощью методов хэширования, таких как {SSHA}, при отправке пароля клиентом серверу для аутентификации он посылается в открытом виде, хэшируется на сервере и сравнивается с хранимым значением. Без принятия дополнительных мер он, таким образом, может быть перехвачен (или отслежен, в зависимости от ваших предпочтений к подобным терминам). Примечание: Когда клиент запрашивает запись, содержащую, скажем, атрибут userPassword , значение которого захэшировано, допустим, по алгоритму {CRYPT}, то этот пароль посылается не в открытом виде, а в своей хэшированной форме (то есть в той, в которой он хранится). Однако, когда осуществляется доступ от имени этой же самой записи, клиент посылает пароль (с помощью которого он проходит аутентификацию) в открытом виде, и, естественно, если аутентификация прошла успешно, перехватывающий может вполне резонно предположить, что посланный в открытом виде пароль был верен.

    При пересылке хэшированных паролей в потоке данных, который может подвергнуться перехвату, они становятся уязвимыми к атакам по словарю — получив хэшированный пароль, атакующий прогоняет список паролей (так называемый словарь) через алгоритм хэширования, пока не найдёт совпадения. Использование соли (одного или нескольких байт, — в зависимости от реализации, — добавляемых к паролю перед хэшированием и отбрасываемых перед сравнением) значительно повышает безопасность хэшированных паролей, и, если у Вас нет веских причин к обратному, нужно всегда использовать форму того или иного алгоритма хэширования с солью . Нужно также использовать ACL для предоставления доступа к паролям только определённому кругу авторизованных пользователей. Например, подразумевая, что пароли хранятся в атрибуте userPassword , следующий ACL будет разрешать доступ к данному атрибуту только владельцу записи и определённой группе пользователей (admin):

    # Форма OLC (cn=config) olcAccess: to attrs=userpassword by self write by anonymous auth by group.exact="cn=admin,ou=groups,dc=example,dc=com" write by * none # Формат slapd.conf access to attrs=userpassword by self write by anonymous auth by group.exact="cn=admin,ou=groups,dc=example,dc=com" write by * none

    Если требуется защитить только пароли, то решением может стать использование SASL с каким-либо алгоритмом (например CRAM-MD5), обеспечивающим выполнение безопасного диалога подключения (с помощью общей секретной последовательности), во время которого пароли никогда не передаются в открытом виде (). Альтернативой может стать использование TLS/SSL (с или без SASL) или Kerberos 5. В этом случае можно использовать простые механизмы паролей, поскольку весь обмен по сети шифруется, и потому не может быть подвержен перехвату.

    До сих пор мы обсуждали вопросы только простого получения доступа к данным. А как насчёт изменения или модификации этих данных? OpenLDAP предоставляет две возможности для ведения аудита: наложение auditlog (для получения дополнительной информации смотрите man-страницу slapo-auditlog) и наложение accesslog . У обоих есть функции журналирования изменений, вносимых в рабочее DIT, а у accesslog даже есть возможность помещать в журнал информацию о подключениях, доступах для чтения/поиска, а также предыдущее содержимое записей или атрибутов.

    Локальный доступ (2): Под локальным доступом подразумеваются любые события, происходящие непосредственно на LDAP-сервере или кластере серверов (либо посредством защищённого удалённого доступа к серверу с помощью, например, ssh). Наиболее очевидно, под эту категорию попадают манипуляции с конфигурационными файлами/директориями (2-1) и локально выполняемые команды (2-2).

    Конфигурационные файлы (2-1): Здесь мы должны рассмотреть два компонента:

    1. Владельцы и права: По умолчанию, современные системы LDAP работают от имени учетных записей пользователя/группы с ограниченными привилегиями (обычно ldap:ldap). OpenLDAP загружается с правами root (чтобы открыть привилегированные порты), а затем очень быстро переходит к работе со своими нормальными (низкими) рабочими привилегиями. При использовании OLC (cn=config) OpenLDAP требует, чтобы у содержимого конфигурационной директории были права как минимум 0750 для учётной записи, от имени которой он будет работать (обычно ldap:ldap), однако самостоятельно соответствующие привилегии он не выставляет. Это поведение отличается от работы с конфигурационным файлом slapd.conf, которому автоматически назначаются права 0600.

      Пароли: Пароли, встречающиеся в директориях slapd.d (при использовании OLC (cn=config)) и конфигурационном файле (slapd.conf), такие как olcRootPw/rootpw , относятся к категории особо конфиденциальных. Лучше вообще полностью удалить и olcRootDn/rootdn , и olcRootPw/rootpw после того, как DIT было запущено в эксплуатацию. Ну и, конечно, все пароли следует хранить в хэшированной форме для предотвращения случайной компрометации (это должно оговариваться на уровне политики безопасности).

    Команды (2-2): Исторически LDAP администрировался через локальный интерфейс, в основном из командной строки. Предполагалось, что локальный (внутрисерверный) трафик не подвержен отслеживанию, и потому даже применение простых паролей в открытом виде считалось адекватной мерой защиты для большинства административных сервисов. Однако, как отмечалось выше, увеличение количества реализаций каталогов с конфигурацией времени исполнения (OLC, cn=config) и мониторингом (cn=monitor) может означать, что удалённые LDAP-браузеры становятся нормой в вопросах администрирования LDAP-систем. В этом случае доступ к указанным сервисам порождает передачу по сети информации высокой степени важности, которую необходимо защищать с помощью специальных технологий обеспечения безопасности данных, таких как TLS/SSL.

    Наконец, поскольку при конфигурации времени исполнения все настройки хранятся в DIT (cn=config), стоит рассмотреть использование мощных возможностей наложения accesslog  — инструмента генерации журнала для аудита изменений, вносимых в данное DIT.

    DIT (3): Безопасность DIT определяется моделью безопасности LDAP и реализуется исключительно при помощи olcAccess/access to Права должны ограничиваться насколько это возможно более строго, и ACL должны тестироваться с помощью slapacl после каждого изменения.

    Репликация (1-3): Даже если обычный клиентский доступ к LDAP-системе не требует серьёзных мер безопасности, иная ситуация может быть при репликации того же DIT. Во время цикла репликации на том или ином этапе все данные в DIT (пользовательские и операционные атрибуты) будут передаваться по сети. Вероятно, часть этой информации будет весьма важной. Сетевое взаимодействие при репликации заслуживает отдельного рассмотрения. Вы можете настроить смешанное соединение TLS/SSL и другого защищённого (или даже незащищённого) типа к одному серверу (смотрите примеры конфигурации смешанного доступа TLS/SSL и SASL ).

Настройка SASL в OpenLDAP

Мы закончим этот раздел уже совсем скоро (one day real soon now ™)

Настройка SASL TLS/SSL в OpenLDAP

В руководстве администратора OpenLDAP утверждается, что при использовании TLS с механизмом EXTERNAL SASL и клиенту, и серверу необходимо иметь действительный сертификат X.509. Если это правда, то мы получаем излишне сложную конфигурацию, а уровень безопасности повышается незначительно, и потому в большинстве случаев её использование представляется сомнительным (но есть заметные исключения, такие как репликация). В настоящее время подробно обсуждать это мы не будем.

Настройка TLS/SSL в OpenLDAP

Обзор

TLS (Transport Level Security) — это просто название стандартизированной IETF версии Secure Sockets Layer (SSL) от Netscape. Практически нет никаких различий между SSL(v3) и TLS(v1), и в этой документации данные термины считаются синонимами. TLS/SSL поддерживается OpenLDAP начиная с версии 2.1.

Обычно для работы TLS/SSL требуется сертификат X.509 (более известный как сертификат SSL), который можно приобрести в коммерческом центре сертификации или удостоверяющем центре (Certificate Authority, CA), либо это может быть самоподписанный сертификат. В этой документации дано пошаговое руководство по созданию самоподписанных сертификатов, а также, в случае необходимости, приводятся дополнительные замечания по использованию коммерческих сертификатов.

# slapd.conf # раздел глобальных настроек... # Безопасность - раздел TLS TLSCertificateFile /certs/ldapscert.pem TLSCertificateKeyFile /certs/keys/ldapskey.pem TLSCipherSuite TLSv1+RSA:!NULL # значение следующей директивы установлено так по умолчанию, # однако мы приводим её здесь для наглядности TLSVerifyClient never # Безопасность - другие директивы # предотвращаем анонимные подключения при любом типе соединения disallow bind_anon # требуем выполнения операции bind перед доступом к DIT require bind # Ожидание подключения только на порту ldaps требует использовать TLS/SSL, # но не выдвигает требований к минимальной длине ключа. # Требования к минимальной длине ключа выдвигает следующая директива: security simple_bind=128 # DIT database bdb suffix "d=example,dc=com" ... # replica provider overlay syncprov # cn=config DIT database config rootdn="cn=admin,cn=config" rootpw .... # cn=monitor DIT database monitor rootdn="cn=admin,cn=monitor" rootpw ....

Примечания:

  1. cn=config: скоро будет.
  2. Ожидаем подключения только для LDAPS URL: аргумента -h при запуске slapd. По умолчанию данное значение не задаётся, что (обычно) соответствует -h ldap:///. По требованиям данной конфигурации мы должны разрешить только операции ldaps, поэтому при запуске slapd должна использоваться команда:

    Slapd -h ldaps:/// -u ldap -g ldap

    slapd_flags="ldaps:///" .

    Если Вы переживаете о конфигурации фаервола, то LDAPS может быть настроен на использование порта 389 (LDAPS — это схема URL, говорящая о том, что будет использоваться TLS, а не о том, какой будет использоваться порт). В этом случае команда запуска будет такая:

    Slapd -h ldaps://:389/ -u ldap -g ldap # при подключении ldaps URL должны быть в форме: ldaps://ldap.server.name:389

  3. Директивы disallow, require и security: Ожидание подключений только на порту (портах) LDAPS приводит к принудительному использованию TLS/SSL при всех соединениях. Никакие другие типы соединений не будут приниматься в данной конфигурации сервера. Чтобы обязать пользователей проходить LDAP-аутентификацию, используется директива require bind , а для предотвращения анонимных подсоединений используется директива disallow bind_anon . Таким образом, чтобы получить какой-либо доступ к DIT, при любом подключении должна выполняться операция подсоединения (bind), и это подсоединение не может быть анонимным. Если указать только директиву security simple_bind=128 , это не приведёт к обеспечению требуемого уровня защиты. Данная директива просто говорит: если выполняется простое подсоединение (simple bind), то должно использоваться TLS/SSL. Она не требует, чтобы подсоединение выполнялось обязательно. Единственная цель использования security simple_bind=128 в данной конфигурации — определить минимальное значение SSF. Если это не нужно, данную директиву можно не указывать.
  4. Доступ к rootDSE: Побочный эффект данной политики — запрет анонимного доступа к rootDSE , что, как уже отмечалось, может быть вполне оправдано для защищённых серверов.
  5. Директивы ACL: В данной конфигурации не предусмотрено дополнительных мер безопасности, основанных на применении ACL — безопасность сервера полностью обеспечивается глобальными директивами конфигурации и ограничением подключений только на LDAPS портах. ACL может использоваться для установления необходимого разграничения доступа на основании учётных данных пользователей.

Настройка клиентов: Из требования, что сервер LDAP будет обслуживать только соединения TLS, следует, что все клиенты при подключении должны использовать URL со схемой LDAPS и выполнять проверку сертификата X.509 сервера, для чего требуется доступ к CA (корневому) сертификату. В нашем контексте под клиентами подразумеваются утилиты и инструменты ldap , а также серверы LDAP, на которых выполняется сервис репликации с использованием syncrepl . Очевидно, что, поскольку утилиты и инструменты ldap являются клиентами, они получают свои настройки из файла ldap.conf . Возможно менее очевидно, что LDAP-серверы, на которых выполняется сервис репликации, также являются TLS-клиентами, и потому также получают информацию по CA (корневым) сертификатам из ldap.conf. Конфигурация ldap.conf:

# скопируйте сертификат, сгенерированный на шаге 1, # в подходящее место на клиентской системе # подразумевается: /certs/ldapscert.pem # добавьте в ldap.conf TLS_CACERT /certs/ldapscert.pem

Конфигурация LDAP-сервера, на котором запущена реплика:

# slapd.conf # раздел глобальных настроек... # Безопасность - раздел TLS # нет никаких настроек # реплицируемое DIT database bdb suffix "d=example,dc=com" ... # настройки потребителя репликации syncrepl rid=000 type=RefreshandPersist provider=ldaps://ldap-master.example.com bindmethod=simple searchbase="dc=example,dc=com" retry="5 3 300 +" attrs="*,+" binddn="...." credentials=.... ...

Примечания:

  1. CA (корневой) сертификат, используемый в примере потребителем syncrepl (и определяемый директивой TLS_CACERT в ldap.conf), является тем же самым, что используется и в качестве сертификата сервера поставщиком главного DIT. Это следствие применения метода с единственным сертификатом, который мы использовали для генерации данного сертификата: он функционирует сразу и как сертификат сервера, и как сертификат CA. При использовании других методов генерации самоподписанных сертификатов сертификат сервера и сертификат CA могут быть различными, и, конечно, они всегда различны при использовании коммерческих сертификатов.

    Если, как обсуждалось выше, сервис ldaps обслуживается на порту 389 (например, для устранения вопросов блокировки трафика фаерволом), то определение syncrepl будет использовать расширенный формат URL с указанием порта:

    Syncrepl ... provider=ldaps://ldap-master.example.com:389 ...

    LDAP-серверы в качестве TLS-клиентов: Когда сервер LDAP выступает в качестве потребителя репликации syncrepl, он выступает в роли TLS-клиента, и потому ему требуется осуществлять проверку подлинности серверного сертификата с помощью CA (корневого) сертификата, которым он подписан. Поскольку данный сервер выступает в роли TLS-клиента, он будет использовать директивы TLS (и, соответственно, файлы сертификатов TLS), определяемые для клиентов LDAP — в частности, он будет использовать директиву TLS_CACERT в ldap.conf. Клиенту TLS требуется сгенерировать сообщение обмена ключами (key-exchange message), зашифрованное с помощью открытого ключа (public key) сервера, который извлекается из посылаемого сервером сертификата X.509. Также клиент TLS при первоначальной установке соединения по протоколу TLS на этапе ClientHello посылает список разрешенных наборов шифров, который контролируется директивой настройки клиента TLS TLS_CIPHER_SUITE (по умолчанию посылаются все возможные наборы шифров (ALL), что эквивалентно команде openssl ciphers -v ALL ). Перед прочтением следующего предложения сделайте глубокий вдох. Если сервер LDAP, являющийся потребителем репликации syncrepl и потому клиентом TLS, также предоставляет доступ к другому DIT (например, к cn=config) и при этом подразумевается, что для контроля этого доступа также необходима поддержка TLS, то он одновременно будет сервером TLS и для него требуется задать все директивы сервера TLS, которые определялись выше на шаге 2 и 3.

Настройка смешанного доступа TLS/SSL в OpenLDAP

Если Вы сразу перешли к этому разделу, минуя описание нормальной конфигурации TLS, пожалуйста, найдите время ознакомиться как минимум с , а желательно и со всем разделом, поскольку в противном случае Вы можете очень быстро прийти в замешательство (хотя после прочтения Вы можете прийти в замешательство еще быстрее). Надеемся, однако, что некоторое просветление настанет.

Конфигурация — кто-то использует TLS, кто-то — нет

В данном случае выдвигается требование, что некоторые пользователи будут использовать TLS, а другие — нет. Например, политика может быть следующей:

  1. Разрешён анонимный доступ (и незащищённый обмен данными) к ограниченному набору общедоступных записей LDAP.
  2. Пользователям, прошедшим LDAP-аутентификацию (простое подключение с незащищённым обменом данными) разрешён доступ на чтение к общедоступным записям LDAP, плюс ограниченные права на обновление только той записи, владельцем которой является данный пользователь.
  3. Пользователи с привилегиями на обновление более одной собственной записи должны использовать TLS и проходить аутентификацию (подразумевается, что все они члены группы admins).
  4. Все потребители репликации должны использовать TLS/SSL.
  5. При удалённом доступе к cn=config должен использоваться TLS/SSL.

Данное решение требует применения ACL и директив настройки сервера, как показано ниже:

    Генерация сертификатов LDAP-сервера и CA: На данном этапе будет сгенерирован самоподписанный сертификат — если будет использоваться коммерческий сертификат X.509 (SSL), данный процесс не требуется и может быть полностью пропущен. Для генерации единого сертификата X.509, который может применяться и для проверки подлинности сервера, и в качестве CA (корневого) сертификата для клиента, используется простой метод в одну команду. Данный метод детально (со всеми диалогами) документирован . Последовательность команд:

    # создаём новые директории (опционально) mkdir /certs mkdir /certs/keys cd /certs # создаём сертификат сервера/CA и закрытый ключ без парольной фразы # действительный в течение 10 лет, использующий текущие рекомендации RSA по размеру ключа # RSA используется в качестве протокола обмена ключами openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout keys/ldapskey.pem -out ldapscert.pem # сертификат может использоваться в качестве сертификата сервера или сертификата CA # помещаем сертификат в: /certs/ldapscert.pem # помещаем закрытый ключ в: /certs/keys/ldapskey.pem # устанавливаем права доступа chown -R ldap:ldap /certs/* chmod 0400 keys/ldapskey.pem

    Примечания:

    1. Полное объяснение параметров команды openssl смотрите .

      У файлов ключей обычно есть парольная фраза (пароль) для защиты конфиденциальных данных. Если сертификат генерируется для сервера, подобная парольная фраза никогда не используется (её генерация подавляется аргументом -nodes).

      В зависимости от требований, предъявляемых к сертификату, могут использоваться другие методы генерации самоподписанных сертификатов, описанные .

    Добавление директив TLS и ACL в slapd.conf: (замечания по cn=config смотрите в конце раздела). Необходимые директивы TLS добавляются в раздел глобальных настроек:

    # slapd.conf # раздел глобальных настроек... # Безопасность - раздел TLS TLSCertificateFile /certs/ldapscert.pem TLSCertificateKeyFile /certs/keys/ldapskey.pem TLSCipherSuite TLSv1+RSA:!NULL # значение следующей директивы установлено так по умолчанию, # однако мы приводим её здесь для наглядности TLSVerifyClient never ... # пользовательское DIT database bdb suffix "d=example,dc=com" # нет директив rootdn и rootpw # смотрите примечания по обеспечению безопасности доступа от имени rootdn ... # ACL # ACL1 - доступ для потребителя репликации # (подразумевается подсоединение от имени cn=replica,dc=example,dc=com) # потребителю, использующему TLS, разрешён доступ на чтение ко всему DIT # все остальные переходят к ACL2 (break) access to * by dn.exact="cn=replica,dc=example,dc=com" tls_ssf=128 read by * break # ACL2 - доступ к атрибуту userpassword # анонимные пользователи могут только проходить аутентификацию # пользователи, прошедшие аутентификацию, могут модифицировать свои собственные пароли (self) # члены группы admins, использующие TLS, могут модифицировать пароли access to attrs=userPassword by self write by anonymous auth by group.exact "cn=admins,ou=groups,dc=example,dc=com" tls_ssf=128 write # ACL3 # ограниченный анонимный доступ только на чтение к поддереву public # любые пользователи, прошедшие аутентификацию, могут модифицировать свои # собственные записи (self) в пределах поддерева # члены группы admins, использующие TLS, имеют право на запись во всём поддереве public access to dn.subtree="ou=public,dc=example,dc=com" by group.exact "cn=admins,ou=groups,dc=example,dc=com" tls_ssf=128 write by self write by anonymous read by users read # ACL4 # члены группы admins, использующие TLS, имеют право на запись в остальном DIT access to * by by group.exact "cn=admins,ou=groups,dc=example,dc=com" tls_ssf=128 write # последний ACL4 слишком прямолинеен - если требуются дополнительные правила, # его нужно заменить приведённым ниже, который будет отфильтровывать всех пользователей, # не использующих TLS. В данном случае break означает, что если пользователь использует TLS, # он переходит к следующему ACL, в противном случае - обработка останавливается. # ACL4 access to * by group.exact "cn=admins,ou=groups,dc=example,dc=com" tls_ssf=128 break # ACL5 etc. access .... # поставщик репликации overlay syncprov # cn=config DIT database config rootdn "cn=admin,cn=config" rootpw {SSHA} hfkhfhfldkhlkhh # SSF больший или равный 128 используется для обеспечения безопасного доступа к cn=config security simple_bind=128

    Примечания:

    1. Дополнительная информация по TLSCipherSuite . Используемые параметры исключают применение NULL-шифров (без шифрования). TLSv1 охватывает SSLv3. Разрешены EXPORT-шифры — допускаются международные подключения. Если вопросы производительности и нагрузки стоят остро, лучше явно задать список шифров с приемлемыми характеристиками производительности и загрузки системы, чем оставлять возможность произвольного выбора шифра во время переговоров TLS/SSL.

      Конфигурация DSA: скоро будет.

      cn=config: скоро будет.

      Примечания по ACL:

      1. ACL1: Данный ACL, который можно с тем же успехом поместить в раздел глобальных настроек, разработан с целью вычленить на раннем этапе подключения потребителей репликации (DN cn=replica,dc=example,dc=com должен присутствовать в DIT с соответствующим паролем). by dn.exact="cn=replica,dc=example,dc=com" tls_ssf=128 read содержит два условия, которые работают (хотя явно не документированы), и совпадения по которым будут найдены в том случае, если потребитель успешно прошёл аутентификацию И использовал SSF (TLS) не ниже 128. Для того чтобы потребитель репликации (да и все остальные) смог пройти аутентификацию (или просто получить доступ к DIT), необходимо наличие условия by * break , позволяющего перейти к ACL2 и продолжить анализ подключения.

        ACL2: Позволяет любому пользователю, прошедшему аутентификацию, модифицировать свой пароль. Анонимный доступ предоставляется в целях аутентификации (auth ). Любой член группы cn=admins,ou=groups,dc=example,dc=com, использующий при подключении TLS, может осуществлять изменения любого пароля.

        ACL3: В указанном порядке — любому члену группы cn=admins,ou=groups,dc=example,dc=com, использующему при подключении TLS, разрешено производить запись в любой атрибут любой записи поддерева public базы данных. Анонимным пользователям предоставляется доступ на чтение к поддереву public DIT (за исключением атрибутов userPassword). Пользователю, прошедшему аутентификацию, разрешено изменять любую часть своей записи. Наконец, пользователю, прошедшему аутентификацию (подключающемуся с использованием или без использования TLS), разрешён доступ только для чтения к поддереву public, за исключением атрибутов userPassword (а также за исключением своих собственных записей, контроль доступа к которым был указан в условии self).

        ACL4: Только членам группы cn=admins,ou=groups,dc=example,dc=com, использующим при подключении TLS, разрешён доступ на осуществление записи во все остальные части DIT. Всем остальным пользователям запрещён любой доступ (неявное условие by * none ).

    2. Ожидаем подключения для LDAPS и LDAP URL: Управление портами, на которых ожидаются подключения, осуществляется с помощью аргумента -h при запуске slapd. По умолчанию данное значение не задаётся, что (обычно) соответствует -h ldap:///. По требованиям данной конфигурации мы должны разрешить как операции ldap , так и ldaps , поэтому при запуске slapd должна использоваться команда:

      Slapd -h "ldap:/// ldaps:///" -u ldap -g ldap

      Чтобы это выполнялось автоматически, необходимо подправить сценарии запуска в linux (/etc/rc.d/init.d/slapd), а в BSD /etc/rc.conf должен содержать такую строку: slapd_flags="ldap:/// ldaps:///" .

      Безопасность доступа от имени rootdn: После того, как DIT было первоначально загружено, какие функции выполняет rootdn ? Во всех штатных случаях привилегии типа rootdn для DIT могут быть предоставлены какому-либо конкретному пользователю (назовём его псевдо-суперпользователь ) с помощью ACL, и потому директиву rootdn можно смело удалять. В хорошо продуманной системе контроля можно предоставить новому псевдо-суперпользователю необходимые полномочия с помощью стандартных ACL — собственно, для этого они и предназначаются. Единственный подводный камень данного подхода — то, что ошибка в ACL может привести к ограничению необходимых полномочий. В худшем случае, rootdn может быть временно восстановлен, а потом удалён вновь, когда проблема будет решена. Лучшим решением обеспечения безопасности доступа от имени rootdn к обычному DIT будет удаление самого rootdn . И точка. Как в приведённой выше конфигурации.

      В тех случаях, когда rootdn является единственным методом доступа, таких как cn=config в приведённом выше примере, для принудительного включения механизмов защиты в конкретном разделе database используется директива security simple_bind=128 .

Проблемы, комментарии, предположения, исправления (включая битые ссылки) или есть что добавить? Пожалуйста, выкроите время в потоке занятой жизни, чтобы написать нам , вебмастеру или в службу поддержки . Оставшийся день Вы проведёте с чувством удовлетворения.