Добавление SPN записей в keytab-файл (на стороне сервера Linux с помощью утилиты ktutil), связанный с учётной записью Computer в домене Active Directory

Представим себе ситуацию, что есть некий сервер на базе Debian GNU/Linux, который уже введён в домен Active Directory с помощью SSSD и realmd и на нём уже имеется keytab-файл, который используется для механизмов аутентификации Kerberos и Single sign-on (SSO) при подключении к серверу по протоколу SSH. И вот возникает необходимость на данном Linux-сервере дополнительно настроить роль веб-сервера для служебных администраторских задач и организовать Kerberos SSO при подключении к веб-узлам этого веб-сервера. По ранее описанным примерам (здесь, здесь и здесь), предполагается, что для целей Kerberos-аутентификации веб-сервера Apache в домене Active Directory (AD) создаётся отдельная сервисная учётная запись типа User, для которой генерируется keytab-файл и в последствии привязывается к настройкам Apache на стороне Linux-сервера. С точки зрения аспектов безопасности такой поход (отдельный Linux-сервис = отдельная учётная запись в AD со своим keytab-файлом) можно считать вполне правильным. Но что, если Linux-сервис, использующий Kerberos-аутентификацию, используется не широким кругом пользователей, а исключительно для административных целей парой-тройкой системных администраторов? В таком случае создание отдельной учётной записи типа User в домене со своим keytab-файлом может показаться избыточным. В этой заметке мы рассмотрим пример того, как добавить дополнительную нужную нам запись servicePrincipalName (SPN) (на примере SPN-записи типа HTTP/) в уже имеющийся на Linux-сервере keytab-файл, ориентированный на сам хост (содержащий SPN-записи типа HOST/). В результате мы получим Kerberos аутентификацию на веб-узлах нашего Linux-сервера и при этом не будем плодить в домене лишние сервисные учётные записи типа User.

Изменение учётной записи компьютера в AD

Для начала нам необходимо обеспечить наличие всех нужных SPN-записей в свойствах учётной записи Linux-сервера (объект типа Computer) в домене AD. В нашем примере используется учётная запись компьютера kom-srv01.holding.com, который уже был ранее заведён в домен.
Посмотрим текущее состояние SPN-записей в каталоге AD для этого хоста на любом Windows-компьютере, входящем в домен (для просмотра SPN достаточно прав рядового пользователя домена) с помощью утилиты setspn:

setspn -L holding.com\kom-srv01

Зарегистрирован ServicePrincipalNames для CN=KOM-SRV01,OU=Servers,DC=holding,DC=com:
        RestrictedKrbHost/KOM-SRV01.holding.com
        RestrictedKrbHost/KOM-SRV01
        HOST/KOM-SRV01.holding.com
        HOST/KOM-SRV01


Как видим, в каталоге AD у учётной записи нашего Linux-сервера присутствуют только базовые SPN-записи типа HOST/ и RestrictedKrbHost/.

Зарегистрируем для этой учётной записи компьютера новую SPN-запись, которая будут содержать имя нужных нам дополнительной службы, например HTTP/kom-srv01.holding.com, следующим образом (для изменения SPN требуются права администратора домена):

setspn -A HTTP/kom-srv01.holding.com holding.com\kom-srv01

Проверка домена DC=holding,DC=com
Регистрация ServicePrincipalNames для CN=KOM-SRV01,OU=Servers,DC=holding,DC=com
        HTTP/kom-srv01.holding.com
Обновленный объект

Снова проверим полный список зарегистрированных SPN-записей:

setspn -L holding.com\kom-srv01

Зарегистрирован ServicePrincipalNames для CN=KOM-SRV01,OU=Servers,DC=holding,DC=com:
        HTTP/kom-srv01.holding.com
        RestrictedKrbHost/KOM-SRV01.holding.com
        RestrictedKrbHost/KOM-SRV01
        HOST/KOM-SRV01.holding.com
        HOST/KOM-SRV01

Порядок. Теперь можно переходить к правке keytab-файла на стороне Linux-сервера.

 

Правка keytab-файла на Linux-сервере

Войдём в режим работы с утилитой ktutil:

# ktutil

Выполним команду list, которая покажет, какими данными оперирует утилита (пока там пусто):

ktutil:  list

slot KVNO Principal
---- ---- ---------------------------------------------------------------------

Выполним команду чтения содержимого из нашего keytab-файла (read_kt), который мы хотим использовать, как исходный. Следом выполним команду list с опциями -k (отображать ключи шифрования) и -e (отображать тип шифрования) (вывод утилиты усечён):

ktutil:  read_kt /etc/apache2/krb5.keytab
ktutil:  list -k -e

slot KVNO Principal
---- ---- ---------------------------------------------------------------------
   1   3 KOM-SRV01$@HOLDING.COM (aes256-cts-hmac-sha1-96)  (0xeaa481895ed765dc171329)
   2   3 KOM-SRV01$@HOLDING.COM (aes128-cts-hmac-sha1-96)  (0xb419907dea0e6d6610a)
   3   3 KOM-SRV01$@HOLDING.COM (des3-cbc-sha1)  (0xbf1bec79328e67310262aa9d0)
   4   3 KOM-SRV01$@HOLDING.COM (arcfour-hmac)  (0x205802fe6a42a245f9)
   5   3 KOM-SRV01$@HOLDING.COM (des-cbc-md5)  (0x22aadb38391fb)
   6   3 KOM-SRV01$@HOLDING.COM (des-cbc-crc)  (0x22aadb38391fb)
...
  12   3 host/kom-srv01.holding.com@HOLDING.COM (des-cbc-crc)  (0x22aadb38391fb)
...
  18   3 HOST/KOM-SRV01@HOLDING.COM (des-cbc-crc)  (0x22aadb38391fb)
...
  24   3 HOST/KOM-SRV01.holding.com@HOLDING.COM (des-cbc-crc)  (0x22aadb38391fb)
...
  30   3 RestrictedKrbHost/KOM-SRV01@HOLDING.COM (des-cbc-crc)  (0x22aadb38391fb)
...
  36   3 RestrictedKrbHost/KOM-SRV01.holding.com@HOLDING.COM (des-cbc-crc)  (0x22aadb38391fb)

Следующей командой add_entry добавим в массив данных, с которыми оперирует утилита, нужную нам дополнительную запись принципала Kerberos. При этом будем использовать ключи:

  • key – используем ключ шифрования вместо пароля. Пароль учётной записи Linux-компьютера в AD нам неизвестен, а вот все нужные нам ключи шифрования для разных типов шифрования мы видим в результате вывода предыдущей команды;
  • p – имя принципала Kerberos (SPN-запись в формате SERVICE/server.fqdn@DOMAIN.FQDN, которую мы хотим добавить в keytab-файл) по аналогии с тем, как оно отображается в результате вывода предыдущей команды;
  • k - текущий номер KVNO (отображается в результате вывода предыдущей команды);
  • e - тип шифрования по аналогии с тем, как он отображается в результате вывода предыдущей команды;

После ввода команды будет запрошен ключ шифрования в hex-формате. Используем значение, которое мы видим в результате вывода ранее выполненной команды (list -k -e) для соответствующего типа шифрования (последнее значение в скобках с отброшенной в начале значения частью 0x)

ktutil:  add_entry -key -p HTTP/kom-srv01.holding.com@HOLDING.COM -k 3 -e aes256-cts-hmac-sha1-96
Key for HTTP/kom-srv01.holding.com@HOLDING.COM (hex): eaa481895ed765dc171329

Таким образом мы можем добавить аналогичные записи для всех необходимых типов шифрования по аналогии с записями типа HOST/:

ktutil:  add_entry -key -p HTTP/kom-srv01.holding.com@HOLDING.COM -k 3 -e aes128-cts-hmac-sha1-96
Key for HTTP/kom-srv01.holding.com@HOLDING.COM (hex): b419907dea0e6d6610a

ktutil:  add_entry -key -p HTTP/kom-srv01.holding.com@HOLDING.COM -k 3 -e des3-cbc-sha1
Key for HTTP/kom-srv01.holding.com@HOLDING.COM (hex): bf1bec79328e67310262aa9d0

ktutil:  add_entry -key -p HTTP/kom-srv01.holding.com@HOLDING.COM -k 3 -e arcfour-hmac
Key for HTTP/kom-srv01.holding.com@HOLDING.COM (hex): 205802fe6a42a245f9

ktutil:  add_entry -key -p HTTP/kom-srv01.holding.com@HOLDING.COM -k 3 -e des-cbc-md5
Key for HTTP/kom-srv01.holding.com@HOLDING.COM (hex): 22aadb38391fb

ktutil:  add_entry -key -p HTTP/kom-srv01.holding.com@HOLDING.COM -k 3 -e des-cbc-crc
Key for HTTP/kom-srv01.holding.com@HOLDING.COM (hex): 22aadb38391fb

Проверим, что у нас получилось в конечном итоге (вывод утилиты усечён):

ktutil:  list -k -e

slot KVNO Principal
---- ---- ---------------------------------------------------------------------
...
 37  3 HTTP/kom-srv01.holding.com@HOLDING.COM (aes256-cts-hmac-sha1-96) (0xeaa481895ed765dc171329)
 38  3 HTTP/kom-srv01.holding.com@HOLDING.COM (aes128-cts-hmac-sha1-96)  (0xb419907dea0e6d6610a)
 39  3 HTTP/kom-srv01.holding.com@HOLDING.COM (des3-cbc-sha1)  (0xbf1bec79328e67310262aa9d0)
 40  3 HTTP/kom-srv01.holding.com@HOLDING.COM (arcfour-hmac)  (0x205802fe6a42a245f9)
 41  3 HTTP/kom-srv01.holding.com@HOLDING.COM (des-cbc-md5)  (0x22aadb38391fb)
 42  3 HTTP/kom-srv01.holding.com@HOLDING.COM (des-cbc-crc)  (0x22aadb38391fb)

По завершению добавления записей командой write_kt сохраняем получившийся массив данных в новый keytab-файл и выходим из интерактивного режима работы утилиты:

ktutil:  write_kt /etc/apache2/krb5_refreshed.keytab
ktutil:  exit

Таким образом мы получили keytab-файл, записи которого соответствуют SPN, зарегистрированным для учётной записи Linux-сервера в каталоге AD.

Осталось подключить обновлённый keytab-файл к конфигурации Apache и проверить результат. Пример настройки с использованием keytab-файла в конфигурации Apache мы уже рассматривали ранее в заметке Настройка Kerberos аутентификации с SSO на веб-сервере Apache с помощью SSSD, поэтому сразу перейдём к проверке результата.

 

Проверка Kerberos аутентификации с SSO на стороне клиента

Перейдём на клиентскую Windows-машину и с правами пользователя, имеющего доступ к только что настроенному веб-сайту Apache, обратимся к этому сайту через веб браузер. Но перед тем как открыть сайт, закроем клиентский браузер и очистим кэш билетов Kerberos командой:

klist purge

После этого откроем веб-сайт Apache с настроенной Kerberos аутентификацией и проверим то, как изменилось состояние кэша билетов на клиентской машине:

klist

...
#1>     Клиент: petya @ HOLDING.COM
        Сервер: HTTP/kom-srv01.holding.com @ HOLDING.COM
        Тип шифрования KerbTicket: AES-256-CTS-HMAC-SHA1-96
        флаги билета 0x40a10000 -> forwardable renewable pre_authent name_canonicalize
        Время начала: 10/12/2017 20:34:24 (локально)
        Время окончания:   10/13/2017 6:34:22 (локально)
        Время продления: 10/19/2017 20:34:22 (локально)
        Тип ключа сеанса: AES-256-CTS-HMAC-SHA1-96
        Флаги кэша: 0
        Вызванный центр распространения ключей: DC01.holding.com
...

Как видим, Kerberos-билет, связанный с веб-сервером на Linux, успешно получен.

Всего комментариев: 3 Комментировать

  1. Алексей Степанов /

    Прекрасно!

  2. Вадим Яковлев /

    Пара комментариев. Во-первых, на самом деле добавлять SPN типа HTTP для учётной записи сервера в AD при помощи setspn не обязательно. По умолчанию в AD SPN-записи типа HOST заменяют некоторые другие, включая HTTP. Т.е. когда клиент запрашивает у доменного контроллера билет для SPN вида "HTTP/server.domain", тот сначала ищет подходящий компьютер с именно такой SPN, но если не находит, то ищет компьютер с SPN "HOST/server.domain" и, в случае успеха, возвращает билет, зашифрованный ключом этой учётки (но билет будет выдан для "HTTP/server.domain", как клиент и запрашивал). При этом добавлять записи в keytab для SPN типа HTTP всё равно надо.

    Во-вторых, по большому счёту, ничего не мешает засунуть в уже имеющийся keytab-файл записи для нового SPN, даже если в AD этот SPN принадлежит другой учётной записи - конечно, при этом сами ключи будут отличаться (ключи можно вытащить, например, при помощи ktpass). Но я не знаю, как в таком случае SSSD будет себя вести при обновлении пароля учётной записи компьютера.

  3. Сергей Васильевич /

    С благодарностью воспользовался инструкцией, но в гораздо более простом виде. Как оказалось, достаточно воспользоваться SPN-конструкцией host/, которая доступна в keytab-файле после ввода сервера AD-домен. Этой SPN-записи хватило, чтобы успешно выдать тикет клиенту для доменной авторизации в СУБД Линтер.
    При этом была важная заминка, не хватало прав на чтение keytab-файла у учетки, от которой был запущен сервис. После выдачи прав sudo chmod go+r /etc/krb5.keytab все заработало.

Добавить комментарий