Аутентификация Kerberos
Аутентификация Kerberos — это современный метод аутентификации, используемый в средах Windows. Он позволяет клиенту и серверу проверять личности друг друга и поддерживает современные методы шифрования, такие как AES.
- Установка Kerberos
- Настройка Kerberos на хосте
- Проверка конфигурации Kerberos
- Управление билетами
- Делегирование
- Устранение неполадок Kerberos
Установка Kerberos
Kerberos предоставляется через библиотеку GSSAPI, входящую в системный пакет. В некоторых дистрибутивах пакеты Kerberos устанавливаются по умолчанию, в других может потребоваться их установка вручную.
Чтобы установить библиотеки Kerberos в системах на базе RHEL/Fedora:
$ sudo dnf install krb5-devel krb5-libs krb5-workstation python3-devel
В системах на базе Debian/Ubuntu:
$ sudo apt-get install krb5-user libkrb5-dev python3-dev
В системах на базе Arch Linux:
$ sudo pacman -S krb5
В системах на базе FreeBSD:
$ sudo pkg install heimdal
Примечание
Пакеты python3-devel / python3-dev можно не устанавливать, если Kerberos используется с подключаемым модулем подключения ssh. Они нужны только при использовании подключения на основе WinRM с аутентификацией Kerberos.
После установки будут доступны пакеты kinit, klist и krb5-config. Проверить их работу можно с помощью следующей команды:
$ krb5-config --version Kerberos 5 release 1.21.3
Для аутентификации Kerberos подключаемым модулям подключения psrp и winrm требуются дополнительные библиотеки Python. Следующий шаг можно пропустить, если Kerberos используется с подключением ssh.
Если вы выбрали pipx инструкцию по установке Ansible, установите необходимые зависимости, выполнив следующую команду:
pipx inject ansible "pypsrp[kerberos]<=1.0.0" # for psrp pipx inject ansible "pywinrm[kerberos]>=0.4.0" # for winrm
Или, если вы выбрали pip инструкцию по установке:
pip3 install "pypsrp[kerberos]<=1.0.0" # for psrp pip3 install "pywinrm[kerberos]>=0.4.0" # for winrm
Настройка Kerberos на хосте
После установки зависимостей необходимо настроить Kerberos для взаимодействия с доменом. Большинство реализаций Kerberos могут находить домен через DNS или с помощью ручной настройки в файле /etc/krb5.conf. Подробнее о параметрах, которые можно задать в файле /etc/krb5.conf, см. в документации krb5.conf. Пример простого файла krb5.conf, который использует DNS для поиска KDC:
[libdefaults]
# Not required but helpful if the realm cannot be determined from
# the hostname
default_realm = MY.DOMAIN.COM
# Enabled KDC lookups from DNS SRV records
dns_lookup_kdc = true
При указанной выше конфигурации, когда запрашивается билет Kerberos для сервера server.my.domain.com, библиотека Kerberos выполнит поиск SRV-записей для _kerberos._udp.my.domain.com и _kerberos._tcp.my.domain.com, чтобы найти KDC. Если вы хотите указать области KDC вручную, используйте следующую конфигурацию:
[libdefaults]
default_realm = MY.DOMAIN.COM
dns_lookup_kdc = false
[realms]
MY.DOMAIN.COM = {
kdc = domain-controller1.my.domain.com
kdc = domain-controller2.my.domain.com
}
[domain_realm]
.my.domain.com = MY.DOMAIN.COM
my.domain.com = MY.DOMAIN.COM
При такой конфигурации любой запрос билета для DNS-суффикса .my.domain.com, а также для самого my.domain.com будет отправлен на KDC domain-controller1.my.domain.com с переключением на domain-controller2.my.domain.com в случае неудачи.
Дополнительные сведения о том, как библиотека Kerberos пытается найти KDC, см. в документации MIT Kerberos.
Примечание
Информация в этом разделе относится к реализации MIT Kerberos, которая обычно используется по умолчанию в большинстве дистрибутивов Linux. Некоторые платформы, например FreeBSD и macOS, используют другую реализацию GSSAPI — Heimdal. Она работает аналогично MIT Kerberos, но некоторые особенности поведения могут отличаться.
Проверка конфигурации Kerberos
Чтобы проверить правильность работы Kerberos, воспользуйтесь командой kinit для получения билета пользователя домена. Следующая команда запросит билет для пользователя username в домене MY.DOMAIN.COM:
$ kinit username@MY.DOMAIN.COM Password for username@REALM.COM
Если пароль указан верно, команда завершится без вывода. Чтобы проверить, получен ли билет, воспользуйтесь командой klist:
> klist
Ticket cache: KCM:1000
Default principal: username@MY.DOMAIN.COM
Valid starting Expires Service principal
29/08/24 13:54:51 29/08/24 23:54:51 krbtgt/MY.DOMAIN.COM@MY.DOMAIN.COM
renew until 05/09/24 13:54:48
Если команда выполнена успешно, это подтверждает правильность конфигурации Kerberos и возможность получения пользователем билета на получение билетов (Ticket Granting Ticket, TGT) от KDC. Если kinit не удается найти KDC для запрошенной области, проверьте конфигурацию Kerberos: убедитесь, что DNS может найти KDC с помощью SRV-записей или что KDC указан вручную в файле krb5.conf.
В системах на базе MIT Kerberos можно использовать команду kvno, чтобы проверить, удается ли получить билет службы для конкретной службы. Например, если для аутентификации с помощью server.my.domain.com используется подключение на основе WinRM, следующей командой можно проверить, удается ли получить билет службы для целевого сервера с помощью TGT:
$ kvno http/server.my.domain.com http/server2025.domain.test@DOMAIN.TEST: kvno = 2
Команду klist также можно использовать, чтобы проверить, сохранен ли билет в кэше Kerberos:
$ klist
Ticket cache: KCM:1000
Default principal: username@MY.DOMAIN.COM
Valid starting Expires Service principal
29/08/24 13:54:51 29/08/24 23:54:51 krbtgt/MY.DOMAIN.COM@MY.DOMAIN.COM
renew until 05/09/24 13:54:48
29/08/24 13:55:30 29/08/24 23:55:30 http/server.my.domain.com@MY.DOMAIN.COM
renew until 05/09/24 13:55:30
В приведенном выше примере TGT сохранен для субъекта-службы krbtgt, а http/server.my.domain.com — для собственного субъекта-службы.
Команду kdestroy можно использовать для удаления кэша билетов.
Управление билетами
Для работы аутентификации Kerberos в Ansible должен быть доступен TGT пользователя, чтобы Ansible мог запросить билет службы для целевого сервера. Некоторые подключаемые модули подключения, например ssh, требуют, чтобы TGT уже был получен и доступен процессу управления Ansible. Другие подключаемые модули подключения, например psrp и winrm, могут автоматически получать TGT пользователя, если его пароль указан в инвентаре.
Чтобы вручную получить TGT пользователя, выполните команду kinit, указав имя пользователя и домен, как описано в разделе Проверка конфигурации Kerberos. Этот TGT будет автоматически использоваться, когда подключаемый модуль подключения Ansible запросит аутентификацию Kerberos.
Если вы используете подключаемый модуль подключения psrp или winrm и пароль пользователя указан в инвентаре, подключаемый модуль автоматически получит TGT пользователя. Для этого выполняется команда kinit с именем пользователя и его паролем. TGT будет сохранен во временном кэше учетных данных и использован для выполнения задачи.
Делегирование
Делегирование Kerberos позволяет учетным данным проходить через несколько узлов. Это полезно, когда необходимо выполнить аутентификацию на сервере, а затем поручить ему пройти аутентификацию на другом сервере от вашего имени. Чтобы включить делегирование, необходимо:
- запросить перенаправляемый TGT при получении билета с помощью
kinit - разрешить подключаемому модулю подключения делегирование учетных данных серверу
- убедиться, что для пользователя AD не установлен атрибут «Учетная запись является конфиденциальной и не может быть делегирована» и что он не входит в группу
Protected Users - в зависимости от конфигурации
krb5.confцелевому серверу может потребоваться разрешить неограниченное делегирование в параметрах делегирования его объекта AD - убедиться, что к целевому ресурсу, которому делегируются учетные данные, можно обратиться с помощью аутентификации Kerberos
Чтобы запросить перенаправляемый TGT, добавьте флаг -f к команде kinit или задайте параметр forwardable = true в разделе [libdefaults] файла krb5.conf. Если для получения TGT по паролю пользователя из инвентаря используется подключаемый модуль подключения psrp или winrm, он автоматически запросит перенаправляемый TGT, если настроен на использование делегирования.
Чтобы подключаемый модуль подключения делегировал учетные данные, задайте в инвентаре следующую переменную хоста:
# psrp ansible_psrp_negotiate_delegate: true # winrm ansible_winrm_kerberos_delegation: true # ssh ansible_ssh_common_args: -o GSSAPIDelegateCredentials=yes
Примечание
Также можно задать GSSAPIDelegateCredentials yes в файле ~/.ssh/config, чтобы разрешить делегирование для всех SSH-подключений.
Чтобы проверить, разрешено ли пользователю делегировать свои учетные данные, выполните следующий сценарий PowerShell на хосте Windows в том же домене:
Function Test-IsDelegatable {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]
$UserName
)
$NOT_DELEGATED = 0x00100000
$searcher = [ADSISearcher]"(&(objectClass=user)(objectCategory=person)(sAMAccountName=$UserName))"
$res = $searcher.FindOne()
if (-not $res) {
Write-Error -Message "Failed to find user '$UserName'"
}
else {
$uac = $res.Properties.useraccountcontrol[0]
$memberOf = @($res.Properties.memberof)
$isSensitive = [bool]($uac -band $NOT_DELEGATED)
$isProtectedUser = [bool]($memberOf -like 'CN=Protected Users,*').Count
-not ($isSensitive -or $isProtectedUser)
}
}
Test-IsDelegatable -UserName username
В более новых версиях MIT Kerberos добавлен параметр конфигурации enforce_ok_as_delegate в разделе [libdefaults] файла krb5.conf. Если для этого параметра задано значение true, делегирование будет работать, только если для учетной записи целевого сервера разрешено неограниченное делегирование. Чтобы проверить или настроить неограниченное делегирование на компьютере Windows, выполните следующий сценарий PowerShell:
# Check if the server allows unconstrained delegation (Get-ADComputer -Identity WINHOST -Properties TrustedForDelegation).TrustedForDelegation # Enable unconstrained delegation Set-ADComputer -Identity WINHOST -TrustedForDelegation $true
Чтобы проверить работу делегирования, выполните команду klist.exe на узле Windows и убедитесь, что билет был перенаправлен. В выводе должно быть указано, что сервер билета — krbtgt/MY.DOMAIN.COM @ MY.CDOMAIN.COM, а флаги билета содержат forwarded.
$ ansible WINHOST -m ansible.windows.win_command -a C:/Windows/System32/klist.exe
WINHOST | CHANGED | rc=0 >>
Current LogonId is 0:0x82b6977
Cached Tickets: (1)
#0> Client: username @ MY.DOMAIN.COM
Server: krbtgt/MY.DOMAIN.COM @ MY.DOMAIN.COM
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x60a10000 -> forwardable forwarded renewable pre_authent name_canonicalize
Start Time: 8/30/2024 14:15:18 (local)
End Time: 8/31/2024 0:12:49 (local)
Renew Time: 9/6/2024 14:12:49 (local)
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0x1 -> PRIMARY
Kdc Called:
Если что-то пошло не так, в выводе команды klist.exe не будет флага forwarded, а в качестве сервера будет указан субъект-служба целевого сервера, а не krbtgt.
$ ansible WINHOST -m ansible.windows.win_command -a C:/Windows/System32/klist.exe
WINHOST | CHANGED | rc=0 >>
Current LogonId is 0:0x82c312c
Cached Tickets: (1)
#0> Client: username @ MY.DOMAIN.COM
Server: http/winhost.my.domain.com @ MY.DOMAIN.COM
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x40a10000 -> forwardable renewable pre_authent name_canonicalize
Start Time: 8/30/2024 14:16:24 (local)
End Time: 8/31/2024 0:16:12 (local)
Renew Time: 0
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0x8 -> ASC
Kdc Called:
Также важно убедиться, что к целевому ресурсу, которому делегируются учетные данные, можно обратиться с помощью аутентификации Kerberos. Для этого у целевого сервера должно быть зарегистрировано имя участника-службы (Service Principal Name, SPN) в Active Directory (AD), а при исходящей попытке аутентификации в Windows должно использоваться имя хоста, а не IP-адрес или псевдоним. Например, к общей папке следует обращаться по пути \\server.fqdn.com\share, а не \\192.168.1.2\share. Чтобы проверить, зарегистрировано ли имя участника-службы и может ли сеанс Ansible делегировать учетные данные с помощью Kerberos, выполните следующую команду klist.exe для запроса билета службы целевого сервера.
$ ansible WINHOST -m ansible.windows.win_command -a 'C:/Windows/System32/klist.exe get cifs/fs.my.domain.com'
WINHOST | CHANGED | rc=0 >>
Current LogonId is 0:0x225639b
A ticket to cifs/fs.my.domain.com has been retrieved successfully.
Cached Tickets: (2)
...
#2> Client: username @ MY.DOMAIN.COM
Server: cifs/fs.my.domain.com @ MY.DOMAIN.COM
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x60a50000 -> forwardable forwarded renewable pre_authent ok_as_delegate name_canonicalize
Start Time: 8/30/2024 14:16:24 (local)
End Time: 8/31/2024 0:16:12 (local)
Renew Time: 0
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0x8 -> ASC
Kdc Called: dc01.my.domain.com
Примечание
Префикс SPN целевого сервера зависит от службы, к которой вы пытаетесь обратиться. Для общих папок используется служба cifs, для веб-служб — http и так далее. Для проверки делегирования Kerberos используйте правильный префикс.
Устранение неполадок Kerberos
Для работы Kerberos необходима правильно настроенная среда. Ниже перечислены распространенные причины сбоев аутентификации Kerberos:
- Для хоста Windows указано имя-псевдоним или IP-адрес
- Время на управляющем узле Ansible не синхронизировано с контроллером домена AD
- Область KDC неправильно указана в файле
krb5.confили не может быть найдена через DNS
При использовании реализации MIT Kerberos можно задать переменную среды KRB5_TRACE=/dev/stdout, чтобы получить более подробные сведения о работе библиотеки Kerberos. Это может помочь при отладке проблем с библиотекой Kerberos, например при поиске KDC, синхронизации времени и поиске имени сервера.
© 2012–2018 Michael DeHaan
© 2018–2025 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/projects/ansible/latest/os_guide/windows_winrm_kerberos.html