В продолжение давней темы про использование двухфакторной аутентификации в ОС GNU/Linux позвольте рассказать про схему работы и настройку аутентификации с помощью Kerberos. В этой статье мы рассмотрим процесс настройки MIT Kerberos для аутентификации пользователей по сертификатам и ключевым парам, находящимся на USB-токене. Также материалы, изложенные в статье, можно использовать для настройки аутентификации в домене Windows.
Краткое введение
Для начала проведем небольшой ликбез по терминологии Kerberos и рассмотрим доступные реализации этого протокола в ОС на базе GNU/Linux. Сразу оговорюсь, что мне не удалось найти однозначного перевода терминов, использующихся в Kerberos, поэтому для избежания путаницы основные термины я буду дублировать на английском.
Итак, начнем. Если процитировать Википедию, то
Kerberos – сетевой протокол аутентификации, позволяющий передавать данные через незащищённые сети для безопасной идентификации. Ориентирован, в первую очередь, на клиент-серверную модель и обеспечивает взаимную аутентификацию – оба пользователя через сервер подтверждают личности друг друга.
Стоит отметить, что Kerberos в первую очередь является протоколом, а не конкретной системой аутентификации. Его реализации используются в различных операционных системах, в том числе и в Windows, как метод аутентификации пользователей в домене. Существует несколько open source реализаций протокола Kerberos, например оригинальная MIT Kerberos и Heimdal. Такой зоопарк возник из-за ограничений США на экспорт криптографических средств защиты информации, на сегодня эта ситуация вокруг MIT Kerberos уже улеглась. В статье мы рассмотрим процесс настройки для MIT Kerberos V5.
Терминология Kerberos
- Билет (ticket) – временные данные, выдаваемые клиенту для аутентификации на сервере, на котором располагается необходимая служба.
- Клиент (client) – некая сущность в сети (пользователь, хост или сервис), которая может получить билет от Kerberos.
- Центр выдачи ключей (key distribution center, KDC) – сервис, выдающий билеты Kerberos.
- Область (realm) – сеть, используемая Kerberos, состоящая из серверов KDC и множества клиентов. Имя realm регистрозависимо, обычно пишется в верхнем регистре и совпадает с именем домена.
- Принципал (principal) – уникальное имя для клиента, для которого разрешается аутентификация в Kerberos. Записывается в виде root[/instance]@REALM.
Файлы настроек Kerberos
На сервере:
- /etc/krb5kdc/kdc.conf — настройки KDC
На клиенте и сервере:
- /etc/kbr5.conf — настройки сервера аутентификации (описание realms, доменных имен и других настроек)
Настройка рабочего окружения
Для начала необходимо развернуть среду, в которой будет производиться аутентификация. Наиболее просто это сделать, взяв две виртуальные машины, находящиеся в одной подсети. Достаточно установить на одну виртуальную машину какую-нибудь Ubuntu (это будет наш сервер), а затем клонировать ее и получить клиента. При написании статьи я воспользовался свежей Ubuntu 12.10 (x86) и виртуальной машиной от VMWare. Чтобы виртуальным машинам было удобнее видеть друг друга по сети, стоит переключить сетевые карты в Bridged-режим.
Важно! Следите за тем, чтобы время на клиенте и сервере было синхронизировано, это необходимо для корректной работы Kerberos.
Настройка сети
Клиенты Kerberos ищут свои сервера по доменным именам, поэтому необходимо настроить DNS и убедиться, что имена серверов успешно разрешаются. В нашем примере достаточно занести доменное имя сервера в /etc/hosts, что я и сделал. Схема «сети» изображена ниже.
Установка необходимых пакетов
На сервере нам потребуются:
- krb5-kdc – сервис KDC
- krb5-admin-server – административный сервер Kerberos (он ведет контроль учетных записей пользователей)
- krb5-pkinit – модуль расширения Kerberos для аутентификации по сертификатам
На клиент надо поставить следующие пакеты:
- krb5-user – базовый набор утилит для работы клиентской аутентификации
- krb5-config – файлы настроек Kerberos
- krb5-pkinit
- libpam-krb5 – модуль PAM для использования Kerberos-аутентификации
- pcscd, opensc, libengine-pkcs11-openssl – пакеты, необходимые для работы с токенами
При установке пакетов у нас спросят настройки по умолчанию, мы будем использовать следующие:
- Default realm: AKTIV-TEST.RU
- Имена серверов (admin server и KDC): aktiv-test.ru (он же прописан в /etc/hosts на клиенте)
- Пользователь: testuser@AKTIV-TEST.RU
Настройка Kerberos
Базовые настройки
После установки пакетов на сервере нужно инициализировать realm командой
$ sudo krb5_newrealm
А на клиенте – обновить файлы конфигурации:
$ sudo dpkg-reconfigure krb5-config
Также на клиенте и сервере надо добавить следующие строки в /etc/krb5.conf:
[domain_realm]
.aktiv-test.ru = AKTIV-TEST.RU
aktiv-test.ru = AKTIV-TEST.RU
Теперь создадим на сервере нового пользователя c именем testuser
$ sudo kadmin.local
# username = testuser
# password = test
# добавляем нового пользователя и устанавливаем его пароль
kadmin.local:$ addprinc testuser
# ...
kadmin.local:$ quit
На клиенте теперь можно проверить, правильно ли мы настроили сеть и Kerberos:
$ kinit testuser@AKTIV-TEST.RU
# вводим пароль пользователя
$ klist
# и видим выданный ticket, после чего его можно удалить следующей командой
$ kdestroy
Настройка аутентификации по открытому ключу
Для работы модуля pkinit нам придется воспользоваться openssl в качестве мини-УЦ, чтобы создать ключевые пары и сертификаты клиента и сервера.
На сервере:
Создадим ключевую пару и сертификат нашего «УЦ». Здесь мы сгененируем ключ УЦ и создадим самоподписанный сертификат с помощью openssl. В реальном мире ключ естественно надо надежно защитить от попадания в чужие руки.
$ openssl genrsa -out cakey.pem 2048
# ...
$ openssl req -key cakey.pem -new -x509 -out cacert.pem
# ...
Создадим ключевую пару для KDC, заявку на сертификат и выпишем его сами себе.
Здесь нам потребуется специальный файл расширений OpenSSL (pkinit_extensions), в котором будут указаны дополнительные поля сертификатов, используемых в Kerberos. В частности, мы зададим:
- Extended Key Usage (EKU) – идентификатор (OID), говорящий о том, как планируется использовать сертификат
- otherName – поле, задающее нашего принципала, для которого выписывается сертификат
$ openssl genrsa -out kdckey.pem 2048
# создание запроса
$ openssl req -new -out kdc.req -key kdckey.pem
# подпись запроса
$ REALM=AKTIV-TEST.RU; export REALM
$ CLIENT=aktiv-test.ru; 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
На сервере отредактируем настройки Kerberos (файл /etc/krb5kdc/kdc.conf) для использования ключей и сертификатов сервера и УЦ:
[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.RU = {
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 0s
max_renewable_life = 7d 0h 0m 0s
master_key_type = 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:afs3
default_principal_flags = +preauth
}
Далее на сервере необходимо включить предварительную аутентификацию для нашего пользователя.
$ kadmin.local
kadmin.local$: modprinc +requires_preauth testuser
Дальнейшие действия будем выполнять на клиенте
Отформатируем токен
$ 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
Сгенерируем на токене ключевую пару RSA 2048 бит и создадим заявку на сертификат. Важно заметить, что пути до библиотек engine_pkcs11.so и opensc-pkcs11.so на вашей системе могут отличатся, поэтому сначала стоит проверить их расположение.
# на данном шаге важно запомнить ID ключевой пары, его мы используем позже
$ pkcs15-init -G rsa/2048 --auth-id 02 --id 42 --label "testuser's key" --public-key-label "testuser's public key"
# ...
$ openssl
# на multiarch-системах opensc-pkcs11.so и engine_pkcs11.so могут лежать в других местах
OpenSSL> engine dynamic -pre SO_PATH:/usr/lib/openssl/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:opensc-pkcs11.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, которую необходимо поместить на сервер и выписать сертификат пользователя на основе данных УЦ:
$ REALM=AKTIV-TEST.RU; export REALM
$ CLIENT=testuser; export CLIENT
$ openssl x509 -CAkey cakey.pem -CA cacert.pem -req -in client.req -extensions client_cert -extfile pkinit_extensions -out client.pem
Затем стоит перезапустить сервер и KDC:
$ /etc/init.d/krb5-admin-server restart
$ /etc/init.d/krb5-kdc restart
На выходе работы openssl мы получим файл с сертификатом клиента client.pem. Его нужно перенести на клиентскую машину, положить в /etc/krb5/ и записать на токен:
$ pkcs15-init --store-certificate client.pem --auth-id 02 --id 42 --format pem
И в завершение нам потребуется внести в файл конфигурации Kerberos настройку, которая укажет, какие данные использовать для аутентификации (в нашем случае это сертификат УЦ и путь до модуля PKCS#11). В документации MIT Kerberos указаны различные параметры, которые позволяют настроить выбор аутентификационных данных на токене, в нашем же случае мы просто указываем модуль PKCS#11, поскольку в данной ситуации этого достаточно.
[libdefaults]
default_realm = AKTIV-TEST.RU
# путь к сертификату УЦ
pkinit_anchors = FILE:/etc/krb5/cacert.pem
# путь к модулю PKCS#11
pkinit_identities = PKCS11:/usr/lib/opensc-pkcs11.so
Проверим, можем ли мы получить ticket на клиенте, используя данные с токена:
$ kinit testuser
# на этом этапе у нас должны спросить PIN-код от токена
$ klist
Настройка PAM-аутентификации с использованием Kerberos
Ранее при настройке клиентской машины мы поставили пакет libpam-krb5. Он поможет нам выполнить аутентификацию в Kerberos при входе в систему, а также в приложениях, использующих системную аутентификацию (например login, lightdm и проч.). Для подключения модуля PAM достаточно выполнить команду
$ sudo pam-auth-update
и выбрать в диалоге необходимые модули аутентификации. Для более тонкой настройки можно заглянуть в файл /etc/pam.d/common-auth и отредактировать его по желанию. Структуру файла я описывал в предыдущей статье.
Заключение
Применение протокола Kerberos для централизованной аутентификации в связке с централизованным созданием хранением и раздачей учетных записей (например, посредством каталога на базе OpenLDAP) позволяет создать «домен UNIX», полностью состоящий из машин под управлением свободного программного обеспечения. Такое решение может применяться в корпоративном секторе, а аутентификация по смарт-картам будет приятным бонусом как для администраторов, так и для пользователей сети компании.
Полезные ссылки
- Описание протокола Kerberos
- Официальная документация
- Инструкция по настройке от сообщества Ubuntu
- Настройка PKINIT
Автор: lunatik42