| |
В этом разделе мы научимся использовать OpenLDAP 2.4 в качестве хранилища принципалов (principals) Kerberos и разберем, как настраивать клиентские рабочие станции. Kerberos — это сетевой протокол, который работает на основе билетов (tickets) и позволяет передавать данные через незащищённые сети для безопасной идентификации и аутентификации. Его дизайн преимущественно опирается на клиент-серверную модель и позволяет произвести взаимную аутентификацию субъекта и объекта доступа. Сообщения протокола устойчивы к прослушиванию и атакам повтора. Kerberos работает на основе криптографии с симметричным ключом и требует наличия доверенной третьей стороны, а так же может применяться с использованием криптографии с открытым ключом на некоторых этапах процесса аутентификации.
В этом руководстве в роли сервера Kerberos будем использовать ldap-srv. Но ничто не мешает Вам использовать для этого отдельную машину.
Где работаем: ldap-srv
Включите NTP и убедитесь, что сервер и клиенты синхронизированы! Мы не будем описывать, как настраивать NTP. Вы можете найти множество примеров в сети, если потребуется.
Теперь, когда наш сервер OpenLDAP настроен, мы можем приступить к конфигурированию сервера Kerberos. В этом разделе мы опишем, как развернуть центр распределения ключей Kerberos (KDC, Key Distribution Center) для области (realm) EXAMPLE.COM. Начнём с установки необходимых пакетов. В процессе будет так же установлено несколько пакетов-зависимостей. Пакет wamerican создаст файл /usr/share/dict/words, используемый kadmind. Вместо него можно использовать любой другой словарь или несколько словарей. Чтобы посмотреть их список, посмотрите содержимое метапакета wordlist.
# apt-get install krb5-kdc krb5-pkinit krb5-admin-server wamerican libsasl2-modules-gssapi-mit
В разделе 2.5 мы уже установили схему Kerberos для OpenLDAP сервера, но давайте лишний раз убедимся, что она на месте:
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn | grep -i kerberos dn: cn={12}kerberos,cn=schema,cn=config
Схема на месте. В ней содержится достаточно много объектов. Чтобы посмотреть их все, используйте следующий запрос:
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b cn={12}kerberos,cn=schema,cn=config | grep NAME | cut -d' ' -f5 | sort
Эта команда должна вернуть список объектов. Это важно, потому что если новых атрибутов Kerberos LDAP нет, то kdb5_ldap_util(8) выдаст следующую ошибку:
kdb5_ldap_util: Kerberos Container create FAILED: No such object while creating realm 'EXAMPLE.COM'
Итак, у нас есть набор схемы данных и объекты. Но есть ли у нас контейнер для принципалов Kerberos?
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b ou=services,dc=example,dc=com dn | grep -i kerberos
Нет, нету. Создадим его, а заодно — пользователя и группу, которые будут использоваться Kerberos для взаимодействия с сервером OpenLDAP. Используем для этой цели вот такой LDIF-файл 9.1-kerberos.ldif:
# Создадим контейнер для Kerberos
dn: cn=kerberos,ou=services,dc=example,dc=com
cn: kerberos
objectClass: top
objectClass: krbContainer
# Добавим группу krbadmin
dn: cn=krbadmin,ou=groups,dc=example,dc=com
objectClass: top
objectClass: posixGroup
cn: krbadmin
gidNumber: 800
description: Kerberos administrator's group.
# Добавим пользователя krbadmin
dn: cn=krbadmin,ou=users,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: posixAccount
objectClass: top
cn: krbadmin
givenName: Kerberos Administrator
mail: kerberos.admin@example.com
sn: krbadmin
uid: krbadmin
uidNumber: 800
gidNumber: 800
homeDirectory: /home/krbadmin
loginShell: /bin/false
displayname: Kerberos Administrator
Загрузим этот файл в базу данных нашего сервера каталогов:
$ ldapadd -xZZWD cn=admin,dc=example,dc=com -f ~/ldap/9.1-kerberos.ldif Enter LDAP Password: adding new entry "cn=kerberos,ou=services,dc=example,dc=com" adding new entry "cn=krbadmin,ou=groups,dc=example,dc=com" adding new entry "cn=krbadmin,ou=users,dc=example,dc=com"
Зададим пароль для пользователя krbadmin. Сохраните пароль в надежном месте (например, используя keepass или gpg).
$ ldappasswd -xZZWSD "cn=admin,dc=example,dc=com" "cn=krbadmin,ou=users,dc=example,dc=com"
Создадим конфигурационный файл 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
admin_server = 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
}
[dbmodules]
openldap_ldapconf = {
db_library = kldap
ldap_kerberos_container_dn = cn=kerberos,ou=services,dc=example,dc=com
ldap_kdc_dn = cn=krbadmin,ou=users,dc=example,dc=com
# этот объект должен иметь права на чтение контейнера области,
# контейнера принципала и поддеревьев области
ldap_kadmind_dn = cn=krbadmin,ou=users,dc=example,dc=com
# этот объект должен иметь права на чтение контейнера области,
# контейнера принципала и поддеревьев области
ldap_service_password_file = /etc/krb5.d/stash.keyfile
ldap_servers = ldapi:///
ldap_conns_per_server = 5
}
Теперь создадим список контроля доступа (ACL) администратора Kerberos. Не путайте этот ACL с ACL OpenLDAP. Это не одно и то же. Чуть ниже мы поработаем с ACL для OpenLDAP. Создадим файл /etc/krb5kdc/kadm5.acl с таким содержимым:
*/admin@EXAMPLE.COM *
Отредактируем /etc/krb5kdc/kdc.conf, конфигурационный файл службы аутентификации (AS, Authentication Service) и центра распределения ключей (KDC):
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
[realms]
EXAMPLE.COM = {
#master_key_type = aes256-cts
acl_file = /etc/krb5kdc/kadm5.acl
dict_file = /usr/share/dict/words
admin_keytab = /etc/krb5kdc/kadm5.keytab
supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal
}
В отдельном терминале включите просмотр журнала сервера OpenLDAP. Так мы сможем увидеть сообщения, генерируемые командой kdb5_ldap_util(8):
# tail -F /var/log/slapd.log
Создайте каталог-тайник для пароля. В файле /etc/krb5.conf он указан в переменной ldap_service_password_file
:
# mkdir /etc/krb5.d # chmod u=rwx,g=,o= /etc/krb5.d
Извлеките пароль пользователя cn=krbadmin,ou=users,dc=example,dc=com
, используя kdb5_ldap_util(8):
# kdb5_ldap_util -D "cn=admin,dc=example,dc=com" stashsrvpw -f /etc/krb5.d/stash.keyfile cn=krbadmin,ou=users,dc=example,dc=com
Вам будет предложено ввести мастер-пароль базы данных. Очень важно, чтобы Вы НЕ ЗАБЫЛИ этот пароль!
В основном терминале выполните следующую команду для добавления записей Kerberos в базу данных OpenLDAP:
# kdb5_ldap_util -D "cn=admin,dc=example,dc=com" create -subtrees "cn=kerberos,ou=services,dc=example,dc=com" -r EXAMPLE.COM -s
Вышеуказанная команда создаст несколько записей в cn=kerberos,ou=services,dc=example,dc=com
. Чтобы увидеть их, выполните запрос:
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b cn=kerberos,ou=services,dc=example,dc=com dn
Но может ли кто-нибудь кроме пользователя cn=admin
увидеть нашу информацию Kerberos? Это было-бы не очень мудро. Поэтому давайте взглянём на ACL нашего сервера OpenLDAP:
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b olcDatabase={1}mdb,cn=config olcAccess
Что нам надо сделать, так это дать права доступа на чтение/запись администратору Kerberos (cn=krbadmin,ou=users,dc=example,dc=com
) к поддереву cn=kerberos,ou=services,dc=example,dc=com
. Никакой другой пользователь не должен иметь доступа к этой информации (за исключением администратора каталога).
Для этого сформируем LDIF-файл 9.1-kerberos.acl.ldif:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to *
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by * break
olcAccess: {1}to attrs=userPassword,userPKCS12
by self write
by anonymous auth
olcAccess: {2}to attrs=shadowLastChange
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" manage
olcAccess: {4}to *
by dn.base="cn=nssproxy,ou=users,dc=example,dc=com" read
by self read
Загрузим данные в сервер каталогов:
# ldapmodify -QY EXTERNAL -H ldapi:/// -f 9.1-kerberos.acl.ldif
Убедитесь, что новые ACL работают. Суперпользователь и пользователь cn=admin,dc=example,dc=com
должны иметь доступ к поддереву cn=kerberos,ou=services,dc=example,dc=com
. Пользователь cn=nssproxy,ou=users,dc=example,dc=com
не сможет обнаружить само существование контейнера Kerberos, а cn=krbadmin,ou=users,dc=example,dc=com
должен не только видеть контейнер, но и иметь для него права на чтение/запись. Мы так же должны убедиться, что обычные пользователи всё ещё могут использовать сервер OpenLDAP для аутентификации и что они могут менять себе пароли.
Этот запрос возвращает поддерево cn=kerberos,ou=services,dc=example,dc=com
:
$ ldapsearch -xZZLLLWD cn=krbadmin,ou=users,dc=example,dc=com -b cn=kerberos,ou=services,dc=example,dc=com dn
Следующий запрос должен завершиться с ошибкой No such object (32)
:
$ ldapsearch -xZZLLLWD cn=nssproxy,ou=users,dc=example,dc=com -b cn=kerberos,ou=services,dc=example,dc=com dn
Теперь с клиентской машины убедимся, что пользователь, учётная запись которого хранится на сервере каталогов, может менять свой пароль:
Где работаем: ldap-client
$ su - test.user $ passwd (current) LDAP Password: Новый пароль : Повторите ввод нового пароля : passwd: password updated successfully
Где работаем: ldap-srv
Настало время настроить журналирование. Для начала добавим в конфигурацию rsyslog следующие строки (/etc/rsyslog.conf):
...
# Пишем журнал демона krb5-kdc в /var/log/krb5kdc.log:
if $programname == 'krb5kdc' then /var/log/krb5kdc.log
& ~
# Пишем журнал демона krb5-admin-server в /var/log/kadmind.log:
if $programname == 'kadmind' then /var/log/kadmind.log
& ~
Создадим файлы журналов и зададим для них права доступа:
# touch /var/log/{krb5kdc,kadmind}.log # chmod 0640 /var/log/{krb5kdc,kadmind}.log # chown syslog:adm /var/log/{krb5kdc,kadmind}.log
Настроим logrotate. Создадим два конфигурационных файла.
Файл /etc/logrotate.d/krb5kdc для демона krb5-kdc:
/var/log/krb5kdc.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
}
Файл /etc/logrotate.d/kadmind для демона krb5-admin-server:
/var/log/kadmind.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
}
Перезапустим демон rsyslog, чтобы конфигурация вступила в силу. Добавим демоны krb5-kdc и krb5-admin-server в автоматический запуск, затем запустим их:
# service rsyslog restart # update-rc.d krb5-kdc defaults # update-rc.d krb5-admin-server defaults # service krb5-kdc start # service krb5-admin-server start
Загляните в журнал /var/log/krb5kdc.log. Вы должны увидеть там подобную строку:
...
Dec 1 15:49:54 ldap-srv krb5kdc[1992]: commencing operation
Проверим, что наши демоны слушают необходимые порты. Порт 88 (krb5kdc), порты 464 и 749 (kadmind):
$ ss -tan | egrep ':88|:464|:749' LISTEN 0 2 *:749 *:* LISTEN 0 5 *:464 *:* LISTEN 0 5 *:88 *:*
Поздравляю, теперь у Вас есть рабочий сервер аутентификации (AS) и сервер распределения ключей (KDC) MIT Kerberos 5!
Что дальше? В первую очередь нам необходимо создать принципал для локального сервера. Затем — принципал для пользователя test.user. Сделаем это так (разобъём вывод на части, чтобы добавить комментарии):
# kadmin.local Authenticating as principal root/admin@EXAMPLE.COM with password.
Здесь мы создаём принципал машины для текущего сервера (на котором залогинены). Далее жирный шрифт — вводимый нами текст:
kadmin.local: addprinc -randkey host/ldap-srv.example.com@EXAMPLE.COM WARNING: no policy specified for host/ldap-srv.example.com@EXAMPLE.COM; defaulting to no policy Principal "host/ldap-srv.example.com@EXAMPLE.COM" created.
После создания принципала сервера мы можем добавить его в набор ключей Kerberos (/etc/krb5.keytab):
kadmin.local: ktadd host/ldap-srv.example.com@EXAMPLE.COM Entry for principal host/ldap-srv.example.com@EXAMPLE.COM with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/ldap-srv.example.com@EXAMPLE.COM with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/ldap-srv.example.com@EXAMPLE.COM with kvno 2, encryption type des3-cbc-sha1 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/ldap-srv.example.com@EXAMPLE.COM with kvno 2, encryption type arcfour-hmac added to keytab FILE:/etc/krb5.keytab. Entry for principal host/ldap-srv.example.com@EXAMPLE.COM with kvno 2, encryption type des-hmac-sha1 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/ldap-srv.example.com@EXAMPLE.COM with kvno 2, encryption type des-cbc-md5 added to keytab FILE:/etc/krb5.keytab.
Следующим шагом создадим принципал для моего пользователя pablo и зададим для него пароль:
kadmin.local: addprinc pablo@EXAMPLE.COM WARNING: no policy specified for pablo@EXAMPLE.COM; defaulting to no policy Enter password for principal "pablo@EXAMPLE.COM": Re-enter password for principal "pablo@EXAMPLE.COM": Principal "pablo@EXAMPLE.COM" created.
Теперь создадим принципал пользователя с правами администратора. Помните файл /etc/krb5kdc/kadm5.acl? Вот где он вступает в игру. С помощью этого файла пользователи с префиксом /admin имеют права администратора на доступ к области Kerberos. Это значит, что они могут создавать и удалять записи пользователей и политики доступа. Поэтому убедитесь, что Вы знаете этих пользователей и доверяете им!
kadmin.local: addprinc pablo/admin@EXAMPLE.COM WARNING: no policy specified for pablo/admin@EXAMPLE.COM; defaulting to no policy Enter password for principal "pablo/admin@EXAMPLE.COM": Re-enter password for principal "pablo/admin@EXAMPLE.COM": Principal "pablo/admin@EXAMPLE.COM" created.
Посмотрим список текущих принципалов в области:
kadmin.local: get_principals K/M@EXAMPLE.COM krbtgt/EXAMPLE.COM@EXAMPLE.COM kadmin/admin@EXAMPLE.COM kadmin/changepw@EXAMPLE.COM kadmin/history@EXAMPLE.COM kadmin/ldap-srv.example.com@EXAMPLE.COM host/ldap-srv.example.com@EXAMPLE.COM pablo@EXAMPLE.COM pablo/admin@EXAMPLE.COM
А эта команда выведет подробную информацию о принципале host/ldap-srv.example.com@EXAMPLE.COM:
kadmin.local: getprinc host/ldap-srv.example.com@EXAMPLE.COM Principal: host/ldap-srv.example.com@EXAMPLE.COM Expiration date: [never] Last password change: Сб. дек. 06 09:21:17 MSK 2014 Password expiration date: [none] Maximum ticket life: 1 day 00:00:00 Maximum renewable life: 0 days 00:00:00 Last modified: Сб. дек. 06 09:21:17 MSK 2014 (root/admin@EXAMPLE.COM) Last successful authentication: [never] Last failed authentication: [never] Failed password attempts: 0 Number of keys: 6 Key: vno 2, aes256-cts-hmac-sha1-96, no salt Key: vno 2, aes128-cts-hmac-sha1-96, no salt Key: vno 2, des3-cbc-sha1, no salt Key: vno 2, arcfour-hmac, no salt Key: vno 2, des-hmac-sha1, no salt Key: vno 2, des-cbc-md5, no salt MKey: vno 1 Attributes: Policy: [none] kadmin.local: exit
Обратите внимание, что был создан новый файл /etc/krb5.keytab. Вот почему мы запустили бинарник kadmin.local от имени суперпользователя. Иначе мы получили бы следующую ошибку:
$ kadmin.local Authenticating as principal pablo/admin@EXAMPLE.COM with password. kadmin.local: Error reading password from stash: Permission denied while initializing kadmin.local interface
Только суперпользователь имеет доступ на чтение к файлу-тайнику (/etc/krb5.d/stash.keyfile).
Давайте посмотрим, что записано в /etc/krb5.keytab:
# klist -ek /etc/krb5.keytab Keytab name: FILE:/etc/krb5.keytab KVNO Principal ---- --------------------------------------------------------------- 2 host/ldap-srv.example.com@EXAMPLE.COM (aes256-cts-hmac-sha1-96) 2 host/ldap-srv.example.com@EXAMPLE.COM (aes128-cts-hmac-sha1-96) 2 host/ldap-srv.example.com@EXAMPLE.COM (des3-cbc-sha1) 2 host/ldap-srv.example.com@EXAMPLE.COM (arcfour-hmac) 2 host/ldap-srv.example.com@EXAMPLE.COM (des-hmac-sha1) 2 host/ldap-srv.example.com@EXAMPLE.COM (des-cbc-md5)
Как мы можем видеть, это список ключей шифрования машины ldap-srv. Неудивительно, что доступ предоставлен только суперпользователю!
У нас осталась ещё одна вещь на сервере, которую надо поправить. Это ошибка
mdb_equality_candidates: (krbPrincipalName) not indexedв журнале /var/log/slapd.log. Создадим LDIF-файл 9.1-kerberos.indexes.ldif, который внесёт поправки в индексы:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: krbPrincipalName eq
-
add: olcDbIndex
olcDbIndex: ou eq
Добавим эти индексы в сервер каталогов:
# ldapadd -QY EXTERNAL -H ldapi:/// -f 9.1-kerberos.indexes.ldif
Отлично! Теперь у нас есть настроенный KDC!
С действующим KDC мы можем заставить клиентские машины и сервисы использовать его. Обозначим основные цели по настройке клиентов, чтобы интегрировать их в инфраструктуру Kerberos:
Где работаем: ldap-client
ВНИМАНИЕ! Клиенты Kerberos должны иметь возможность подключения к TCP портам KDC с номерами 88 и 749!
Установим необходимые пакеты:
# apt-get install krb5-user libpam-krb5 libsasl2-modules-gssapi-mit
Во время установки в качестве области Kerberos можете задать EXAMPLE.COM, а в качестве серверов, обслуживающих область, ldap-srv.example.com.
Отредактируйте конфигурацию клиента в файле /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
admin_server = ldap-srv.example.com
default_domain = example.com
}
[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
}
Создайте новый принципал машины для этого хоста. Мы запускаем команду kadmin от имени суперпользователя, чтобы можно было записать результирующий файл /etc/krb5.keytab. Иначе мы получим не очень понятную ошибку No such file or directory while adding key to keytab
. Мы так же должны использовать модификатор -p
, чтобы дать понять команде kadmin, от имени какого принципала мы хотим подключиться. Если мы его не зададим, то получим ошибку Client not found in Kerberos database while initializing kadmin interface
, потому что не создавали принципал root/admin@EXAMPLE.COM. Не создавайте этот принципал! Мы хотим знать, кто подключается с правами администратора (пользователи с префиксом /admin). Если создадим — не сможем различать администраторов между собой.
# kadmin -p pablo/admin@EXAMPLE.COM Authenticating as principal pablo/admin@EXAMPLE.COM with password. Password for pablo/admin@EXAMPLE.COM: kadmin: addprinc -randkey host/ldap-client.example.com@EXAMPLE.COM kadmin: ktadd host/ldap-client.example.com@EXAMPLE.COM kadmin: exit
Эта команда создала файл /etc/krb5.keytab.
Теперь мы можем отредактировать /etc/ssh/sshd_config и включить аутентификацию Kerberos. Не забудьте добавить test.group в директиву AllowGroups
. Иначе мы не сможем протестировать конфигурацию и увидим ошибку
User test.user from ldap-srv.example.com not allowed because none of user's groups are listed in AllowGroupsв файле /var/log/auth.log.
AddressFamily inet
Port 22
Protocol 2
AllowGroups sysadmin test.group
SyslogFacility AUTHPRIV
LoginGraceTime 30s
PermitRootLogin no
StrictModes yes
IgnoreRhosts yes
PermitEmptyPasswords no
PasswordAuthentication yes
AllowTcpForwarding no
X11Forwarding yes
PrintLastLog yes
ClientAliveInterval 120
ClientAliveCountMax 2
Banner /etc/issue
UsePAM yes
ChallengeResponseAuthentication yes
KerberosAuthentication yes
KerberosOrLocalPasswd yes
KerberosTicketCleanup yes
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
Перезапустим демон:
# service ssh restart
Запустите на клиентской рабочей станции отображение файла журнала:
# tail -F /var/log/auth.log
А пока вернёмся на сервер.
Где работаем: ldap-srv
Создадим принципал пользователя test.user:
$ kadmin -p pablo/admin@EXAMPLE.COM Authenticating as principal pablo/admin@EXAMPLE.COM with password. Password for pablo/admin@EXAMPLE.COM: kadmin: addprinc test.user@EXAMPLE.COM WARNING: no policy specified for test.user@EXAMPLE.COM; defaulting to no policy Enter password for principal "test.user@EXAMPLE.COM": Re-enter password for principal "test.user@EXAMPLE.COM": Principal "test.user@EXAMPLE.COM" created. kadmin: exit
Возьмём билет Kerberos у test.user и прикинемся этим пользователем. Сначалы мы уничтожим свои собственные билеты (если они есть), используя kdestroy, затем возьмём билет test.user с помощью kinit, а в итоге проверим, что он у нас есть с помощью klist:
$ kdestroy $ kinit -p test.user@EXAMPLE.COM Password for test.user@EXAMPLE.COM: $ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: test.user@EXAMPLE.COM Valid starting Expires Service principal 06.12.2014 14:58:06 07.12.2014 14:58:06 krbtgt/EXAMPLE.COM@EXAMPLE.COM
Теперь попробуем авторизоваться на клиенте без пароля, используя этот билет:
$ ssh test.user@ldap-client.example.com
Где работаем: ldap-client
В открытом нами журнале на клиенте /var/log/auth.log мы должны увидеть что-то подобное:
Dec 6 15:00:55 ldap-client sshd[2170]: Authorized to test.user, krb5 principal test.user@EXAMPLE.COM (krb5_kuserok) Dec 6 15:00:55 ldap-client sshd[2170]: Accepted gssapi-with-mic for test.user from 192.168.122.150 port 45995 ssh2 Dec 6 15:00:55 ldap-client sshd[2170]: pam_unix(sshd:session): session opened for user test.user by (uid=0)
Успех! Переходим к следующей цели.
Где работаем: ldap-srv
Для настройки аутентификаци SASL GSSAPI мы должны изменить конфигурацию сервера OpenLDAP таким образом, чтобы он знал о существовании нашей области Kerberos. После этого мы можем настроить клиентов.
Подключимся к KDC и создадим новый принципал. Мы по-прежнему запускаем kadmin от имени суперпользователя, потому что хотим создать новый набор ключей в файле /etc/ldap/krb5.keytab, чтобы наш демон slapd имел свой набор.
# kadmin -p pablo/admin@EXAMPLE.COM kadmin: addprinc -randkey ldap/ldap-srv.example.com@EXAMPLE.COM kadmin: ktadd -k /etc/ldap/krb5.keytab ldap/ldap-srv.example.com@EXAMPLE.COM
Поменяем права доступа на этот файл, чтобы демон slapd смог его читать:
# chown root:openldap /etc/ldap/krb5.keytab # chmod 640 /etc/ldap/krb5.keytab
Создадим LDIF-файл 9.2.2-sasl.ldif с директивами SASL:
dn: cn=config
changetype: modify
add: olcSaslSecProps
olcSaslSecProps: noanonymous,noplain
-
add: olcSaslHost
olcSaslHost: ldap-srv.example.com
-
add: olcSaslRealm
olcSaslRealm: EXAMPLE.COM
И загрузим его в базу данных службы каталогов:
# ldapadd -QY EXTERNAL -H ldapi:/// -f 9.2.2-sasl.ldif
На самом деле нам не нужно играться с olcSaslSecProps
, но я оставил его, потому что пытался добавить ключевое слово noactive
. Если при этом попытаться выполнить поиск, то получим следующую ошибку:
# ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=config -s base | grep -i sasl SASL/EXTERNAL authentication started ldap_sasl_interactive_bind_s: Authentication method not supported (7) additional info: SASL(-4): no mechanism available: security flags do not match required
В данный момент такое поведение — не совсем то, что нам нужно. Может быть позже. Сейчас проверим, загрузил ли демон slapd нашу конфигурацию SASL:
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b cn=config -s base | grep -i sasl olcSaslSecProps: noanonymous,noplain olcSaslHost: ldap-srv.example.com olcSaslRealm: EXAMPLE.COM
Хорошо! Теперь нам нужно добавить параметр 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
Для того, чтобы изменения вступили в силу, нам нужно перезапустить демон slapd:
# service slapd restart
Демон slapd снова запущен — мы можем переходить к настройке клиента.
Где работаем: ldap-client
Зайдём на клиентскую рабочую станцию по ssh от имени пользователя pablo:
$ ssh pablo/admin@ldap-client.example.com
Или даже так:
$ ssh pablo/admin@EXAMPLE.COM@ldap-client.example.com
Получим билет от KDC:
$ kdestroy $ kinit -p pablo/admin $ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: pablo@EXAMPLE.COM Valid starting Expires Service principal 07.12.2014 14:16:24 08.12.2014 14:16:24 krbtgt/EXAMPLE.COM@EXAMPLE.COM
Все настройки для доступа на сервер у нас уже внесены в файл /etc/ldap/ldap.conf. Проверим, можем ли мы сделать запрос к LDAP-серверу:
$ ldapwhoami ldap_sasl_interactive_bind_s: No such object (32)
Такая ошибка может показаться странной. Нужно указать механизм GSSAPI для доступа с помощью SASL. Такой вариант должен сработать:
$ ldapwhoami -Y GSSAPI SASL/GSSAPI authentication started SASL username: pablo@EXAMPLE.COM SASL SSF: 56 SASL data security layer installed. dn:uid=pablo,cn=example.com,cn=gssapi,cn=auth
Супер! Добавленный модификатор мы тоже можем внести в /etc/ldap/ldap.conf, чтобы его не приходилось вбивать вручную каждый раз:
BASE dc=example,dc=com
URI ldap://ldap-srv.example.com
TLS_CACERT /etc/ssl/certs/rootca.crt
TLS_CRLFILE /etc/ssl/rootca.crl
TLS_REQCERT allow
TIMELIMIT 15
TIMEOUT 20
SASL_MECH GSSAPI
Вы заметили, что OpenLDAP преобразовал имя принципала Kerberos в формат DN (Distinguished Name)? У нас был принципал с таким именем:
pablo@EXAMPLE.COM
который был преобразован slapd в это:
dn:uid=pablo,cn=example.com,cn=gssapi,cn=auth
Это значит нам нужно вернуться на сервер и задать новые правила доступа (ACL), если мы хотим, чтобы наш Kerberos-принципал AutoFS мог читать информацию для автоматического монтирования.
Вздохните поглубже, далее от Вас потребуется внимательность и терпение. ;)
Где работаем: ldap-srv
Вернёмся на наш сервер OpenLDAP и отредактируем правила доступа ACL. Но прежде чем мы продолжим, всегда неплохо проверить текущую конфигурацию. Теперь мы можем формировать запросы с использованием GSSAPI (без модификатора -x
):
$ ldapsearch -xZZLLLWD cn=admin,dc=example,dc=com -b cn=config olcAccess
Запрос вернёт нам четыре DN с атрибутами olcAccess
:
dn: olcDatabase={-1}frontend,cn=config dn: olcDatabase={0}config,cn=config dn: olcDatabase={1}mdb,cn=config dn: olcDatabase={2}monitor,cn=config
Мы должны изменить ACL для olcDatabase={0}config
и olcDatabase={1}mdb
. Приготовьтесь, ACL станут немного сложней. Создадим LDIF-файл 9.2.3-gssapi.acl.ldif и запишем в него:
dn: olcDatabase={0}config,cn=config
changetype: modify
delete: olcAccess
-
add: olcAccess
olcAccess: {0}to *
by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcAccess
-
add: olcAccess
olcAccess: {0}to *
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by * break
-
add: olcAccess
# Позволять принципалам Kerberos с префиксом /admin
# менять любые пароли.
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
-
add: olcAccess
# Позволять принципалам Kerberos с префиксом /admin
# записывать метку времени об изменении пароля.
olcAccess: {2}to attrs=shadowLastChange
by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
by self write
-
add: olcAccess
# Позволять принципалам Kerberos с префиксом /admin просматривать
# контейнер с настройками Kerberos, но не менять его содержимое.
# Это правило заставит пользоваться инструментами Kerberos при администрировании области.
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
-
# Позволять принципалам Kerberos с именем autofsclient/*
# видеть содержимое карт автоматического монтирования.
add: olcAccess
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
-
add: olcAccess
# Позволять принципалам Kerberos с префиксом /admin доступ на запись к остальному каталогу.
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
Ух! Вы поняли все производимые изменения? Напоминаю, что cn=admin,dc=example,dc=com
(RootDN
) всегда имеет полный доступ к olcDatabase={1}mdb,cn=config
. То же касается и olcDatabase={0}config
. Поэтому cn=admin
явно не упомянут в ACL. Не волнуйтесь и внимательно прочитайте правила, одно за другим. У Вас всё получится ;)
Изменения масштабные, поэтому сделаем резервную копию на случай, если всё пойдёт наперекосяк:
# tar zcvf ~/ldap/slapd.d.backup.tar.gz /etc/ldap/slapd.d
Загрузим новые ACL в конфигурацию OpenLDAP:
# ldapmodify -QY EXTERNAL -H ldapi:/// -f 9.2.3-gssapi.acl.ldif modifying entry "olcDatabase={-1}frontend,cn=config" modifying entry "olcDatabase={0}config,cn=config" modifying entry "olcDatabase={1}mdb,cn=config" modifying entry "olcDatabase={2}monitor,cn=config"
Проверим, что cn=admin,dc=example,dc=com
имеет права доступа к базе данных сервера OpenLDAP. Следующий запрос должен вернуть dn: cn=config
:
$ ldapsearch -xLLLZWD cn=admin,dc=example,dc=com -b cn=config -s base dn
Суперпользователь с UID и GID равными нулю имеет аналогичный уровень доступа:
# ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config -s base dn
Такой же уровень доступа имеют принципалы с префиксом /admin. Получим билет принципала и выполним запрос от его имени с помощью SASL:
$ kdestroy $ kinit -p pablo/admin@EXAMPLE.COM $ ldapsearch -ZZLLLQb cn=config -s base dn dn: cn=config
Проверьте, работают ли права для пользователя cn=nssproxy
. Следующая команда должна вернуть все DN из DIT кроме записей, в которых присутствует cn=kerberos
:
$ ldapsearch -xZZLLLWD cn=nssproxy,ou=users,dc=example,dc=com -b dc=example,dc=com dn
А могут ли обычные пользователи менять свой пароль? Проверим это с клиентской рабочей станции.
Где работаем: ldap-client
Процесс обновления пароля изменился. Если мы попытаемся запустить команду passwd от имени пользователя, которого нет в локальном файле /etc/passwd, пароль будет изменен с использованием механизмов Kerberos:
$ su - test.user $ passwd Current Kerberos password: Новый пароль : Повторите ввод нового пароля : passwd: password updated successfully
Для спокойствия убедимся, что пароль поменялся в нужном месте. Сверим текущее время и время изменения пароля в принципале test.user@EXAMPLE.COM. Они должны различаться незначительно.
Время изменения пароля записывается в принципалах в атрибуте krbLastPwdChange
. Запись содержит время по Гринвичу (GMT). Поэтому для начала посмотрим текущее время GMT на клиентской машине:
$ date -u Сб. дек. 20 17:19:24 UTC 2014
Теперь получим билет администратора, чтобы заглянуть в атрибуты принципала test.user@EXAMPLE.COM.
$ kdestroy $ kinit -p pablo/admin@EXAMPLE.COM
И наконец, отправим вот такой длиннющий запрос (ответ сервера — только последняя строчка) к серверу каталогов по атрибуту krbLastPwdChange
:
$ ldapsearch -ZZLLLQb krbPrincipalName=test.user@EXAMPLE.COM,cn=EXAMPLE.COM,cn=kerberos,ou=services,dc=example,dc=com -s base krbLastPwdChange dn: krbPrincipalName=test.user@EXAMPLE.COM,cn=EXAMPLE.COM,cn=kerberos,ou=servi ces,dc=example,dc=com krbLastPwdChange: 20141220171526Z
Как мы можем видеть, пароль принципала test.user@EXAMPLE.COM был изменён четыре минуты назад (буква Z
указывает на время по Гринвичу). Замечательно!
Теперь мы можем настроить клиентскую машину для использования механизма GSSAPI в работе с картами автомонтирования AutoFS. На этом этапе Вы должны быть авторизованы на клиентской машине от имени пользователя, домашний каталог которого не лежит на сервере NFS! Если это не так, авторизуйтесь повторно.
Перед тем как продолжить, проверьте, отмонтированы ли все каталоги NFS:
$ df -h
Проверьте общесистемную конфигурацию AutoFS в файле /etc/defaults/autofs:
TIMEOUT=300
BROWSE_MODE="no"
MOUNT_NFS_DEFAULT_PROTOCOL=4
LOGGING="debug"
OPTIONS="-d -v"
LDAP_URI="ldap://ldap-srv.example.com"
SEARCH_BASE="ou=autofs,ou=services,dc=example,dc=com"
MAP_OBJECT_CLASS="automountMap"
ENTRY_OBJECT_CLASS="automount"
MAP_ATTRIBUTE="ou"
ENTRY_ATTRIBUTE="cn"
VALUE_ATTRIBUTE="automountInformation"
USE_MISC_DEVICE="yes"
Заметьте, что атрибут LOGGING
установлен в значение debug
, а OPTIONS
— в -d -v
. Это для того, чтобы помочь нам с поиском проблем, если они возникнут. В рабочей конфигурации этот параметр должен быть изменён. Мы вернёмся к этому через пару минут.
Далее нам нужно создать принципал Kerberos для демона autofs. Мы так же должны добавить ключи этого нового принципала в набор ключей нашего клиента.
# kadmin -p pablo/admin@EXAMPLE.COM kadmin: addprinc -randkey autofsclient/ldap-client.example.com@EXAMPLE.COM kadmin: ktadd autofsclient/ldap-client.example.com@EXAMPLE.COM
Как мы можем видеть, ключи autofsclient теперь являются частью набора ключей клиента:
# klist -ek /etc/krb5.keytab Keytab name: FILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 host/ldap-client.example.com@EXAMPLE.COM (aes256-cts-hmac-sha1-96) 2 host/ldap-client.example.com@EXAMPLE.COM (aes128-cts-hmac-sha1-96) 2 host/ldap-client.example.com@EXAMPLE.COM (des3-cbc-sha1) 2 host/ldap-client.example.com@EXAMPLE.COM (arcfour-hmac) 2 host/ldap-client.example.com@EXAMPLE.COM (des-hmac-sha1) 2 host/ldap-client.example.com@EXAMPLE.COM (des-cbc-md5) 2 autofsclient/ldap-client.example.com@EXAMPLE.COM (aes256-cts-hmac-sha1-96) 2 autofsclient/ldap-client.example.com@EXAMPLE.COM (aes128-cts-hmac-sha1-96) 2 autofsclient/ldap-client.example.com@EXAMPLE.COM (des3-cbc-sha1) 2 autofsclient/ldap-client.example.com@EXAMPLE.COM (arcfour-hmac) 2 autofsclient/ldap-client.example.com@EXAMPLE.COM (des-hmac-sha1) 2 autofsclient/ldap-client.example.com@EXAMPLE.COM (des-cbc-md5)
Теперь мы можем изменить порядок аутентификации autofs в файле /etc/autofs_ldap_auth.conf, используя механизм GSSAPI и новый принципал:
<?xml version="1.0" ?>
<autofs_ldap_sasl_conf
usetls="yes"
tlsrequired="yes"
authrequired="yes"
authtype="GSSAPI"
clientprinc="autofsclient/ldap-client.example.com@EXAMPLE.COM"
/>
<!-- EOF -->
Перезапустим демон autofs:
# service autofs restart
Проверим журнал /var/log/syslog, всё ли работает?
... Dec 20 22:12:27 ldap-client automount[943]: Starting automounter version 5.0.7, master map auto.master Dec 20 22:12:27 ldap-client automount[943]: using kernel protocol version 5.02 Dec 20 22:12:27 ldap-client automount[943]: lookup_nss_read_master: reading master ldap auto.master Dec 20 22:12:28 ldap-client kernel: [ 4.116950] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX Dec 20 22:12:28 ldap-client kernel: [ 4.118253] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready Dec 20 22:12:28 ldap-client nslcd[972]: version 0.8.13 starting Dec 20 22:12:28 ldap-client nslcd[972]: accepting connections Dec 20 22:12:28 ldap-client automount[943]: master_do_mount: mounting /nfs Dec 20 22:12:28 ldap-client automount[943]: automount_path_to_fifo: fifo name /var/run/autofs.fifo-nfs Dec 20 22:12:28 ldap-client automount[943]: lookup_nss_read_map: reading map ldap ldap:ou=auto.nfs,ou=autofs,ou=services,dc=example,dc=com Dec 20 22:12:28 ldap-client automount[943]: mounted indirect on /nfs with timeout 300, freq 75 seconds Dec 20 22:12:28 ldap-client automount[943]: st_ready: st_ready(): state = 0 path /nfs ...
Отлично! Попробуем перейти в каталог /nfs/home:
$ cd /nfs/home $ pwd /nfs/home
Супер! Изменим атрибуты LOGGING
и OPTIONS
в файле /etc/defaults/autofs на повседневные:
...
LOGGING="none"
# OPTIONS="-d -v"
...
И перезапустим демон autofs:
# service autofs restart
Вот и всё! На этом фокусы с Kerberos закончились. :)
В следующем разделе мы опишем, как создавать резервную копию сервера OpenLDAP и восстанавливаться из неё. Затем мы настроим репликацию. Принимая во внимание зависимость наших клиентов от сервера OpenLDAP, нам надо обеспечить некоторый уровень отказоустойчивости.
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |