Установка и настройка FreeIPA – IT Pro Blog

Глава 16. службы каталога – администрирование linux систем для профессионалов. 2е изд.

Службы каталогов широко распространены в основных компьютерных вычислительных средах. Каталог облегчённого
протокола службы каталогов (LDAP, Lightweight Directory Access Protocol) является примером службы такого типа.
Каталоги LDAP являются специализированными базами данных, которые обычно содержать имена пользователей, пароли,
общие имена, адреса электронной почты, бизнес- адреса, а также прочие атрибуты. Вначале организации использовали
службы каталогов для обеспеченности распределёнными книгами адресов и информацией о пользователях. Со временем
службы каталогов выросли до роли централизованного хранилища всей пользовательской информации служб
аутентификации. Приложения разрабатываются с возможностью аутентификации от служб каталога, что ещё больше
расширяет её важность внутри некоторой организации.

В данной главе мы собираемся показать вам как установить и настроить сервер OpenLDAP. Мы также собираемся
рассказать о расширении вашего сервера каталога OpenLDAP путём добавления вашей собственной схемы. Мы покажем вам
как проектировать списки управления доступом (ACL, access control list) для придания безопасности вашей
установке, а также как управлять вашим сервером LDAP через инструменты командной строки и GUI на основе веб
интерфейса. Наконец, вы увидите как интегрировать ваш сервер LDAP с вашими уже имеющимися сетевой средой и
приложениями, включая возможность реализации служб с единой подписью и веб аутентификацией Apache.

Реализация служб каталога может быть сложной. Хотя её установка проста, она часто является вычурной при
настройке безопасности. OpenLDAP не имеет версии с коммерческой поддержкой, однако даже самые простейшие вопросы
к списку электронной почты OpenLDAP постоянно получают ответы со стороны серьёзных инженеров и разработчиков
данного проекта (что является огромной помощью и полным доверием к их преданности данному делу). Тем не менее,
вам неплохо было бы приобрести некую книгу, посвящённую обсуждаемому предмету, прежде чем вы приступите к своей
установке для дальнейшего освоения вами данного программного обеспечения. Мы бы хотели порекомендовать вам
следующее:

В данной главе мы исследуем OpenLDAP и воспользуемся ею в качестве службы аутентификации. Мы можем применять
её как службу с единой подписью для любых механизмов аутентификации, которые поддерживают LDAP. Она может
применяться для централизованного хранения информации подлинности. В данной главе мы собираемся провести вас
через:

Вы можете осуществлять поиск, добавление, изменение, удаление и аутентификацию со своими записями в вашей
службе LDAP. Эти действия ограничиваются списками доступа, причём различные пользователи могут иметь различные
права доступа. Именно этот процесс аутентификации осуществляется при той начальной стадии, которая определяет
уровень доступа, и именно это называется связыванием (binding).
Это может быть выполнено одним пользователем, но относиться к другому пользователю или анонимно в зависимости
от того, как вы настроили свои спсики доступа. Когда это выполнено, мы можем получать доступ ко всем элементам
в данной службе.

ЧИтайте, и мы объясним чем является LDAP и предоставим вам понимание основных компонентов, которые
формируют всю службу LDAP.

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

Имеются различные общие типы служб каталогов, причём все они предоставляются из модели OSI DAP X.500.
Такими примерами могут служить: Microsoft’s Active Directory, Red Hat’s Directory Services и Oracle Directory
Server Enterprise Edition.

В данной главе мы сосредоточимся на общеупотребимом и надёжном сервере OpenLDAP. OpenLDAP вычленился из
своего первоначального проекта, вначале разрабатывавшегося Университетом Мичигана и теперь продолжается
работой сообщества инженеров и разработчиков в проекте OpenLDAP (www.openldap.org/project/).

Модель OSI DAP X.500 описывает некоторые основополагающие концепции, которым подчиняется LDAP. Во- первых, вам
необходимо иметь одно- единственное дерево информационного каталога (DIT, directory information tree). Оно
является иерархической организацией записей. Каждая такая запись требует некоего отличительного имени
(DN, distinguished name). Это DN некоторого элемента состоит из относительного отличительного имени
(RDN, relative distinguished name) и предшествующих записей, к которым оно относится.
Рисунок 16-01 отображает основные взаимозависимости
между DIT, DN и RDN.

DIT является деревом каталога и в нашем случае оно имеет корневое DN
dn=com. Существуют различные способы определения вашего корня и главных
ответвлений (филиалов). Некоторые люди выбирают схему, основанную на их доменах DNS, как это имеется в нашем случае, а
некоторые люди применяют географические местоположения, например, o=US,
o=AU, o=DE в качестве своего корня.
В нашем случае мы воспользовались стандартом именования DNS, поскольку мы не собираемся рассматривать все
географические местоположения своей организации. Мы всегда можем вводить определённый атрибут
LocalityName в последующем движении вниз по дереву, если пожелаем, как мы
имеем в случае с филиалом compB, в котором мы определили
l=Amsterdam. Стоит поразмыслить над тем как вы желаете расположить свою
структуру каталога, но, в конце концов, вы хотите чтобы эта схема была настолько простой и лёгкой, чтобы вы могли
по возможности понимать её.

Филиалы (branches) применяются для организации вашей информации в логические группы. Эти логические группы
называются подразделениями (organizational
units
) и представляются как ou. Вы можете группировать что
пожелаете вместе, однако главными подразделениями (ou), которые вы обычно
видите в своём дереве LDAP это обычно People,
Groups и Machines. Вы сохраняете
всё, что делаете со своим персоналом в ou=people, свои группы пользователей
в ou=groups, а не связанные с персоналом ресурсы в
ou=Machines (также обычно именуемые
ou=hosts). Подразделения в свою очередь могут содержать другие подразделения
(ou) и могут быть настолько сложными, насколько вы пожелаете, хотя мы
вновь рекомендуем что чем проще, тем лучше, когда дело доходит до разработки вашего DIT.

DN является уникальной записью от вашего корня, который выстраивает соответствующий RDN и его предков.
Вы можете обнаружить на Рисунке 16-01, что у нас имеется DN,
состоящий из cn=Angela Taylor,ou=people,dc=example,dc=com.
Он составляется из RDN cn=Angela Taylor и его предков
ou=people, dc=example и
dc=com. Подобно тому, как
ou=people,dc=example,dc=com является DN (отличительным именем) для
подразделения People, а ou=people
является в нём RDN (относительным отличительным именем).

Каждая запись DN составляется из классов объектов
(object classes) и атрибутов
(attributes), которые описывают эту запись. Классы объектов какие
атрибуты должны быть представлены или допустимы быть представленными. Классы могут поддерживать другие классы
чтобы предоставлять расширение атрибутов в них. Эти атрибуты описываются соответствующими значениями RDN
(относительных отличительных имён). Классы и атрибуты должны быть определены в схеме и должны быть
уникальными.

Схема (schema) является
набором определений, которые описывают те данные, которые могут сохраняться в вашем сервере каталога. Эта
схема используется для определения вашего синтаксиса и соответствует правилам для неких доступных классов
и определений атрибутов. Если вы находите, что ваша организация не описывается должным образом имеющимися
в вашем распоряжении файлами схемы, вы, если пожелаете, можете создать ваш родной файл схемы для своей
собственной компании. Когда вы создадите свой файл схемы, вы затем включите его в ваши файлы настройки
OpenLDAP.

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

Хорошим практическим приёмом является добавление некоторого префикса ко всем создаваемым атрибутам и
классам, чтобы обеспечить их уникальность. Предположим, мы хотим добавить некий атрибут себе, который бы
позволил нам знать когда пользователь был отключён. В этом случае мы можем определить атрибут
“active” для своего примера компании в виде exampleActive.
Затем мы можем применять exampleActive для включения и отключения
записей устанавливая его в значение TRUE или
FALSE.

Вот как могла бы выглядеть некая запись LDAP:


dn: uid=user1,ou=people,dc=example,dc=com
uid: user1
exampleActive: TRUE
 	   

Раз этот атрибут добавлен в некий элемент LDAP, мы можем применять фильтры для поиска всех экземпляров, в
которых в нашем каталоге LDAP exampleActive = TRUE, что ускорит
результаты для активных пользователей. Это всего лишь пример того, как применять собственные определения схемы;
могут иметься и другие способы достижения того же самого результата.

OpenLDAP может применять различные серверы хранения. По умолчанию, OpenLDAP использует MDB
(Memory Mapped Database), которая основывается на LMDB (Lightning Memory Mapped Database). LMDB была
разработана Symas, организацией программного обеспечения, основанной многими, если не всеми, командами
разработки ядра OpenLDAP. Она чрезвычайно быстрая и масштабируемая, причём для баз данных, содержащих
миллионы записей. Она оптимизирована для чтения, поиска и просмотра. OpenLDAP может применять и другие
базы данных в качетсве сервера хранения, если вам это потребуется.

Ubuntu и CentOS предлагают различные версии OpenLDAP. И CentOS, и Ubuntu предлагают самый последний
выпуск OpenLDAP 2.4. Ниже перечислены некоторые из поддерживаемых ими функций:

Если вы искали поддержку для возможностей репликации MultiMaster (т.е. возможности иметь более одной
главной службы каталога LDAP), именно MultiMaster расширяет резервирование ваших установок LDAP.

Вы также можете применять перекрытия (overlays). Перекрытия предоставляют OpenLDAP дополнительную
функциональность изменять или расширять обычное поведение LDAP. Такие оверлеи, как ppolicy (Password Policy),
перекрывают включение управлений паролем, которые не предоставляются в основном коде OpenLDAP. Оверлей
ppolicy делают возможной установку таких вещей как время действия пароля и минимальная длина символов.

Вам также необходимо определить какие методы аутентификации вы собираетесь поддерживать в своей
организации. OpenLDAP поддерживает два метода аутентификации, простой (simple) и SASL. Простой метод имеет
три режима работы.

Про метод SASL OpenLDAP Administrator’s Guide сообщает, что вам
необходима имеющаяся работающая установка Cyrus SASL для предоставления механизма SASL. Это не совсем верно,
в зависимости от того, какой из механизмов SASL вы хотите реализовать. Вы достаточно просто можете установить
механизмы PLAIN/LOGIN и DIGESTMD5.
Однако вам необходимо иметь в наличии установленным Cyrus SASL. SASL предоставляет следующие механизмы:

Выможете прочитать дополнительно об этих методах аутентификации на следующих страницах в
OpenLDAP Administrator’s Guide:

Прежде чем мы покажем вам как устанавливать ваш сервер OpenLDAP в нашей системе примера, нам необходимо
обсудить некоторые подробности реализации.

Давайте просмотрим только одну часть своей сетевой среды. Предположим, что у нас в сетевой среде имеется
некий веб сервер и мы хотим гарантировать, что только персонал из какой- то определённой группы внутри нашей
организации имеет возможность доступа к нему. Обычно нам не требуется добавлять усложнённый механизм
регистрации в свой веб сайт, иметь некий вид базы данных пользователей для хранения этой информации и тому
подобного. При помощи нашего веб сервера Apache мы можем применять свой модуль LDAP Apache чтобы заставить
наш веб сервер применять некий сервер LDAP для запросов на аутентификацию. Без такой аутентификации этот веб
сайт не будет доступен. Мы также можем иметь другие службы аутентификации вместо своего сервера каталога
LDAP. На Рисунке 16-02 вы можете увидеть как мы могли
бы осуществлять аутентификацию своих веб серверов.

Рисунjк 16-02 представляет простую схему,
отображающую применение LDAP для аутентификации наших клиентов рабочих мест или из Интернета на веб службах
(и служба LDAP, и веб служба могут находиться на одном и том же хосте, если у вас не имеется достаточных
аппаратных ресурсов). Когда веб сайтом получается запрос, проводится проверка этого пользователя прежде
чем ему будет предоставлен доступ. К службе LDAP на headoffice.example.com
отправляется запрос на аутентификацию. Если пользователь получает подтверждение, сервер LDAP отправляет
соответствующий запрос данной веб службе и этот пользователь может осуществлять доступ к данному сайту.

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

Мы намереваемся показать как установить и службу LDAP и аутентификацию для веб службы Apache.

OpenLDAP доступен и в CentOS, и в Ubuntu через их интернет репозитории. Опять же, для OpenLDAP в этих двух
дистрибутивах имеются требующие уточнения различия и мы подробно рассмотрим их далее.

В настоящий момент мы выполним установку сервера OpenLDAP на нашем хосте CentOS. Двоичные файлы доступны в
репозиториях CentOS, и мы можем установить их при помощи команды yum или
через GUI управления пакетомю Мы устанавливаем его посредством команды yum
следующим образом:


$ sudo yum install openldap openldap-clients openldap-servers
 	   

Это установит необходимые файлы для настройки, исполнения и управления сервером LDAP. пакет
openldap установит основные пакеты, необходимые для того, чтобы позволить
интеграцию данного хоста с сервером OpenLDAP. Пакет openldap-clients
установит все инструменты для управления и запросов к вашему серверу LDAP. А пакет
openldap-servers установит необходимые файлы для работы некоего сервера
OpenLDAP.

Чтобы установить OpenLDAP на хосте Ubuntu, нам понадобятся установленными пакет
ldap-utils и пакет slapd.
Команда ниже выполнит эту установку:


$ sudo aptitude install ldap-utils slapd
 	   

Когда вы выполните эту команду, полученный пакет slapd запросит
вас предоставить ваш пароль и выполнит установку. Если вы не желаете предоставлять пароль, вы можете просто
нажать клавишу Enter дважды (мы покажем вам как создавать некий пароль в последующем разделе
Настройка). После своей установки, пакет
ldap-utils установит необходимые для работы и настройки вашего каталога
LDAP файлы.

Пакетами настройки клиента являются auth-client-config (переключатель
профиля PAM и NSS) и ldap-auth-client (метапакет для аутентификации
LDAP поставляемый совместно с ldap-auth-config). Вы можете захотеть
установить и эти два пакета также.

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

OpenLDAP использует для управления SLAPD динамическую настройку времени исполнения, что означает что он
настраивает себя через своё собственное DIT (дерево каталога). Это подразумевает, что изменения настройки
SLAPD могут выполняться динамически посредством изменения записей в её DIT при помощи стандартных инструментов,
применяемых для изменения прочих записей LDAP такими командами, как, например,
ldapmodify.

В своём примере мы настроим наш SLAPD в хосте Ubuntu; для CentOS некоторые пути каталога будут другими. Для
хоста CentOS, сам каталог настроек будет называться /etc/openldap вместо
/etc/ldap, который вы обнаруживаете в хостах Ubuntu. Оба дистрибутива
сохраняют свои базы данных в /var/lib/ldap.

Например, файлы настройки для OpenLDAP в хосте CentOS сохраняются в
/etc/openldap/.


$ sudo ls -l /etc/openldap/
total 12
drwxr-xr-x. 2 root root 85 Oct 26 12:46 certs
-rw-r--r--. 1 root root 121 Mar 31 2022 check_password.conf
-rw-r--r--. 1 root root 365 Oct 3 13:47 ldap.conf
drwxr-xr-x. 2 root root 4096 Oct 26 12:46 schema
drwx------. 3 ldap ldap 43 Oct 26 12:46 slapd.d
 	   

Секретная информация хранится в каталоге certs. Файлом настройки,
предназначенным для конфигурирования клиентов LDAP является ldap.conf.
Каталог schema содержит файлы схемы для нашей службы
ldap. Там вы обнаружите файлы .schema
и файлы .ldif. Файлы LDIF
являются файлами взаимообменного формата LDAP, специализированного формата для определения изменения данных в
LDAP. В каталоге slapd.d вы найдёте все файлы, составляющие DIT SLAPD.
Мы будем объяснять их по ходу данной главы.

Похожее:  SSH-Bastion. Замковые ворота вашей инфраструктуры — KAZARIN OnLine

Прежде чем приступить к настройке OpenLDAP, мы собираемся установить несколько требований. Нам необходимо
создать сертификат TLS и ключ, а также некое имя записи DNS.

Самый первый шаг состоит в создании записи DNS. Системы аутентификации, подобные LDAP, обычно не выставляются
для всеобщего доступа, а если они там, то могут оказаться предметом для внешних атак. По этой причине мы обычно
не предоставляем им никакого общедоступного адреса IP. Для ваших внешних офисов, которым требуется аутентификация
для соответствующей службы, мы рекомендуем использовать для доступа частный VPN.

Данную службу OpenLDAP мы собираемся установить в своём хосте headoffice.example.com.
Мы собираемся предоставить своему серверу DNS новую запись CNAME для указания
ldap.example.com на headoffice.example.com.
Нам необходимо находиться на своём хосте сервера DNS и выполнить следующую команду:


$ sudo nsupdate -k /etc/bind/ddns_update.key
> server localhost
> update add ldap.example.com 8600 CNAME headoffice.example.com
> send
> quit
$ host ldap.example.com
ldap.example.com is an alias for headoffice.example.com.
headoffice.example.com has address 192.168.0.1
 	   

Так как эти пункты указывают на некий внутренний частный адрес IPv4, мы не сможем воспользоваться Let’s Encrypt
для создания своего сертификата TLS и нам придётся применять свой собственный частный CA. Клиенты, которые будут
соединяться с нашим сервером LDAP, должны будут иметь установленным сертификат корня (root) этого CA.

Вначале создадим некий новый каталог с названием /etc/ldap/certs, а
затем изменим в нём права доступа.


$ sudo mkdir /etc/ldap/certs
 	   

Мы создадим свои ключ и CDR в нашем хосте ldap.example.com и
выполним следующее изнутри каталога /etc/ldap/certs:


$ sudo openssl req -new -newkey rsa:4096 -nodes -keyout ldap.example.com.key -out ldap.example.com.req
 	   

Пройдите далее и подпишите данный запрос как мы делали это в Главах 11 и 15 в своём частном CA. Когда нам необходимо
добавить общедоступный сертификат, он создаётся в каталог /etc/ssl/certs
вместе с вашим CA корня, если там его ещё нет, cacert.pem.

Когда все сертификаты установлены в каталог certs, мы должны изменить
их владельца и права доступа следующим образом:


$ sudo chown openldap:openldap –R /etc/ldap/certs
$ sudo chmod 600 /etc/ldap/certs/ldap.example.com.key
 	   

Пользователем, который исполняет службу LDAP в CentOS является ldap
и в предыдущей команде chown необходимо применять его.

Выполнив указанные требования, мы теперь можем приступить к настройке своего сервера LDAP. После того, как мы
установили свои пакеты slapd и получили запрос на пароль администратора
в Ubuntu, был настроен, установлен и запущен базовый сервер OpenLDAP (в CentOS вам придётся вначале запустить
службу slapd чтобы выполнить эту команду).

В листинге 16-1 мы выполнили вывод команды
ldapsearch. Эта команда является частью общего комплекта команд,
применяемых для взаимодействия с сервером нашим LDAP (или любым сервером LDAP). В данном примере му передали в
ldapsearch аргумент –Q чтобы
включить тихий (quiet) режим SASL (так как мы применяем повышающие полномочия –sudo).
В трёх L (-LLL) каждая имеет некоторое значение. Наличие одной подразумевает
вывод в формате LDIF; другие две уменьшают объём вывода. Аргумент –H
является тем URI, к кторомы мы намереваемся подключиться, ldapi:///,
что сообщает о необходимости подключения к локальному серверу LDAP через сокет Unix в данном локальном хосте.
Таким образом мы можем передать свои UID и GUID нашему пользователю для аутентификации этим сервером LDAP. Далее,
-b определяет базу для поиска; мы осуществляем поиск в своём DIT
cn=config для всех dn
(или отличительных имён) применяя в качесве фильтра dn.

 

Листинг 16-1


$ sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn
dn: cn=config
dn: cn=module{0},cn=config
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: olcBackend={0}mdb,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}mdb,cn=config
 	   

Просмотр конфигурации, определённой по умолчанию

В листинге 16-1 мы также видим, что мы передали
опцию -Y. Это определяет какой механизм аутентификации SASL мы желаем
применять. Здесь EXTERNAL предписывает использовать в данном случае
аутентификацию локального хоста. Через сокет Unix мы передаём UID и GUID своего пользователя root для выполнения
аутентификации. Установка по умолчанию делает возможным доступ локального root к установленному на нём серверу
LDAP.

[Замечание]Формат LDIF

Формат обмена каталога LDAP (LDIF, LDAP Directory interchange Format) является определением того, как
добавлять и удалять записи в базе данных LDAP. Он имеет свой собственный RFC (https://www.ietf.org/rfc/rfc2849.txt) и может применяться инструментами LDAP для изменения всех
записей в базе данных LDAP, к которой они осуществляют доступ.

Формат файла LDiF выглядит следующим образом:


dn: <отличительное имя, которое вы собираетесь изменить>
changetype: необязательный тип изменения из списка add, replace или delete
<атрибут или класс объекта>: значение
 	   

Ниже приводится пример:


dn: dc=example,dc=com
objectclass: dcObject
objectclass: organizationalUnit
dc: example
ou: example
 	   

Здесь мы определили самый верхний уровень своего DIT. Отличительное имя (DN)
dc=example,dc=com пополнит эти определённые классы объектов и
атрибуты.

Для изменения существующей записи DN мы можем применить нечто подобное такому:


dn: uid=ffrank,ou=people,dc=example,dc=com
changetype: replace
replace: userPassword
userPassword: <new password>
-
 	   

Здесь мы изменили userPassword для
ffrank, воспользовавшись текстовым файлом в формате LDIF. Вы
можете заметить DN, который мы собираемся изменять, тип изменения, которое мы намереваемся произвести
(replace) и тот атрибут, который мы собираемся заменять
(userPassword); наконец, мы назначаем своё новое значение этому
атрибуту. Мы можем иметь множество таких операторов в данном единственном файле и мы разделяем их все
при помощи - в новой строке.

Затем в Листинге 16-1 мы имеем перечень
глобальных направляющих (directive) отличительных имён (DN), которые находятся в нашей глобальной настройке DIT
cn=config. Как вы можете видеть, этот глобальный DIT включает в себя
сам корень cn=config, а затем соответствующие DN вкладываются далее,
как на Рисунке 16-03.

Вы можете увидеть из в Листинга 16-1 и
Рисунка 16-03, что наша схема LDAP,
cn={1}cosine,cn=schema,cn=config расположена под нашим отличительным
именем (DN) cn=schema, которое в свою очередь находится под
cn=config. Здесь {1}
обозначает некий индекс нашей схемы отличительных имён.

Помимо этого, в Листинге 16-1 присутствуют
некоторые прочие глобальные директивы, такие как olcBackend и
olcDatabase. Они, как и подразумевают их имена, определяют само
хранилище данных, лежащее в основе.


dn: olcBackend={0}mdb,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}mdb,cn=config
 	   

Для получения полного листинга или некоторой резервной копии вашего DIT cn=config,
вы можете выполнить следующую команду:


sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config > slapd.ldif
 	   

Мы применили ту же самую команду, которая приведена выше, однако имеет удалённый фильтр
dn в самом конце и направить вывод в файл
slapd.ldif. Если вы просмотрите этот файл, вы увидите как были настроены
все директивы.

Взглянув на первую директиву мы получаем необходимое отличительное имя (DN) для
cn=config. оно имеет некий
ObjectClassolcGlobal,
который является тем классом объекта, который определяет всё глобальное DIT. Вы также можете увидеть, что мы можем
определить конкретное общее имя (common name, cn:), некий файл
аргументов для slapd (olcArgsFile:),
уровень протоколирования (olcLogLevel:), идентификатор процесса
(olcPidFile:) и потоки для применения
(olcToolThreads:).

Следующая директива olcToolThreads: сообщает нашему демону
slapd применять только один ЦПУ для осуществления индексации. Если у вас
имеется более одного ЦПУ, вы можете настроить её на большее значение, но не выше чем общее число имеющихся у
вас ЦПУ. Прочие настройки производительности включают olcThreads,
olcTimeLimits, olcSockBuffMaxIncoming
и olcSockBuffMinIncoming.

Всякий раз, когда вы определяете DN, вам необходимо предоставлять соответствующий класс объекта (или классы),
к которым оно относится. Поэтому класс объекта olcGlobal имеет
olcArgsFile в качестве некоторого атрибута, причём это будет определено в
самом файле схемы.

 

Определение LogLevels

В классе объекта olcGlobal мы можем определить наше протоколирование.
По умолчанию оно установлено в значение none. Это ключевое слово, но
значение также может выражаться в виде числа (или даже шестнадцатеричного), как это описывается в
Таблице 16-1:

Уровень протоколирования важен в помощи при отладке вашей установки. Честно говоря, для начинающего пользователя
то что сообщается, может оказаться сильно запутанным. Однако уровень ведения журнала является аддитивным, и вы
можете получать в журналах подробности. В производственной среде мы рекомендуем установить это значение в 0 а
если пожелаете, использовать проверочное перекрытие для отслеживания того, что произошло с вашей установкой
(перекрытие оверлей – это программный модуль, который может подключаться
к серверной части для предоставления определённой информации, в данном случае – хвотовую часть аудита).

Мы бы хотели установить свой уровень протоколирования в значение 480.
Это будет отображать в наших журналах обработку фильтрации, файла настройки, управление доступом и информацию о
соединениях. Как уже упоминалось, описываемая установка Loglevel является
аддитивной, что означает, что вы можете добавить дополнительное протоколирование прибавляя значения тех вещей,
которые вы желаете протоколировать. Как вы вероятно уже вычислили, наше значение Loglevel480 состоит из уровня 32 (фильтр
поиска), 64 (обработка настройки), 128
(обработка списка управления доступом) и 256 (результаты соединений и
операций LDAP). Это хороший набор настроек пока мы устанавливаем свою службу LDAP, так как он предоставляет
достаточный уровень информированности. Если мы упираемся в стену, мы можем изменить Loglevel
на -1 чтобы включить режим отладки, что включает все свойства ведения журнала.
Также помните, что в производственной среде вы обычно пожелаете иметь Loglevel
установленным в значение . Для установки Loglevel
вы также можете применять шестнадцатеричные значения в одной строке для достижения того же самого результата:
в этом случае мы бы установили свой уровень протокола в Loglevel0x20 0x40 0x80 0x100.

 

Изменение настройки LogLevels при помощи ldapmodify

Давайте изменим Loglevel до нужного нам уровня. Чтобы выполнить это,
мы воспользуемся командой ldapmodify. Это потребует аргументов, аналогичных
применявшейся нами ранее в команде ldapsearch. Мы собираемся предоставить
этой команде файл с названием loglevel.ldif, который будет выглядеть
так:


dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: 480
 	   

Чтобы изменить некий атрибут, нам необходимо предоставить то значение dn,
которое мы желаем поменять (dn: cn=config), тип этого изменения
(changetype: modify), тот атрибут, который мы хотим менять
(replace: olcLogLevel) и, наконец, устанавливаемое нами значение этого
атрибута (olcLogLevel: 480).

Теперь даввайте применим ldapmodify для изменения атрибута ведения протокола.


$ sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f loglevel.ldif
 	   

Чтобы убедиться, что всё было установлено, мы снова выполним для проверки команду
ldapsearch.


$ sudo ldapsearch –Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config cn=config
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/slapd/slapd.args
olcPidFile: /var/run/slapd/slapd.pid
olcToolThreads: 1
olcLogLevel: 480
 	   

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

 

Добавление модулей

В файле slapd.ldif у нас имеется раздел модулей. Модули добавляются в
конфигурацию для предоставления определённой функциональности.


dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib/ldap
olcModuleLoad: {0}back_mdb
 	   

Здесь мы определяем тот путь, по которому ищутся наши модули, olcModulePath:
/usr/lib/ldap
. У нас имеется один загруженный модуль, а именно
back_mdb, который является той самой иерархической базой данных Memory
Mapped, которую мы обсуждали ранее.

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


$ ll /usr/lib/ldap/pp*
-rw-r--r-- 1 root root 39328 May 11 17:11 /usr/lib/ldap/ppolicy-2.4.so.2.10.5
-rw-r--r-- 1 root root   948 May 11 17:11 /usr/lib/ldap/ppolicy.la
 	   

Чтобы загрузить требующуюся политику мы собираемся создать некий файл с названием
ppolicy_module.ldif, а для его добавления воспользоваться
ldapmodify.


dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: ppolicy.la
 	   

Когда мы выполняем требующуюся команду ldapmodify, мы можем
заметить, что мы теперь получаем запрос на добавление модуля ppolicy.la.
Если мы теперь выполним фильтрацию ldapearch только для тех DN,
которые содержат класс объекта olcModuleList, мы увидим
следующее:


$ sudo ldapsearch -H ldapi:// -Y EXTERNAL -b "cn=config" -LLL -Q "objectClass=olcModuleList"
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib/ldap
olcModuleLoad: {0}back_mdb
olcModuleLoad: {1}ppolicy.la
 	   

Мы обратимся в последствии к настройке оверлея ppolicy,
когда мы загрузим свой LDIF в имеющуюся базу данных OpenLDAP в разделе “Покрытие политики пароля“.

 

Установка Suffix, RootDN и RootPW

Теперь мы намереваемся настроить серверную базу данных, которая будет содержать наше DIT. Мы можем
по своему желанию свой установленный по умолчанию сервер базы данных и у нас здесь имеется ряд вариантов.
Обычно, вы по умолчанию применяете mdb. Все остальные типы, которые вы
можете выбрать (ldap, ldif,
metadirectory, perl и т.п.)
применяются для представления (proxying) вашего сервера.

Чтобы просмотреть текущие настройки базы данных мы можем выполнить следующий
ldapsearch:


$ sudo ldapsearch -H ldapi:/// -Y EXTERNAL -b "olcDatabase={1}mdb,cn=config" -LLL -Q
dn: olcDatabase={1}mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: {1}mdb
olcDbDirectory: /var/lib/ldap
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcDbIndex: objectClass eq
olcDbIndex: cn,uid eq
olcDbIndex: uidNumber,gidNumber eq
olcDbIndex: member,memberUid eq
olcDbMaxSize: 1073741824
olcSuffix: dc=nodomain
olcRootDN: cn=admin,dc=nodomain
olcRootPW: {SSHA}EEyEuYme4zBPYbRzHc l4rApfvrXjXnV
 	   

Значение по умолчанию для нашего типа базы данных определено так: olcDatabase:
{1}mdb
. Вы можете определять более одного экземпляра базы данных. Следующими подробностями,
которые мы настраиваем, являются вершина нашего DIT, основной суффикс и некий пользователь, который будет
иметь полный доступ к ним, как пользователь root.

теперь мы создадим некий файл с именем db.ldif, которыей имеет
такое содержимое:


dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=example,dc=com
-
replace: olcRootDN
olcRootDN: cn=admin,dc=example,dc=com
-
replace: olcRootPW
olcRootPW: {SSHA}QN NZNjLxIsG/ PGDvb/6Yg3qX2SsX95
 	   

Наш olcSuffix направляет запросы для
dc=example,dc=com в этот экземпляр базы данных. Поскольку уже имеются
значения для этих атрибутов, мы в своём файле LDIF применяем дерективу замены, например:
replace:olcRootPW. Здесь вы можете иметь объявленными более одного
суффикса. olcRootDN является пользователем root, который имеет полный
доступ к базе данных; его пароль определяется в olcRootPW.
Вы можете создать пароль, применив команду slappasswd следующим
образом:


$ sudo slappasswd
 	   

Выдаваемый пароль может быть затем скопирован и подставлен в olcRootPW,
как это было сделано ранее. Прежде чем мы применим этот LDIF, мы рассмотрим наши индексы.

 

Создание индексов

Далее мы можем настроить свои индексы. Индексы применяются для ускорения поиска в имеющейся базе данных.
Вы можете просмотреть все текущие индексы в своей базе данных выполнив следующее:


$ sudo ldapsearch -H ldapi:/// -Y EXTERNAL -b "olcDatabase={1}mdb,cn=config" -LLL –Q
olcDbIndex
olcDbIndex: objectClass eq
olcDbIndex: cn,uid eq
olcDbIndex: uidNumber,gidNumber eq
olcDbIndex: member,memberUid eq
 	   

Каак правило, вам следует выполнять индексацию того, что ваши клиенты обычно собираются просматривать.
Некая адресная книга электронной почты клиентов может осуществлять поиск обычного имени, или
cn, когда она осуществляет просмотр имён людей для заполнения ими
своих записей адресной книги. При таком раскладе вы можете пожелать наличия некоторого индекса имеющегося
у вас атрибута cn, оптимизированного для подстрок,
sub (substrings). Таблица 16-2:

Похожее:  Аутентификация на основе одноразовых паролей в Active Directory. Теоретические основы. / Двухфакторная аутентификация / PKI Guru
Таблица 16-2. Обычные типы индексации
ТипОписание

sub

Полезен при оптимизации поисковых строк, которые содержат
символы замещения, например, cn=Jane*

eq

Полезен для оптимизации поиска, содержащего точные строки, например,
sn=Smith

pres

Полезен для оптимизации поиска классов объектов или атрибутов,
например, objectclass=person

approx

Полезен для оптимизации поиска, содержащего близкие по звучанию строки,
например, sn~=Smi*

Доступны и прочие типы индексации, и вы можете прочитать о них на странице man для
slapd.conf. Мы же собираемся выполнить индексацию
objectclass, cn и
uid, которые, как мы знаем, будут наиболее часто искомыми в случае,
когда пользователи патаются осуществлять аутентификацию. В нашем предыдущем коде вы можете обнаружить уже
имеющуюся индексацию для этих полей. Мы собираемся добавить некий индекс для атрибута, который мы вскоре создадим, с
именем exampleActive. Мы добавим следующее в свой файл
db.ldif:


add: olcDbIndex
olcDbIndex: exampleActive pres,eq
 	   

Теперь давайте продвинемся далее и воспользуемся ldapmodify для
применения своих изменений db.ldif.


$ sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f db.ldif
 	   

Схема представляет определённую структуру ваших классов объектов и атрибутов имеющемуся серверу SLAPD.
Хотя она и не является тем же самым, чем является некая схема базы данных, такая схема LDAP определяет те
классы объектов и атрибутов, которые будет содержать ваш сервер LDAP, во многом как некая схема {реляционной}
базы данных описывала бы таблицы и кортежи. Вы можете просмотреть загруженные в настоящее время схемы при помощи
такого ldapsearch:


$ sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
 	   

Вершиной отличительного имени (dn) является
cn=schema,cn=config, и именно она является родителем нашей схемы.
Затем у нас имеется множество схем по умолчанию, которые предоставлены нам нашей установкой. Центральная схема
предоставляет такие классы объектов, как dcObject
(dc) и organizationalUnit (ou)
(ou). Схема cosine предоставляет
определённый класс объектов dNSDomain и атрибут
host. Другая схема nis
предоставляет объекты учётных записей пользователей и атрибуты такие, как
posixAccount и теневые настройки пароля. Ещё одна схема,
inetorgperson, содержит различные прочие объекты и классы, связанные со
служащими. Вы можете применять или нет производимые ими объекты и атрибуты.

Для просмотра всех доступных вам схем вы можете пролистать имеющийся каталог
/etc/ldap/schema. Например, мы сможем там обнаружить там такие каталоги,
как ppolicy.schema и ppolicy.ldif
для представленных схем ppolicy.


$ ls /etc/ldap/schema/pp*
/etc/ldap/schema/ppolicy.ldif /etc/ldap/schema/ppolicy.schema
 	   

Файл ppolicy.ldif был произведён для нас из имеющегося файла
ppolicy.schema. Мы собираемся добавить свою схему
ppolicy.ldif в наш SLAPD. Мы сделаем это воспользовавшись командой
ldapadd. Она имеет аргументы, аналогичные аргументам
ldapsearch и ldapmodify.


$ sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif
adding new entry "cn=ppolicy,cn=schema,cn=config"
 	   

Давайте посмотрим что было загружено.


$ sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: cn={4}ppolicy,cn=schema,cn=config
 	   

Вы можете увидеть, что наша схема ppolicy была добавлена под
индексом {4}. Помните номер индекса, так как он понадобится нам, когда
мы добавим свою собственную схему. Давайте рассмотрим как мы создадим и добавим свою собственную схему.

 

Создание вашей схемы

Мы создадим некий файл с именем /etc/ldap/schema/exampleactive.schema.
В этот файл схемы мы включим некие примера класса и атрибутов, которые мы применим для отображения того
является ли некая учётная запись пользователя активной, либо нет.

Чтобы начать, давайте рассмотрим как создавать какой- либо класс объекта в данной схеме. В нашем файле
core.schema в каталоге schema
появляется следующее:


objectclass ( 1.3.6.1.4.1.1466.344 NAME 'dcObject'
       DESC 'RFC2247: domain component object'
       SUP top AUXILIARY MUST dc )
 	   

Это один из основных классов объектов, который будет включён в наше DIT. Нам необходимо объявить какой
тип сущности мы применяем, причём для некоторого класса объекта мы начинаем с objectclass
( подробности схемы )
. Пробелы важны при определении ваших классов объектов и атрибутов, причём
некие пробелы должны присутствовать в ( ) при каждом окончании.
Определение некоторого класса объекта должно удовлетворять следующему формату:


objectclass ( <OID> NAME <name> DESC <description> SUP <parent class> <class type> <MUST|MAY> attritubutes )
 	   

Тот номер, который вы тут можете обнаружить, 1.3.6.1.4.1.1466.344,
является номером частной компании (PEN, private enterprise number), или идентификатором объекта (OID, object
identifier), который является уникальной последовательностью номеров для идентифицируемых объектов; если вы
знакомы с такими вещами, как SNMP, вы должны в этом разобраться, так как они применяют ту же самую концепцию
OID. {Прим. пер.: с описанием OID вы можете ознакомится в разделе
Zabbix
мониторинг SNMP
нашего перевода отдельных глав “Zabbix. Полное руководство”, 2е изд.
Андреа Далле Ваккье, Packt Pub.
}

Класс объекта имеет полученное имя, dcObject и описание
(DESC). Следующая строка сообщает нам, что он будет наследовать
указанный класс объекта SUP top. SUP
определяет наивысшее положение, а top означает, что этот класс объекта
не имеет родительского класса объекта; это является наивысшим в иерархии имеющегося класса объекта. Прочие
последующие классы объекта могут использовать данный класс объекта как свой
SUP, или наследуемый класс объекта.

AUXILIARY обозначает определение типа класса объекта. Имеется три
типа классов объектов:

Имеющийся dcMUST сообщает,
что если этот объект определён в рассматриваемом каталоге сервера, тогда также должен добавляться и этот
атрибут dc. Атрибуты, которые не являются обязательными, однако
доступны этому классу объекта могут быть определены как MAY.

Атрибуты также имеют определённые правила. Они должны определяться в своей схеме и те же самые атрибуты могут
включаться в один или более классов объектов. Помимо этого, по умолчанию, атрибуты являются
MULTI-VALUE, что подразумевает, что мы можем иметь более одного значения,
определяемого для нашего DN. Обычным примером являются адреса электронной почты;
всякий пользователь может иметь более одного адреса электронной почты. Остальные атрибуты могут объявляться
как SINGLE-VALUE и могут определяться только один раз, например, как
значение пароля пользователя.

Атрибуты могут быть иерархическими и могут наследовать соответствующие свойства своих родителей. Они
выражаются по разному для классов объектов иерархии следующими путями:

Обычным примером наследования атрибутов является атрибут name.
Атрибут name является родителем для
common name (cn),
given name (gn),
urname (sn).

Давайте взглянем на наш собственный файл схемы, который мы создали, а именно
/etc/ldap/schema/exampleactive.schema:


# $Id$

attributetype ( 1.1.3.10 NAME 'exampleActive'
DESC 'Example User Active'
SINGLE-VALUE
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7)

objectclass ( 1.1.1.2 NAME 'exampleClient'
SUP top AUXILIARY
DESC 'Example.com User objectclass'
MAY ( exampleActive ))
 	   

В этих двух объектах схемы у нас имеется два созданных нами OID. Эти представители в данном примере могут
вступать в конфликт с прочими существующими файлами схемы и служат только для демонстрации. Чтобы избежать
этого нам бы в обычных условиях пришлось применять наш собственные PEN. Мы притворимся, что мы сделали это и
что мы получили некий OID 1.3.6.1.4.1.111111, где
1.3.6.1.4.1 является дугой (arc)
IANA, или узлом, а 111111 является специальным номером, который
отличает нашу компанию от прочих компаний. Теперь мы можем использовать собственный IOD в тех местах, где
он требовался в предыдущих схемах.


attributetype ( 1.3.6.1.4.1.111111.3.1.1 NAME 'exampleActive'
DESC 'Example User Active'
SINGLE-VALUE
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )
objectclass ( 1.3.6.1.4.1.111111.3.2.1 NAME 'exampleClient' SUP top AUXILIARY DESC 'Example.com User objectclass'
MAY ( exampleActive ))
 	   

Как только вы получили собственные PEN или некий OID, вы можете делить его на полезные сегменты
(Также называемые узлами – nodes – или дугами
arcs). Обычно вы можете применять некий OID не только для объектов
схемы LDAP, но и для таких вещей как MIB SNMP. Как вы можете видеть, у нас выделена ветвь
1.3.6.1.4.1.1111113 для определений нашей схемы LDAP.
Под ней мы помещаем все свои определения класса объекта вслед за
1.3.6.1.4.1.1111113.2 и свои атрибуты вслед за
1.3.6.1.4.1.1111113.1.

Наш атрибут exampleActive даже может определяться всего лишь один
раз, поэтому мы сделаем его SINGLE-VALUE. Если мы попытаемся определить
этот атрибут более одного раза для конкретного отличительного имени (DN), мы получим ошибку применения.

Мы настроим свой атрибут exampleActive как Boolean, что означает,
что он может быть либо истиной, либо ложью. Установление этого атрибута в значение
TRUE будет означать, что наша учётная запись активна. Установка
FALSE будет означать что эта учётная запись не активна. Мы можем
проиндексировать этот атрибут, что вновь ускорит наши операции поиска. Именно поэтому мы добавили ранее в свой
db.ldif следующее:


olcDbIndex: exampleActive pres,eq
 	   

Класс объекта exampleClient определяет, что мы можем иметь наличие
атрибута exampleActive (что отображается значением
MAY), когда мы включили это как класс объекта в своей записи DN. Если
мы желаем усилить его присутствие, мы можем определить вместо этого
MUST. Данный класс объекта является типом
AUXILARY и имеет значение суперкласса, определяемого
SUP top. Типом объекта по умолчанию является
STRUCTURAL. Вы должны иметь один класс объекта
STRUCTURAL в своих записях и вы не можете иметь два класса объектов
STRUCTURAL указывающих на один и тот же родительский или старший
класс.

 

Добавление вашей схемы

Для добавления своей схемы нам необходимо осуществить следующие процессы:

Для преобразования нашего файла схемы в LDIF мы используем команду slaptest.
Данная команда slaptest полезна для преобразования файлов схемы на основе
текстового формата в формат LDIF.

В slaptest мы передадим
/etc/ldap/schema/exampleactive.schema, а файл вывода будет создан во
временном каталоге настроек SLAPD.

Вначале создадим временный каталог для хранения наших преобразованных файлов.


$ sudo mkdir /etc/ldap/ldif_converted && cd /etc/ldap
 	   

В данном каталоге мы теперь создадим некий файл с именем schema_load.conf
в старом формате slapd.conf, который будет применяться напрямую в
команде slaptest для чтения в нашем файле схемы. Он имеет следующее
содержимое:


include /etc/ldap/schema/exampleactive.schema
 	   

Теперь мы можем применить его как входной файл для своей команды slaptest.


$ sudo slaptest –f schema_load.conf –F ldif_converted
 	   

Это создаст некий файл в формате LDIF.


/etc/ldap/ldif_converted/cn=config/cn=schema/cn={0}exampleactive.ldif
 	   

Если вы получите такую ошибку:


58180fbb schema/exampleactive.schema: line 1 attributetype: Missing closing parenthesis before end of input
 	   

это отображает тот факт, что в вашем файле схемы имеются ошибки пробелов. Вы должны помещать свои объявления
в отдельную строку, без символа возврата каретки (carriage return) и обратить внимание на наличие пробелов.
Вот некий пример:


attributetype ( attribute detail )

objectclass ( object detail )
 	   

Мы собираемся изменить свой файл LDIF, который был выведен с применением нашего редактора
vi и применяет sudo для
подъёма наших полномочий.


# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 39f1bf5a
dn: cn={0}exampleactive
objectClass: olcSchemaConfig
cn: {0}exampleactive
olcAttributeTypes: {0}( 1.3.6.1.4.1.111111.3.1.1 NAME 'exampleActive' DESC 'Example User Active' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
olcObjectClasses: {0}( 1.3.6.1.4.1.111111.3.2.1 NAME 'exampleClient' DESC 'Example.com User objectclass' SUP top AUXILIARY MAY exampleActive )
structuralObjectClass: olcSchemaConfig
entryUUID: 53a98d60-3432-1036-9ae2-35c34321a848
creatorsName: cn=config
createTimestamp: 20221101035217Z
entryCSN: 20221101035217.399551Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20221101035217Z
 	   

нам необходимо удалить те строки, которые выделены жирным шрифтом, а именно, начинающиеся с
structuralObjectClass: olcSchemaConfig по
modifyTimestamp: 20221101035217Z и первые две строки комментария
#. Затем вы можете увидеть следующую строку:


dn: cn={0}exampleactive
 	   

Как вы помните, {0} относится к нашему индексу, если мы попытаемся
загрузить это DN (отличительное имя), мы будем конфликтовать со всеми существующими схемами, которые имеют
cn={0}, который, возвращаясь назад к нашему выводу
ldapsearch, является нашей схемой ядра. Когда мы добавили схему
ppolicy, мы предупреждали запомнить её номер индекса
({4}), а теперь нам необходимо добавить единицу к нему чтобы быть
уверенным в отсутствии конфликта индексов.


dn: cn={5}exampleactive
 	   

Затем мы сохраним это файл в /etc/ldap/schema/exampleactive.ldif.
Теперь вы можете воспользоваться командой ldapadd для добавления
созданного LDIF в наш сервер SLAPD.


$ sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f schema/exampleactive.ldif adding new entry "cn={5}exampleactive,cn=schema,cn=config"
 	   

Мы воспользуемся данным файлом ldapadd, когда мы будем объявлять
своих пользователей в разделе “LDIF и добавление
пользователей
” данной главы.

Всякое соединение, которое осуществляет доступ к вашему серверу LDAP должно быть снабжено определённым
доступом к частям общего дерева если вы желаете находиться в безопасности. Доступом по умолчанию для OpenLDAP
является read, но вы пожелаете его закрыть если вы храните такую
секретную информацию как пароли. Там где вы получаете соединения вы можете определить необходимый уровень
безопасности, либо шифрование, которое соединение должно иметь для получения доступа, причём вплоть до той
ветки или атрибута, к которым вы разрешаете доступ. У вас также имеются различные уровни доступа, которые вы
далее можете предоставлять запрашивающему то соединению: является manage,
write, read,
search и auth.

 

Перечисление управлений доступом

Управления доступом подключаются к существующей настройке базы данных. Для просмотра текущих списков
управления доступом нам необходимо выполнить следующее:


$ sudo ldapsearch -H ldapi:/// -Y EXTERNAL -b "olcDatabase={1}mdb,cn=config" -LLL -Q
dn: olcDatabase={1}mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: {1}mdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=example,dc=com

olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read

olcLastMod: TRUE
...
 	   

В предыдущих строках мы можем обнаружить списки доступа. Они начинаются с olcAccess
и были снабжены номером индекса, {0}. Мы можем просмотреть индекс
{0} следующим образом:


(access) to attrs=userPassword
    by self write
    by anonymous auth
    by * none
 	   

Это делает возможным пользователю выполнять запись в свой собственный атрибут
userPassword, а анонимный пользователь может выполнить
аутентификацию. Все остальные не могут делать ничего (by * none).

 

Как определять списки контроля доступа

Вы обнаружите документацию для списков управления доступом в “старом slapd.conf
стиле и в в динамическом, либо LDIF формате. В более раннем формате вы будете иметь директиву
access предваряющую данный список доступа. В новом формате LDIF вы
будете иметь соответствующий номер индекса.

В наиболее общей форме, доступ предоставляется с применением следующего синтаксиса:


[access|{n}]to what [ by who [ access-level ] [ control ] ]
 	   

what является субъектом в базе данных LDAP,
who является запрашивающим данную информацию клиентом, а
access-level является уровнем доступа, который вы хотите, чтобы он
имелся у этого клиента. control определяет как этот список
обрабатывается после данной записи и является необязательным.

В приводимом ниже простом примере мы предоставляем доступ на чтение всем в нашем DIT.


to *
   by * read stop
 	   

Вы можете пользоваться символом подстановки * для разрешения
неограниченного доступа. Имеющееся здесь управление доступом обозначает, что любой пользователь имеет доступ
на чтение ко всему. Следующим является выражение управления, которое сообщает slapd
остановить обработку всех остальных директив. Порядок является существенным в вашем списке управления доступом,
причём директивы более высокого порядка обрабатываются до тех, которые имеют более низкий порядок. Когда вы
получаете некоторую привилегию или уровень доступа, он подразумевает всё что ему предшествует. Например,
доступ по чтению автоматически предоставляет уровни доступа disclose,
auth, compare и
search включёнными в права доступа
read. Таблица 16-3 перечисляет все уровни доступа, которые вы можете назначать для запроса
к некоторому субъекту.

Похожее:  Что такое JWT токен?

Когда вы выбираете none, вы отклоняете люьой доступ к данному субъекту
без возвращения какой- либо ошибки запрашивающему. Это помогает предотвращать утечку информации о том что
содержится, а что нет в вашем DIT. Право доступа disclose,
в отличие от none будет возвращать некую ошибку запрашивающему
клиенту.

 

Определение who

Заглядывая далее в запрос доступа к субъекту вам необходимо знать кто осуществляет этот запрос.
Может иметься более одного объявления who, причём каждое использует
определённые ключевые слова. Эти ключевые слова могут комбинироваться с определителем
style, который может быть чем-то навроде
regex или exact.
Стилем regex называется регулярное выражение которое может применяться
для установки соответствия различным частям DN. Он более затратен при предоставлении вам списка управления
доступом.

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


to dn.subtree=ou=people,dc=example,dc=com
   by dn.exact="cn=admin,ou=meta,dc=example,dc=com" read
 	   

Здесь мы вновь предоставляем доступ на чтение всем входящим в подразделение (ou)
People. Мы являемся конкретными и определяем что такой доступ
предоставляется только DN (отличительному имени)
cn=admin,ou=meta,dc=example,dc=com.

Определение того, что вы предоставляете может стать коварным. Для предоставления доступа имеются некоторые
стандартные метода. Вы можете применять следующее:


dn.base
dn.one
dn.subtree
dn.children
 	   

Чтобы объяснить как это относится к объектам, с которыми мы работаем, позаимствуем пример из OpenLDAP Administrator’s Guide. Допустим,
что у нас имеются следующие списки:


0: dc=example,dc=com
1: cn=Manager,dc=example,dc=com
2: ou=people,dc=example,dc=com
3: uid=jsmith,ou=people,dc=example,dc=com
4: cn=addresses,uid=jsmith,ou=people,dc=example,dc=com
5: uid=ataylor,ou=people,dc=example,dc=com
 	   

Когда мы пытаемся работать с частями данного DIT (дерева информационного каталога), мы можем определить
конкретную сферу своих моделей соответствий:


dn.base="ou=people,dc=example,dc=com" match 2;
dn.one="ou=people,dc=example,dc=com" match 3, and 5;
dn.subtree="ou=people,dc=example,dc=com" match 2, 3, 4, and 5; and
dn.children="ou=people,dc=example,dc=com" match 3, 4, and 5.
 	   

Определение имеющейся сферы прав вырежет часть прав из имеющегося дерева DIT. Как вы можете видеть, данная
сфера dn.base будет всего лишь ссылаться на уровень данного определённого
дерева, ou=people,dc=example,dc=com. Область действия
dn.one будет воздействовать на непосредственную часть этого дерева
после ou=people,dc=example,dc=com.

Сфера dn.subtree будет воздействовать везде под
ou=people,dc=example,dc=com, в то время как
dn.children будет работать повсеместно ниже
ou=people,dc=example,dc=com.

 

Определение who при помощи фильтра

В LDAP вы можете применять фильтры, что означает искоренение нежелательных данных и оставление после этого
в точности тех результатов, которые вам необходимы. Применяя списки управления доступом, вы можете воспользоваться
фильтрами чтобы быть более конкретным в том, к чему вы предоставляете доступ. Давайте взглянем на следующую
строку:

	   
to dn.subtree="ou=people,dc=example,dc=com" attrs="userPassword"
   by dn.exact="cn=admin,ou=meta,dc=example,dc=com" write
   by * none
 	   

В данном примере мы определили, что мы бы хотели применить это ко всему ниже и включая
ou=people,dc=example,dc=com, а также к любому атрибуту с названием
userPassword, который может быть обнаружен там. В данном случае,
этот атрибут userPassword является определённым фильтром. Мы
предоставляем пользователю admin право на запись для userPassword
и всё будет отклоняться втихую.

Страницы руководства являются исключительными ресурсами для получения дополнительной информации по спискам
управления доступос, а OpenLDAP Administrator’s Guide также очень хорош: www.openldap.org/doc/admin24/access-control.html.

 

Определение наших списков контроля доступа

Теперь мы хотим провести вас по спсику управления доступа, в качестве которого мы воспользуемся нашим
DIT LDAP example.com. Вот что мы собираемся сделать:

Мы собираемся дать пользователю root нашей системы право управлять нашим DIT. Это можно впоследствии удалить,
однако это даст нам возможность доступа к тем событиям, которые мы посчитаем почему- либо неверными в
своих списках доступа. Это в точности тот же доступ, который по умолчанию предоставляется в базе данных
cn=config.


to *
    by dn.exact=gidNumber=0 uidNumber=0,cn=peercred,cn=external,cn=auth manage
    by * break
 	   

Это говорит о том, что пользователь root (uid 0, gid 0) имеет возможность
manage всем DIT (to *).
Затем мы break (прерываем) обработку и переходим к следующему
списку доступа. Такой пользователь, как мы уже говорили ранее, аутентифицирован внешним поставщиком
(имеющейся системой аутентификации, либо PAM). Когда мы предоставим -Y EXTERNAL,
LDAP предоставит доступ для UID и
GID 0 (или пользователя root) совсем без запроса на свою аутентификацию.

Далее мы определяем доступ к нашей информации по паролям. Как мы уже ранее упомянули, списки управления
доступом читаются и реализуются сверху вниз. Важно сохранять самые существенные списки управления доступом в
верхней части с тем, чтобы они не перекрывались более высокими записями.

В данном разделе мы ограничиваем доступ к информации о паролях пользователей, которая хранится в наших
атрибутах userPassword, shadowLastChange,
entry и member во всём DIT.
entry является специализированным псевдоатрибутом, который должен
определять доступ к некоторой записи, а member служит для членства в
группе доступа.

мы собираемся разрешить иметь специализированный доступ только своим администраторам. Пользователь
webadmin будет применяться для связывания с нашим сервером LDAP
с нашего веб сервера с тем, чтобы наши пользователи web могли выполнять аутентификацию. Мы разрешаем доступ
только к тем атрибутам, соединения которых осуществляются с некоторым показателем силы безопасности TLS
(tls_ssf) эквивалентным или превосходящим значение
128. Мы поясним ssf далее в
своём разделе Обеспечение безопасности slapd при помощи
TLS
данной главы, однако на текущий момент значение tls_ssf
определяет минимальный размер ключа, требуемый для доступа к этим атрибутам, что означает, что мы
разрешим доступ к этим атрибутам только если они имеют некий адекватный безопасный транспортный
уровень.

Мы предоставляем доступ anonymous auth; то есть, клиентам, нет нужды
связываться (или выполнять аутентификацию) с нашим сервером LDAP для выполнения удостоверения. Существует три
способа выполнить подтверждение подлинности; один состоит в отказе от предоставления имени пользователя или
пароля (анонимный), другой предоставляет только некоторое имя пользователя, а все остальные предоставляют некие
имя пользователя и пароль. Анонимный доступ не рекомендуется в частности без строгих условий доступа.
Аноним никогда не должен применяться в случае, если ваш сервер LDAP общедоступен во Всемирном интернете.

Анонимная аутентификация потребуется когда мы реализуем службы с единственной подписью, которые мы объясним
далее в разделе Единая подпись: централизованная аутентификация
Linux
этой главы. У нас имеются безопасные анонимные пользователи, только если они имеют некий показатель
силы безопасности TLS (tls_ssf) со значением 128.
Мы также предоставим пользователям возможность изменять их подробности собственного пароля разрешая доступ
self write.

Самая последняя строка в Листинге 16-2
является существенной. Она является управляющим оператором для предотвращения доступа далее вниз по данному
списку доступа.

 

Листинг 16-2


olcAccess: {1}to attrs=userPassword,shadowLastChange,entry,member
        by dn.exact="cn=webadmin,ou=meta,dc=example,dc=com" tls_ssf=128 auth
        by anonymous tls_ssf=128 auth
        by group.exact="cn=admins,ou=groups,dc=example,dc=com" tls_ssf=128 write
        by self tls_ssf=128 write
        by * tls_ssf=128 search
        by * none stop

by * none stop
 	   

Список доступа для чувствительных атрибутов

Она сообщает, что все остальные пользователи (*) не имеют никакого
доступа (none) и после этого останавливает дальнейшую обработку.

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

Ветвь ou=meta содержит всех пользователей, которых мы используем для
представления (proxy) наших проверок подлинности нашему же серверу каталога. Мы не всегда требуем чтобы
пользователь связывался напрямую с нашим сервером каталога, однако иногда мы хотим чтобы они всё же осуществляли
на них проверку подлинности, например, когда мы выполняем веб аутентификацию. Вы уже видели, что мы
предоставляем доступ аутентификации к записям паролей пользователя для
webadmin. теперь мы объявим для такой DN (отличительной записи) способность
просматривать их собственную информацию.


to dn.children="ou=meta,dc=example,dc=com"
        by dn.exact="cn=webadmin,ou=meta,dc=example,dc=com" read
        by group.exact="cn=admins,ou=groups,dc=example,dc=com" write
        by self read
 	   

Мы разрешаем доступ write для данного подразделения (ou) по его
группе cn=admins, в которую мы помести своего пользователя системного
администратора и доступ read для самих пользователей
meta. Это не позволит тем пользователям, которые определены в
подразделении ou=meta, возможность изменения никаких своих собственных
записей, а также это придаст дополнительную безопасность таким пользователям.

Далее мы предоставим доступ всем в ветви ou=people, держа в памяти то,
что мы уже определили доступ к этим атрибутам пароля пользователя ранее в данном списке управления доступом.
Более раннее определение доступа перекроет любой уточняемый здесь доступ для предварительно определённых
атрибутов. Учётные записи администратора, по крайней мере, требуют доступа на чтение, и мы должны дать группе
admins доступ write. Мы также
пожелаем, чтобы группа admins также время от времени изменяла
подробности. Пользователю webadmin всего лишь нужен доступ на чтение.
Мы предоставляем доступ на чтение для самой такой записи при помощи ключевого слова
self.


to dn.children="ou=people,dc=example,dc=com"
        by dn.exact="cn=webadmin,ou=meta,dc=example,dc=com" read
        by group.exact="cn=admins,ou=groups,dc=example,dc=com" write
        by self write
        by users read
 	   

В своей сетевой среде вы можете иметь различные требования, и это достаточно распространено иметь
доступ self вместо write.
такая установка даст данным пользователям возможность изменять подробности своих собственных атрибутов,
которые определяют их персональную информацию, в то время как доступ read
не даёт такой возможности.

В приводимом ниже коде мы предоставляем доступ ветви ou=groups,
в которой мы будем сохранять свою информацию о группах.


to dn.children="ou=groups,dc=example,dc=com"
        by dn.exact="cn=webadmin,ou=meta,dc=example,dc=com" read
        by group.exact="cn=admins,ou=groups,dc=example,dc=com" write
        by anonymous read
 	   

Как мы можем отметить, это аналогично ветке ou=people с
теми же самыми учётными записями администратора, имеющего тот же самый доступ. Однако, мы позволили
аутентифицированным пользователям возможность чтения этих групп определив users
read
.

Далее у нас имеется подразделение ou=hosts. Некоторые люди именуют
эту единица как machines, однако выбор за вами. Оно будет содержать
всю вашу информацию о хосте, IP адреса, местоположения и тому подобное. Мы должны использовать область действия
subtree, а также имеется минимальное предоставление доступа
write для всех, за исключением группы
cn=admins.


to dn.children="ou=hosts,dc=example.com"
        by group.exact="cn=admins,ou=groups,dc=example,dc=com" write
        by anonymous read
 	   

Здесь наша группа cn=admins потребует доступа
write. Мы предоставим клиентам anonymous,
которые являются клиентами, которые не должны выполнять связывание соединения (без аутентификации) доступ
read. различные приложения могут использовать такое подразделение
ou=hosts, включая такие приложения, как Samba.

Самое последнее правило, которое мы будем иметь, это правило общего отклонения. Это усилит отказ во всех
прочих доступах. Обычно это излишне, так как всё, что не предоставлено в явном виде будет отклонено; однако,
оно обозначает самый конец вашего набора списка управления доступом и предотвращает какие- либо списки управления
доступом, которые могут быть представлены ниже и могут быть прочтены по ошибке.


to * by * none stop
 	   

Символы подстановки здесь помечают всё, что означает что любой вид доступа отклоняется, а также вся
дальнейшая обработка останавливается посредством опции stop в данном
поле управления. Другими доступным управлением обработки являются break
и continue.

Управляющая опция break, будучи достигнутой, останавливает последующую
обработку в данной группе управления доступом и перепрыгивает к следующей. Опция continue,
по её достижению, продолжит последующую обработку вниз по текущей группе управления доступом, делая возможным
инкрементальное предоставление полномочий. Опция stop всего лишь
немедленно останавливает любую дальнейшую обработку и является управлением по умолчанию. Листинг 16-3 отображает полный список управления доступом.

 

Листинг 16-3


dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to *
        by dn.exact=gidNumber=0 uidNumber=0,cn=peercred,cn=external,cn=auth manage
        by * break
-
add: olcAccess
olcAccess: {1}to attrs=userPassword,shadowLastChange,entry,member
        by dn.exact=&qout;cn=webadmin,ou=meta,dc=example,dc=com&qout; tls_ssf=128 auth
        by anonymous tls_ssf=128 auth
        by group.exact=&qout;cn=admins,ou=groups,dc=example,dc=com&qout; tls_ssf=128 write
        by self tls_ssf=128 write
        by * tls_ssf=128 search
        by * none stop
-
add: olcAccess
olcAccess: {2}to dn.children=&qout;ou=meta,dc=example,dc=com&qout;
        by dn.exact=&qout;cn=webadmin,ou=meta,dc=example,dc=com&qout; read
        by group.exact=&qout;cn=admins,ou=groups,dc=example,dc=com&qout; write
        by self read
-
add: olcAccess
olcAccess: {3}to dn.children=&qout;ou=people,dc=example,dc=com&qout;
        by dn.exact=&qout;cn=webadmin,ou=meta,dc=example,dc=com&qout; read
        by group.exact=&qout;cn=admins,ou=groups,dc=example,dc=com&qout; write
        by self write
        by users read
-
add: olcAccess
olcAccess: {4}to dn.children=&qout;ou=groups,dc=example,dc=com&qout;
        by dn.exact=&qout;cn=webadmin,ou=meta,dc=example,dc=com&qout; read
        by group.exact=&qout;cn=admins,ou=groups,dc=example,dc=com&qout; write
        by anonymous read
-
add: olcAccess
olcAccess: {5}to dn.children=&qout;ou=hosts,dc=example.com&qout;
        by group.exact=&qout;cn=admins,ou=groups,dc=example,dc=com&qout; write
        by dn.exact=&qout;cn=webadmin,ou=meta,dc=example,dc=com&qout; search
-
add: olcAccess
olcAccess: {6}to * by * none
 	   

Имеется несколько моментов по обновлению списков управления доступом, которые следует отметить. В
Листинге 16-3 мы видим, что мы используем
формат LDIF для добавления таких списков доступа. Давайте возьмём самый первый раздел и объясним его.


dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}<access list>
-
add: olcAccess
olcAccess: {1}<access list>
 	   

Самая первая строка является DN (отличительным именем), в данном случае, базой данных основных настроек,
с которой мы хотим работать. Вторая строка является изменением типа, который состоит в модификации. Для первого
элемента индекса {0} нем необходимо применить замену типа модификации.
После всего, для данных списков доступа нам необходимо добавить эти списки. Когда мы работаем со списками
динамического доступа и ldapmodify, имеются некоторые правила,
которые следует запомнить.

Теперь мы можем поместить эти директивы списка доступа в файл под названием
access.ldif и затем воспользоваться
ldapmodify для его применения.


$ sudo ldapmodify -H ldapi:/// -Y EXTERNAL -f access.ldif
 	   

В скором времени мы объясним как провести тестирование.

 

Обеспечение безопасности slapd при помощи TLS

 

Работа с SSF

Рекомендации по установке

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

  • Рекомендуется использовать именно встроенный сервер DNS. Возможен вариант с использованием внешнего сервера DNS, но это сопряжено с гораздо более сложной настройкой внешнего сервера DNS. И, как следствие, поле для ошибок в конфигурации потенциально больше.
  • Рекомендуется развертывать два сервера – основной сервер и реплику. Про развертывание сервера реплики мы поговорим в отдельной публикации.
  • Не отключайте IPv6 командой  ipv6.disable=1.
  • Для продуктивной системы размер оперативной памяти должен составлять 4-8 ГБ.
  • Рекомендуется создавать уникальное имя для домена FreeIPA. Если у вас уже есть какие-либо системы, использующие Kerberos (MS Active Directory, например), то настройка доверительных отношений будет невозможна.
  • После установки сервера FreeIPA нельзя изменить имя домена или имя области Kerberos. Планируйте соответствующие имена с учетом этой особенности.
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

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

Ваш адрес email не будет опубликован.

Adblock
detector