nodejs: SSO-авторизация через Kerberos +12
- 16.02.17 09:16
•
sjoekle
•
#321962
•
Хабрахабр
•
Из песочницы
•
•
4200
Node.JS, Криптография, Разработка веб-сайтов
Рекомендация: подборка платных и бесплатных курсов веб разработки — https://katalog-kursov.ru/
Всё гениальное просто. Но до этой простоты нужно перечитать тысячи мануалов. Поэтому, разобравшись, мне захотелось написать quick start по тому, как сделать прозрачную авторизацию в Web-приложении для пользователя, авторизованного в AD, и поделиться своим тестовым проектом. Интересен взгляд со стороны.
Для начала немного теории. SSO, она же прозрачная авторизация, это идея, по которой пользователь раз вводит логин/пароль своей учётной записи в Active Directory при входе на компьютер, и дальше, открывая Web-приложение (не только, но речь о нём) уже автоматически авторизуется с данными своей учётки.
В браузерах для этого заложен принцип — получая в ответ на свой Get-запрос HTTP-код 401 «Not Authorized», и в HTTP-заголовках <WWW-Authenticate: Negotiate>, он, браузер, делает запрос в KDC (Key Distribution Center — одна из служб AD) на получение специального SPNEGO-токена для данного Web-сервиса. Если учётки для такого Web-сервиса нет в AD, то браузер берёт стандартный ответ для авторизации по NTLM. Но в данном случае мы считаем, что что-то пошло не так.
Итак, браузер, в случае корректных настроек данного Web-сервиса в AD, на ответ 401 вновь отправляет Get-запрос, но уже с заголовком вида <Authorization: YIIJvwYGKw… > Если токен начинается так, с «YII», значит это Kerberos-закодированный тикет, содержащий данные для авторизации.
Kerberos — это просто тип шифрования, но поскольку он в основном используется для SSO, эти понятия тесно связаны.
Далее Web-сервис, получив токен, с помощью kerberos-клиента отправляет его в KDC на проверку. И, в случае успеха, получает имя пользователя в AD. Которое дальше уже можно использовать для поиска данных о пользователе (например, групп, в которых он состоит) уже через другой сервис доступа к AD — LDAP.
Наиболее наглядно описывает этот процесс схема из официальной документации Microsoft. И, надо сказать, на удивление именно их документация дала наибольшее понимание предмета.Отсюда
Таким образом, помимо создания Web-приложения, нужны следующие действия:Что требуется сделать на стороне администраторов AD
— задать в AD SPN-имя для Web-сервиса (вида HTTP/webservice.example.com@EXAMPLE.COM). Это позволит клиентским браузерам запрашивать токен для данного сервиса и передавать его в HTTP-заголовке Web-сервису, а Kerberos-клиенту через данный сервис на основе ключа проверять подлинность пользователей,
— сформировать для этого сервиса ключ krb5.keytab, который будет использоваться в Kerberos-клиенте для проверки подлинности пользователей.Дополнительные действия на сервере Web-сервиса
— потребуется установить Kerberos-клиент (в Windows он уже есть, в случае Linux — например, для RedHat команда для установки: yum install krb5-workstation krb5-libs krb5-auth-dialog krb5-devel);
— для него нужно будет настроить файл конфигурации krb5.conf для доступа к KDC (как — администраторы AD назовут правильные настройки, главный параметр — kdc);
— а также подложить файл ключа /etc/krb5.keytab.В Web-приложении
— устанавливается модуль kerberos, для работы с kerberos-клиентом,
— и модуль activedirectory, для выполнения LDAP-запросов.
Один неприятный момент — для Windows модуль kerberos предоставляет отдельный API, и использовать его не вышло. Если у кого-то есть решение — это была бы неоценимая помощь.
Для Linux модуль kerberos предоставляет два основных метода, которые нужны в работе:
— authGSSServerStep — отправка токена на проверку,
— authUserKrb5Password — авторизация по логин/пароль, на случай если прозрачная авторизация не сработала.
Документации по использованию методов нет, но есть толковые комментарии в файле lib\kerberos.js.
Вот основной кусок кода, проверяющий пришедший от браузера токен:
тестовый проект на GitHub
Настройка squid для авторизации на основе членства в доменной группе LDAP
Приступаем к финальному шагу. Для реализации авторизации на основе членства в доменной группе в squid используется внешний acl, т.н. параметр external_acl_type. Общая схема работы примерно следующая:
# задаем external_acl_type для взаимодействия с LDAP external_acl_type произвольное_имя_ext_acl %LOGIN /путь/к/хелперу/squid_ldap_group -R \ -b "BaseDN" -f "фильтр с переменной %v и %a" -D пользователь_ad@домен -K -W /файл/с/паролем имя_dc # где переменная %v подставляется за счет указания значения %LOGIN, # которое извлекает имя аутентифицированного пользователя # далее необходимо задать acl, которое будет передавать в переменную %a имя групп acl имя_acl external произволное_имя_ext_acl передаваемое_название_группы # далее необходимо с образовавшимся acl работать как с обычным acl, # то есть задавать какие-то разрешения с помощью соответствующих параметров
Если данную схему наложить на наш домен и нашу задачу, то получится примерно следующий конфиг:
ldap ~ # grep -v ^# /etc/squid3/squid.conf | grep -v ^$ auth_param negotiate program /usr/lib/squid3/squid_kerb_auth auth_param negotiate children 15 auth_param negotiate keep_alive on external_acl_type ldap_verify %LOGIN /usr/lib/squid3/squid_ldap_group -R \ -b "dc=ad,dc=local" -f "(&(objectclass=user)(sAMAccountName=%v)(memberOf=cn=%a,ou=groups,ou=UNIXs,dc=ad,dc=local))"\ -D -K -W /etc/squid3/aduser dc.ad.local. acl manager proto cache_object acl localhost src 127.0.0.1/32 acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https acl CONNECT method CONNECT acl localnet src 10.0.0.0/16 acl to_localnet dst 10.0.0.0/16 acl users external ldap_verify squid acl users-list external ldap_verify squid-list acl whitelist dstdomain "/etc/squid3/acls/whitelist.acl" acl allusers proxy_auth REQUIRED http_access allow manager localhost http_access allow localhost http_access deny manager http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow users http_access allow users-list whitelist http_access deny !allusers all http_access deny all http_port 10.0.0.10:3129 http_port 127.0.0.1:3129 hierarchy_stoplist cgi-bin ? coredump_dir /var/spool/squid3 refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 20% 4320
Давайте разберем получившийся конфиг. Как видно, добавился параметр external_acl_type, заставляющий sqiud обращаться к каталогу LDAP, расположенному на контроллере домена dc.ad.local, через хелпер squid_ldap_group. squid_ldap_group ищет пользователей в каталоге, начиная с пути dc=ad,dc=local, авторизованных пользователей, принадлежащих некоторым группам, имена которых (групп) передаются из acl в переменную %a. Как мы видим, у нас пропал параметр -d за ненадобностью и появился параметр -K. Давайте его разберем. Мы , что при Negotiate Kerberos аутентификации имя пользователя у нас получается в виде пользователь@ДОМЕН, а хелпер squid_ldap_group использует имена в формате пользователь (то есть без доменной части). Так вот, ключ -K заставляет squid_ldap_group «обрезать» часть имени @ДОМЕН и корректно сравнивать имя пользователя и группу.
Далее мы видим, что появилось 3 новых acl — users, users-list и whitelist, которые проверяют принадлежность пользователя к группе с именем squid, к группе с именем squid-list и задает белый список сайтов соответственно. При этом, про первые 2 acl было бы понятней сказать, что они передают в external_acl_type с именем ldap_verify имя группы, которой должен принадлежать аутентифицированный пользователь.
Ну и последнее — это появление двух параметров http_access, которые разрешают доступ acl с именем users и acl с именем users-list при доступе этих пользователей к сайтам из acl whitelist. Кроме того, был убран параметр http_access allow allusers, который разрешал доступ всем аутентифицированным пользователям.
На этом в настройке можно поставить точку. Перезапускаем сквид и наши пользователи, которые входят в доменные группы squid и squid-list могут работать в интернете.
Как контролировать протокол NTLM
Когда мы говорим о мониторинге трафика NTLM, вы можете узнать, какие приложения или порты отправляют или получают пакеты NTLM на вашем ПК. Это можно сделать как на серверах Windows, так и на клиентской ОС Windows.
Трафик NTLM можно отслеживать различными способами:
Мониторинг NTLM с помощью групповой политики
Microsoft предоставляет групповую политику, которую можно использовать для проверки подлинности NTLM в доменах AD. Кроме того, он показывает запросы проверки подлинности NTLM к контроллерам домена. Кроме того, политика также предлагает различные параметры, которые обсуждаются в следующих шагах.
Выполните следующие действия, чтобы начать мониторинг трафика NTLM в вашей сети:
-
Откройте редактор групповой политики, введя «gpedit.msc» в поле «Выполнить команду».
Откройте редактор групповой политики
-
Перейдите к следующему на левой панели:
Конфигурация компьютера >> Параметры Windows >> Параметры безопасности >> Локальные политики >> Параметры безопасности
-
На правой панели откройте политику «Сетевая безопасность: Ограничить NTLM: Аудит проверки подлинности NTLM в этом домене».
Открытая политика аудита NTLM
-
Теперь выберите один из следующих вариантов в раскрывающемся меню:
- Включить для учетных записей домена серверы домена – регистрирует события, связанные с аутентификацией NTLM для учетных записей домена на контроллерах домена.
- Включить для учетных записей домена – Записывает события для попыток входа в систему NTLM с использованием учетных записей домена.
- Включить для серверов домена – Регистрировать аутентификацию NTLM на всех серверах в домене.
- Включить все (рекомендуемый вариант) – Записывает сквозные проверки подлинности NTLM с серверов и для учетных записей.
Установите политику, чтобы начать мониторинг трафика NTLM
-
Нажмите Применять и Хорошо.
-
Запустите следующий командлет в командной строке с повышенными привилегиями, чтобы применить изменения политики:
GPUUpdate/Force
Применить изменения политики
Теперь компьютер начнет записывать и регистрировать трафик NTLM и сохранять журналы в средстве просмотра событий. Вот как вы можете просматривать журналы в средстве просмотра событий:
-
Откройте средство просмотра событий, введя «eventvwr.msc» в поле «Выполнить команду».
Откройте средство просмотра событий
-
Перейдите к следующему на левой панели:
Журналы приложений и служб >> Microsoft >> Windows >> NTLM >> Operational
-
Здесь будут отображаться все события о протоколе NTLM.
Просмотр журналов NTLM в средстве просмотра событий
Еще один более быстрый способ просмотра всех журналов NTLM — из Windows PowerShell.
Мониторинг NTLM с помощью PowerShell
Журналы трафика NTLM также можно проверить с помощью PowerShell. Однако вам все равно потребуется включить групповую политику, как обсуждалось выше.
Используйте следующую команду для получения событий NTLM в PowerShell с повышенными правами:
Get-WinEvent -LogName «Microsoft-Windows-NTLM/Operational»
Просмотр журналов NTLM из PowerShell
Мониторинг NTLM с помощью событий входа в систему
Вы также можете узнать, какие приложения используют NTLMv1, отслеживая успешность событий входа в систему на контроллере домена. Конечно, для этого необходимо настроить групповую политику. Следуй этим шагам:
-
Откройте редактор групповой политики, введя «gpedit.msc» в поле «Выполнить команду».
Откройте редактор групповой политики
-
Перейдите к следующему на левой панели:
Конфигурация компьютера >> Параметры Windows >> Параметры безопасности >> Локальные политики >> Политика аудита
-
На правой панели откройте политику «Аудит событий входа в учетную запись».
-
Выбирать «Успех«, а затем нажмите Применять и Хорошо.
Аудит событий входа в систему
-
Запустите следующий командлет в командной строке с повышенными привилегиями, чтобы применить изменения политики:
GPUUpdate/Force
Применить изменения политики
Теперь вы можете снова проверить в средстве просмотра событий события входа в систему, чтобы определить приложения, все еще использующие протокол NTLM. Эти события будут иметь идентификатор события «4624».
Это все способы узнать и отслеживать, какие приложения используют протокол NTLM. Давайте теперь посмотрим, как отключить/заблокировать аутентификацию NTLM в вашем домене.
История
LAN Manager был основан на OS / 2 операционная система разработана совместно IBM и Microsoft. Первоначально он использовал Блок сообщений сервера (SMB) поверх любого Кадры NetBIOS (NBF) или специализированная версия Сетевые системы Xerox (XNS) протокол. Эти устаревшие протоколы были унаследованы от предыдущих продуктов, таких как MS-Net за MS-DOS, Xenix-NET за MS-Xenix, и вышеупомянутый 3 + Share. Версия LAN Manager для систем на базе Unix, называемая LAN Manager / X также был доступен.
В 1990 году Microsoft анонсировала LAN Manager 2.0 с множеством улучшений, включая поддержку TCP / IP как транспортный протокол. Последняя версия LAN Manager, 2.2, которая включала базовую операционную систему MS-OS / 2 1.31, оставалась стратегической серверной системой Microsoft до выпуска Сервер Windows NT Advanced в 1993 г.
Версии
- 1987 — MS LAN Manager 1.0 (базовый / расширенный)
- 1989 — MS LAN Manager 1.1
- 1991 — MS LAN Manager 2.0
- 1992 — MS LAN Manager 2.1
- 1992 — MS LAN Manager 2.1a
- 1993 — MS LAN Manager 2.2
- 1994 — MS LAN Manager 2.2a
Многие поставщики поставляли лицензионные версии, в том числе:
- 3Com Corporation 3 + Открыть
- HP LAN Manager / X
- Сервер IBM LAN
- Гобелен Тор
- Операция Санта-Крус
Принцип работы NTLM
Принцип работы NTLM имеет много общего с LAN Manager и эти протоколы обратно совместимы, но есть и существенные отличия. NT-хэш формируется на основе пароля длиной до 128 символов по алгоритму MD4, пароль регистрозависимый и может содержать не только ACSII символы, но и Unicode, что существенно повышает его стойкость по сравнению с LM. Работа происходит следующим способом(рис.1):
Для получения доступа к ресурсу клиент направляет серверу запрос с именем пользователя. Сервер в ответ передает ему случайное число, называемое запросом сервера. Клиент зашифровывает данный запрос по алгоритму DES, используя в качестве ключа NT-хэш пароля, использую 40 или 56 битный ключ(хеш делится на три части и каждая часть шифрует запрос сервера отдельно), так как NT-хэш имеет 128 битную длину.
Зашифрованный хэшем пароля запрос сервера называется ответом NTLM и возвращается обратно серверу, сервер берет из SAM хэш пароля пользователя, чье имя было ему передано и выполняет те же самые действия с запросом сервера, и после сравнивает полученный результат с ответом от NTLM. При совпадении значений, аутентификация считается успешной, и это значит пользователь клиента действительно тот, за кого себя выдает.
При получении доступа третьими ресурсами схема изменяется(рис.2):
Получив запрос от клиента, сервер направляет ему запрос сервера, но получив NTLM-ответ он не имеет возможности посчитать значение для проверки у себя на стороне, так как у него нету хэша пароля доменного пользователя, и тогда он переадресует NTLM-ответ контроллеру домена и отправляет ему свой запрос сервера. Получив эти данные, контроллер домена извлекает хэш указанного пользователя и вычисляет на основе запроса сервера проверочную последовательность, которую уже и сравнивает с полученным NTLM-ответом. Если они равны, на сервер отправляется сообщение, что аутентификация успешно пройдена.
Несмотря на на что, протокол NTLM на сегодняшний день считается слабым. Слабое шифрование делает возможным достаточно быстро восстановить хэш пароля, а если использовался не только NTLM, а еще и LM-ответ, то и восстановить пароль.
Пользователям запрещается доступ к развертыванию, которое использует Remote Credential Guard с несколькими брокерами подключений к удаленному рабочему столу
Эта проблема возникает в развертываниях с высоким уровнем доступности, в которых используются не менее двух брокеров подключений к удаленному рабочему столу и Remote Credential Guard в Защитнике Windows. Пользователям не удается войти на удаленные рабочие столы.
Эта проблема связана с тем, что Remote Credential Guard использует Kerberos для проверки подлинности, а также запрещает использовать NTLM. Но в конфигурации с высоким уровнем доступности и балансировкой нагрузки брокеры подключений к удаленному рабочему столу не могут поддерживать операции Kerberos.
Если нужно использовать конфигурации с высоким уровнем доступности и балансировкой нагрузки брокеров подключений к удаленному рабочему столу, эту проблему можно устранить, отключив Remote Credential Guard. Дополнительные сведения об управлении Remote Credential Guard в Защитнике Windows см. в статье (Защита учетных данных удаленного рабочего стола с помощью Remote Credential Guard в Защитнике Windows).
Аудит событий NTLM аутентификации в домене
Перед полным отключением NTLM в домене и переходе на Kerberos желательно убедиться, что в домене не осталось приложений, которые требуют и используют NTLM авторизацию.
Для отслеживания учетных записей и приложение, которые используют NTLM аутентификацию, вы можете включить политики аудита на всех компьютерах с помощью GPO. В разделе Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> Security Options найдите и включите политику Network Security: Restrict NTLM: Audit NTLM authentication in this domain, установив ее значение на Enable all.
Аналогичным образом включите политику Network Security: Restrict NTLM: Audit Incoming NTLM Traffic, установив ее значение на Enable auditing for domain accounts.
После включения данных политик события использования NTLM аутентификации записываться в журнал событий Event Viewer в секцию Application and Services Logs-> Microsoft -> Windows -> NTLM.
Можно проанализировать события на каждом сервере, или собрать все события в центральный Event Log.
Вам нужно собрать события от Microsoft-Windows-Security-Auditing c Event ID 4624 – An Account was successfully logged on
Обратите внимание на информацию в секции “Detailed Authentication Information”. Если в строке Authentication Package указано NTLM, значит для аутентификации этого пользователя использовался протокол NTLM
Теперь обратите внимание на значение Package Name (NTLM only). Здесь должно быть указано какой протокол (LM, NTLMv1 или NTLMv2) использовался для аутентификации
Таким образом вам нужно идентифицировать все сервера/приложения, которые используют устаревший протокол.
Например, для поиска всех событий аутентификации по NTLMv1 по всем контроллерам домена можно использовать такой PowerShell скрипт:
$ADDCs = Get-ADDomainController -filter * -Server winitpro.ru $Now = Get-Date $Yesterday = $Now.AddDays(-1) $NewOutputFile = "c:\ps\Events$($Yesterday.ToString('yyyyMMdd'))_AD_NTLMv1_events.log" function GetEvents($DC){ Write-Host "Searching log on " $DC.HostName $Events = Get-EventLog "Security" -After $Yesterday.Date -Before $Now.Date -ComputerName $DC.HostName -Message "*V1*" -instanceid 4624 foreach($Event in $Events){ Write-Host $DC.HostName $Event.EventID $Event.TimeGenerated Out-File -FilePath $NewOutputFile -InputObject "$($Event.EventID), $($Event.MachineName), $($Event.TimeGenerated), $($Event.ReplacementStrings),($Event.message)" -Append } } foreach($DC in $ADDCs){GetEvents($DC)}
После того, как вы нашли пользователей и приложения, использующие NTLM в вашем домене, попробуйте перевести их на использование Kerberos (возможно с использованием SPN). Некоторые приложения достаточно донастроить для работы Kerberos авторизации (см. статьи Kerberos авторизация в IIS, использование Kerberos авторизация в браузерах). Из личного опыта: даже действительно большие коммерческие продукты иногда еще не перешли с использования NTLM на Kerberos, некоторые продукты требуют обновления или изменений конфигурации. Все сводится к определению того, какие приложения используют проверку подлинности NTLM, и теперь у вас есть способ для выяснения этого софта и устройств.
Те приложений, которые нельзя переключить на использование NTLM можно добавить в исключения, разрешив им использовать NTLM аутентификацию, даже если она отключена на уровне домена. Для этого используется политика Network security: Restrict NTLM: Add server exceptions for NTLM authentication in this domain. В список исключений нужно добавить имена серверов, для аутентификации на которых можно использовать NTLM (конечно, в идеале этот список исключений должен быть пустым). Можно использовать знак подстановки *.
Computer Account–Related Kerberos Events
To support Windows infrastructure features such as AD,
Group Policy, and Dynamic DNS updates, workstations and servers must
communicate frequently with the DC. This communication begins when a computer
boots up. Each system that boots up obtains a TGT from the DC, followed by
service tickets to krbtgt and the DC. These communications result in a ,
, event ID pattern.
Windows logs many Kerberos events that most people
consider extraneous and that you can simply ignore. The events are a result of
computers authenticating to the DC. You can identify such computer-to-computer
authentication events because the listed username will be a computer instead of
a user. Computer account names are easily recognizable because they have a $
appended to the name (e.g., FS2$).
You will also see plenty of occurrences of event ID ,
resulting from ticket expirations. When a computer remains up for an extended
period of time, its service ticket reaches the lifetime limit imposed by the
domain’s Kerberos policy. When that happens, the computer attempts to renew the
ticket. When the renewal succeeds, the DC logs event ID . When the ticket
has reached its maximum renewal lifetime, the renewal fails and the DC logs
event ID . This forces the computer to re-authenticate to the DC and obtain
a TGT all over again, thus causing a repeat of the event sequence that is
logged when a computer first starts. Ticket expiration is a natural part of
Kerberos activity and can be ignored.
Проверка
Для проверки на сервере открываем лог:
tail -f /var/log/squid/access.log | grep dmosk
* dmosk — учетная запись в AD, от которой будем проверять работу squid.
Теперь на клиентском компьютере заходим в систему под нашей учетной записью (в данном примере, dmosk) и грузим любой сайт.
На сервер в логах должны появиться записи, примерно, такого вида:
1526474100.078 240 192.168.1.16 TCP_TUNNEL/200 934 CONNECT syndication.twitter.com:443 dmosk HIER_DIRECT/134.144.40.72 —
1526474100.743 45 192.168.1.16 TCP_TUNNEL/200 559 CONNECT login.vk.com:443 dmosk HIER_DIRECT/187.244.139.145 —