В нашей компании давно и успешно работает такая связка: Samba 3.x, установленная на FreeBSD (6.x или 7.x), для доступа к шарам использует аутентификацию пользователей в домене Active Directory. Все клиенты – Windows XP и выше. Домен AD – Windows 2003.
Все было хорошо, пока один из серверов FreeBSD не был обновлен до версии 8.2. После обновления пользователи с кириллическими логинами не смогли получить доступ к расшаренным ресурсам этого сервера. В то же время пользователи с логинами в латинице нормально аутентифицировались. Команды wbinfo -u и wbinfo -g как и положено показывали всех пользователей и группы AD, включая кириллические. Другой сервер FreeBSD 7.3 с такой же версией Samba – 3.4.9 и с таким же конфигом работал нормально с любыми логинами.
Исследование логов Samba показало, что при попытке аутентификации с использованием кириллического логина происходит ошибка в библиотеке kerberos – не проходит проверка клиентского тикета:
Была замечена еще вот такая штука: если обращаться к серверу не по имени, а по адресу IP (\\192.168.1.1), то аутентификация проходит успешно! В логах Samba находим, что в этом случае клиент инициирует аутентификацию по протоколу NTLM, а не по kerberos. После этого уже однозначно стало понятно, что причина наших бед – библиотека kerberos.
Уже с давних пор библиотека kerberos включена в базовую инсталляцию FreeBSD. В FreeBSD 8.2 это Heimdal 1.1. Кроме того, в портах есть еще две библиотеки kerberos: Heimdal 1.4 и MIT krb5 1.9. Идея состояла в том, чтобы перекомпилировать Samba с керберосом из портов и посмотреть, что получится.
Сначала было решено попробовать Heimdal, поскольку он хорошо интегрируется с базовой библиотекой kerberos (так, во всяком случае, пишут в Интернете). Устанавливаем порт heimdal-1.4_1, перестраиваем порт samba34-3.4.9_2.
С помощью переменной окружения HEIMDAL_HOME мы указываем, что при компиляции Samba надо использовать библиотеку heimdal, установленную из портов (в /usr/local/lib), иначе будет использована стандартная библиотека (из /usr/lib). Пробуем логиниться. Результат тот же.
Теперь пробуем библиотеку MIT, предварительно удалив Heimdal.
Сборка порта неожиданно прерывается с ошибкой:
Неожиданно потому, что это явно недочет того, кто готовил порт самбы для FreeBSD. Открываем файл work/samba-3.4.9/source3/include/config.h и исправляем строку
на
После этого снова запускаем компиляцию. Переменную KRB5_HOME уже можно не определять, поскольку она была необходима только на этапе configure.
Порт собрался и установился, но Samba не запускается. В логах самбы видим следующее:
Причина в том, что динамические библиотеки (.so) сначала ищутся загрузчиком в /usr/lib, а затем в /usr/local/lib. Поскольку имена некоторых файлов библиотек стандартного heimdal и установленного из портов krb5 совпадают, то первым отыскивается и загружается стандартная библиотека. А нам надо сделать так, чтобы для демонов самбы первыми в списке поиска были библиотеки из /usr/local/lib. Это можно сделать с помощью переменной окружения LD_LIBRARY_PATH, которую необходимо определить перед запуском демонов. В переменную надо занести имена каталогов, в которых загрузчик приложения будет искать динамические библиотеки в первую очередь. Т.е. в нашем случае будет так: LD_LIBRARY_PATH=/usr/local/lib.
Я не нашел ничего лучше, чем внести изменения в скрипт запуска /usr/local/etc/rc.d/samba. Это, конечно, совсем нехороший вариант, поскольку при переустановке или обновлении Samba изменения будут утеряны. Итак, в функции samba_cmd перед вызовом run_rc_command вставляем строку:
Теперь перезапускаем Samba и радуемся жизни с кириллическими логинами.
Из-за того, что в системе установлены две библиотеки керберос, которые между собой совсем не дружат, могут возникнуть осложнения. Из того, что было замечено, команду net ads теперь необходимо запускать так:
Другие субкоманды net, похоже, работают нормально и без LD_LIBRARY_PATH.
В качестве резюме приведу основные операции и настройки, необходимые для запуска Samba 3.4 на FreeBSD 8.2 в окружении Active Directory. Об установке и настройке Samba достаточно много написано в Инете, так что тривиальных пояснений давать не буду.
Подразумевается, что все команды выполняются от имени root. Вместо vi воспользуйтесь своим любимым редактором текстов.
Все было хорошо, пока один из серверов FreeBSD не был обновлен до версии 8.2. После обновления пользователи с кириллическими логинами не смогли получить доступ к расшаренным ресурсам этого сервера. В то же время пользователи с логинами в латинице нормально аутентифицировались. Команды wbinfo -u и wbinfo -g как и положено показывали всех пользователей и группы AD, включая кириллические. Другой сервер FreeBSD 7.3 с такой же версией Samba – 3.4.9 и с таким же конфигом работал нормально с любыми логинами.
Исследование логов Samba показало, что при попытке аутентификации с использованием кириллического логина происходит ошибка в библиотеке kerberos – не проходит проверка клиентского тикета:
[2011/04/26 15:06:18, 3] libads/kerberos_verify.c:378(ads_secrets_verify_ticket)
ads_secrets_verify_ticket: enc type [23] failed to decrypt with error Invalid argument
[2011/04/26 15:06:18, 3] libads/kerberos_verify.c:378(ads_secrets_verify_ticket)
ads_secrets_verify_ticket: enc type [1] failed to decrypt with error Message size is incompatible with encryption type
[2011/04/26 15:06:18, 3] libads/kerberos_verify.c:378(ads_secrets_verify_ticket)
ads_secrets_verify_ticket: enc type [3] failed to decrypt with error Message size is incompatible with encryption type
Была замечена еще вот такая штука: если обращаться к серверу не по имени, а по адресу IP (\\192.168.1.1), то аутентификация проходит успешно! В логах Samba находим, что в этом случае клиент инициирует аутентификацию по протоколу NTLM, а не по kerberos. После этого уже однозначно стало понятно, что причина наших бед – библиотека kerberos.
Уже с давних пор библиотека kerberos включена в базовую инсталляцию FreeBSD. В FreeBSD 8.2 это Heimdal 1.1. Кроме того, в портах есть еще две библиотеки kerberos: Heimdal 1.4 и MIT krb5 1.9. Идея состояла в том, чтобы перекомпилировать Samba с керберосом из портов и посмотреть, что получится.
Сначала было решено попробовать Heimdal, поскольку он хорошо интегрируется с базовой библиотекой kerberos (так, во всяком случае, пишут в Интернете). Устанавливаем порт heimdal-1.4_1, перестраиваем порт samba34-3.4.9_2.
$ cd /usr/ports/security/heimdal
$ sudo make install clean
$ cd /usr/ports/net/samba34
$ sudo HEIMDAL_HOME=/usr/local make deinstall reinstall clean
$ sudo /usr/local/etc/rc.d/samba restart
С помощью переменной окружения HEIMDAL_HOME мы указываем, что при компиляции Samba надо использовать библиотеку heimdal, установленную из портов (в /usr/local/lib), иначе будет использована стандартная библиотека (из /usr/lib). Пробуем логиниться. Результат тот же.
Теперь пробуем библиотеку MIT, предварительно удалив Heimdal.
$ sudo pkg_delete heimdal-1.4_1
$ cd /usr/ports/security/krb5
$ sudo make install clean
$ cd /usr/ports/net/samba34
$ sudo KRB5_HOME=/usr/local make deinstall reinstall clean
Сборка порта неожиданно прерывается с ошибкой:
Compiling libsmb/clikrb5.c
libsmb/clikrb5.c:1623:2: error: #error UNKNOWN_KRB5_ENCTYPE_TO_STRING_FUNCTION
Неожиданно потому, что это явно недочет того, кто готовил порт самбы для FreeBSD. Открываем файл work/samba-3.4.9/source3/include/config.h и исправляем строку
/* #undef HAVE_KRB5_ENCTYPE_TO_STRING_WITH_SIZE_T_ARG */
на
#define HAVE_KRB5_ENCTYPE_TO_STRING_WITH_SIZE_T_ARG 1
После этого снова запускаем компиляцию. Переменную KRB5_HOME уже можно не определять, поскольку она была необходима только на этапе configure.
$ sudo vi work/samba-3.4.9/source3/include/config.h
$ sudo make deinstall reinstall clean
$ sudo /usr/local/etc/rc.d/samba restart
Порт собрался и установился, но Samba не запускается. В логах самбы видим следующее:
/libexec/ld-elf.so.1: /usr/local/sbin/smbd: Undefined symbol "krb5_set_default_tgs_ktypes"
Причина в том, что динамические библиотеки (.so) сначала ищутся загрузчиком в /usr/lib, а затем в /usr/local/lib. Поскольку имена некоторых файлов библиотек стандартного heimdal и установленного из портов krb5 совпадают, то первым отыскивается и загружается стандартная библиотека. А нам надо сделать так, чтобы для демонов самбы первыми в списке поиска были библиотеки из /usr/local/lib. Это можно сделать с помощью переменной окружения LD_LIBRARY_PATH, которую необходимо определить перед запуском демонов. В переменную надо занести имена каталогов, в которых загрузчик приложения будет искать динамические библиотеки в первую очередь. Т.е. в нашем случае будет так: LD_LIBRARY_PATH=/usr/local/lib.
Я не нашел ничего лучше, чем внести изменения в скрипт запуска /usr/local/etc/rc.d/samba. Это, конечно, совсем нехороший вариант, поскольку при переустановке или обновлении Samba изменения будут утеряны. Итак, в функции samba_cmd перед вызовом run_rc_command вставляем строку:
samba_cmd() {
...
export LD_LIBRARY_PATH=/usr/local/lib
run_rc_command "${_rc_prefix}${rc_arg}" ${rc_extra_args}
...
}
Теперь перезапускаем Samba и радуемся жизни с кириллическими логинами.
Ложка дегтя
Из-за того, что в системе установлены две библиотеки керберос, которые между собой совсем не дружат, могут возникнуть осложнения. Из того, что было замечено, команду net ads теперь необходимо запускать так:
LD_LIBRARY_PATH=/usr/local/lib net ads …
Другие субкоманды net, похоже, работают нормально и без LD_LIBRARY_PATH.
Установка «с нуля»
В качестве резюме приведу основные операции и настройки, необходимые для запуска Samba 3.4 на FreeBSD 8.2 в окружении Active Directory. Об установке и настройке Samba достаточно много написано в Инете, так что тривиальных пояснений давать не буду.
Подразумевается, что все команды выполняются от имени root. Вместо vi воспользуйтесь своим любимым редактором текстов.
# cd /usr/ports/security/krb5
# make install clean
# cd /usr/ports/net/samba34
# make config
Устанавливаем опцию «With Active Directory support».
# KRB5_HOME=/usr/local make configure
# vi work/samba-3.4.9/source3/include/config.h
исправляем
/* #undef HAVE_KRB5_ENCTYPE_TO_STRING_WITH_SIZE_T_ARG */
на
#define HAVE_KRB5_ENCTYPE_TO_STRING_WITH_SIZE_T_ARG 1
# make install clean
# vi /usr/local/etc/rc.d/samba
вставляем export LD_LIBRARY_PATH=/usr/local/lib перед вызовом run_rc_command:
samba_cmd() {
...
export LD_LIBRARY_PATH=/usr/local/lib
run_rc_command "${_rc_prefix}${rc_arg}" ${rc_extra_args}
...
}
# echo samba_enable=\"YES\" >> /etc/rc.conf
# vi /etc/nsswitch.conf
изменяем строки
group: compat
passwd: compat
на такие
group: files winbind
passwd: files winbind
# vi /usr/local/etc/smb.conf
Основные настройки такие:
[global]
security = ads
# DNS-имя домена.
realm = DOMAIN.LOCAL
# NETBIOS-имя домена. Возможно, что это совсем не обязательный параметр.
workgroup = DOMAIN
# Кодировка имен файлов и настроек в smb.conf. В этой кодировке надо будет вводить логины и имена групп безопасности AD в правилах доступа к шарам. В Samba 3.5 есть известный баг: кириллические логины будут работать только при значении этого параметра UTF-8.
unix charset = CP1251
# Кодировка консоли. Необходимо для правильного отображения кириллических имен в консольных утилитах.
display charset = KOI8-R
Пример шары:
[share_name]
path = /tmp
valid users = \
+staff \
DOMAIN\Пупкин.Вася \
@"DOMAIN\Группа товарищей"
writable = yes
# LD_LIBRARY_PATH=/usr/local/lib net ads join -U administrator
Присоединяем наш сервер к домену. administrator – имя пользователя с правами администратора домена. Имя домена можно не указывать, поскольку по умолчанию будет использоваться значение realm из smb.conf.
Заметьте, что файл конфигурации кербероса /etc/krb5.conf, о котором так много пишут в Инете, совершенно не нужен. Вся необходимая информация о домене и KDC берется из DNS.
# /usr/local/etc/rc.d/samba start