Аутентификация Kerberos

# Термины и определения

термин описание пример
DOMAIN_NAME название домена test.com
REALM для Active Directory это всегда DOMAIN_NAME в верхнем регистре TEST.COM
SERVER_NAME название компьютера, где установлен RunaWFE Server runaserver
SERVER_USER логин пользователя, под которым работает RunaWFE Server runauser
SERVER_SPN SPN (Service principal name), который соответствует SERVER_USER

Формат FQDN для Windows2008: HTTP/{SERVER_NAME}.{DOMAIN_NAME}

Формат FQDN для Windows2003: HTTP/{SERVER_NAME}.{DOMAIN_NAME}@{REALM}

Формат NetBIOS для Windows2008: HTTP/{SERVER_NAME}

Формат NetBIOS для Windows2003: HTTP/{SERVER_NAME}@{REALM}

HTTP/runaserver.test.com

HTTP/runaserver.test.com@TEST.COM

HTTP/runaserver

HTTP/runaserver@TEST.COM

KEYTAB_PATH Путь к keytab-файлу ключей, хранящему хеши паролей пользователей C:/runawfe/krb5.keytab

# Инструменты

название описание расположение комментарии
kinit Получение тикета TGT из контроллера домена JDK bin, есть альтернативные реализации пользователь может быть задан в виде {SERVER_USER} или {SERVER_USER}@{REALM}
klist Просмотр полученных тикетов и возможность их удаления из локального кеша JDK bin, есть альтернативные реализации
setspn Создаёт SPN и назначает его пользователю входит в Windows Server 2008+, ранее доступен в пакете Windows Server support tools
ktpass Меняет логин пользователя на SPN или формирует keytab файл входит в Windows Server 2008+, ранее доступен в пакете Windows Server support tools
ktab Формирует keytab файл JDK bin
ADSIEdit Просмотр свойств пользователя в контроллере домена Windows Server
WireShark Анализатор траффика https://www.wireshark.org/

# Описание

Более строгое описание можно найти в интернете, например https://blogs.technet.microsoft.com/askds/2008/03/06/kerberos-for-the-busy-admin/.

KerberosAuthenticationOverview.png

этап протокол описание данные запроса данные ответа примечания
0 KRB аутентификация пользователя клиента логин пользователя тикет TGT при входе в систему
1 HTTP вход в систему без HTTP заголовка Authorization HTTP 401 http://{SERVER_SPN}:8080/wfe/krblogin.do
2 KRB получение сервисного тикета для сервера {SERVER_SPN} сервисный тикет шаг выполняется если тикета ещё нет в кеше клиента
3 HTTP продолжение входа в систему HTTP заголовок Authorization = YIIV… HTTP 200 http://{SERVER_SPN}:8080/wfe/krblogin.do
4 KRB аутентификация пользователя сервера {SERVER_SPN} тикет TGT выполняется при отсутствии TGT во время взаимодействия с клиентом, происходит до возврата ответа 3 клиенту

# Типы шифрования

Выбранный тип шифрования зависит от участников взаимодействия — версии ПО домена (Windows Server), настроек домена, настроек пользователя, настроек ПО клиента.

В ранних версиях (Windows 2000, 2003) настраивали DES, в поздних (Windows 2008, 2012) рекомендуют использованием AES.

Настройки пользователя, оказывающие влияние на поведение Kerberos:

  • This account supports Kerberos AES 128/256 bit encryption — разрешение использования соответствущего типа шифрования для пользователя

(TODO — при невключённых чекбоксах всё равно использовался AES128)

  • Use Kerberos DES encryption for this acount — включает шифрование DES для пользователя, после установки чекбокса требуется смена пароля

# krb5.ini

Файл не является обязательным, но может влиять на поведение процесса аутентификации.

Детальное описание файла конфигурации Kerberos

На сервере и клиентских машинах Windows он может быть расположен в ${windir}/krb5.ini.

Пример файла krb5.ini

[domain_realm]
 .test.com = TEST.COM
 test.com = TEST.COM
[libdefaults]
 default_realm = TEST.COM
 kdc_timesync = 1
 ccache_type = 4
 ticket_lifetime = 600
 default_tkt_enctypes = des-cbc-md5 des-cbc-crc des3-cbc-sha1
 default_tgs_enctypes = des-cbc-md5 des-cbc-crc des3-cbc-sha1
 permitted_enctypes = des-cbc-md5 des-cbc-crc des3-cbc-sha1
[logging]
 kdc = CONSOLE
[realms]
 TEST.COM = {
  kdc = 192.168.0.1
  kdc = 192.168.1.1
  default_domain = test.com
 }
[appdefaults]
 autologin = true
 forward = true
 forwardable = true
 encrypt = true

# Настройка сервера

Данная инструкция сделана в окружении Windows Server2008R2 (контроллер домена), Windows Server2012R2 (RunaWFE Server), Windows7 (RunaWFE client).

В данном разделе регистр может иметь значение, хотя опытным путём было выяснено что логин пользователя, название компьютера сервера и SPN не являются регистрозависимыми.

# Создание пользователя для сервера

На контроллере домена нужно создать пользователя {SERVER_USER} с настройками по умолчанию.

Проверка: kinit {SERVER_USER} должен успешно получить тикет.

# Создание SPN

На контроллере домена нужно выполнить команды:

setspn -A {SERVER_SPN} {SERVER_USER}

Проверка: через ADSIEdit можно увидеть что свойство пользователя servicePrincipalName установлено либо посмотреть св-во servicePrincipalName с помощью команды Get-ADUser {SERVER_USER} -Properties *.

Если планируется использовать SPN на основании NetBIOS имени — то нужно зарегистрировать и его (https://msdn.microsoft.com/en-us/library/ms677949.aspx)

setspn -A HTTP/{SERVER_NAME} {SERVER_USER}

# Привязка SPN к пользователю сервера

На контроллере домена нужно выполнить команду:

ktpass /princ {SERVER_SPN} /mapuser {SERVER_USER} +setupn /pass *

Можно игнорировать предупреждение «WARNING: pType and account type do not match. This might cause problems».

Для обхода бага со сбросом пароля https://support.microsoft.com/en-us/kb/939980 рекомендуют вписать пароль вместо звёздочки. А если выполнить данную команду без пароля — то почему-мо возникает ошибка 24 с некорректным salt.

Проверка: в свойствах пользователя User logon name стал равен SPN либо посмотреть св-во UserPrincipalName с помощью команды Get-ADUser {SERVER_USER} -Properties *.

UserLogonName.png

Проверка: kinit {SERVER_SPN} должен успешно получить тикет.

# Создание keytab для SPN

Выполнить команду из {JAVA_HOME}/bin:

ktab -a {SERVER_SPN} -n 0 -k {KEYTAB_PATH}

Проверка: kinit -k -t {KEYTAB_PATH} {SERVER_SPN} должен успешно получить тикет без запроса пароля.

Этот файл также можно получить в результате вызова команды ktpass на контроллере домена.

# Настройка kerberos.properties

Создайте файл kerberos.properties в директории {RUNAWFE_JBOSS}/standalone/wfe.custom. Замените в нем имена на настоящие.

# задействовать аутентификацию используя RunaWFE API
api.auth.enabled=true
appName=com.sun.security.jgss.krb5.accept
moduleClassName=com.sun.security.auth.module.Krb5LoginModule
principal={SERVER_SPN}
storeKey=true
useKeyTab=true
keyTab={KEYTAB_PATH}
doNotPrompt=true
# режим отладки аутентификации
debug=true
# задействовать аутентификацию по протоколу HTTP (из веб-интерфейса)
http.auth.enabled=true
jcifs.http.enableNegotiate=true
# режим отладки аутентификации
sun.security.krb5.debug=true
jcifs.spnego.servicePrincipal={SERVER_SPN}
http.auth.preference=Kerberos

# Команды для выполнения по вышеперечисленным пунктам

На контроллере домена:

setspn -A HTTP/runaserver.test.com runauser

ktpass -princ HTTP/runaserver.test.com -pass * -mapuser runauser

На сервере:

ktab -a HTTP/runaserver.test.com -n 0 -k C:/runawfe/krb5.keytab

# Настройка браузера

Для того чтобы браузер пытался использовать Kerberos для аутентификации:

  • в нём должна быть включена настройка Enable Integrated Windows Authentication (в некоторых версиях IE её нет)
  • настройки зоны безопасности должны позволять её использование, по умолчанию это настроено для LocalIntranet
  • настройка {SERVER_SPN} должна быть корректно произведена

Во время запроса на сервере формируется в логе Request Authorization:

  • Negotiate YIIV… — правильно
  • Negotiate TlRMT… — неправильно (попытка использовать NTLM)

Если по нажатию на ссылке Сквозная аутентификация (kerberos) будет выведено окно с вводом логина/пароля — то это значит что браузер не получил сервисный тикет в контроллере домена или даже не пытался это сделать. При возникновении такой ситуации самым действенным оказывается использование WireShark для прослушивания траффика по порту 88 с контроллером домена.

# Настройка оповещателя

На сервере должна быть корректно настроена аутентификация.

# Настройка для получения заданий

Настроить kerberos.properties если authentication.type установлено в kerberos (для sspiKerberos это не требуется):

appName=com.sun.security.jgss.initiate
moduleClassName=com.sun.security.auth.module.Krb5LoginModule
useTicketCache=true
doNotPrompt=true
debug=true
serverPrincipal=HTTP/runaserver.test.com

# Настройка для браузера

Настройку login.relative.url установить в /krblogin.do.

# Типичные проблемы

https://technet.microsoft.com/en-us/library/bb463167.aspx

ошибка описание что делать

Client not found in Kerberos database (6)

SPN не зарегистрирован как пользователь (UserPrincipalName) либо продублирован (setspn -x) Зарегистрировать SPN либо удалить дубликат

Pre-authentication information was invalid (24)

Неправильный пароль либо несовпадение информации по логину (UserPrincipalName изменён?).

Обратите внимание на атрибут salt в пакете KRB Error: KRB5KDC_ERR_PREAUTH_FAILED, он должен совпадать с principal, для которого вы получаете тикет; если не совпадает — то в БД kerberos что-то не так, попробуйте вновь воспользоваться командой ktpass

Сменить пароль (у пользователя и при формировании keytab)

Message stream modified (41)

Некорректно задано имя Задать имя корректно — как оно задано на контроллере домена с учётом регистра

Clients credentials have been revoked (18)

Пользователь заблокирован В настройках пользователя снять галочку Account is disabled

HTTP 400 при попытке обработки тикета YIIV…

Заголовок превышает разрешённый максимум в Jboss, по умолчанию = 8Кб (https://access.redhat.com/solutions/1173073, http://www.novell.com/support/kb/doc.php?id=7005181) Увеличить разрешённый максимум в Jboss с помощью настройки org.apache.coyote.http11.Http11Protocol.MAX_HEADER_SIZE в standalone.xml

No valid credentials provided (Mechanism level: Attempt to obtain new ACCEPT credentials failed!)

Настройка appName=com.sun.security.jgss.accept является устаревшей — для старых версий JDK Изменить на com.sun.security.jgss.krb5.accept в kerberos.properties

Encryption type AES256 CTS mode with HMAC SHA1-96 is not supported/enabled

Нет поддержки типа шифрования AES-256 в JDK Изменить тип шифрования (https://blogs.msdn.microsoft.com/openspecification/2011/05/30/windows-configurations-for-kerberos-supported-encryption-type/) или установить «Unlimited Strength Java(TM) Cryptography Extension Policy Files».

Включение аудита на контроллере домена иногда помогает понять проблему (логирование происходит в журнале событий, категория Безопасность.

Kerberos audit enable.png