| |
Для организации репликации нашего DIT понадобится развернуть второй сервер OpenLDAP. Новую виртуальную машину назовём ldap-srv-repl. В соответствии с терминологией Syncrepl, мы будем работать со следующими сущностями:
Первая задача — прочитать раздел о репликации в руководстве администратора OpenLDAP. Отдельный интерес представляет следующий отрывок:
Syncrepl поддерживает синхронизацию как на основе запросов, так и на основе посылок. В его базовом режиме синхронизацииrefreshOnly
(только обновление), поставщик использует синхронизацию на основе запросов, не требующей отслеживания серверов-потребителей и хранения истории операций. Информация, которая нужна поставщику для обработки периодических запросов на проверку содержимого каталога, находится в синхронизационных куки самих запросов. Для оптимизации синхронизации на основе запросов, Syncrepl использует фазу наличия (present phase) и фазу удаления (delete phase) протокола LDAP Sync, вместо того, чтобы возвращаться к частым полным перезагрузкам содержимого каталога. Для дальнейшей оптимизации синхронизации на основе запросов поставщик может вести журнал в рамках сессии в качестве хранилища истории операций. В режиме синхронизацииrefreshAndPersist
(обновление и непрерывность) поставщик использует синхронизацию на основе посылок. Поставщик отслеживает серверы-потребители, запросившие непрерывно-действующий поиск, и посылает им необходимые обновления по мере изменения реплицируемого содержимого каталога поставщика.
Репликация реализуется через наложения OpenLDAP. Ознакомьтесь с инструкцией slapo-syncprov в документации man. В ней представлена информация о наложении поставщика репликации. С её помощью мы настроим репликацию в режиме refreshAndPersist
с использованием схемы дельта-syncrepl. Обратите внимание, что говорит официальная документация:
Как видите, в использовании Syncrepl и slapd-ldap(8) Вы можете позволить разгуляться своему воображению, адаптируя технологии репликации к своей конкретной сетевой топологии.
Настройка дельта-syncrepl предполагает работу и с поставщиком (мастер-сервер), и с потребителем (сервер-реплика). Для начала займёмся поставщиком. У нас это ldap-srv.example.com.
План действий по настройке поставщика:
cn=accesslog
);dc=example,dc=com
);Где работаем: ldap-srv
Чтобы подключить динамические модули для наложений accesslog и syncprov не помешает проверить, как подключены уже имеющиеся модули. Мы делали это в разделе 2.4. Воспользуемся настроенным Kerberos и механизмом аутентификации SASL GSSAPI, чтобы упростить наши запросы. Заметьте, что Вы всегда можете использовать учётную запись RootDN (cn=admin,dc=example,dc=com
), но это будет длиннее.
$ cd ~/ldap $ kdestroy $ kinit -p pablo/admin $ ldapsearch -ZZQLLLb cn=config dn |grep module dn: cn=module{0},cn=config
Как мы видим, информация о подключенных модулях содержится в записи cn=module{0},cn=config
. Посмотрим, какие атрибуты в ней есть:
$ ldapsearch -ZZQLLLb cn=module{0},cn=config dn: cn=module{0},cn=config objectClass: olcModuleList cn: module{0} olcModulePath: /usr/lib/ldap olcModuleLoad: {0}back_mdb.la olcModuleLoad: {1}back_monitor.la
Два динамических модуля у нас уже подключены. Лежат ли в одном каталоге с ними искомые модули наложений?
$ ls /usr/lib/ldap/ |egrep '(accesslog.la|syncprov.la)' accesslog.la syncprov.la
Вот этот короткий LDIF-файл 11.1.1-new-modules.ldif поможет нам их подключить:
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: {2}accesslog.la
-
add: olcModuleLoad
olcModuleLoad: {3}syncprov.la
Загружаем LDIF:
$ ldapmodify -ZZQf 11.1.1-new-modules.ldif
Проверяем результат:
$ ldapsearch -ZZQLLLb cn=module{0},cn=config dn: cn=module{0},cn=config objectClass: olcModuleList cn: module{0} olcModulePath: /usr/lib/ldap olcModuleLoad: {0}back_mdb.la olcModuleLoad: {1}back_monitor.la olcModuleLoad: {2}accesslog.la olcModuleLoad: {3}syncprov.la
Где работаем: ldap-srv
После подключения динамического модуля наложения accesslog мы должны создать базу данных для хранения журнала доступа. Очевидно, мы можем сделать это с помощью ещё одного LDIF-файла (11.1.2-accesslog.ldif):
dn: olcDatabase=mdb,cn=config
changetype: add
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcDbDirectory: /var/lib/ldap/accesslog
olcSuffix: cn=accesslog
olcRootDN: cn=admin,dc=example,dc=com
olcDbIndex: default eq
olcDbIndex: entryCSN,objectClass,reqEnd,reqResult,reqStart
Создадим каталог для этой базы данных:
# mkdir -p /var/lib/ldap/accesslog # chown -R openldap:openldap /var/lib/ldap
И загрузим конфигурацию LDIF в наш сервер каталогов:
$ ldapadd -ZZQf 11.1.2-accesslog.ldif adding new entry "olcDatabase=mdb,cn=config"
Посмотрим, какой порядковый номер у новой базы данных:
$ ldapsearch -ZZQLLLb cn=config dn |grep mdb dn: olcDatabase={1}mdb,cn=config dn: olcDatabase={3}mdb,cn=config
Первая строка вывода — наше основное DIT. Значит вторая — только что добавленная запись. Проверим только что загруженую конфигурацию:
$ ldapsearch -ZZQLLLb olcDatabase={3}mdb,cn=config
Где работаем: ldap-srv
Определим наложение syncprov для новой базы данных с помощью LDIF-файла 11.1.3-overlay.accesslog.ldif:
dn: olcOverlay=syncprov,olcDatabase={3}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpNoPresent: TRUE
olcSpReloadHint: TRUE
Так как мы будем использовать репликацию на основе журнала доступа, отключаем использование фазы наличия с помощью атрибута olcSpNoPresent
. Атрибут olcSpReloadHint
указывает, что наложение должно соблюдать флаг reloadHint
в Sync Control. Этот флаг используется потребителем, запрашивающим операцию репликации, для указания того, что он хочет принудительно выполнить загрузку полного DIT независимо от всех остальных параметров и значений, таких как Sync Cookie.
Загрузим конфигурацию:
$ ldapadd -ZZQf 11.1.3-overlay.accesslog.ldif adding new entry "olcOverlay=syncprov,olcDatabase={3}mdb,cn=config"
В базе данных olcDatabase={3}mdb,cn=config
должна появиться новая DN-запись:
$ ldapsearch -ZZQLLLb olcDatabase={3}mdb,cn=config dn: olcDatabase={3}mdb,cn=config objectClass: olcDatabaseConfig objectClass: olcMdbConfig olcDatabase: {3}mdb olcDbDirectory: /var/lib/ldap/accesslog olcSuffix: cn=accesslog olcRootDN: cn=admin,dc=example,dc=com olcDbIndex: default eq olcDbIndex: entryCSN,objectClass,reqEnd,reqResult,reqStart dn: olcOverlay={0}syncprov,olcDatabase={3}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpNoPresent: TRUE olcSpReloadHint: TRUE
Где работаем: ldap-srv
Новый LDIF-файл 11.1.4-overlay.primary.ldif преследует три цели:
Запишем в 11.1.4-overlay.primary.ldif:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: entryCSN eq
-
add: olcDbIndex
olcDbIndex: entryUUID eq
# Добавить наложение syncprov поверх базы данных dc=example,dc=com.
dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpCheckPoint: 500 15
# Добавить наложение accesslog поверх базы данных dc=example,dc=com.
# Ежедневно сканировать журнал доступа к базе данных и очищать записи старше 7 дней.
dn: olcOverlay=accesslog,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcAccessLogConfig
olcOverlay: accesslog
olcAccessLogDB: cn=accesslog
olcAccessLogOps: writes
olcAccessLogPurge: 7+00:00 1+00:00
olcAccessLogSuccess: TRUE
Загрузим конфигурацию:
$ ldapadd -ZZQf 11.1.4-overlay.primary.ldif modifying entry "olcDatabase={1}mdb,cn=config" adding new entry "olcOverlay=syncprov,olcDatabase={1}mdb,cn=config" adding new entry "olcOverlay=accesslog,olcDatabase={1}mdb,cn=config"
Убедимся, что новые наложения на месте:
$ ldapsearch -ZZQLLLb olcDatabase={1}mdb,cn=config dn dn: olcDatabase={1}mdb,cn=config dn: olcOverlay={0}syncprov,olcDatabase={1}mdb,cn=config dn: olcOverlay={1}accesslog,olcDatabase={1}mdb,cn=config
Где работаем: ldap-srv
Для функций репликации нам нужна новая учётная запись пользователя. Она будет использоваться для аутентификации и выгрузки данных сервером-репликой. Ни больше, ни меньше. Очередной LDIF-файл 11.1.5-replication.ldif поможет нам добавить эту запись:
dn: cn=replication,dc=example,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: replication
description: OpenLDAP Replication User
userPassword: {SSHA}6yudY3jO+yyTyvov9LhIl1j9S9RZt7Dx
Напоминаю, следующая команда генерирует посоленый хэш вводимого пароля. Замените в вышеприведённом файле значение атрибута userPassword
на результат её работы:
$ slappasswd -h '{SSHA}'
Загрузим конфигурацию:
$ ldapadd -ZZQf 11.1.5-replication.ldif adding new entry "cn=replication,dc=example,dc=com"
Обратите внимание, в нашем примере пользователь для репликации называется просто replication. Если Вы планируете иметь несколько серверов для репликации, то в идеальном случае нужно создать отдельного пользователя с уникальным именем для каждого из них. Благодаря этому Вы сможете отслеживать, какой сервер и когда производил репликацию. Вы так же можете задать, какая часть DIT будет реплицироваться каждой машиной, но это уже другая история.
Где работаем: ldap-srv
Осталось только задать новому пользователю ограничения и прописать для него ACL. Проделаем это в два шага, начиная с ограничений. Создадим LDIF-файл 11.1.6-limits.ldif и запишем в него:
# Добавить ограничения для базы данных cn=accesslog
dn: olcDatabase={3}mdb,cn=config
changetype: modify
add: olcLimits
olcLimits: dn.exact="cn=replication,dc=example,dc=com" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
-
add: olcAccess
olcAccess: to *
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth read
by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" read
by dn.exact="cn=admin,dc=example,dc=com" read
by dn.exact="cn=replication,dc=example,dc=com" read
# Добавить ограничения для базы данных dc=example,dc=com
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcLimits
olcLimits: dn.exact="cn=replication,dc=example,dc=com" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
Загрузим конфигурацию:
$ ldapadd -ZZQf 11.1.6-limits.ldif modifying entry "olcDatabase={3}mdb,cn=config" modifying entry "olcDatabase={1}mdb,cn=config"
Следующий шаг — предоставить новому пользователю доступ на чтение в основной базе данных. Очень хорошая идея — дважды проверить текущие ACL перед подобной операцией:
$ ldapsearch -ZZQLLLb cn=config olcAccess
Теперь можем создать ещё один LDIF-файл, который обновит наши ACL. Здесь идея в том, чтобы иметь одинаковый набор ACL как у поставщика, так и у потребителя. За исключением того, что у потребителя нам не нужны ACL для пользователя replication (который будет описан далее в атрибуте olcSyncRepl
). Сейчас же мы должны просто добавить его в ACL с номером 0. Запишем в LDIF-файл 11.1.6-provider.acl.ldif:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {0}
-
add: olcAccess
olcAccess: {0}to *
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
by dn.exact="cn=replication,dc=example,dc=com" read
by * break
Загрузим изменение ACL:
$ ldapadd -ZZQf 11.1.6-provider.acl.ldif modifying entry "olcDatabase={1}mdb,cn=config"
Так мы можем проверить результат:
$ ldapsearch -ZZQLLLb olcDatabase={1}mdb,cn=config olcAccess
Нам надо убедиться, что пользователь cn=replication,dc=example,dc=com
имеет доступ ко всему DIT:
$ ldapsearch -xZZLLLWD cn=replication,dc=example,dc=com -H ldap://ldap-srv.example.com
Наличие доступа ко всему DIT — обязательно. Не идите дальше, пока этого не добъётесь. Когда всё получилось, мы можем перейти к настройке сервера-реплики (потребителя).
Развернём новый сервер по аналогии с разделом 1.
Где работаем: dns-srv
Для начала обновим информацию на DNS сервере (файл /etc/hosts):
127.0.0.1 localhost
192.168.122.140 dns-srv.example.com
192.168.122.150 ldap-srv.example.com
192.168.122.151 ldap-client.example.com
192.168.122.154 nfs-srv.example.com
192.168.122.160 ldap-srv-repl.example.com
Теперь установим Ubuntu 14.04 server на наш сервер-реплику и перейдём к его настройке.
Где работаем: ldap-srv-repl
Настроим сеть в файле /etc/network/interfaces:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.122.160
netmask 255.255.255.0
gateway 192.168.122.1
dns-nameservers 192.168.122.140
Настроим имя сервера-реплики. В Ubuntu 14.04 останов или перезапуск сервиса networking не поддерживается, поэтому придётся сделать так:
# echo 'ldap-srv-repl.example.com' > /etc/hostname # reboot
Проверим разрешение имени будущего сервера-реплики LDAP:
$ dig ldap-srv-repl.example.com +short 192.168.122.160
Проверим обратное разрешение имени:
$ dig -x `dig ldap-srv-repl.example.com +short` +short ldap-srv-repl.example.com.
Убедитесь, что время на ldap-srv и ldap-srv-repl совпадает. Часы всех наших серверов должны быть синхронизированы с использованием NTP, атомных часов или любого другого источника.
Где работаем: ldap-srv-repl
Зададим пароль для суперпользователя и установим необходимые пакеты:
# passwd # apt-get install -y slapd ldap-utils krb5-kdc-ldap krb5-pkinit wamerican libsasl2-modules-gssapi-mit
Теперь мы должны настроить сервер OpenLDAP с пустой базой данных. Подробно этот процесс описан в разделе 2. Но некоторые детали будут различаться, поэтому нельзя дословно повторять его здесь. Тезисно пробежим по основным моментам.
Создадим временный каталог для работы со службой каталогов:
$ mkdir ~/ldap $ cd ~/ldap
Подготовим каталоги для конфигурации и базы данных демона slapd:
# service slapd stop # rm -rf /etc/ldap/slapd.d # rm -rf /var/lib/ldap # mkdir /etc/ldap/slapd.d # mkdir /var/lib/ldap # chown openldap:openldap /var/lib/ldap # chmod 0700 /var/lib/ldap
Утянем с сервера ldap-srv схемы наборов данных в формате LDIF (мы их готовили самостоятельно):
# scp user@ldap-srv.example.com:/etc/ldap/schema/{autofs,sudo,kerberos}.ldif /etc/ldap/schema
Подготовим посоленый хэш пароля для администратора OpenLDAP на текущем сервере:
$ slappasswd -h '{SSHA}' New password: Re-enter new password: {SSHA}AUEv75PLvTDOyrO5yYvQXmyRurYwTdmn
Теперь у нас есть всё, чтобы написать конфигурацию сервера в LDIF-формате. Для понимания синтаксиса Syncrepl ознакомьтесь с документацией. Запишем в файл 11.2.2-consumer.slapd.ldif:
dn: cn=config
objectClass: olcGlobal
cn: config
olcPidFile: /var/run/slapd/slapd.pid
olcArgsFile: /var/run/slapd/slapd.args
dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcRootDN: cn=config
olcAccess: to *
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by * none
dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib/ldap
olcModuleLoad: back_mdb.la
olcModuleLoad: back_monitor.la
include: file:///etc/ldap/schema/core.ldif
include: file:///etc/ldap/schema/cosine.ldif
include: file:///etc/ldap/schema/inetorgperson.ldif
include: file:///etc/ldap/schema/collective.ldif
include: file:///etc/ldap/schema/corba.ldif
include: file:///etc/ldap/schema/duaconf.ldif
include: file:///etc/ldap/schema/openldap.ldif
include: file:///etc/ldap/schema/dyngroup.ldif
include: file:///etc/ldap/schema/java.ldif
include: file:///etc/ldap/schema/misc.ldif
include: file:///etc/ldap/schema/nis.ldif
include: file:///etc/ldap/schema/ppolicy.ldif
include: file:///etc/ldap/schema/kerberos.ldif
include: file:///etc/ldap/schema/sudo.ldif
include: file:///etc/ldap/schema/autofs.ldif
# Основная база данных
dn: olcDatabase=mdb,cn=config
objectClass: olcMdbConfig
olcDatabase: mdb
olcSuffix: dc=example,dc=com
olcDbDirectory: /var/lib/ldap
olcDbMaxsize: 1073741824
olcRootDN: cn=admin,dc=example,dc=com
olcRootPW: {SSHA}AUEv75PLvTDOyrO5yYvQXmyRurYwTdmn
# Специальные индексы для Syncrepl
olcDbIndex: entryUUID eq
# Директивы Syncrepl
olcSyncRepl: rid=0
provider=ldap://ldap-srv.example.com:389
bindmethod=simple
starttls=yes
binddn="cn=replication,dc=example,dc=com"
credentials="пароль.пользователя.replication"
searchbase="dc=example,dc=com"
logbase="cn=accesslog"
logfilter="(&(objectClass=auditWriteObject)(reqResult=0))"
schemachecking=on
type=refreshAndPersist
retry="60 +"
syncdata=accesslog
# Ссылка на мастер-сервер (поставщик)
olcUpdateRef: ldap://ldap-srv.example.com
# Правила доступа практически идентичны
# (нет записи для пользователя replication)
olcAccess: {0}to *
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
by * break
olcAccess: {1}to attrs=userPassword,userPKCS12
by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
by self write
by anonymous auth
olcAccess: {2}to attrs=shadowLastChange
by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
by self write
olcAccess: {3}to dn.subtree="cn=kerberos,ou=services,dc=example,dc=com"
by dn.exact="cn=krbadmin,ou=users,dc=example,dc=com" write
by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" read
olcAccess: {4}to dn.subtree="ou=autofs,ou=services,dc=example,dc=com"
by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
by dn.regex="uid=autofsclient/.*,cn=example.com,cn=gssapi,cn=auth" read
olcAccess: {5}to *
by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
by dn.exact="cn=krbadmin,ou=users,dc=example,dc=com" write
by self read
by dn.base="cn=nssproxy,ou=users,dc=example,dc=com" read
dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: monitor
Атрибут olcUpdateRef
играет очень важную роль. Вы можете настроить клиентские машины для использования сервера-реплики в качестве поставщика информации из каталога. Но эта информация будет доступна только для чтения. Если клиентская машина (или пользователь) выполнит запрос, требующий изменения записи, его запрос будет перенаправлен на основной сервер (ldap-srv.example.com).
Сгенерируем первичную конфигурацию:
# slapadd -n 0 -F /etc/ldap/slapd.d -l 11.2.2-consumer.slapd.ldif _#################### 100.00% eta none elapsed none fast! Closing DB...
Проверим корректность конфигурации:
# slaptest -uF /etc/ldap/slapd.d config file testing succeeded
Поправим права доступа к файлам конфигурации:
# chown -R openldap:openldap /etc/ldap/slapd.d
Подготовим систему журналирования. В конфигурации /etc/rsyslog.conf добавим несколько строк:
$ModLoad imuxsock # provides support for local system logging $ModLoad imklog # provides kernel logging support $KLogPermitNonKernelFacility on $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat $RepeatedMsgReduction on $FileOwner syslog $FileGroup adm $FileCreateMode 0640 $DirCreateMode 0755 $Umask 0022 $PrivDropToUser syslog $PrivDropToGroup syslog $WorkDirectory /var/spool/rsyslog $IncludeConfig /etc/rsyslog.d/*.conf # Send slapd logs to /var/log/slapd.log if $programname == 'slapd' then /var/log/slapd.log & ~ if $programname == 'krb5kdc' then /var/log/krb5kdc.log & ~
Создадим файлы для журналов наших демонов и зададим для них права доступа. Затем перезапустим rsyslog, чтобы изменения вступили в силу:
# touch /var/log/{slapd,krb5kdc}.log # chmod 0640 /var/log/{slapd,krb5kdc}.log # chown syslog:adm /var/log/{slapd,krb5kdc}.log # service rsyslog restart
Настроим logrotate для управления этими журналами.
Создадим файл конфигурации /etc/logrotate.d/slapd и запишем в него:
/var/log/slapd.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
}
Файл /etc/logrotate.d/krb5kdc для демона krb5-kdc:
/var/log/krb5kdc.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
}
Проверим настройку logrotate:
# logrotate -df /etc/logrotate.conf
Отредактируем общесистемную конфигурацию демона slapd в файле /etc/default/slapd:
SLAPD_CONF=
SLAPD_USER="openldap"
SLAPD_GROUP="openldap"
SLAPD_PIDFILE=
SLAPD_SERVICES="ldap:/// ldapi:///"
SLAPD_SENTINEL_FILE=/etc/ldap/noslapd
SLAPD_OPTIONS="-4"
Первичная загрузка позволяет загрузить DIT на сервер-реплику через файл, не прибегая к репликации и без формирования большого потока траффика в сети. Это не обязательно, но если DIT достаточно большое, мы можем сэкономить много времени.
Но у Вас ничего не получится, если версия используемого сервера OpenLDAP — 2.4.31 и более ранняя. Связано такое поведение с ошибкой ITS#7255, исправленной в версии 2.4.32.
Проверить версию можно так:
$ dpkg --status slapd|grep Version Version: 2.4.31-1+nmu2ubuntu8
Самый благоразумный вариант при развёртывании OpenLDAP в такой ситуации — не предпринимать ничего и просто пропустить этот раздел. Пусть пакет slapd спокойно обновится и данный функционал у Вас заработает. А первичную загрузку DIT можно произвести просто запустив механизм репликации по сети. Но в любом случае с информацией ознакомиться стоит. Она описывает более подробно процесс, тезисно зафиксированный в документации.
Где работаем: ldap-srv
Последний этап пред тем, как мы запустим репликацию — выгрузить всё DIT от поставщика потребителю.
Выгрузим всё DIT в LDIF-файл. В целях безопасности сначала зададим umask:
# umask 066 # slapcat | tee -a /tmp/provider.slapcat.ldif
Где работаем: ldap-srv-repl
Создадим каталог-приёмник для этого файла:
$ mkdir ~/dit $ chmod u=rwx,g=,o= ~/dit
Где работаем: ldap-srv
Отправим файл на сервер-реплику (если уж DIT совсем большое, вместо scp можно использовать съёмный носитель). Затем — удалим исходный файл:
# scp /tmp/provider.slapcat.ldif user@ldap-srv-repl.example.com:~/dit # shred /tmp/provider.slapcat.ldif
Где работаем: ldap-srv-repl
Уничтожим каталог с базой данных и воссоздадим его пустым:
# service slapd stop # rm -rf /var/lib/ldap # mkdir /var/lib/ldap # chmod u=rwx,g=,o= /var/lib/ldap # chown openldap:openldap /var/lib/ldap
Загрузим DIT из скопированного нами файла в базу данных поставщика. Обратите внимание на модификатор -w
у команды slapadd. Он позволит записать в базу данных информацию о контексте Syncrepl. Как только все записи будут загружены, значение contextCSN
обновится в соответствии с самым большим entryCSN
. В нашем случае это очень кстати :)
# slapadd -l provider.slapcat.ldif -w
(именно здесь возникает проблема при использовании slapd версии 2.4.31, процесс загрузки просто зависает)
И снова уничтожим временный файл, теперь уже на клиентской машине. В конце концов, в этом файле содежится всё DIT открытым текстом:
$ shred ~/dit/provider.slapcat.ldif
Убедимся, что всё DIT находится на сервере-реплике:
$ ldapsearch -xWD cn=admin,dc=example,dc=com -b dc=example,dc=com -H ldap://ldap-srv-repl.example.com
Где работаем: ldap-srv-repl
Запускаем демон slapd и добавляем его в автозагрузку:
# service slapd start # update-rc.d slapd defaults
Слегка изменим права доступа с помощью LDIF-файла 11.2.4-consumer.acl.ldif:
dn: olcDatabase={0}config,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=admin,dc=example,dc=com
-
replace: olcAccess
olcAccess: to *
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
by * none
Загрузим изменение ACL:
# ldapmodify -QY EXTERNAL -H ldapi:/// -f 11.2.4-consumer.acl.ldif modifying entry "olcDatabase={0}config,cn=config"
Настроим общесистемную конфигурацию клиентских запросов в файле /etc/ldap/ldap.conf. Это немного сократит количество печатаемого нами текста. Пока не обращайте внимание на параметры TLS, мы разберёмся с ними в следующем разделе. Не забудьте, что в этом разделе мы работаем с ldap-srv-repl.example.com и запросы мы отправляем именно ему. Это важно, потому что мы хотим опрашивать и модифицировать только потребителя, не поставщика (ldap-srv.example.com). Итак, запишем в /etc/ldap/ldap.conf:
BASE dc=example,dc=com
URI ldap://ldap-srv-repl.example.com
# TLS_CACERT /etc/ssl/certs/rootca.crt
# TLS_CRLFILE /etc/ssl/rootca.crl
# TLS_REQCERT demand
TIMELIMIT 15
TIMEOUT 20
Проверим, может ли наш администратор выполнить запрос:
$ ldapwhoami -WD cn=admin,dc=example,dc=com Enter LDAP Password: dn:cn=admin,dc=example,dc=com
Если в соответствии с разделом 8.4.2 мы меняли схему данных nis, то нам придётся это повторить и здесь. Три простых шага и всё готово:
Посмотрим, какой порядковый номер у схемы данных nis в нашем каталоге и у атрибута nisNetgroupTriple
в схеме данных nis:
$ ldapsearch -LLLxWD cn=admin,dc=example,dc=com -b cn=schema,cn=config dn |grep nis Enter LDAP Password: dn: cn={10}nis,cn=schema,cn=config $ ldapsearch -LLLxWD cn=admin,dc=example,dc=com -b cn=schema,cn=config | grep nisNetgroupTriple Enter LDAP Password: olcAttributeTypes: {12}( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' DESC 'Netgr a netgroup' SUP top STRUCTURAL MUST cn MAY ( nisNetgroupTriple $ memberNisNe
Номера 10 и 12 соответственно. Сформируем новый LDIF под названием 11.2.4-nis-schema-change.ldif для изменения схемы. Если два последних номера у Вас отличаются — подставьте свои значения:
dn: cn={10}nis,cn=schema,cn=config
changetype: modify
delete: olcAttributeTypes
olcAttributeTypes: {12}( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' DESC 'Netgr
oup triple' SYNTAX 1.3.6.1.1.1.0.0 )
-
add: olcAttributeTypes
olcAttributeTypes: {12}( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' DESC 'Netgr
oup triple' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
Загрузим его в наш сервер каталогов:
$ ldapadd -xZWD cn=admin,dc=example,dc=com -f 11.2.4-consumer.nis-change.ldif Enter LDAP Password: modifying entry "cn={10}nis,cn=schema,cn=config"
Дважды проверьте по журналам, что Вы подключаетесь именно к серверу-реплике!
Где работаем: ldap-srv
Создадим закрытый ключ для сервера-реплики:
# cd /root/CA # openssl genrsa -out private/ldap-srv-repl.example.com.key 4096 # chmod 400 private/ldap-srv-repl.example.com.key
Сгенерируем запрос на подпись сертификата:
# openssl req -sha256 -new \
-key private/ldap-srv-repl.example.com.key -out certs/ldap-srv-repl.example.com.csr \
-subj /C=RU/ST=Moscow/L=Moscow/O=ExampleInc/OU=ITdept/CN=ldap-srv-repl.example.com/emailAddress=support@example.com
Подпишем его с помощью своего CA:
# openssl ca -extensions usr_cert -notext -md sha256 \ -keyfile private/rootca.key -cert certs/rootca.crt \ -in certs/ldap-srv-repl.example.com.csr -out certs/ldap-srv-repl.example.com.crt # chmod 444 certs/ldap-srv-repl.example.com.crt
Теперь нужно безопасным образом переместить на сервер ldap-srv-repl четыре файла:
Где работаем: ldap-srv-repl
Подготовим каталог для временного хранения этой информации на сервере-реплике в домашнем каталоге пользователя, которого Вы создали при установке операционной системы (допустим, user):
$ whoami user $ mkdir ~/certs $ chmod u=rwx,g=,o= ~/certs
Где работаем: ldap-srv
Скопируем файлы в этот каталог с сервера, где находится наш CA, используя учётную запись user:
# pwd /root/CA # scp private/ldap-srv-repl.example.com.key certs/ldap-srv-repl.example.com.crt certs/rootca.crt crl/rootca.crl user@ldap-srv-repl.example.com:~/certs
Где работаем: ldap-srv-repl
Создадим каталог для ключевой информации нашего сервера и поместим туда получившиеся у нас файлы:
# mkdir /etc/ldap/ssl # chown openldap:openldap /etc/ldap/ssl # chmod 0500 /etc/ldap/ssl # cd /home/user/certs # mv ldap-srv-repl.example.com.crt ldap-srv-repl.example.com.key /etc/ldap/ssl
Установим права доступа для ключевой информации:
# chown openldap:openldap /etc/ldap/ssl/{ldap-srv-repl.example.com.crt,ldap-srv-repl.example.com.key} # chmod 0400 /etc/ldap/ssl/{ldap-srv-repl.example.com.crt,ldap-srv-repl.example.com.key}
Поместим корневой сертификат и список отозванных сертификатов в каталог с сертификатами операционной системы и зададим для них права доступа:
# mv rootca.crt /etc/ssl/certs/ # chmod 0644 /etc/ssl/certs/rootca.crt # mv rootca.crl /etc/ssl/ # chmod 0644 /etc/ssl/rootca.crl
Опишем конфигурацию TLS для ldap-srv-repl в LDIF-файле 11.2.5-tls.consumer.ldif:
dn: cn=config
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/ssl/ldap-srv-repl.example.com.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap-srv-repl.example.com.key
-
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/rootca.crt
-
add: olcTLSVerifyClient
olcTLSVerifyClient: never
Загрузим конфигурацию:
$ ldapmodify -xWD cn=admin,dc=example,dc=com -f 11.2.5-tls.consumer.ldif
И проверим результат:
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b cn=config -s base | grep olcTLS olcTLSCertificateFile: /etc/ldap/ssl/ldap-srv-repl.example.com.crt olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap-srv-repl.example.com.key olcTLSCACertificateFile: /etc/ssl/certs/rootca.crt olcTLSVerifyClient: never
Раскомментируем строчки в /etc/ldap/ldap.conf:
BASE dc=example,dc=com
URI ldap://ldap-srv-repl.example.com
TLS_CACERT /etc/ssl/certs/rootca.crt
TLS_CRLFILE /etc/ssl/rootca.crl
TLS_REQCERT demand
TIMELIMIT 15
TIMEOUT 20
И попробуем выполнить запрос с использованием TLS (параметр -Z
):
$ ldapwhoami -xZZWD cn=admin,dc=example,dc=com Enter LDAP Password: dn:cn=admin,dc=example,dc=com
С помощью LDIF-файла 11.2.5-consumer.dbindexes.ldif изменим настройки журналирования сервера каталогов и добавим индексы для основной базы данных:
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: entryCSN eq
-
add: olcDbIndex
olcDbIndex: uid eq
-
add: olcDbIndex
olcDbIndex: cn eq
-
add: olcDbIndex
olcDbIndex: ou eq
-
add: olcDbIndex
olcDbIndex: dc eq
Теперь журнал сервера будет достаточно подробным. Это поможет нам в отладке. Загрузим конфигурацию:
$ ldapadd -xZZWD cn=admin,dc=example,dc=com -f 11.2.5-consumer.dbindexes.ldif
Проверим, что у нас получилось в итоге следующей командой:
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b cn=config "(|(cn=config)(olcDatabase={1}mdb))"
Где работаем: ldap-srv-repl
Включим аутентификацию SASL GSSAPI на новом сервере каталогов с помощью LDIF-файла 11.2.6-consumer.gssapi.ldif:
dn: cn=config
changetype: modify
add: olcSaslHost
olcSaslHost: ldap-srv-repl.example.com
-
add: olcSaslRealm
olcSaslRealm: EXAMPLE.COM
-
add: olcSaslSecProps
olcSaslSecProps: noanonymous,noplain
Загрузим конфигурацию:
$ ldapadd -xZZWD cn=admin,dc=example,dc=com -f 11.2.6-consumer.gssapi.ldif
Теперь нам нужно добавить параметр KRB5_KTNAME
в файл /etc/default/slapd:
SLAPD_CONF=
SLAPD_USER="openldap"
SLAPD_GROUP="openldap"
SLAPD_PIDFILE=
SLAPD_SERVICES="ldap:/// ldapi:///"
SLAPD_SENTINEL_FILE=/etc/ldap/noslapd
SLAPD_OPTIONS="-4"
export KRB5_KTNAME=/etc/ldap/krb5.keytab
Скопириуем конфигурацию-описание области EXAMPLE.COM с основного сервера, чтобы не было проблем при подключении с помощью устилиты kadmin:
# scp user@ldap-srv.example.com:/etc/krb5.conf /etc/
Создадим набор ключей Kerberos для сервера OpenLDAP, ключ принципала сервера ldap-srv-repl и ключ autofsclient для автоматического монтирования на этом сервере в диалоге команды kadmin. ВНИМАНИЕ: заметьте, как мы размещаем принципалы в наборах ключей. Принципалы host/ и autofsclient/ размещаются в /etc/krb5.keytab, а принципал ldap/ — в /etc/ldap/krb5.keytab:
# kadmin -p pablo/admin@EXAMPLE.COM kadmin: addprinc -randkey ldap/ldap-srv-repl.example.com@EXAMPLE.COM kadmin: ktadd -k /etc/ldap/krb5.keytab ldap/ldap-srv-repl.example.com@EXAMPLE.COM kadmin: addprinc -randkey host/ldap-srv-repl.example.com@EXAMPLE.COM kadmin: ktadd -k /etc/krb5.keytab host/ldap-srv-repl.example.com@EXAMPLE.COM kadmin: addprinc -randkey autofsclient/ldap-srv-repl.example.com@EXAMPLE.COM kadmin: ktadd -k /etc/krb5.keytab autofsclient/ldap-srv-repl.example.com@EXAMPLE.COM kadmin: exit
Поправим права доступа на новый набор ключей:
# chown root:openldap /etc/ldap/krb5.keytab # chmod 640 /etc/ldap/krb5.keytab
Перезапустим демон службы каталогов:
# service slapd restart
Проверим аутентификацию SASL GSSAPI:
$ kdestroy $ kinit -p pablo/admin@EXAMPLE.COM $ ldapwhoami SASL/GSSAPI authentication started SASL username: pablo/admin@EXAMPLE.COM SASL SSF: 56 SASL data security layer installed. dn:uid=pablo/admin,cn=example.com,cn=gssapi,cn=auth
Сервер-реплика ldap-srv-repl.example.com (потребитель OpenLDAP), настроен с использованием TLS и SASL GSSAPI. Сервер получает данные от поставщика ldap-srv.example.com. Проверим, работает ли процедура репликации. В качестве примера будем менять рабочую оболочку (loginShell
) пользователя test.user.
Где работаем: ldap-srv
Посмотрим текущее значение атрибута loginShell
пользователя test.user:
$ ldapsearch -QLLLZZb cn=test.user,ou=users,dc=example,dc=com loginShell dn: cn=test.user,ou=users,dc=example,dc=com loginShell: /bin/bash
Где работаем: ldap-srv-repl
Проверим значение того же поля на сервере-реплике:
$ ldapsearch -QLLLZb cn=test.user,ou=users,dc=example,dc=com loginShell dn: cn=test.user,ou=users,dc=example,dc=com loginShell: /bin/bash
Где работаем: ldap-srv
Поменяем оболочку пользователя на /bin/sh
:
$ ldapmodify <<-EOF dn: cn=test.user,ou=users,dc=example,dc=com changetype: modify replace: loginShell loginShell: /bin/sh EOF
Где работаем: ldap-srv-repl
Проверим, применились ли изменения на сервере-реплике:
$ ldapsearch -QLLLZb cn=test.user,ou=users,dc=example,dc=com loginShell dn: cn=test.user,ou=users,dc=example,dc=com loginShell: /bin/sh
Репликация работает! Ура!
Смысл репликации DIT — иметь запасную копию на случай выхода из строя основного сервера (поставщика). Но наше DIT помимо прочего поддерживает инфраструктуру Kerberos. Поэтому мы должны настроить сервер-реплику так, чтобы он выполнял роль подчинённого сервера Kerberos на случай выхода из строя основного.
Для развёртывания подчинённого сервера Kerberos мы уже установили необходимые пакеты и произвели некоторые настройки (в предыдущих разделах). Сейчас нам нужно переместить на подчинённый сервер три файла: закрытый ключ Kerberos, конфигурацию области и файл-тайник.
Где работаем: ldap-srv-repl
Создадим на сервере-реплике каталог для их временного хранения:
$ mkdir ~/kerberos $ chmod u=rwx,g=,o= ~/kerberos/ $ cd ~/kerberos/
Где работаем: ldap-srv
Скопируем файлы во временный каталог:
# scp /etc/krb5kdc/{.k5.EXAMPLE.COM,kdc.conf,kadm5.acl} /etc/krb5.d/stash.keyfile user@ldap-srv-repl.example.com:~/kerberos
Где работаем: ldap-srv-repl
Поместим эти файлы на свои места и поправим права доступа:
# mkdir /etc/krb5.d/ # chmod u=rwx,g=,o= /etc/krb5.d/ # mv {.k5.EXAMPLE.COM,kdc.conf,kadm5.acl} /etc/krb5kdc/ # mv stash.keyfile /etc/krb5.d/ # chown -R root:root /etc/krb5kdc /etc/krb5.d
Добавим в базу данных некоторые индексы. Запишем в файл 11.2.8-kerberos.indexes.ldif:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: objectClass eq
-
add: olcDbIndex
olcDbIndex: krbPrincipalName eq
-
add: olcDbIndex
olcDbIndex: sudoUser eq,sub
-
add: olcDbIndex
olcDbIndex: uidNumber,gidNumber,memberUid,uniqueMember eq
Загрузим конфигурацию:
$ ldapadd -QZZf 11.2.6-kerberos.indexes.ldif
Проверим, на месте ли новые индексы:
$ ldapsearch -QZZLLLb olcDatabase={1}mdb,cn=config olcDbIndex dn: olcDatabase={1}mdb,cn=config olcDbIndex: entryUUID eq olcDbIndex: entryCSN eq olcDbIndex: uid eq olcDbIndex: cn eq olcDbIndex: ou eq olcDbIndex: dc eq olcDbIndex: objectClass eq olcDbIndex: krbPrincipalName eq olcDbIndex: sudoUser eq,sub olcDbIndex: uidNumber,gidNumber,memberUid,uniqueMember eq
Убедитесь, что подчинённый KDC стартует автоматически и запустите его. Обратите внимание, что демон управления доменом Kerberos (kadmind) на подчинённом сервере мы не запускаем!
# update-rc.d krb5-kdc defaults # service krb5-kdc start
Настройте резервное копирование и восстановление на сервере-реплике в соответствии с методикой, приведённой в разделе 10.
Порой файлы журналов не дают чёткого представления, закончен процесс репликации или нет. Чтобы в этом удостовериться, просто запросите у поставщика и потребителя значение contextCSN. Если ответы от обоих серверов совпадают, репликация закончена.
Где работаем: ldap-srv
$ kdestroy $ kinit -p pablo/admin $ ldapsearch -ZZQLLL -s base contextCSN dn: dc=example,dc=com contextCSN: 20150112110636.224261Z#000000#000#000000
Где работаем: ldap-srv-repl
$ kdestroy $ kinit -p pablo/admin $ ldapsearch -ZZQLLL -s base contextCSN dn: dc=example,dc=com contextCSN: 20150112110636.224261Z#000000#000#000000
Всё отлично.
Где работаем: ldap-client
Когда второй сервер OpenLDAP заработал, нам остаётся настроить клиентов, чтобы они использовали оба. Для этого отредактируем несколько файлов.
Конфигурация sudoers через LDAP (/etc/sudo-ldap.conf):
BASE dc=example,dc=com
URI ldap://ldap-srv.example.com ldap://ldap-srv-repl.example.com
BINDDN cn=nssproxy,ou=users,dc=example,dc=com
BINDPW пароль.пользователя.nssproxy
TLS_CACERTFILE /etc/ssl/certs/rootca.crt
TLS_CRLFILE /etc/ssl/rootca.crl
TLS_CHECKPEER no
TIMELIMIT 15
TIMEOUT 20
SUDOERS_BASE ou=sudo,ou=services,dc=example,dc=com
Клиентская конфигурация LDAP (/etc/ldap/ldap.conf):
BASE dc=example,dc=com
URI ldap://ldap-srv.example.com ldap://ldap-srv-repl.example.com
TLS_CACERT /etc/ssl/certs/rootca.crt
TLS_CRLFILE /etc/ssl/rootca.crl
TLS_REQCERT demand
TIMELIMIT 15
TIMEOUT 20
SASL_MECH GSSAPI
Конфигурация локальной службы имён (/etc/nslcd.conf):
uid nslcd
gid nslcd
uri ldap://ldap-srv.example.com
uri ldap://ldap-srv-repl.example.com
base dc=example,dc=com
binddn cn=nssproxy,ou=users,dc=example,dc=com
bindpw nssproxyuserpass
rootpwmoddn cn=admin,dc=example,dc=com
base group ou=groups,dc=example,dc=com
base passwd ou=users,dc=example,dc=com
base shadow ou=users,dc=example,dc=com
bind_timelimit 5
timelimit 10
idle_timelimit 60
ssl start_tls
tls_reqcert demand
tls_cacertfile /etc/ssl/certs/rootca.crt
nss_initgroups_ignoreusers bin,daemon,games,lp,mail,nobody,nslcd,root,sshd,sync,uucp
nss_initgroups_ignoreusers sys,man,news,proxy,www-data,backup,list,irc,gnats,landscape
Конфигурация Kerberos (/etc/krb5.conf):
[logging]
default = SYSLOG:INFO:LOCAL1
kdc = SYSLOG:NOTICE:LOCAL1
admin_server = SYSLOG:WARNING:LOCAL1
[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
EXAMPLE.COM = {
kdc = ldap-srv.example.com
kdc = ldap-srv-repl.example.com
admin_server = ldap-srv.example.com
master_kdc = ldap-srv.example.com
default_domain = example.com
database_module = openldap_ldapconf
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}
Как можно видеть, изменения требуются совсем небольшие. Поэтому, возможно, Вы захотите такой процесс автоматизировать. Сделать это можно разными путями. От простой раздачи файлов по сети с помощью ftp/http/nfs до развесистой системы управления версиями вроде Puppet.
После внесения всех изменений на клиентской машине, попробуйте выключить ldap-srv.example.com и проверить, будут ли доступны сервисы, которые он поддерживал, с нового сервера ldap-srv-repl.example.com.
Если Вы испытываете трудности с Syncrepl, попробуйте настроить журналирование:
ldapmodify -Z <<-EOF dn: cn=config changetype: modify replace: olcLogLevel olcLogLevel: stats sync EOF
Вы можете сделать это как на поставщике, так и на потребителе.
Если в журнале slapd.log Вы видите подобную запись:
syncrepl_message_to_entry: rid=000 mods check (objectClass: value #1 invalid per syntax)то это значит, что на сервере-реплике нет необходимой схемы набора данных. Конечно, значение
rid=000
может быть другим на Вашем сервере. Это идентификатор репликации, задаваемый в атрибуте olcSyncrepl
на севере-реплике. Сравните набор загруженных схем с основным сервером (поставщиком). Они должны совпадать. Выявите, каких схем не хватает, выполнив на каждом сервере запрос:
$ ldapsearch -ZZQLLLb cn=schema,cn=config dn
Где работаем: ldap-srv-repl
Загрузите недостающие схемы на сервер-реплику, пользуясь таким шаблоном (с использованием Kerberos):
$ ldapadd -ZZQf schema.ldif
За дополнительной информацией обратитесь к разделу 2.5.
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |