18. Репликация

Реплицируемая служба каталогов — фундаментальное требование для развёртывания устойчивой информационно-вычислительной системы уровня предприятия.

В OpenLDAP есть различные варианты настройки для создания реплицируемой службы каталогов. В предыдущих версиях репликация описывалась в терминах главного (master) сервера и некоторого количества подчинённых (slave) серверов. На главном сервере было разрешено выполнять операции обновления каталога, инициируемые любым клиентом, а на подчинённом было разрешено выполнять операции обновления каталога, инициируемые только единственным главным сервером. Структура репликации была жёстко определена, и конкретный сервер службы каталогов мог выполнять только одну роль: либо главного, либо подчинённого. Ещё один исторический термин, введённый в OpenLDAP 2.4, — репликация с несколькими главными серверами (multimaster).

Поскольку сейчас OpenLDAP поддерживает разнообразные варианты топологий репликации, эти устаревшие термины заменены на поставщика (provider)/нескольких поставщиков (multi-provider) и потребителя (consumer): поставщик может принимать внешние операции обновления каталога и делать их доступными для извлечения потребителями; потребители получают реплицируемые обновления от поставщиков. В отличие от жёстко определённых отношений главный/подчинённый, роли поставщика/потребителя довольно расплывчаты: реплицируемые обновления, полученные потребителем, могут быть далее распространены от этого потребителя на другие серверы, таким образом потребитель может также выступать одновременно и в качестве поставщика. Кроме того, потребителю не обязательно быть реальным сервером LDAP; это может быть и LDAP-клиент.

В следующих подразделах описывается технология репликации и обсуждаются различные доступные варианты настройки репликации.


18.1. Технология репликации

18.1.1. Репликация на основе LDAP Sync

Механизм репликации на основе LDAP Sync, коротко syncrepl, — это механизм репликации на стороне потребителя, позволяющий LDAP-серверу-потребителю поддерживать теневую копию фрагмента DIT. Механизм syncrepl исполняется на стороне потребителя как один из потоков slapd(8). Он создаёт и поддерживает реплику путём соединения с поставщиком репликаций для выполнения начальной загрузки содержимого DIT, а затем либо выполнения периодического опроса содержимого DIT поставщика, либо ожидания посылки ему обновлений по мере изменения этого содержимого.

Syncrepl использует LDAP Content Synchronization protocol (протокол синхронизации содержимого LDAP), или коротко LDAP Sync, в качестве протокола синхронизации потребителя. LDAP Sync реализует динамическую репликацию с отслеживанием состояния, поддерживающую синхронизацию как на основе запроса (pull-based), так и на основе посылок (push-based), и не требующую использования хранилища истории операций. В репликации на основе запроса потребитель периодически запрашивает обновления у поставщика. В репликации на основе посылок потребитель ждёт прихода обновлений, которые посылает ему поставщик сразу же после изменения содержимого своего каталога. Поскольку протокол не требует наличия хранилища истории операций, поставщику не нужно вести каких-либо журналов полученных им обновлений (обратите внимание на то, что механизм syncrepl является расширяемым и в будущем возможна поддержка дополнительных протоколов репликации).

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

Syncrepl поддерживает синхронизацию как на основе запросов, так и на основе посылок. В его базовом режиме синхронизации refreshOnly (только обновление), поставщик использует синхронизацию на основе запросов, не требующей отслеживания серверов-потребителей и хранения истории операций. Информация, которая нужна поставщику для обработки периодических запросов на проверку содержимого каталога, находится в синхронизационных куки самих запросов. Для оптимизации синхронизации на основе запросов, syncrepl использует фазу наличия (present phase) и фазу удаления (delete phase) протокола LDAP Sync, вместо того, чтобы возвращаться к частым полным перезагрузкам содержимого каталога. Для дальнейшей оптимизации синхронизации на основе запросов поставщик может вести журнал в рамках сессии в качестве хранилища истории операций. В режиме синхронизации refreshAndPersist (обновление и непрерывность) поставщик использует синхронизацию на основе посылок. Поставщик отслеживает серверы-потребители, запросившие непрерывно-действующий поиск, и посылает им необходимые обновления по мере изменения реплицируемого содержимого каталога поставщика.

При использовании syncrepl, потребитель может создать соглашение о репликации без изменения конфигурации сервера-поставщика и без его перезапуска, если сервер-потребитель имеет соответствующие привилегии доступа к реплицируемому фрагменту DIT. Сервер-потребитель также может прекратить репликацию без необходимости внесения изменений и перезапуска на стороне поставщика.

Syncrepl поддерживает частичные, разреженные и дробные репликации. Фрагмент теневого DIT определяется общими критериями поиска, состоящими из базы, диапазона, фильтра и списка атрибутов. Также у учётной записи, от имени которой осуществляется подсоединение к поставщику для выполнения репликации syncrepl, должны быть привилегии доступа к содержимому каталога потребителя.

18.1.1.1. Протокол синхронизации содержимого LDAP

Протокол LDAP Sync позволяет клиенту поддерживать синхронизированную копию фрагмента DIT. Операции LDAP Sync определяются как набор элементов управления и других элементов протокола, расширяющих поисковые операции LDAP. В этом подразделе даётся очень краткое введение в протокол синхронизации содержимого LDAP. Полное описание в RFC4533.

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

Операция refreshOnly и стадия refresh операции refreshAndPersist могут быть представлены с помощью фазы наличия и фазы удаления.

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

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

Поставщик LDAP Sync может использовать фазу удаления в случае, если он ведёт хранилище истории операций, и может определить, какие записи стали отличными от копии потребителя со времени последней синхронизации. Если поставщик не ведёт никакого хранилища истории операций и не может с его помощью определить ставшие различными записи, либо хранилище не содержит достаточного количества операций с соответствующими сроками давности, чтобы можно было восстановить копию потребителя с момента последней синхронизации, поставщик должен использовать фазу наличия. Тем не менее, использование фазы наличия гораздо более эффективно с точки зрения синхронизационного трафика, чем перезаливка всего содержимого каталога. Для дальнейшего повышения эффективности протокол LDAP Sync также предусматривает некоторое количество оптимизаций, таких как передача нормализованных entryUUID и передача нескольких entryUUID в одном сообщении syncIdSet.

В концовке ответа синхронизации refreshOnly поставщик отправляет потребителю синхронизационное куки, как индикатор состояния, что копия потребителя после синхронизации полна. Потребитель, при отправке поставщику следующего запроса на инкрементную синхронизацию, будет предоставлять данное полученное куки.

При использовании синхронизации refreshAndPersist поставщик отправляет синхронизационное куки в конце стадии refresh путём посылки сообщения Sync Info с параметром refreshDone=TRUE. Он также отправляет синхронизационное куки путём присоединения его к сообщениям SearchResultEntry, генерируемым в стадии persist синхронизационного поиска. В течении стадии persist поставщик также может отправлять сообщения Sync Info, содержащие синхронизационные куки, в любой момент, когда поставщик захочет обновить индикатор состояния на стороне потребителя.

В протоколе LDAP Sync записи уникально идентифицируются значением атрибута entryUUID. Оно может выступать в качестве надежного идентификатора записи, в отличие от DN записи, которое может со временем измениться. entryUUID присоединяется к каждому сообщению SearchResultEntry или SearchResultReference как часть элементов управления синхронизацией.

18.1.1.2. Детали Syncrepl

Механизм syncrepl использует и refreshOnly и refreshAndPersist операции протокола LDAP Sync. Если спецификация syncrepl включена в раздел настроек какой-либо из баз данных (на стороне потребителя), slapd(8) запускает механизм syncrepl отдельным потоком slapd(8) и задаёт время его исполнения. Если при настройке указана операция refreshOnly, механизм syncrepl будет перезадавать время запуска на определённый интервал времени всякий раз по окончании операции синхронизации. Если при настройке была указана операция refreshAndPersist, поток slapd(8) механизма syncrepl будет оставаться активным и обрабатывать сообщения постоянной синхронизации от поставщика.

В механизме syncrepl может использоваться как фаза наличия, так и фаза удаления refresh-стадии синхронизации. На стороне поставщика возможно настроить журнал сессий, который будет хранить конечное число entryUUID удалённых из базы данных записей. При обслуживании нескольких потребителей все они будут пользоваться одним и тем же журналом сессий. Механизм syncrepl использует фазу удаления, если есть журнал сессий и время последней синхронизации сервера-потребителя не раньше времени создания самой старой записи в журнале, оставшейся после его усечения до заданного числа записей. Механизм syncrepl использует фазу наличия, если для реплицируемого содержимого каталога не был сконфигурирован журнал сессий или если время последней синхронизации потребителя не перекрывается временем создания записей журнала сессий. Текущая реализация хранилища журнала сессий размещает его записи в оперативной памяти, поэтому при перезапуске поставщика информация в журнале не сохраняется. Также в настоящий момент не поддерживается доступ к хранилищу журнала сессий посредством LDAP-операций и на него невозможно установить контроль доступа.

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

Механизм syncrepl, как механизм репликации на стороне потребителя, может работать с любым механизмом манипуляции данными. На стороне поставщика LDAP Sync может быть настроен как наложение на любой механизм манипуляции данными, но лучше всего оно работает поверх механизмов манипуляции данными back-bdb, back-hdb или back-mdb.

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

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

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

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

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

Поскольку при спецификации syncrepl могут использоваться обычные поисковые фильтры, некоторые записи из контекста именования каталога могут не попасть в синхронизируемое содержимое каталога. Механизм syncrepl создаёт связующие записи для заполнения промежутков в содержимом каталога потребителя, если какая-либо часть этого содержимого является подветкой от таких пропущенных записей. Связующие записи не будут возвращаться в результате поискового запроса, если при запросе не указан элемент управления ManageDsaIT.

Кроме того, в следствии применения поисковых фильтров при спецификации syncrepl, может возникнуть ситуация, когда в результате внесения изменений запись будет перемещена из одного места в другое и уже не будет попадать в диапазон реплицирования, хотя фактически запись на сервере-поставщике не была удалена. Логично было бы удалить эту запись на сервере-потребителе, но в режиме refreshOnly поставщик не сможет определить и передать данное изменение без использования журнала сессий.

Информация о настройке в разделе Syncrepl.


18.2. Варианты развёртывания

Если спецификация LDAP Sync определяет только узкий диапазон возможностей репликации, то реализация OpenLDAP чрезвычайно гибкая и поддерживает различные режимы работы для реализации сценариев репликации, в том числе такие, которые прямо не рассматриваются в спецификации.

18.2.1. Дельта-syncrepl репликация

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

Предположим, у Вас есть база данных, состоящая из 102 400 объектов по 1 KB каждый. Далее, предположим Вы периодически запускаете на выполнение задание, которое меняет значение размером в 2 байта одного-единственного атрибута у каждого из 102 400 объектов на сервере-поставщике репликации. Не считая заголовков протоколов LDAP и TCP/IP, каждый раз при запуске этого задания каждый из потребителей должен получить и обработать 100 MB данных для внесения 200 KB изменений!

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

Дельта-syncrepl, вариант syncrepl основанный на журнале изменений, разработан для разрешения ситуаций наподобие описанной выше. Дельта-syncrepl работает путём ведения журнала изменений настраиваемой глубины в отдельной базе данных на сервере поставщика. Потребители проверяют этот журнал изменений на наличие изменений, которые им необходимы, и, в случае, если журнал содержит требуемые изменения, потребитель извлекает эти изменения из журнала изменений и применяет их к своей базе данных. Однако, если база данных потребителя слишком долго не синхронизировалась (или она полностью пуста), то для приведения её в соответствие используется стандартный syncrepl, а затем происходит обратное переключение в режим дельта-syncrepl.


Примечание: поскольку состояние базы данных на сервере поставщика хранится и в базе данных журнала изменений, и в основной базе данных, важно производить резервирование обеих этих баз данных (с помощью slapcat), а при восстановлении или копировании на другую машину также восстанавливать обе эти базы данных (с помощью slapadd).

Информация о настройках в подразделе Дельта-syncrepl.

18.2.2. Разнонаправленная репликация с несколькими поставщиками (Multi-Provider)

Репликация с несколькими поставщиками (Multi-Provider) — это техника репликации с использованием Syncrepl для реплицирования данных на несколько серверов-поставщиков ("Provider") службы каталогов.

18.2.2.1. Преимущества репликации с несколькими поставщиками

18.2.2.2. Развенчание некоторых мифов об использовании репликации с несколькими поставщиками

(Они часто позиционируются в качестве преимуществ репликации с несколькими поставщиками, хотя в действительности таковыми не являются):

18.2.2.3. Отрицательные моменты репликации с несколькими поставщиками

Информация о настройках в подразделе Разнонаправленная репликация с несколькими поставщиками ниже.

18.2.3. Репликация в режиме зеркала (MirrorMode)

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

18.2.3.1. Положительные моменты репликации в режиме зеркала

18.2.3.2. Отрицательные моменты репликации в режиме зеркала

Информация о настройках в подразделе Режим зеркала ниже.

18.2.4. Режим Syncrepl-прокси

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

Этот режим может быть сконфигурирован с помощью механизма манипуляции данными LDAP (смотрите раздел Механизмы манипуляции данными и slapd-ldap(8)). Вместо того, чтобы запускать механизм syncrepl на действительном сервере-потребителе, около сервера-поставщика (или прямо на нём) настраивается slapd-ldap прокси, указывающий на сервер-потребитель, и на нём запускается механизм syncrepl.

Информация о настройках в подразделе Syncrepl-прокси.

18.2.4.1. Замена Slurpd

Старый механизм slurpd работал только в режиме посылок, инициированных поставщиком. Репликация Slurpd устарела в пользу репликации Syncrepl, и была полностью удалена из OpenLDAP 2.4.

Демон slurpd был оригинальным механизмом репликации, унаследованным от UMich LDAP, работавшим в режиме посылок: сервер-поставщик репликации рассылал изменения на реплики. Он был заменён по многим причинам, если коротко, то:

У Syncrepl нет ни одного из этих недостатков:


18.3. Настройка различных типов репликации

18.3.1. Syncrepl

18.3.1.1. Настройка Syncrepl

Поскольку syncrepl — это механизм репликации на стороне потребителя, спецификация syncrepl определяется в файле slapd.conf(5) сервера-потребителя, а не в конфигурационном файле сервера-поставщика. Первоначальная загрузка содержимого потребителя может быть выполнена как запуском механизма syncrepl без синхронизационного куки, так и наполнением потребителя путём загрузки LDIF-файла, который был сгенерирован как резервная копия на поставщике.

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

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

18.3.1.2. Настройка slapd поставщика

Часть протокола, выполняющаяся на стороне поставщика, реализована в виде наложения. Само наложение, перед тем, как его можно будет использовать, должно быть сконфигурировано в slapd.conf(5). На поставщике могут быть заданы две основных директивы конфигурации, а также две дополнительных при использовании дельта-syncrepl. Поскольку поиск LDAP Sync — это процесс, который требуется контролировать с точки зрения доступа к данным, для реплицируемого содержимого каталога должны быть настроены корректные привилегии контроля доступа.

Две основных директивы конфигурации настраивают контрольные точки (checkpoint) и ведение журнала сессий (sessionlog).

Контрольная точка contextCSN конфигурируется следующей директивой:

        syncprov-checkpoint <количество операций> <количество минут>

Контрольные точки проверяются только после успешной операции записи. Если с момента последней контрольной точки прошло указанное <количество операций> или больше заданного <количества минут>, срабатывает новая контрольная точка. По умолчанию контрольные точки отключены.

Журнал сессий конфигурируется директивой:

        syncprov-sessionlog <количество записей>

Здесь <количество записей> — это максимальное число записей, которые могут быть записаны в журнал сессий. В этот журнал помещаются все операции записи (за исключением добавлений (Add)).

Обратите внимание, что использование журнала сессий требует поиска по атрибуту entryUUID. Установка eq-индекса на этот атрибут увеличит производительность журнала сессий на сервер-поставщике.

Необязательный параметр reloadhint настраивается директивой

        syncprov-reloadhint <TRUE|FALSE>

Он должен быть задан в TRUE при использовании наложении accesslog для поддержки репликации дельта-syncrepl. Значение по умолчанию — FALSE.

Необязательный параметр nonpresent следует настраивать только в том случае, если наложение syncprov конфигурируется поверх базы данных журнала, как в случае использования её совместно с дельта-syncrepl.

Параметр nonpresent настраивается директивой

        syncprov-nopresent <TRUE|FALSE>

Данное значение должно быть установлено в TRUE лишь в том случае, если syncprov настраивается поверх базы данных журнала (например, такой, которая управляется наложением accesslog). Значение по умолчанию — FALSE.

Вот более полный пример содержимого файла slapd.conf(5) на стороне поставщика:

        database mdb
        maxsize 85899345920
        suffix dc=example,dc=com
        rootdn dc=example,dc=com
        directory /var/ldap/db
        index objectclass,entryCSN,entryUUID eq

        overlay syncprov
        syncprov-checkpoint 100 10
        syncprov-sessionlog 100

18.3.1.3. Настройка slapd потребителя

Директива настройки репликации syncrepl указывается в разделе database, описывающем контекст потребителя, в файле slapd.conf(5). Механизм syncrepl не зависит от используемого механизма манипуляции данными, и данная директива может настраиваться с любым типом базы данных.

        database mdb
        maxsize 85899345920
        suffix dc=example,dc=com
        rootdn dc=example,dc=com
        directory /var/ldap/db
        index objectclass,entryCSN,entryUUID eq

        syncrepl rid=123
                provider=ldap://provider.example.com:389
                type=refreshOnly
                interval=01:00:00:00
                searchbase="dc=example,dc=com"
                filter="(objectClass=organizationalPerson)"
                scope=sub
                attrs="cn,sn,ou,telephoneNumber,title,l"
                schemachecking=off
                bindmethod=simple
                binddn="cn=syncuser,dc=example,dc=com"
                credentials=secret

В этом примере потребитель будет подключаться к slapd поставщика на порт 389 по адресу ldap://provider.example.com для выполнения синхронизации в режиме опроса (refreshOnly) один раз в день. Он будет подключаться как cn=syncuser,dc=example,dc=com с использованием простой аутентификации с паролем "secret". Обратите внимание, что привилегии контроля доступа на поставщике должны быть заданы таким образом, чтобы cn=syncuser,dc=example,dc=com мог получать нужное ему реплицируемое содержимое каталога. Также права на поиск на стороне поставщика должны быть достаточными для того, чтобы позволить syncuser получать полную копию запрашиваемого содержимого каталога. Потребитель использует права rootdn для записи в свою базу данных, поэтому с его стороны нет ограничений на запись всего реплицируемого содержимого.

Синхронизационный поиск в примере выше ищет записи с объектным классом organizationalPerson, во всём поддереве каталога, начиная от dc=example,dc=com. Запрашиваемые атрибуты: cn, sn, ou, telephoneNumber, title, и l. Проверка целостности схемы данных отключена, поэтому slapd(8) потребителя не будет проверять соответствие записи схеме данных при обработке обновлений, получаемых от slapd(8) поставщика.

Более детальную информацию о директиве syncrepl смотрите в подразделе syncrepl раздела Конфигурационный файл slapd данного руководства администратора.

18.3.1.4. Запуск slapd поставщика и потребителя

Перезагрузки slapd(8) поставщика не требуется. contextCSN создаётся автоматически по мере необходимости: он может сразу содержаться в LDIF-файле, загружаемом с помощью slapadd(8), создаваться во время изменений содержимого каталога, или генерироваться при первом поисковом запросе LDAP Sync, поступившем поставщику. При загрузке LDIF-файла, не содержащего contextCSN, для его генерации нужно использовать slapadd(8) с опцией -w. Это позволит серверу произвести первый запуск немного быстрее.

При запуске slapd(8) потребителя можно с помощью параметра командной строки -c cookie задать синхронизационное куки, если Вы хотите начать синхронизацию с какого-то определённого состояния. Куки — это разделённый запятыми список пар имя=значение. Поддерживаемые в настоящий момент поля syncrepl куки: csn=<csn> и rid=<rid>. <csn> представляет собой текущее состояние синхронизации (current synchronization state) потребителя. <rid> (replica identifier) идентифицирует конкретного потребителя локально на сервере потребителя. Он используется, чтобы сопоставить куки определению syncrepl в файле slapd.conf(5), имеющему такой же идентификатор <rid>. <rid> должен быть не более 3 десятичных цифр. Куки, задаваемое в командной строке, переопределяет синхронизационное куки, хранящееся в базе данных потребителя.

18.3.2. Дельта-syncrepl

18.3.2.1. Настройка поставщика дельта-syncrepl

Настройка дельта-syncrepl требует внесения изменений в конфигурацию как сервера-поставщика репликации, так и сервера-реплики:

     # Задаём DN записи, от имени которой выполняется репликация, неограниченные права
     # на чтение. Этот ACL нужно объединить с другими определениями ACL, и/или
     # поместить в определение базы данных. Часть "by * break"
     # вызывает оценку последующих правил. Детали в slapd.access(5).
     access to *
        by dn.base="cn=replicator,dc=example,dc=com" read
        by * break

     # Указываем местонахождение модулей
     modulepath /usr/lib/openldap

     # Загружаем механизм mdb
     moduleload back_mdb.la

     # Загружаем наложение accesslog
     moduleload accesslog.la

     # Загружаем наложение syncprov
     moduleload syncprov.la

     # Определение базы данных журнала доступа (Accesslog)
     database mdb
     suffix cn=accesslog
     directory /var/lib/db/accesslog
     maxsize 85899345920
     rootdn cn=accesslog
     index default eq
     index entryCSN,objectClass,reqEnd,reqResult,reqStart,reqDN

     overlay syncprov
     syncprov-nopresent TRUE
     syncprov-reloadhint TRUE

     # Разрешим DN записи, от имени которой выполняется репликация,
     # осуществлять поиск без ограничений (в рамках БД Accesslog)
     limits dn.exact="cn=replicator,dc=example,dc=com" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited

     # Определение основной базы данных
     database mdb
     suffix "dc=example,dc=com"
     rootdn "cn=manager,dc=example,dc=com"
     maxsize 85899345920

     ## Далее поместим остальные требуемые настройки БД

     # Индексы, задаваемые для syncprov
     index entryCSN eq
     index entryUUID eq

     # Определение Поставщика syncrepl для основной БД
     overlay syncprov
     syncprov-checkpoint 1000 60

     # Определение наложения accesslog для основной БД
     overlay accesslog
     logdb cn=accesslog
     logops writes
     logsuccess TRUE
     # Сканируем БД accesslog каждый день и удаляем записи старше 7-ми дней
     logpurge 07+00:00 01+00:00

     # Разрешим DN записи, от имени которой выполняется репликация,
     # осуществлять поиск без ограничений (в рамках основной БД)
     limits dn.exact="cn=replicator,dc=example,dc=com" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited

Для получения дополнительной информации смотрите соответствующие man-страницы (slapo-accesslog(5) и slapd.conf(5))

18.3.2.2. Настройка потребителя дельта-syncrepl

     # Конфигурация базы данных реплики
     database mdb
     suffix "dc=example,dc=com"
     rootdn "cn=manager,dc=example,dc=com"
     maxsize 85899345920

     ## Далее поместим остальные требуемые настройки для реплики,
     ## например нужное индексирование

     # Индексы, задаваемые для syncrepl
     index entryUUID eq

     # Директивы syncrepl
     syncrepl  rid=0
               provider=ldap://ldapprovider.example.com:389
               bindmethod=simple
               binddn="cn=replicator,dc=example,dc=com"
               credentials=secret
               searchbase="dc=example,dc=com"
               logbase="cn=accesslog"
               logfilter="(&(objectClass=auditWriteObject)(reqResult=0))"
               schemachecking=on
               type=refreshAndPersist
               retry="60 +"
               syncdata=accesslog

     # Отсылка обновлений на сервер поставщика
     updateref               ldap://ldapprovider.example.com

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


Примечание: База данных accesslog уникальна для конкретного поставщика репликации. Её не следует реплицировать.

18.3.3. Разнонаправленная репликация с несколькими поставщиками

В следующем примере мы будет использовать 3 сервера-поставщика. Последуем тесту test050-syncrepl-multiprovider из пакета тестов OpenLDAP, и настроим slapd(8) через cn=config

Сначала настроим базу данных конфигурации:

     dn: cn=config
     objectClass: olcGlobal
     cn: config
     olcServerID: 1

     dn: olcDatabase={0}config,cn=config
     objectClass: olcDatabaseConfig
     olcDatabase: {0}config
     olcRootPW: secret

Второй и третий серверы, очевидно, будут иметь отличные от первого сервера olcServerID:

     dn: cn=config
     objectClass: olcGlobal
     cn: config
     olcServerID: 2

     dn: olcDatabase={0}config,cn=config
     objectClass: olcDatabaseConfig
     olcDatabase: {0}config
     olcRootPW: secret

Затем настроим syncrepl в качестве сервера-поставщика (поскольку все они поставщики):

     dn: cn=module,cn=config
     objectClass: olcModuleList
     cn: module
     olcModulePath: /usr/local/libexec/openldap
     olcModuleLoad: syncprov.la

Теперь настроим первый сервер-поставщик репликации (замените $URI1, $URI2 и $URI3 Вашими актуальными ldap url):

     dn: cn=config
     changetype: modify
     replace: olcServerID
     olcServerID: 1 $URI1
     olcServerID: 2 $URI2
     olcServerID: 3 $URI3

     dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config
     changetype: add
     objectClass: olcOverlayConfig
     objectClass: olcSyncProvConfig
     olcOverlay: syncprov

     dn: olcDatabase={0}config,cn=config
     changetype: modify
     add: olcSyncRepl
     olcSyncRepl: rid=001 provider=$URI1 binddn="cn=config" bindmethod=simple
       credentials=secret searchbase="cn=config" type=refreshAndPersist
       retry="5 5 300 5" timeout=1
     olcSyncRepl: rid=002 provider=$URI2 binddn="cn=config" bindmethod=simple
       credentials=secret searchbase="cn=config" type=refreshAndPersist
       retry="5 5 300 5" timeout=1
     olcSyncRepl: rid=003 provider=$URI3 binddn="cn=config" bindmethod=simple
       credentials=secret searchbase="cn=config" type=refreshAndPersist
       retry="5 5 300 5" timeout=1
     -
     add: olcMirrorMode
     olcMirrorMode: TRUE

Теперь запустим этот сервер-поставщик и потребителей, также добавляя приведённый выше LDIF на первый сервер-потребитель, второй сервер-потребитель и т.д., и при изменении базы данных cn=config она будет реплицироваться. Итак, Вы получили систему разнонаправленной репликации с несколькими поставщиками, реплицирующую базу данных конфигурации.

Но, поскольку, помимо конфигурационных, требуется реплицировать еще и реальные данные, добавим следующий LDIF на один из серверов-поставщиков (все настроенные нами потребители/поставщики применят ту же конфигурацию, так как они все синхронизируются). Опять же, замените переменные ${} на требуемые Вам значения:

     dn: olcDatabase={1}$BACKEND,cn=config
     objectClass: olcDatabaseConfig
     objectClass: olc${BACKEND}Config
     olcDatabase: {1}$BACKEND
     olcSuffix: $BASEDN
     olcDbDirectory: ./db
     olcRootDN: $MANAGERDN
     olcRootPW: $PASSWD
     olcLimits: dn.exact="$MANAGERDN" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
     olcSyncRepl: rid=004 provider=$URI1 binddn="$MANAGERDN" bindmethod=simple
       credentials=$PASSWD searchbase="$BASEDN" type=refreshOnly
       interval=00:00:00:10 retry="5 5 300 5" timeout=1
     olcSyncRepl: rid=005 provider=$URI2 binddn="$MANAGERDN" bindmethod=simple
       credentials=$PASSWD searchbase="$BASEDN" type=refreshOnly
       interval=00:00:00:10 retry="5 5 300 5" timeout=1
     olcSyncRepl: rid=006 provider=$URI3 binddn="$MANAGERDN" bindmethod=simple
       credentials=$PASSWD searchbase="$BASEDN" type=refreshOnly
       interval=00:00:00:10 retry="5 5 300 5" timeout=1
     olcMirrorMode: TRUE

     dn: olcOverlay=syncprov,olcDatabase={1}${BACKEND},cn=config
     changetype: add
     objectClass: olcOverlayConfig
     objectClass: olcSyncProvConfig
     olcOverlay: syncprov


Замечание: Системное время на всех Ваших серверах должно быть чётко синхронизировано с помощью NTP http://www.ntp.org/, атомных часов или любой другой технологии синхронизации времени.


Замечание: Как сказано в slapd-config(5), указанные в директиве olcSyncRepl URL — это URL серверов, с которых нужно производить репликацию. Они должны точно соответствовать URL, на которых слушают slapd (согласно параметру командной строки -h). В противном случае slapd может попытаться произвести репликацию с самого себя, что приведёт к образованию петли.

18.3.4. Режим зеркала

Настройка режима зеркала, на самом деле, очень проста. Если Ваш slapd уже настроен в нормальный режим поставщика syncrepl, то все изменения будут заключаться в следующих двух директивах:

       mirrormode  on
       serverID    1


Замечание: Необходимо убедиться, что serverID каждого сервера-зеркала различаются, и добавить эту директиву в раздел глобальных директив конфигурации.

18.3.4.1. Настройка зеркальных серверов

Сначала нужно настроить поставщика syncrepl как описано в подразделе Настройка slapd поставщика.

Вот отрывок примера использования LDAP Sync в режиме refreshAndPersist, касаемый репликации в режиме зеркала:

Зеркальный сервер 1:

       # Глобальный раздел
       serverID    1
       # Раздел базы данных

       # Директива syncrepl
       syncrepl      rid=001
                     provider=ldap://ldap-sid2.example.com
                     bindmethod=simple
                     binddn="cn=mirrormode,dc=example,dc=com"
                     credentials=mirrormode
                     searchbase="dc=example,dc=com"
                     schemachecking=on
                     type=refreshAndPersist
                     retry="60 +"

       mirrormode on

Зеркальный сервер 2:

       # Глобальный раздел
       serverID    2
       # Раздел базы данных

       # Директива syncrepl
       syncrepl      rid=001
                     provider=ldap://ldap-sid1.example.com
                     bindmethod=simple
                     binddn="cn=mirrormode,dc=example,dc=com"
                     credentials=mirrormode
                     searchbase="dc=example,dc=com"
                     schemachecking=on
                     type=refreshAndPersist
                     retry="60 +"

       mirrormode on

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

18.3.4.1.1. Настройка отказоустойчивости

Для этого есть 2 основных способа: 1. использование аппаратного устройства прокси/балансировщика нагрузки или специального программного прокси; 2. использование Back-LDAP прокси в качестве поставщика syncrepl.

Типичный пример каталога уровня предприятия:

Рисунок 18.1: Конфигурация режима зеркала в двух центрах обработки информации

18.3.4.1.2. Настройка обычного потребителя

Настройка производится точно также, как описано в подразделе Настройка slapd потребителя. Можно произвести настройку репликации как в нормальном режиме syncrepl, так и в дельта-syncrepl режиме.

18.3.4.2. Резюме по зеркальному режиму

Теперь у Вас есть архитектура каталога, предоставляющая одновременно все гарантии целостности репликации с одним поставщиком и высокую доступность репликации с несколькими поставщиками.

18.3.5. Syncrepl прокси

Рисунок 18.2: Замена slurpd

В следующем примере показано автономное решение репликации, основанной на посылках (поставщик и прокси на одном сервере):

        #######################################################################
        # Стандартный сервер-поставщик OpenLDAP
        #######################################################################

        include     /usr/local/etc/openldap/schema/core.schema
        include     /usr/local/etc/openldap/schema/cosine.schema
        include     /usr/local/etc/openldap/schema/nis.schema
        include     /usr/local/etc/openldap/schema/inetorgperson.schema

        include     /usr/local/etc/openldap/slapd.acl

        modulepath  /usr/local/libexec/openldap
        moduleload  back_mdb.la
        moduleload  syncprov.la
        moduleload  back_monitor.la
        moduleload  back_ldap.la

        pidfile     /usr/local/var/slapd.pid
        argsfile    /usr/local/var/slapd.args

        loglevel    sync stats

        database    mdb
        suffix      "dc=suretecsystems,dc=com"
        directory   /usr/local/var/openldap-data
        maxsize     85899345920

        checkpoint      1024 5

        index       objectClass eq
        # остальные индексы
        index       default     sub

        rootdn          "cn=admin,dc=suretecsystems,dc=com"
        rootpw          testing

        # индексы, специфичные для syncprov
        index entryCSN eq
        index entryUUID eq

        # настройка поставщика syncrepl для основной БД
        overlay syncprov
        syncprov-checkpoint 1000 60

        # Разрешим DN репликатора производить поиск без ограничений
        limits dn.exact="cn=replicator,dc=suretecsystems,dc=com" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited

        database    monitor

        database    config
        rootpw          testing

        #########################################################################################
        # Прокси-потребитель, получающий данные через Syncrepl и отправляющий их через slapd-ldap
        #########################################################################################

        database        ldap
        # проигнорируем конфликты с другими БД, поскольку 
        # нам требуется отправлять данные с тем же суффиксом
        hidden              on
        suffix          "dc=suretecsystems,dc=com"
        rootdn          "cn=slapd-ldap"
        uri             ldap://localhost:9012/

        lastmod         on

        # Нам не нужно никаких прав на доступ к данному DSA
        restrict        all

        acl-bind        bindmethod=simple
                        binddn="cn=replicator,dc=suretecsystems,dc=com"
                        credentials=testing

        syncrepl        rid=001
                        provider=ldap://localhost:9011/
                        binddn="cn=replicator,dc=suretecsystems,dc=com"
                        bindmethod=simple
                        credentials=testing
                        searchbase="dc=suretecsystems,dc=com"
                        type=refreshAndPersist
                        retry="5 5 300 5"

        overlay         syncprov

Настройка реплики для подобных случаев может быть такой:

        #######################################################################
        # Стандартная реплика OpenLDAP без использования Syncrepl
        #######################################################################

        include     /usr/local/etc/openldap/schema/core.schema
        include     /usr/local/etc/openldap/schema/cosine.schema
        include     /usr/local/etc/openldap/schema/nis.schema
        include     /usr/local/etc/openldap/schema/inetorgperson.schema

        include     /usr/local/etc/openldap/slapd.acl

        modulepath  /usr/local/libexec/openldap
        moduleload  back_mdb.la
        moduleload  syncprov.la
        moduleload  back_monitor.la
        moduleload  back_ldap.la

        pidfile     /usr/local/var/slapd.pid
        argsfile    /usr/local/var/slapd.args

        loglevel    sync stats

        database    mdb
        suffix      "dc=suretecsystems,dc=com"
        directory   /usr/local/var/openldap-consumer/data

        maxsize         85899345920
        checkpoint      1024 5

        index       objectClass eq
        # остальные индексы
        index       default     sub

        rootdn          "cn=admin,dc=suretecsystems,dc=com"
        rootpw          testing

        # Разрешим DN репликатора производить поиск без ограничений
        limits dn.exact="cn=replicator,dc=suretecsystems,dc=com" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited

        updatedn "cn=replicator,dc=suretecsystems,dc=com"

        # Отсылаем попытки внесения изменений на сервер-поставщик
        updateref   ldap://localhost:9011

        database    monitor

        database    config
        rootpw          testing

Обратите внимание на директиву updatedn в приведённых настройках. Примерные ACL (usr/local/etc/openldap/slapd.acl) для данного случая могут быть такими:

        # Дадим DN репликатора неограниченный доступ на чтение.
        # Данный ACL нужно совместить с другими настройками ACL.

        access to *
             by dn.base="cn=replicator,dc=suretecsystems,dc=com" write
             by * break

        access to dn.base=""
                by * read

        access to dn.base="cn=Subschema"
                by * read

        access to dn.subtree="cn=Monitor"
            by dn.exact="uid=admin,dc=suretecsystems,dc=com" write
            by users read
            by * none

        access to *
                by self write
                by * read

Для поддержки большего числа реплик, просто добавьте секции database ldap в настройки прокси и увеличьте номер syncrepl rid соответственно.


Замечание: В отличие от использования нормального Syncrepl, Вы должны предварительно наполнить каталоги поставщика и потребителя репликации одинаковыми данными.

Если у Вас нет доступа для изменения настроек каталога поставщика, можно настроить отдельностоящий LDAP-прокси как показано на рисунке:

Рисунок 18.3: Версия замены slurpd с отдельностоящим LDAP-прокси

Пример настройки отдельностоящего LDAP-прокси:

        include     /usr/local/etc/openldap/schema/core.schema
        include     /usr/local/etc/openldap/schema/cosine.schema
        include     /usr/local/etc/openldap/schema/nis.schema
        include     /usr/local/etc/openldap/schema/inetorgperson.schema

        include     /usr/local/etc/openldap/slapd.acl

        modulepath  /usr/local/libexec/openldap
        moduleload  syncprov.la
        moduleload  back_ldap.la

        #########################################################################################
        # Прокси-потребитель, получающий данные через Syncrepl и отправляющий их через slapd-ldap
        #########################################################################################

        database        ldap
        # проигнорируем конфликты с другими БД, поскольку 
	# нам требуется отправлять данные с тем же суффиксом
        hidden              on
        suffix          "dc=suretecsystems,dc=com"
        rootdn          "cn=slapd-ldap"
        uri             ldap://localhost:9012/

        lastmod         on

        # Нам не нужно никаких прав на доступ к данному DSA
        restrict        all

        acl-bind        bindmethod=simple
                        binddn="cn=replicator,dc=suretecsystems,dc=com"
                        credentials=testing

        syncrepl        rid=001
                        provider=ldap://localhost:9011/
                        binddn="cn=replicator,dc=suretecsystems,dc=com"
                        bindmethod=simple
                        credentials=testing
                        searchbase="dc=suretecsystems,dc=com"
                        type=refreshAndPersist
                        retry="5 5 300 5"

        overlay         syncprov

Как видите, в использовании Syncrepl и slapd-ldap(8) Вы можете позволить разгуляться своему воображению, адаптируя технологии репликации к своей конкретной сетевой топологии.

Эта страница

Содержание

18.1. Технология репликации18.2. Варианты развёртывания18.3. Настройка различных типов репликации
18. Репликация
OpenLDAP 2.4 Руководство

Содержание

Введение в службы каталогов OpenLDAPБыстрое развёртывание и начало работыОбщая картина - варианты конфигурацииСборка и установка OpenLDAPНастройка slapd

 

Конфигурационный файл slapdЗапуск slapdКонтроль доступаОграниченияИнструментыМеханизмы манипуляции даннымиНаложенияСпецификация схемы

 

БезопасностьSASLTLSРаспределённая служба каталоговРепликацияОбслуживаниеМониторингПроизводительностьУстранение неполадок
Перевод официального руководства OpenLDAP 2.4 Admin Guide
Полное содержание здесь
LDAP для учёных-ракетчиков

Содержание

О книгеКонцепции LDAPОбъекты LDAPУстановка LDAPПримерыНастройкаРепликация и отсылкиLDIF и DSMLПротоколLDAP API

 

HOWTOНеполадкиПроизводительностьИнструменты LDAPБезопасностьЗаметкиРесурсы LDAPRFC и X.500ГлоссарийОбъекты
Перевод "LDAP for Rocket Scientists"
Полное содержание здесь
Ресурсы

Книги

Руководство OpenLDAP 2.4LDAP для учёных-ракетчиков

Другие

СтатьиТермины LDAPman-страницы OpenLDAP 2.4Список RFCКлиенты LDAPФайлы наборов схемы
Полезные ресурсы
Форум

 

Разделы форумаНепрочитанные сообщенияПоследние сообщения
Форум проекта
Главная

Pro-LDAP.ru

О проектеНовости проектаУчастникиСтаньте участником!Сообщите об ошибке!Об авторских правахСоглашения проекта
Присоединяйсь!