...
Введение
Related links
Основные понятия
- Key Distribution Center (KDC) - хранилище информации о паролях пользователей.
- Admin server - основной сервер kerberos. У нас KDC и admin server находятся на одной машине.
- Realm - "среда", в которой производится аутентификация.
- Principal - пользователь или сервис, участвующий в механизме аутентификации. Мы пока рассматриваем только пользователей.
Стенды
...
Перед настройкой
Центральной частью схемы аутентификации Kerberos является третья доверенная сторона - Key Distribution Center (KDC), которая является централизованным хранилищем информации о пользователях. Перед разворачиванием Kerberos, должен быть выбран сервер, который будет выполнять роль KDC. Физическая и сетевая безопасность критичны для этого сервера, так как его компрометация ведет к компрометации всего realm.
Выбор хорошего имени для realm так же важен. По правилам, имя realm это доменное имя сайта в верхнем регистре. Например, для сайта или доменной зоны example.com рекомендуется выбрать EXAMPLE.COM в качестве имени realm.
Все серверы и клиенты, которые входят в realm Kerberos должны иметь возможность взаимодействовать между собой. Время между устройствами в realm должно быть синхронизовано. Далее описано как этого добиться.
Host Names
Каждый сервер внутри Kerberos realm должен иметь Fully Qualified Domain Name (FQDN).
Kerberos так же ожидает, что FQDN сервера является reverse-resolvable. Если выяснение доменного имени по IP недоступно, то установите значение переменной rdns в значение false на клиентах в файле krb5.conf.
Note |
---|
Active Directory сильно зависит от DNS, поэтому весьма вероятно что ваш Active Directory Domain Controller уже имеет роль DNS. В этом случае убедитесь в том, что каждый сервер имеет свое FQDN перед выполнением тестов, описанных ниже в этом разделе. |
Если сервер уже имеет назначенное FQDN, проверьте корректность обнаружения forward и reverse выполнив на клиенте следующие команды:
Code Block |
---|
|
$ nslookup server.example.com
$ nslookup <server ip address>
|
Note |
---|
Если вы используете Astra Linux (или другой дистрибутив), то для установки программы nslookup, вам необходимо установить пакет dnsutils. Вы можете воспользоваться Synaptic Package Manager или выполнить из командной строки $ apt-get install dnsutils |
Вывод первой команды должен содержать IP адрес сервера. Вывод второй команды должен содержать FQDN сервера.
Если у сервера нет назначенного FQDN и сервис DNS не доступен, то вы можете отредактировать локальные файлы hosts (обычно они находятся в /etc) на сервере добавив туда следующую строку:
127.0.0.1 server.aktiv-test.ru localhost server
А на каждом клиенте добавить строку
<IP-address> server.aktiv-test.ru <IP-address> server
Где IP-address - это IP адрес сервера. В нашем примере это будет 10.0.0.1.
После этого проверьте работу локальных DNS имен используя команду nslookup как показано выше.
Наличие соединения
Для проверки соединения между хостами, выполните ping для каждого хоста по его FQDN:
Code Block |
---|
|
$ ping server.aktiv-test.ru
PING server.aktiv-test.ru (10.0.0.1) 56(84) bytes of data.
64 bytes from server.aktiv-test.ru (10.0.0.1): icmp_seq=1 ttl=128 time=0.176ms |
Вывод команды ping показывает успешное определение IP адреса по FQDN, и простой ответ от сервера. Ответ от сервера является подтверждением того, что между хостом и сервером есть соединение.
Проблемы при работе ping указывают на проблемы настройки сервера или клиента.
Синхронизация времени
Протокол Kerberos требует синхронизации времени сервера и клиента: если системные часы клиентов и сервера расходятся, то аутентификация не будет выполнена. Простейший способ синхронизировать системные часы - использование Network Time Protocol (NTP) сервера. Некоторый линуксы, например, Astra Linux по-умолчанию синхронизирует время с российскими NTP-серверами. Для настройки собственного NTP-сервера смотрите документацию на ваш дистрибутив (например, UbuntuTime для Ubuntu).
Note |
---|
Active Directory Domain Controllers обычно так же являются NTP серверами.
|
Брандмауэры
Так же как и все остальные сетевые службы, Kerberos должен иметь возможность проходить через любые брандмауэры между хостами. Инструкция Kerberos System Administration Manual имеет детальное описание портов, которые необходимо открыть при настройке брандмауэров.
Проверка модели устройства
- Подключите USB-токен к компьютеру.
- Для определения названия модели USB-токена откройте Терминал и введите команду:
$ lsusb
В результате в окне Терминала отобразится название модели USB-токена:
Image Added
Убедитесь, что используете: Aktiv Rutoken ECP
Стенд
- две виртуальные машины с Ubuntu
...
|
---|
Важно: время на клиенте и сервере должно быть синхронизировано. Невыполнение этого требования может привести к возникновению проблем. |
<username> = testuser
<realm> = AKTIV-TEST
<server> = aktiv-test.
...
Сервер
- Установлены
krb5-kdc, krb5-admin-server, krb5-pkinit
Ubuntu
<username> = testuser
<realm> = AKTIV-TEST
- Kerberos realm:
AKTIV-TEST
, доменное имя <server> = aktiv-test.ru
Сервер
- (прописано в /etc/hosts на клиенте)
Примечание: доменное имя стоит делать минимум второго уровня для избежания ошибок - Пользователи:
testuser@AKTIV-TEST
Клиент
- Установлены
krb5-user, libpam-krb5, libpam-ccreds, auth-client-config, krb5-pkinit, opensc, libengine-pkcs11-openssl
- default
- Установлены
krb5-kdc, krb5-admin-server, krb5-pkinit
- Kerberos realm:
AKTIV-TEST
, доменное имя aktiv-test.ru
(прописано - серверы (kdc, admin) указаны по IP-адресу (лучше указать их в /etc/hosts на клиенте)
Примечание: доменное имя стоит делать минимум второго уровня для избежания ошибок - Пользователи:
testuser@AKTIV-TEST
Клиент
- Установлены
krb5-user, krb5-config, krb5-pkinit
- default realm:
AKTIV-TEST
- сервера (kdc, admin) указаны по IP-адресу (лучше указать их в /etc/hosts)
Astra Linux 1.3 Смоленск
<username> = test1
<realm> = RUSBITECH.RU
<server> = server.rusbitech.ru
Клиент
Установлены стандартные пакеты для работы с токенами (openct, opensc
)
Сервер и клиент
- Kerberos realm: RUSBITECH.RU, доменное имя
server.rusbitech.ru
(прописано в /etc/hosts на клиенте) - Пользователи:
test1@RUSBITECH.RU
Добавочно к предустановленным пакетам ald/kerberos установлен krb5-pkinit (krb5-pkinit_1.10.1+dfsg-3_amd64.deb, Debian Wheezy):
Code Block |
---|
|
$ dpkg -i --force-depends krb5-pkinit_1.10.1+dfsg-3_amd64.deb |
Общий порядок действий
1. /* только для Ubuntu */ Установить пакеты и создать новый realm
Для Astra Linux достаточно только установить krb5-pkinit
Первичная настройка
Сервер
Установить пакеты и создать новый realm
Code Block |
---|
|
$ sudo apt-get install krb5-kdc krb5-admin-server krb5-pkinit
# В диалогах указать:
# realm = AKTIV-TEST
# домен = aktiv-test.ru
$ sudo krb5_newrealm
# ввести пароль |
В файле конфигурации сервера /etc/krb5.conf указать
Code Block |
---|
language | bash |
---|
title | /etc/krb5.conf |
---|
|
[domain_realm]
.aktiv-test.ru = AKTIV-TEST
aktiv-test.ru = AKTIV-TEST |
Создать на сервере нового пользователя
...
Code Block |
---|
|
$ sudo apt-get install krb5-kdc krb5-admin-server krb5-pkinitkadmin.local
# Вusername диалогах= указать:testuser
# realmpassword = AKTIV-TEST
# домен = aktiv-test.ru
$ sudo krb5_newrealm
# ввести пароль |
...
test
kadmin.local:$ addprinc <username>
# ...
kadmin.local:$ quit |
На сервере проверить, что для этого пользователя можно получить тикет
Code Block |
---|
|
$ kinit <username>
...
$ klist
...
$ kdestroy |
Клиент
Установим pkcs11 модуль rtpkcs11ecp.so
Установим необходимые пакеты и сконфигурируем kerberos
Code Block |
---|
|
$ sudo apt-get install krb5-user libpam-krb5 libpam-ccreds auth-client-config krb5-pkinit
# В диалогах указать:
# realm = AKTIV-TESTopensc libengine-pkcs11-openssl
# доменВ = aktiv-test.ru
$ sudo dpkg-reconfigure krb5-config |
Добавить секцию[domain_realm]
в /etc/krb5.conf
на клиенте и сервере
Code Block |
---|
|
[domain_realm]
.aktiv-test.ruдиалогах указать:
# realm = AKTIV-TEST
# домен = aktiv-test.ru = AKTIV-TEST |
...
$ sudo dpkg-reconfigure krb5-config |
В файле конфигурации клиента /etc/krb5.conf указать
Code Block |
---|
|
$ sudo kadmin.local
# username = testuser
# password = test
kadmin.local:$ addprinc <username>
# ...
kadmin.local:$ quit |
...
|
[domain_realm]
...
.aktiv-test.ru = AKTIV-TEST
aktiv-test.ru = AKTIV-TEST |
Проверим, что пользователь может аутентифицироваться по паролю
Code Block |
---|
|
$ kinit <username>
...
$ klist
...
$ kdestroy |
...
Настройка аутентификации по Рутокену
Сервер
Создадим ключ и самоподписанный сертификат УЦ
Code Block |
---|
|
$ kinit <username>@<realm>
...
$ klist
...
$ kdestroy |
6. Настроить работу с сертификатами и токеном.
Сервер
Создать ключ и сертификат CA:
openssl genrsa -out cakey.pem 2048
$ openssl req -key cakey.pem -new -x509 -out cacert.pem |
Создадим файл pkinit_extensions со следующим содержимым
Code Block |
---|
|
$ openssl genrsa -out cakey.pem 2048
$ openssl req -key cakey.pem -new -x509 -out cacert.pem |
Создать ключ и сертификат KDC
Code Block |
---|
|
$ openssl genrsa -out kdckey.pem 2048
# создание запроса
$ openssl req -new -out kdc.req -key kdckey.pem
# подпись запроса
$ REALM=<realm>; export REALM
$ CLIENT=<server>; export CLIENT
# содержимое файла pkinit_extensions см ниже
$ openssl x509 -req -in kdc.req -CAkey cakey.pem -CA cacert.pem -out kdc.pem -extfile pkinit_extensions -extensions kdc_cert -CAcreateserial |
Перенести следующие файлы в /var/lib/krb5kdc/:
kdc.pem
kdckey.pem
cacert.pem
| title | pkinit_extensions |
---|
collapse | true |
---|
|
[ kdc_cert ]
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
#Pkinit EKU
extendedKeyUsage = 1.3.6.1.5.2.3.5
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# Copy subject details
issuerAltName=issuer:copy
# Add id-pkinit-san (pkinit subjectAlternativeName)
subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name
[kdc_princ_name]
realm = EXP:0, GeneralString:${ENV::REALM}
principal_name = EXP:1, SEQUENCE:kdc_principal_seq
[kdc_principal_seq]
name_type = EXP:0, INTEGER:1
name_string = EXP:1, SEQUENCE:kdc_principals
[kdc_principals]
princ1 = GeneralString:krbtgt
princ2 = GeneralString:${ENV::REALM}
[ client_cert ]
# These extensions are added when 'ca' signs a request.
basicConstraints=CA:FALSE
keyUsage = |
Code Block |
---|
language | bash |
---|
title | pkinit_extensions |
---|
collapse | true |
---|
|
[ kdc_cert ]
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
#Pkinit EKU
extendedKeyUsage = 1.3.6.1.5.2.3.5
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# Copy subject details
issuerAltName=issuer:copy
# Add id-pkinit-san (pkinit subjectAlternativeName)4
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name
# Copy subject details
issuerAltName=issuer:copy
[kdc_princ_name]
realm = EXP:0, GeneralString:${ENV::REALM}
principal_name = EXP:1, SEQUENCE:kdc_principal_seq
[kdc_principal_seq]
name_type = EXP:0, INTEGER:1
name_string = EXP:1, SEQUENCE:kdc_principals
[kdc_principals]
princ1 = GeneralString:krbtgt
princ2 = GeneralString:${ENV::REALM}
[ client_cert ]
# These extensions are added when 'ca' signs a request.
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage = 1.3.6.1.5.2.3.4
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:princ_name
# Copy subject details
issuerAltName=issuer:copy
[princ_name]
realm = EXP:0, GeneralString:${ENV::REALM}
principal_name = EXP:1, SEQUENCE:principal_seq
[principal_seq]
name_type = EXP:0, INTEGER:1
name_string = EXP:1, SEQUENCE:principals
[principals]
princ1 = GeneralString:${ENV::CLIENT} |
Включить preauth на сервере
Astra Linux: надо просто переписать секцию kdcdefaults из примера ниже:
Создадим ключ и сертификат KDC
Code Block |
---|
|
$ openssl genrsa -out kdckey.pem 2048
# создание запроса
$ openssl req -new -out kdc.req -key kdckey.pem
# подпись запроса
$ REALM=<realm>; export REALM
$ CLIENT=<server>; export CLIENT
# содержимое файла pkinit_extensions выше
$ openssl x509 -req -in kdc.req -CAkey cakey.pem -CA cacert.pem -out kdc.pem -extfile pkinit_extensions -extensions kdc_cert -CAcreateserial |
Переместим файлы kdc.pem, kdckey.pem, cacert.pem в директорию /etc/krb5/
Code Block |
---|
|
$ sudo mkdir /etc/krb5
$ sudo cp kdc.pem kdckey.pem cacert.pem /etc/krb5/ |
Включим preauth на сервере. Для этого опишем realm AKTIV-TEST в файле /etc/krb5kdc/kdc.conf
Code Block |
---|
language | bash |
---|
title | /etc/krb5kdc/kdc.conf |
---|
|
Code Block |
---|
language | bash |
---|
title | /etc/krb5kdc/kdc.conf |
---|
collapse | true |
---|
|
[kdcdefaults]
kdc_tcp_ports = 88
pkinit_identity = FILE:/var/lib/krb5kdc/kdc.pem,/var/lib/krb5kdc/kdckey.pem
pkinit_anchors = FILE:/var/lib/krb5kdc/cacert.pem
[realms]
AKTIV-TEST = {
database_name = /var/lib/krb5kdc/principal
admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab
acl_file = /etc/krb5kdc/kadm5.acl
key_stash_file = /etc/krb5kdc/stash
max_life = 10h 0m 0skadm5.acl
maxkey_renewablestash_lifefile = 7d 0h 0m 0s/etc/krb5kdc/stash
mastermax_key_typelife = des3-hmac-sha1
supported_enctypes = aes256-cts:normal arcfour-hmac:normal des3-hmac-sha1:normal des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs310h 0m 0s
max_renewable_life = 7d 0h 0m 0s
defaultmaster_principalkey_flagstype = +preauthdes3-hmac-sha1
} |
Включить preauth для пользователя
Code Block |
---|
|
$ kadmin.local
kadmin.local$: modprinc +requires_preauth <username> |
Клиент
Скопировать сертификат CA (cacert.pem) c сервера в /etc/krb5/ на клиенте
Отформатировать токен
Code Block |
---|
|
$ pkcs15-init --erase-card -p rutoken_ecp
$ pkcs15-init --create-pkcs15 --so-pin "87654321" --so-puk ""
$ pkcs15-init --store-pin --label "User PIN" --auth-id 02 --pin "12345678" --puk "" --so-pin "87654321" --finalize |
Сгенерировать ключевую пару и заявку на сертификат на токене
supported_enctypes = aes256-cts:normal arcfour-hmac:normal des3-hmac-sha1:normal des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3
default_principal_flags = +preauth
pkinit_anchors = FILE:/etc/krb5/cacert.pem
pkinit_identity = FILE:/etc/krb5/kdc.pem,/etc/krb5/kdckey.pem
} |
Включим preauth для пользователя
Code Block |
---|
|
$ sudo kadmin.local
$ kadmin.local$: modprinc +requires_preauth <username> |
Клиент
Сгенерируем ключевую пару клиента. Создаем заявку на сертификат.
Tip |
---|
|
Если вы используете OpenSSL 3.0, то необходимо выполнить следующую инструкцию |
Code Block |
---|
|
# не забываем про ID!
$ pkcs11-tool --module /usr/lib/librtpkcs11ecp.so --keypairgen --key-type rsa:2048 -l --id 45
openssl |
Code Block |
---|
|
# не забываем про ID!
$ pkcs15-init -G rsa/2048 --auth-id 02 --id 42 --label "testuser's key" --public-key-label "testuser's public key"
# ...
$ openssl
# NB: пути! на multiarch-системах opensc-pkcs11.so и engine_pkcs11.so могут лежать в других местах
OpenSSL> engine dynamic -pre SO_PATH:/usr/lib/opensslx86_64-linux-gnu/engines-1.1/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:opensc-pkcs11librtpkcs11ecp.so
(dynamic) Dynamic engine loading support
[Success]: SO_PATH:/usr/lib/openssl/engines/engine_pkcs11.so
[Success]: ID:pkcs11
[Success]: LIST_ADD:1
[Success]: LOAD
[Success]: MODULE_PATH:opensc-pkcs11.so
Loaded: (pkcs11) pkcs11 engine
OpenSSL> req -engine pkcs11 -new -key 1:42 -keyform engine -out client.req -subj "/C=RU/ST=Moscow/L=Moscow/O=Aktiv/OU=dev/CN=testuser/emailAddress=testuser@mail.com"
engine "pkcs11" set.
PKCS#11 token PIN:
OpenSSL> quit |
Снова сервер
Скопировать с клиента заявку (client.req) и подписать ее ключом CA:
...
OpenSSL> req -engine pkcs11 -new -key 45 -keyform engine -out client.req -subj "/C=RU/ST=Moscow/L=Moscow/O=Aktiv/OU=dev/CN=testuser/emailAddress=testuser@mail.com" |
Сервер
Копируем заявку на сертификат (client.req). И подписываем ее.
Code Block |
---|
|
$ REALM=<realm>; export REALM
$ CLIENT=<username>; export CLIENT
$ openssl x509 -CAkey cakey.pem -CA cacert.pem -req -in client.req -extensions client_cert -extfile pkinit_extensions -out client.pem |
Перезапустим сервер и KDC
Code Block |
---|
$ /etc/init.d/krb5-admin-server restart
$ /etc/init.d/krb5-kdc restart |
Обратно клиент
Получаем сертификат и записываем его на токен. Также нужно положить корневой сертификат в /etc/krb5/
Code Block |
---|
|
$ REALM=<realm>; export REALM
$ CLIENT=<username>; export CLIENT
$ openssl x509 -CAkey cakey.pem -CA cacert.pem -req -in client.req -extensions client_cert -extfile pkinit_extensions -out client.pem |
Перезапустить сервер и kdc:
Code Block |
---|
$ /etc/init.d/krb5-admin-server restart
$ /etc/init.d/krb5-kdc restart |
Обратно клиент
Вернуть сертификат клиента (client.pem) и положить его в /etc/krb5/
Также записать его на токен
pkcs11-tool --module /usr/lib/librtpkcs11ecp.so -l -y cert -w ./client.pem --id 45
$ sudo cp cacert.pem /etc/krb5/cacert.pem |
Изменим файл конфигурации /etc/krb5.conf
Code Block |
---|
language | bash |
---|
title | /etc/krb5.conf |
---|
|
[libdefaults]
default_realm = <realm>
pkinit_anchors = FILE:/etc/krb5/cacert.pem
# для аутентификации по локальному ключу
# pkinit_identities = FILE:/etc/krb5/client.pem,/etc/krb5/clientkey.pem
# для аутентификации по токену
pkinit_identities = PKCS11:/usr/lib/librtpkcs11ecp.so |
Пробуем аутентифицироваться
Code Block |
---|
|
$ pkcs15-init --store-certificate client.pem --auth-id 02 --id 42 --format pem |
Настроить kerberos
Примечание
Если по каким-то причинам не удалось аутентифицироваться, то можно узнать об причине неисправности с помощью логирования. Для этого в файле настройки /etc/krb5.conf и /etc/krb5kdc/kdc.conf.
Code Block |
---|
language | bash | title | /etc/krb5.conf |
---|
|
[libdefaultslogging]
default_realm = <realm>FILE:/var/log/krb5.log
pkinit_anchorskdc = FILE:/etcvar/krb5log/cacert.pem
# для аутентификации по локальному ключу
# pkinit_identitieskrb5kdc.log
admin_server = FILE:/etcvar/krb5log/client.pem,/etc/krb5/clientkey.pem
# для аутентификации по токену
pkinit_identities = PKCS11:/usr/lib/opensc-pkcs11.so |
Проверить как оно все работает
При этом после этого нужно перезагрузить KDC с помощью команд:
Code Block |
---|
$ /etc/init.d/krb5-admin-server restart
$ /etc/init.d/krb5-kdc restart |
Code Block |
---|
|
$ kinit <username> |