АЛЕКСЕЙ БАРАБАНОВ
Настраиваем Kerberos поверх LDAP
Сегодня мы рассмотрим настройку открытой версии Kerberos Heimdal для работы с OpenLDAP в качестве хранилища учетных данных. Такое решение позволит вам создать однородную информационную среду для обеспечения процесса аутентификации и авторизации пользователей в Linux.
Системы аутентификации на основе стандартов Kerberos все чаще используются в практических решениях. Безусловно, Kerberos обладает массой привлекательных качеств. Но сама по себе аутентификация – это «паспорт» несуществующей страны, поскольку всегда успешная аутентификация предполагает следующую фазу – авторизацию. Если продолжим паспортную аналогию, то именно на стадии авторизации владелец действительного «паспорта» получает соответствующие права. Авторизационная база, содержащая перечень данных на каждую снабженную «паспортом» персону должна содержать еще и данные, позволяющие установить соответствие персоны и паспорта. Но ведь и база аутентификации, т.е. база фактически проверяемых при сопоставлении «паспорта» и персоны данных, тоже содержит информацию, частично продублированную в «паспорте», как минимум имя персоны. Возвращаясь к информационным технологиям, далее будем называть набор прав к «паспорту» бюджетом, как это принято в практике администрирования, а персону с «паспортом» – принципалом, как это принято в Kerberos.
Итак, если информация о бюджетах хранится в одной базе, а информация о принципалах в другой, то получается, что для нормального функционирования неразрывного механизма аутентификации и авторизации необходимо поддерживать обе базы, обеспечивать их связанность, иметь для каждой собственное средство управления доступом. Кроме этого, архивирование информации системы аутентификации и авторизации тоже в таком случае не может производиться единым образом. Напрашивается очевидное решение – разместить обе базы в одном хранилище. В качестве такого хранилища может выступать LDAP. Для реализации этой идеи надо обеспечить возможность для системных средств получать информацию о бюджетах из базы LDAP, во-первых, и, во-вторых, заставить Kerberos хранить свои записи о принципалах и соответствующих им ключах тоже в LDAP. И то и другое уже достижимо.
Размещение бюджетной информации в LDAP – это отдельная большая тема. Ей посвящено много руководств и даже учебников. Вы можете воспользоваться рекомендациями из заметок [1] на эту тему. Кроме того, использование LDAP зачастую является стандартнным для некоторых платформ. Поэтому предположим, что данный вопрос уже решен. Вся дальнейшая работа будет производится в среде SuSE Linux с уже настроенным хранением бюджетов в OpenLDAP, например, так как это сделано согласно требованиям Samba PDC. Теперь к такой системе добавляем Kerberos. Воспользуемся открытой версией Kerberos, что поставлялась в SuSE до версии 9.3 – Heimdal. С версии 9.3 в SuSE произошел переход на Kerberos от MIT, в опциях настройки которого отсутствует возможность работы с LDAP, поэтому далее эту реализацию Kerberos не будем рассматривать.
Итак, в OpenLDAP уже хранятся аутентификационные данные, соответствующие системным службам в атрибуте userPassword, аутентификационные данные, соответствующие Samba в атрибутах sambaLMPassword и sambaNTPassword. Если в систему добавится Kerberos, то дополнительно каждому бюджету будет сопоставлены данные о принципале Kerberos. Это тот же пароль и права на участие в отношениях внутри определенной области Kerberos (Kerberos realm). Далее рассмотрим настройку Kerberos, работающего с LDAP, по шагам.
Собираем Heimdal
Да-да, собираем. Оказывается, стандартный Heimdal, поставляемый в SuSE, собирается без поддержки LDAP. Для проверки установим дистрибутивные пакеты:
# rpm -qa | grep heimdal
heimdal-devel-0.6-67
heimdal-lib-0.6-67
heimdal-tools-0.6-67
heimdal-0.6-67
|
И посмотрим, с какими библиотеками скомпонован демон kdc:
# ldd /usr/lib/heimdal/sbin/kdc | grep ldap
Так как ссылок на ldap нет, то придется пересобрать Heimdal заново. Для этого установим исходные тексты:
# rpm -ivh heimdal-0.6-67.src.rpm
Можно даже взять версию поновее с сайта разработчиков [2]. Режим сборки задается в файле rpm-спецификации в строках, где производится конфигурирование пакета перед непосредственным выполнением команды make. Заглянем в оригинальный файл rpm-спецификации:
# cat /usr/src/packages/SPECS/heimdal.spec | sed -n "/^# building with openldap/,+14p"
# building with openldap support does not work right now because
# autobuild cannot handle circular dependencies such as
# libhdb -> libldap -> libsasl -> libgssapi -> libhdb
# with_openldap="--with-openldap=/usr"
#
CFLAGS="$RPM_OPT_FLAGS -DOPENSSL_DES_LIBDES_COMPATIBILITY"
./configure --enable-shared --prefix=/usr/lib/heimdal
--with-x --mandir=%{_mandir}
--libdir=%{_libdir}
--infodir=%{_infodir} --libexecdir=/usr/lib/heimdal/sbin
--includedir=/usr/include/heimdal
--with-readline-include=/usr/include/readline
--with-readline-lib=/usr/lib
$with_openldap
make
|
Читаем предупреждение. Не верим. Снимаем комментарий с управляющей переменной и собираем пакеты заново. Протокол сборки завершается сообщениями об успешной записи новых rpm:
# rpmbuild -ba /usr/src/packages/SPECS/heimdal.spec
.....
Wrote: /usr/src/packages/SRPMS/heimdal-0.6-67.src.rpm
Wrote: /usr/src/packages/RPMS/i586/heimdal-0.6-67.i586.rpm
Wrote: /usr/src/packages/RPMS/i586/heimdal-devel-0.6-67.i586.rpm
Wrote: /usr/src/packages/RPMS/i586/heimdal-lib-0.6-67.i586.rpm
Wrote: /usr/src/packages/RPMS/i586/heimdal-tools-0.6-67.i586.rpm
|
Удивительно, но все собралось вопреки предупреждениям SuSE-гуру. Устанавливаем полученное.
# rpm -Uvh --force /usr/src/packages/RPMS/i586/heimdal-*.rpm
Проверяем, что теперь сборка выполнена с поддержкой LDAP:
# ldd /usr/lib/heimdal/sbin/kdc | grep ldap
libldap.so.2 => /usr/lib/libldap.so.2 (0x4007a000) |
Все отлично, ссылка на библиотеку LDAP появилась. Как и следовало ожидать, в информационных технологиях здоровый скепсис всегда кстати.
Настраиваем OpenLDAP
В отличие от NSS и PAM сервер Kerberos не имеет специального файла настройки LDAP-клиента. В отличие от Postfix, Squid, Courier-IMAP он не имеет также опций настройки LDAP-клиента в своих конфигурационных файлах. И это совершенно правильное решение. Дело в том, что если подключения Kerberos к LDAP будет использовать уязвимый способ аутентификации, то грош цена всей остальной системной безопасности, которую несет технология Kerberos. Защита внутри Kerberos, а в предлагаемом способе подключения LDAP становится частью Kerberos, должна гарантироваться физическими, а не информационными условиями. Другими словами, Kerberos может работать только с локальным сервером LDAP и только через локальное подключение, не допускающее перехвата информационного обмена.
Для этого настроим LDAP на прослушивание локального сокета. В SuSE это делается путем изменения специального файла в sysconfig.
# cat /etc/sysconfig/openldap | grep LDAPI
OPENLDAP_START_LDAPI="yes" |
А в других дистрибутивах надо просто настроить ключи запуска LDAP.
Вся информация внутри LDAP размещается согласно определенным схемам. Есть такая схема и для размещения информации Kerberos. Эта схема не входит в состав дистрибутивных пакетов. Но ее нетрудно разыскать в Интернете. Авторство этой схемы принадлежит PADL Software Pty Ltd. Можно взять версию, прилагаемую к статье [3], или поискать поновее по ссылке [4]. Эту схему надо положить ко всем остальным схемам и добавить соответствующую ссылку на нее в файл настроек LDAP:
# cat /etc/openldap/slapd.conf | grep krb5
include /etc/openldap/schema/krb5-kdc.schema |
Разрешим полный доступ через локальный сокет, добавив соответствующие строки в настройки ограничений доступа LDAP. Здесь используется специальный подключаемый файл slapd.access.conf , содержащий очень грубую настройку условий доступа. Можно даже сказать так, что эта настройка носит только учебный характер.
# cat /etc/openldap/slapd.access.conf | grep -v "^(#|$)"
access to dn=".*,dc=office,dc=localnet"
by sockurl="^ldapi:///$" write
by self write
by * read
|
Согласно указанным правилам все пользователи могут читать всю базу LDAP, а вот править могут только лишь собственные контейнеры. Строка «by sockurl=”^ldapi:///$”» выбирает из всех запросов те, что поступают в LDAP через локальный сокет, и дает таким клиентским подключениям права на запись, то есть самые высокие по шкале эскалации прав LDAP. Как уже стало понятно, базовый контейнер LDAP имеет имя dc=office,dc=localnet.
Заметим, что хотя все атрибуты, использованные для хранения ключей принципалов, шифруются по мастер-ключу конкретного KDC (Kerberos Key Distribution Ceter или в русской аналогии ЦРК – центр распределения ключей), для предотвращения доступа к таким записям со стороны иных служб рекомендуется настроить соответствующим образом правила доступа к LDAP базе. Да и права, собственно, Kerberos тоже можно ограничить определенным уровнем дерева LDAP.
Но разрешить все со стороны локального сокета не достаточно. Поскольку Kerberos никак себя не аутентифицирует при подключении к LDAP, то в сеансе связи он будет считаться анонимным пользователем. В версиях OpenLDAP с индексом более 2 модификация базы через такое подключение приводит к ошибке.
Например, попытка инициализации области Kerberos завершается сообщением:
kadmin: kadm5_create_principal: ldap_add_s:
Strong(er) authentication required
|
Добавим специальную опцию «allow update_anon» в управляющий файл LDAP перед директивами, описывающими базу данных. Эта опция допускает изменение базы LDAP анонимным клиентом, если последнее разрешено операторами access.
Теперь можно запустить LDAP.
# rcldap start
Starting ldap-server done |
server:~ # netstat -apn | grep slapd
tcp 0 0 127.0.0.1:389 0.0.0.0:* LISTEN 11036/slapd
unix 2 [ ACC ] STREAM LISTENING 82235 11036/slapd /var/run/slapd/ldapi
unix 2 [ ] DGRAM 182233 11036/slapd
|
Видно, что процесс slapd слушает не только локальный адрес, но и сокет /var/run/slapd/ldapi. Здесь есть еще один «подводный камень», который, возможно, будет иметь значение для владельцев дистрибутивов, отличных от SuSE. Дело в том, что традиционно LDAP запускается от соответствующего пользователя.
# ps -eo user,args | grep slapd | grep -v grep | head -n 1
ldap /usr/lib/openldap/slapd -h ldapi:///
ldap://127.0.0.1:389/ -u ldap -g ldap
|
И несмотря на это, сокет для связи создается от пользователя root и с правами, ограничивающими доступ к нему от иных пользователей и групп, но с установленным битом «set user ID». Вроде все верно, только расположен он внутри директории, доступной лишь для ldap.ldap.
# ls -als /var/run/slapd
total 24
4 drwx------ 4 ldap ldap 4096 Jun 12 13:04 .
4 drwxr-xr-x 20 root root 4096 Jun 12 23:02 ..
0 srwx------ 1 root root 0 Jun 12 13:04 ldapi
4 drwx------ 2 ldap ldap 4096 Sep 24 2003 openldap-data
4 drwx------ 2 ldap ldap 4096 Sep 24 2003 openldap-slurp
4 -rw-r--r-- 1 ldap ldap 76 Jun 12 13:04 slapd.args
4 -rw-r--r-- 1 ldap ldap 5 Jun 12 13:04 slapd.pid
|
Процесс kdc в SuSE запускается от пользователя root, и поэтому нет никаких проблем с подключением к сокету для связи с LDAP. Если в некоторой системе приняты иные соглашения, то недоступность локального сокета, созданного LDAP, со стороны процесса kdc может быть причиной отказа Kerberos. Для исправления этого надо просто поменять права доступа у сокета после запуска slapd.
Подключенный через локальный сокет Kerberos имеет исключительно доверительные права на доступ к базе LDAP. Но это нужно только для режима наполнения базы данными. Для регулярной работы Kerberos, аутентификации и выдачи билетов достаточно иметь доступ на чтение. То есть всегда остается возможность «заморозить» состояние базы Kerberos. Хотя верно это лишь для применяемой версии Heimdal, которая не обновляет индексы в базе при выдаче билетов, и, естественно, в таком случае станет невозможным изменение паролей принципалов.
Настраиваем Kerberos
Создадим файл управления службой Kerberos. Рабочей областью Kerberos (в оригинале realm) назначим OFFICE.LOCALNET и ограничим перечень прослушиваемых адресов внутрисетевыми. Должно получиться так:
# cat /etc/krb5.conf
[kdc]
database = {
dbname = ldap:ou=KerberosPrincipals,dc=office,dc=localnet
log_file = /var/heimdal/log
acl_file = /var/heimdal/kadmind.acl
}
addresses = 127.0.0.1 192.168.0.1
[libdefaults]
default_realm = OFFICE.LOCALNET
clockskew = 300
dns_lookup_kdc = 1
[realms]
OFFICE.LOCALNET = {
kdc = kerberos.office.localnet
admin_server = kerberos.office.localnet
kpasswd_server = kerberos.office.localnet
}
[domain_realm]
.office.localnet = OFFICE.LOCALNET
[logging]
default = SYSLOG:NOTICE:DAEMON
kdc = FILE:/var/log/kdc.log
kadmind = FILE:/var/log/kadmind.log
[appdefaults]
pam = {
ticket_lifetime = 1d
renew_lifetime = 1d
forwardable = true
proxiable = false
}
Проверим настройки специальной программой.
# verify_krb5_conf
verify_krb5_conf: /kdc/database/log_file: unknown entry
verify_krb5_conf: /kdc/database/acl_file: unknown entry
|
Сообщения игнорируем, так как они ошибочные. Можно или собрать более свежую версию verify_krb5_conf, или сразу писать авторам сообщение об ошибке.
Прокомментирую секцию kdc и оператор database. Внутри указывается контейнер LDAP, в котором будут размещаться записи, используемые Kerberos. Дополнительно определим файл протокола и файл с установками ограничений доступа к самой базе со стороны принципалов. Эти строки надо указывать обязательно. Но Kerberos работает со своей базой на очень примитивном уровне и поэтому не имеет возможности анализировать специфические ошибки LDAP. Иначе говоря, он не может распознать отсутствие подготовленного контейнера в LDAP и создать его самостоятельно. Значит, нужно предварительно создать контейнер для Kerberos ou=KerberosPrin-cipals,dc=office,dc=localnet. Для этого подготовим данные в специальном файле kerberos.ldif.
# cat kerberos.ldif
dn: ou=KerberosPrincipals,dc=office,dc=localnet
ou: KerberosPrincipals
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: office.localnet
Здесь отмечу одну забавную особенность. На сайте [4] в описании аналогичной настройки записан контейнер с ou= KerberosPrincpals, который отличается отсутствием буквы «i» в слове «Principals». Это именно описка, поскольку там же в примере с ldapsearch приведен грамматически правильный вариант. Но тем не менее многими такая форма была воспринята как стандарт и бездумно повторена. Этот случай свидетельствует о высоком уровне априорного доверия всякому экспертному мнению в области компьютерной безопасности.
Создадим контейнер для Heimdal.
# ldapadd -v -H ldap://localhost -D "cn=ldapadmin,dc=office,dc=localnet" -x -w secret -f kerberos.ldif
ldap_initialize( ldap://localhost )
add ou:
KerberosPrincipals
add objectClass:
top
organizationalUnit
domainRelatedObject
add associatedDomain:
office.localnet
adding new entry "ou=KerberosPrincipals,dc=office,dc=localnet"
modify complete
|
Теперь все готово для настройки Kerberos.
Оффлайновое администрирование
В первую очередь подготовим мастер-ключ.
# kstash
Master key:
Verifying - Master key:
kstash: writing key to `/var/heimdal/m-key"
|
Проверим, что появился соответствующий файл.
# ls -als /var/heimdal
4 -rw------- 1 root root 72 Jun 11 00:04 m-key |
В дальнейшем пароль, использованный для генерации мастер-ключа, можно забыть. Самое главное, не терять файл с мастер-ключом, так как без него KDC не сможет работать с собственной базой. Считается, что копию файла с мастер-ключом надо хранить отдельно от архива базы Kerberos.
Подключимся к Kerberos в оффлайне (ключ -l) и настроим область Kerberos.
# kadmin -l
kadmin> init OFFICE.LOCALNET
Realm max ticket life [unlimited]:
Realm max renewable ticket life [unlimited]:
|
kadmin> exit
Проверим, используя опять же оффлайновое подключение, что вышло.
# kadmin -l
kadmin> list *
krbtgt/OFFICE.LOCALNET@OFFICE.LOCALNET
kadmin/changepw@OFFICE.LOCALNET
kadmin/admin@OFFICE.LOCALNET
changepw/kerberos@OFFICE.LOCALNET
kadmin/hprop@OFFICE.LOCALNET
default@OFFICE.LOCALNET
|
kadmin> exit
Интерпретируем результат. Итак, выше приведен перечень служебных принципалов, созданных автоматически. Структура именования принципалов следующая: primary_name/instance@REALM. Но в данном случае часть instance имеет значение «роль». Для администрирования зарегистрируем принципала sysadmin/admin.
# kadmin -l
kadmin> add sysadmin/admin
Max ticket life [1 day]:
Max renewable life [1 week]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
sysadmin/admin@OFFICE.LOCALNET"s Password:
Verifying - sysadmin/admin@OFFICE.LOCALNET"s Password:
|
kadmin> exit
Вот пароль этого принципала надо запомнить обязательно. Хотя в случае утери его можно восстановить через оффлайновое подключение. Создание sysadmin/admin в файле-реплике LDAP отображается следующим образом:
time: 1118439261
dn: cn=sysadmin/admin@office.localnet,ou=KerberosPrincipals,dc=office,dc=localnet
changetype: add
objectClass: top
objectClass: person
objectClass: krb5Principal
objectClass: krb5KDCEntry
krb5PrincipalName: sysadmin/admin@OFFICE.LOCALNET
krb5KeyVersionNumber: 1
krb5MaxLife: 86400
krb5MaxRenew: 604800
krb5KDCFlags: 126
krb5Key:: MCWhIzAhoAMCARChGgQYCCzqjwcCvAduYvIOzSVKuq33j9qeBJe5
krb5Key:: MBWhEzARoAMCAQOhCgQIUl6ATDGML2g=
krb5Key:: MBWhEzARoAMCAQKhCgQIUl6ATDGML2g=
krb5Key:: MBWhEzARoAMCAQGhCgQIUl6ATDGML2g=
cn: sysadmin/admin@office.localnet
sn: sysadmin/admin@office.localnet
structuralObjectClass: person
entryUUID: 271bfa42-6e43-1029-90f0-b1a0d84cadb1
creatorsName: cn=anonymous
createTimestamp: 20050610213421Z
entryCSN: 2005061021:34:21Z#0x0001#0#0000
modifiersName: cn=anonymous
modifyTimestamp: 20050610213421Z
|
Здесь видно, что создатель записей в контейнерах Kerberos anonymous.
Настраиваем DNS
Перейдем к настройкам удаленного доступа к сервисам Kerberos. Сначала настроим DNS. Здесь предполагается, что KDC запускается в локальной сети 192.168.0.0/24 на хосте 192.168.0.1. Добавим в описание зоны office.localnet следующие строки:
$ORIGIN .office.localnet.
$TTL 86400 ; 1 day
_kerberos TXT "OFFICE.LOCALNET."
kdc A 192.168.0.1
kerberos A 192.168.0.1
$ORIGIN _tcp.office.localnet.
$TTL 600 ; 10 minutes
_kerberos SRV 0 100 88 kerberos.office.localnet.
_kerberos-adm SRV 0 100 749 kerberos.office.localnet.
_kpasswd SRV 0 100 464 kerberos.office.localnet.
$ORIGIN _udp.office.localnet.
$TTL 600 ; 10 minutes
_kerberos SRV 0 100 88 kerberos.office.localnet.
_kpasswd SRV 0 100 464 kerberos.office.localnet.
Перезапустим сервер DNS и проверим, что разрешение имен работает нужным образом.
# dig _kerberos._tcp.office.localnet any +short
0 100 88 kerberos.office.localnet. |
Запускаем Kerberos
Настало время запустить службы Kerberos.
# rckdc start
Посмотрим, что вышло.
# netstat -apn | grep "(kdc|kadmin|kpasswd)"
tcp 0 0 192.168.0.1:88 0.0.0.0:* LISTEN 10984/kdc
tcp 0 0 127.0.0.1:88 0.0.0.0:* LISTEN 10984/kdc
tcp 0 0 :::749 :::* LISTEN 10986/kadmind
udp 0 0 XX.XXX.XX.XX:464 0.0.0.0:* 10988/kpasswdd
udp 0 0 192.168.0.1:464 0.0.0.0:* 10988/kpasswdd
udp 0 0 YYY.YY.Y.YY:464 0.0.0.0:* 10988/kpasswdd
udp 0 0 10.0.0.1:464 0.0.0.0:* 10988/kpasswdd
udp 0 0 127.0.0.1:464 0.0.0.0:* 10988/kpasswdd
udp 0 0 192.168.0.1:88 0.0.0.0:* 10984/kdc
udp 0 0 127.0.0.1:88 0.0.0.0:* 10984/kdc
udp 0 0 ::1:464 :::* 10988/kpasswdd
unix 2 [ ] DGRAM 359313 10988/kpasswdd
|
Примечательно, что kdc, т.е. сервис аутентификации и выдачи билетов, запустился на внутренних адресах и порту 88, как и планировалось. Сервис удаленного администрирования kadmind прослушивает все возможные адреса по порту 749, а вот kpasswdd, т.е. сервис изменения паролей, слушает на всех активных в данный момент адресах по порту 464, не исключая и двух внешних подключений к ISP. Другими словами, без firewall не обойтись, иначе если не атаки, то сканирований не избежать. Но все вышесказанное относится только к принятой в SuSE схеме запуска. Ничего не мешает запустить kadmind и kpasswdd через суперсервер xinetd, и уже средствами последнего ограничить доступ. Схема запуска через суперсервер, кроме прочего, еще и позволит сэкономить ресурсы.
Работаем в сети
Теперь проверим, как будет работать не оффлайновое, а сетевое администрирование Kerberos.
# kadmin -p sysadmin/admin
kadmin> list *
sysadmin/admin@OFFICE.LOCALNET"s Password:
kadmin: get *: Operation requires `get" privilege
|
kadmin> exit
Это значит, в базе Kerberos не настроены права доступа. Ранее все подключения делались напрямую к базе данных, и права доступа не учитывались. Настроим их.
# cat >/var/heimdal/kadmind.acl <
> sysadmin/admin all
> * cpw
> EOT
|
Это значит, sysadmin/admin может делать все, а остальные только менять пароли. И теперь повторим попытку подключения.
# kadmin -p sysadmin/admin
kadmin> list *
sysadmin/admin@OFFICE.LOCALNET"s Password:
krbtgt/OFFICE.LOCALNET@OFFICE.LOCALNET
kadmin/changepw@OFFICE.LOCALNET
kadmin/admin@OFFICE.LOCALNET
changepw/kerberos@OFFICE.LOCALNET
kadmin/hprop@OFFICE.LOCALNET
default@OFFICE.LOCALNET
sysadmin/admin@OFFICE.LOCALNET
|
kadmin> exit
Как показала эта проверка, kdc перечитывает правила доступа к базе при каждом обращении, то есть нет необходимости перезагружать демон.
И теперь проделаем все то же самое, но с удаленного компьютера, предварительно переложив туда файл настроек krb5.conf, который одновременно является и файлом настроек клиента Kerberos.
Получим билет для принципала sysadmin/admin на рабочей станции:
alekseybb@wsalekseybb:~> kinit sysadmin/admin
sysadmin/admin@OFFICE.LOCALNET"s Password:
kinit: NOTICE: ticket renewable lifetime is 1 week
|
alekseybb@wsalekseybb:~> klist
Credentials cache: FILE:/tmp/krb5cc_500
Principal: sysadmin/admin@OFFICE.LOCALNET
Issued Expires Principal
Jun 11 02:14:33 Jun 11 12:15:57 krbtgt/OFFICE.LOCALNET@OFFICE.LOCALNET
|
Здесь видно, что в кеше Kerberos для локального клиента alekseybb лежит билет от krbtgt/OFFICE.LOCALNET, выписанный на принципала – администратора sysadmin/admin@OFFICE.localnet. Такой билет называется супербилет (в оригинале – Ticket Granting Ticket), поскольку он дает право на получение билетов на доступ ко всем другим принципалам, расположенным в той же области Kerberos. В нашем случае это список, полученный по команде «list *». Проверим доступ к базе на правах администратора.
alekseybb@wsalekseybb:~> /usr/sbin/kadmin
kadmin> list *
krbtgt/OFFICE.LOCALNET@OFFICE.LOCALNET
kadmin/changepw@OFFICE.LOCALNET
kadmin/admin@OFFICE.LOCALNET
changepw/kerberos@OFFICE.LOCALNET
kadmin/hprop@OFFICE.LOCALNET
default@OFFICE.LOCALNET
sysadmin/admin@OFFICE.LOCALNET
|
kadmin> exit
Теперь снова заглянем в кеш билетов.
alekseybb@wsalekseybb:~> klist
Credentials cache: FILE:/tmp/krb5cc_500
Principal: sysadmin/admin@OFFICE.LOCALNET
Issued Expires Principal
Jun 11 02:14:33 Jun 11 12:15:57 krbtgt/OFFICE.LOCALNET@OFFICE.LOCALNET
Jun 11 02:14:47 Jun 11 03:14:47 kadmin/admin@OFFICE.LOCALNET
|
Кроме супербилета, там появился второй билет, полученный на основании универсального и предназначенный для доступа к принципалу kadmin/admin@ OFFICE.LOCALNET. Оба билета выданы на «имя» sysadmin/admin.
Значит, работает. Удостоверимся в том, что Heimdal не модифицирует в процессе аутентификации записи в базе. Для этого есть много способов, но достаточно более внимательно просмотреть записи в самой базе.
alekseybb@wsalekseybb:~> /usr/sbin/kadmin
kadmin> list -l kadmin/admin
Principal: kadmin/admin@OFFICE.LOCALNET
Principal expires: never
Password expires: never
Last password change: never
Max ticket life: 1 hour
Max renewable life: 1 hour
Kvno: 1
Mkvno: 0
Policy: none
Last successful login: never
Last failed login: never
Failed login count: 0
Last modified: 2005-06-10 20:04:12 UTC
Attributes: requires-pre-auth
Keytypes(salttype[(salt-value)]): des-cbc-crc(pw-salt),
des-cbc-md4(pw-salt), des-cbc-md5(pw-salt), des3-cbc-sha1(pw-salt)
|
kadmin> exit
Видно, что поля с указанием времени последней аутентификации и прочие не установлены. Точно также можно убедиться в отсутствии модификаций по файлу-реплике LDAP, в который должны заноситься все такие операции.
Взвесим «за» и «против»
Итак, давайте взвесим, какие преимущества достигаются комбинацией Kerberos и LDAP. Быть может, не стоило все это и городить.
Перечислим положительные приобретения:
- Вся аутентификационная и бюджетная информация хранится в одной базе и, значит, может быть архивирована единым образом.
- Появляется возможность «заморозки» изменений в базе Kerberos, что позволяет сделать его работу более надежной.
- Появляется второй канал репликации базы Kerberos за счет реплики LDAP. То есть возрастает доступность (availability) службы KDC.
Теперь подсчитаем отрицательные:
- У KDC появляется зависимость от дополнительной службы, надежность предоставления сервиса которой надо гарантировать теперь вдвойне.
- Хотя использование мастер-ключа не позволяет вскрыть или подменить ключи принципалов, но гарантия того, что они не будут простого уничтожены, теперь лежит на другом сервисе и его настройках. Значит, в подобной схеме хранения надежность определяется по наислабейшему компоненту. Скорее всего, таким нужно считать LDAP.
Во всех руководствах по созданию KDC записано требование размещать KDC на отдельном хосте, который более ничем не может быть занят. Ну разве что SSH для администрирования. Но здесь же основанием для сочетания Kerberos и LDAP главными были мотивы интегрального характера. С другой стороны, есть успешный пример такой интеграции – разработка фирмы Microsoft под названием ActiveDirectory. Конечно, вопросы безопасности нужно прорабатывать очень тщательно и применительно к конкретному составу приложений, которые будет обслуживать LDAP. Поскольку если в общей директории хранится еще и информация Kerberos, то надо будет оградить ее от потенциально небезопасных приложений.
Ну и последнее соображение. Как следует из материалов работы [5], использование LDAP в качестве хранилища увеличило среднее время обработки запроса с 8 мс до 2.4 с, то есть почти в 300 раз. Конечно, измерения проводились на области, содержащей 1000 принципалов, и на не очень сильном компьютере. Но даже с поправкой на закон Мура надо учитывать фактор снижения производительности при переводе системы на подобную конфигурацию.
Ссылки:
- Заметки по настройке размещения пользовательских бюджетов в LDAP: http://www.barabanov.ru/arts/LDAPremarks-2.pdf.
- Домашний сайт проекта Heimdal: http://www.pdc.kth.se/heimdal.
- Схема для размещения информации Kerberos в LDAP: http://www.barabanov.ru/arts/kerberos_over_ldap/krb5-kdc.schema.
- Лидер в области разработок АиА с использованием LDAP: http://www.padl.com.
- Different database methods in Heimdal. Assar Westerlund, Swedish Institute of Computer Science: http://www.chips.chalmers.se/Chips/conference/made2000/presentations/danielsson.et.al.pdf.