LDAP-репликация и Samba


Samba и LDAP
Файловый сервер Samba хранит служебную информацию, в частности, информацию об учётных записях пользователей, в специальной базе данных, passdb backend. Сейчас Samba поддерживает большое количество разнообразных видов хранилищ, начиная от простого текстового файла (smbpasswd) и заканчивая MySQL-сервером.
Одним из распространённых в последнее время типов хранилищ, используемых вместе с Samba, является LDAP-хранилище, то есть фактически, сервер каталога, доступный по протоколу LDAP.
Наиболее важными преимуществами этого хранилища в сравнении с остальными является:
" Простота интеграции с другими системами;
" Возможность масштабирования.
Простота интеграции с другими системами позволяет добиться того чтобы все (или большинство) систем, используемых в сети, имели доступ и использовали в своей работе одну и ту же учётную информацию. Это позволяет упростить процесс администрирования и избежать создания внутренних противоречий.
Грубо говоря, если почтовый сервер и файловый сервер пользуются одними и теми же учётными записями, не нужно создавать одну и ту же запись два раза, и не может возникнуть ситуация, когда для почты поменяли пользователю пароль, а для файлового сервера - нет.
Чаще всего причиной, заставляющей перейти на использование LDAP-каталога для хранения учётной информации является первая, то есть простота интеграции. Масштабируемость нужна как можно реже: традиционное файловое хранилище используемое в Samba легко справляется с несколькими сотнями учётных записей. На LDAP переходят и при значительно меньшем количестве пользователей. Тем не менее, возможность распределения является тоже очень важной, и рано или поздно при росте системы она приобретает большое значение.
Возможность масштабирования даёт возможность роста системы в нескольких направлениях:
" размер системы (другими словами, количество учётных записей и интенсивность обращений);
" территориальная распределённость (географическая удалённость систем, использующих базу данных учётных записей);
" административная распределённость (за разные учётные записи отвечают разные люди).
В первом и втором случае создаётся несколько LDAP-серверов, один из которых является master-сервером, в него заносятся все изменения, которые делаются в каталоге; остальные же - slave-серверами, они хранят копию данных master-сервера. Передача данных с master-сервера на slave выполняется с помощью репликации.
Для решения третьей задачи, как правило, используются распределённые подкаталоги (поддомены).
На этой странице рассматриваются процедура подготовки slave-сервера LDAP и вопросы использования файлового сервера Samba совместно с slave-сервером LDAP. Вопросы распределения каталога (создания поддоменов) здесь не рассматриваются.

Сценарий
Есть центральный офис и есть отделение. Есть файловые серверы Samba, работающие в сети центрального офиса и в сети отделения.
В настоящий момент Samba-сервер отделения использует LDAP-сервер центрального офиса.
Это плохо по нескольким причинам:
" Данные между LDAP-сервером и Samba постоянно должны передаваться между центральным офисом и удалённым отделением;
" Когда центральный офис не работает, Samba-сервер использовать не удаётся.
Нужно сделать так чтобы файловый сервер Samba в сети отделения (и прочие службы тоже) использовали при чтении локальную реплику LDAP-каталога. Запись же (которая происходит значительно реже, чем чтение) должна выполняться в сервер центрального офиса.

Использование Samba с репликой LDAP
Samba-сервер использует локальную реплику LDAP. При чтении данных всё очевидно - данные просто читаются из локального LDAP-сервера.
С записью возникает несколько вопросов:
" Куда Samba-сервер должен записывать данные?
" Если в локальный LDAP-сервер, то как они попадут в центр?
" Если в центральный LDAP-сервер, то как сообщить Samba-серверу, что читать данные он должен на одном сервере, а записывать на другой.
Samba-сервер, в зависимости от того какую операцию он выполняет, может записывать данные в LDAP двумя способами:
" Посредством внешних скриптов (чаще всего smbldap-tools), которые используются при выполнении ряда операций (управление учётными записями пользователей и машин);
" Напрямую, непосредственно обращаясь к серверу, адрес которого указан в конфигурации Samba.
Рассмотрим каждый процесс более детально.
Модификация каталога через smldap-tools
На схеме показан типичный процесс изменения данных в каталоге по отправленному Samba запросу клиента, выполняющийся посредством внешних скриптов (например, добавление пользователя в каталог).

Шаги:
1. Обращение к локальному samba-серверу;
2. Samba не выполняет запись в LDAP-сервер напрямую; она использует для этого скрипты smbldap-tools;
3. Прямое обращение;
4. Репликация изменений в каталоге через slurpd;
5. Чтение информации из локального ldap;
6. Ответ локального samba-сервера.
Модификация каталога без smbldap-tools
На схеме показан типичный процесс изменения в каталоге по отправленному Samba запросу клиента, выполняющийся самим файловым сервером Samba (например, изменение пароля пользователя).

Шаги:
1. Обращение к локальному samba-серверу;
2. Samba пытается записать информацию в локальный LDAP-сервер напрямую, с помощью протокола LDAP;
3. LDAP-сервер возвращает Samba ответ-ссылку (referral);
4. Samba пытается записать информацию в центральный LDAP-сервер, адрес которого получен на предыдущем этапе;
5. Репликация изменений в каталоге через slurpd;
6. Чтение информации из локального ldap;
7. Ответ локального samba-сервера.
Переход на использование реплицированного LDAP-сервера
Процесс подготовки отделения к использованию локального (реплицированного) LDAP-сервера состоит из нескольких шагов:
1. Создание в каталоге специальной учётной записи для выполнения репликаций (репликатора);
2. Настройка центрального LDAP-сервера на отправку реплик на LDAP-сервер отделения;
3. Инсталляция локального LDAP-сервера;
4. Первичное копирование данных с центрального LDAP-сервера;
5. Перевод Samba и других LDAP-клиентов на использование локального LDAP-сервера.
Создание replicatora
Создайте файл, который будет содержать LDIF-запись, добавляемую в каталог:
%# cat > /tmp/replicator.ldif <<REPLICATOR
dn: cn=replicator,dc=example,dc=com
cn: replicator
objectclass: top
objectclass: organizationalRole
objectclass: simpleSecurityObject
userPassword: {SSHA}GYlNLdJctxRtLcqiMA5XsJvCVMtFjkeN
REPLICATOR
Хэш пароля можно определить с помощью команды slappasswd:
%# slappasswd
New password:
Re-enter new password:
{SSHA}GYlNLdJctxRtLcqiMA5XsJvCVMtFjkeN
После этого вы можете добавить запись в каталог:
%# ldapadd -D cn=manager,dc=example,dc=com -x -W -f /tmp/replicator.ldif

Есть искушение не создавать учётную запись репликатора, а проводить репликацию пользуясь учётной записью менеджера (cn=manager,dc=example,dc=com). Так делать нельзя! Поскольку в этом случае локальный LDAP-сервер при обращении к нему с запросами на запись не возвращает ссылку на центральный сервер, а отрабатывает запросы самостоятельно.
Изменение конфигурации master-сервера
В конфигурационный файл master-сервера OpenLDAP slapd.conf необходимо добавить следующие строки (директивы replica нужно добавлять по одной для каждого slave-сервера, если их несколько):
replogfile /var/lib/ldap/replog

replica uri=ldaps://slave.example.com:636
binddn="cn=replicator,dc=example,dc=com"
bindmethod=simple credentials=replicator-pass
Здесь вместо replicator-pass необходимо указать пароль, который был введён в slappasswd на предыдущем шаге.
Убедитесь, что каталог (в данном случае /var/lib/ldap), предназначенный для хранении журнала репликации LDAP, существует.
Изменение конфигурации slave-сервера
Убедитесь, что в конфигурационном файле salve-сервера есть следующие директивы:
Здесь важна строка replicator, которая разрешает выполнять запись от имени пользователя-репликатора. Запись будет выполняться master-сервером (а точнее, его процессом slurpd), когда в каталоге будут появляться изменения, которые нужно отреплицировать.
access to *
by dn="cn=admin,dc=example,dc=com" write
by dn="cn=replicator,dc=example,dc=com" write
by * read
Директива updatedn указывает учётную запись, обращения от имени которой должны отрабатываться непосредственно самим сервером. При обращении от имени любой другой учётной записи сервер не будет выполнять запись, а будет перенаправлять клиента на master-сервер.
updatedn cn=replicator,dc=example,dc=com
Директива updateref указывает куда должны перенаправляться клиенты, которые хотели выполнить запись на этот LDAP-сервер. Здесь необходимо указать адрес мастер-сервера LDAP.
updateref ldap://10.0.3.11:389
Пример. Конфигурационный файл slave-сервера OpenLDAP.
root@slave:~# grep -v ^# /etc/ldap/slapd.conf | grep -xv ''
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/samba.schema

pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args

loglevel 256

modulepath /usr/lib/ldap
moduleload back_bdb

sizelimit 500
tool-threads 1
backend bdb
checkpoint 512 30
database bdb

suffix "dc=example,dc=com"
rootdn "cn=manager,dc=example,dc=com"
rootpw {SSHA}4AJKTEFYkaJz/2fmYcKJIt85StohXBs

updatedn cn=replicator,dc=example,dc=com
updateref ldap://10.0.3.11:389

directory "/var/lib/ldap"
dbconfig set_cachesize 0 2097152 0
dbconfig set_lk_max_objects 1500
dbconfig set_lk_max_locks 1500
dbconfig set_lk_max_lockers 1500
index objectClass eq
lastmod on

access to attrs=userPassword,shadowLastChange,sambaLMPassword,sambaNTPassword,sambaPwdLastSet,sambaPwdMustChange
by dn="cn=admin,dc=example,dc=com" write
by anonymous auth
by self write
by * none
access to dn.base="" by * read
access to *
by dn="cn=admin,dc=example,dc=com" write
by dn="cn=replicator,dc=example,dc=com" write
by * read
Копирование базы данных с master-сервера на slave-сервер
Копирование базы данных выполняется очень просто: нужно просто синхронизировать каталоги.
Убедиться что master- и slave-серверы остановлены:
master%# /etc/init.d/slapd stop
slave%# /etc/init.d/slapd stop
На slave-сервере выполнить синхронизацию:
slave%# rsync -auvz master:/var/lib/ldap/ /var/lib/ldap/
Запустить master-сервер и slave-сервер вновь.
master%# /etc/init.d/slapd start
slave%# /etc/init.d/slapd start
Конфигурация Samba
В конфигурации Samba-сервера отделения необходимо сделать следующие изменения.
Во-первых, нужно указать новый LDAP-сервер в качестве backend-сервера, в котором хранится учётная информация Samba.
passdb backend = ldapsam:ldap://10.0.103.11
Здесь - 10.0.103.11 адрес LDAP-сервера отделения.
Во-вторых, нужно сказать Samba-серверу, что изменения в локальном сервере LDAP (в том, которым он пользуется), могут быть доступны не мгновенно, а спустя небольшое время. Это время определяется директивой ldap replication sleep в конфигурационном файле Samba. Например, в случае, когда в файле smb.conf присутствует строка:
ldap replication sleep = 5000
репликация должна успеть завершиться за 5 секунд.
Другие клиенты LDAP
Необходимо нацелить на новый LDAP-сервер не только Samba, но и другие клиенты LDAP.
libnss-ldap
Необходимо отредактировать конфигурационный файл библиотеки libnss_ldap, который расположен в /etc/libnss-ldap.conf или другом месте, которое можно определить с помощью команды:
%# strings /usr/lib/libnss_ldap.so | grep /etc
/etc/libnss-ldap.conf
/etc/libnss-ldap.secret
pam_ldap
Необходимо отредактировать конфигурационный файл библиотеки pam_ldap, который расположен в /etc/pam_ldap.conf или другом месте, которое можно определить с помощью команды:
# strings /lib/security/pam_ldap.so | grep /etc
/etc/pam_ldap.conf
/etc/pam_ldap.secret
smbldap-tools
Скрипты smbldap-tools могут оставаться нацеленными на master-сервер как и раньше. В большинстве своём работа скриптов требует модификации данных в каталоге, поэтому работа в любом случае будет выполняться с центральным сервером (либо сразу, либо после получения referral).
Как проверить
Изменить пароль пользователем в сети отделения. Проверить, изменился ли пароль в центре.
Ошибки при настройке
Использование unix password sync
Может возникнуть мысль вместо того чтобы воспользоваться механизмом ссылок (referral) в LDAP, переложить все задачи по обновлению на скрипты smbldap-tools, которые работают с центральным LDAP-сервером.
Несостоятельность этой мысли выяснится сразу же при попытке поменять пароль пользователем в сети отделения.
Если не указывать директиву updateref в конфигурационном файле slave-сервера LDAP, пароль меняется, но только на локальном сервер отделения и изменения не попадают в центральный каталог.
Попытка воспользоваться механизмом unix password sync в Samba и менять пароль с помощью smbldap-passwd тоже ни к чему не приводит.
В лог-файлах при этом появляются сообщения вида:
[2007/09/05 14:08:50, 0] libsmb/smbencrypt.c:decode_pw_buffer(552)
decode_pw_buffer: incorrect password length (1174457325).
[2007/09/05 14:08:50, 0] libsmb/smbencrypt.c:decode_pw_buffer(553)
decode_pw_buffer: check that 'encrypt passwords = yes'
Этот путь неправильный и по нему идти не следует.
Использование rootdn вместо updatedn
Если в записи updatedn указать идентификатор пользователя rootdn, и, который для записи использует Samba, перенаправление в центр выполняться не будет. Запись будет выполняться непосредственно на LDAP-сервере отделения, что является ошибкой.
Что дальше?
Рассмотреть переход с традиционной репликации с помощью slurpd, которая используется в описанной процедуре, на более прогрессивный механизм LDAP Sync Replication.

Обновлено: 12.03.2015