Кратко об NTLM-аутентификации
Как многие знают, протокол NTLM до недавнего времени являлся основным протоколом аутентификации в сетях Windows. Давайте вспомним общие принципы работы протокола.
Протокол NTLM относится к семейству протоколов, функционирующих по принципу challenge/response (запрос/ответ). В общем случае на клиентскую попытку аутентификации сервер отвечает определенного вида запросом. Клиент, в свою очередь, вычисляет ответ и, кроме всего прочего, включает в него данные запроса сервера. Сервер в состоянии произвести подобный расчет самостоятельно. После получения ответа клиента сервер может удостовериться, знает ли клиент общий секрет и, как следствие, аутентифицирован ли он.
В случае удачной аутентификации система или приложение, которое использует этот механизм аутентификации, обычно создает маркер безопасности того пользователя, который пытается провести аутентификацию. В целях безопасности этот маркер имеет тип «маркер олицетворения» (impersonating token); его особенность в том, что поток или процесс, созданный с ним, обладает правами только на локальной системе.
Однако представим себе сценарий, в котором клиенты работают с неким внешним сервером, который, в свою очередь, подключается к другому серверу для получения каких-то данных. Типичным сценарием, например, является связка Web-сервера и сервера баз данных, расположенных на разных физических или виртуальных хостах. Как видно из свойств протокола, он не предоставляет возможности внешнему серверу корректно передать запрос пользователя другим серверам и ресурсам сети.
Кроме того, сам протокол довольно уязвим для разного рода атак, по большей части в связи со своим возрастом. Его периодически стараются усовершенствовать, пытаются обеспечить его безопасность, в частности меняют методы генерации ответов клиента.
Возможности Kerberos
В конечном итоге на замену NTLM для решения указанных проблем был призван протокол Kerberos, разработанный в MIT. Этот механизм удачно решает проблему переноса прав пользователей на всем пути следования запроса. Он называется «делегированием полномочий» (не путать с делегированием полномочий управления объектами Active Directory).
Попробуем, опять же вкратце, рассмотреть работу этого протокола, для того чтобы понять, как работает делегирование и как его настраивать.
Архитектура SSP
Работа с протоколами аутентификации в Windows унифицирована при помощи интерфейса Security Support Provider Interface (SSPI). Интерфейс SSPI в Windows предоставляет собой механизм, который позволяет приложениям не зависеть от принципов протоколов аутентификации и дает возможность универсальной работы с любым из них, то есть обеспечивает возможность применения любого протокола любым приложением. Кроме того, интерфейс изолирует сетевой транспорт от протоколов аутентификации. Другими словами, эти протоколы становятся независимыми от протоколов передачи данных по сети, и приложение в равной степени может использовать любой из них для целей аутентификации. Структура интерфейса представлена на рис. 1.
Основными действующими лицами в этой архитектуре являются провайдеры Security Support Provider (SSP). Именно эти модули реализуют механизмы аутентификации. В Windows встроены основные модули, однако разработчики могут создавать и подключать свои модули к SSPI, дополнительная информация об этом приведена во врезке «Встроенные модули аутентификации». Здесь можно вспомнить странное сообщение об ошибке, которое мы видим порой в различных приложениях: Cannot generate SSPI context. Это сообщение говорит об ошибке аутентификации с использованием одного из провайдеров SSPI.
Kerberos: общие принципы
Ключи. Работа протокола основана в первую очередь на криптографических ключах и на предположении, что если двум сторонам известен некий ключ и они в состоянии подтвердить этот факт, то они смогут однозначно идентифицировать друг друга.
В текущей реализации протокола используется несколько видов ключей:
1. Пользовательский ключ. Когда создается учетная запись пользователя, его пароль используется для создания ключа. Ключ хранится вместе с объектом пользователя в Active Directory. Таким образом, ключ знают два участника безопасности: клиент, то есть пользователь, и контроллер домена.
2. Системный ключ. Когда компьютер присоединяется к домену, он получает пароль. На его основе создается ключ, по тому же принципу, что и для пользовательского объекта.
3. Ключ службы (service key). Здесь все зависит от ситуации. Если некая служба запускается под учетной записью некоего доменного пользователя, он получает ее ключ. Если же он запускается под учетной записью LocalSystem, то получает ключ компьютера, на котором она запущена. Например, это службы KDC (см. врезку «За билеты отвечает KDC»).
4. Междоменный ключ (inter-realm key). Этот ключ обеспечивает междоменную аутентификацию и используется для обеспечения доверительных отношений в среде Aсtive Directory.
Билеты. Основным компонентом протокола являются билеты (tickets). Их всего два: Ticket-Granting Ticket (TGT) и Ticket-Granting Service (TGS).
- Ticket-Granting Ticket (TGT). Во время процесса аутентификации клиент обращается к KDC и запрашивает TGT. Это специальный билет, который хранит информацию об авторизовавшемся пользователе и таким образом, обеспечивает передачу этой информации службе, выдающей следующий тип билетов. Здесь важно помнить, что TGT шифруется при помощи ключа, общего для служб KDC, то есть клиент не может прочитать информацию из своего билета. Этот билет используется клиентом для получения других билетов.
- Ticket-Granting Service. Эти билеты выдаются клиенту по запросу и используются для передачи информации о клиенте тому серверу или службе, к которому этот клиент пытается обратиться. Для получения билета клиент предоставляет KDC информацию о том, куда он хочет подключиться, и свой TGT.
Еще одна очень важная для дальнейшего понимания статьи деталь. В ответ на запрос клиента сервер возвращает ему две копии сессионного ключа для связи с запрашиваемым ресурсом. Одна копия — клиентский сессионный ключ. Эта копия зашифрована ключом, общим между KDC и клиентом. Вторая копия — собственно билет для доступа к службе. В нем содержится копия сессионного ключа, а также информация о клиенте. Все эти данные зашифрованы ключом, общим между этим сервисом и KDC. Таким образом, для клиента эти данные недоступны, однако служба, которой предназначен билет, сможет его расшифровать и прочесть. Важно понять, что для выдачи билета KDC должен точно знать, какой именно службе или серверу он выдает билет и каким именно ключом его шифровать. Однако как же KDC узнает, чем шифровать этот билет?
Service Principal Names (SPN). Service Principal Names — это уникальный идентификатор службы. Он должен быть уникален в пределах леса, в котором регистрируется. Каждая служба, которая будет использовать Kerberos, должна иметь зарегистрированный SPN. Без правильно настроенного идентификатора протокол для этой службы или сервера работать не будет.
Данный идентификатор сохраняется в атрибуте Service-Principal-Name объекта Active DIrectory той учетной записи, под которой стартует служба. Если она стартует под учетной записью компьютера, то SPN сохраняется в учетной записи компьютера. В общем случае SPN представляет собой строку (см. врезку «Формат SPN»).
Таким образом, SPN связывает воедино все части процесса. Клиент знает, к какой службе он хочет получить доступ. И при запросе ключа он строит строку SPN, к примеру, при помощи функции DsMakeSpn. Сервер KDC, получив эти данные, может найти учетную запись, под которой стартует эта служба, и, используя ключ этой учетной записи из Active Directory, создать билет доступа к службе и зашифровать его этим ключом.
Регистрация SPN. Идентификатор службы регистрируется двумя путями. В первом случае, если служба запускается под учетной записью локальной системы, она должна зарегистрировать его сама. Так поступают многие службы Microsoft, например SQL Server. Если же служба использует созданную администратором учетную запись и вы хотите, чтобы для работы с ней выполнялась аутентификация Kerberos, то необходимо создать этот идентификатор самостоятельно. Для этого существует утилита setspn, которая позволяет просматривать, добавлять и удалять регистрации SPN (см. врезку «Параметры командной строки setspn»).
Выполняем делегирование
Существует два метода делегирования полномочий в Kerberos:
- Proxy tickets. В данном случае клиент получает билет для внутреннего сервера самостоятельно и затем передает его внешнему серверу. А тот, в свою очередь, использует его для работы с внутренним. Проблема здесь заключается в том, что клиент должен знать имя внутреннего сервера.
- Forwarded Tickets. В этом сценарии клиент может передать внешнему серверу свой TGT, при помощи которого последний может запрашивать билеты доступа к любым службам. Имея TGT клиента, внешний сервер сам как бы становится клиентом. Этот метод свободен от проблемы, указанной в первом методе.
Для того чтобы делегирование работало, должно выполняться три условия.
- Компьютеры, которые выполняют клиентское приложение, промежуточные между внешним и внутренним сервером, или конечные внутренние серверы должны работать под управлением операционной системы не ниже Widows 2000 и быть членами домена Active Directory. Это обусловлено тем, что Kerberos поддерживается начиная с Windows 2000, а служба KDC работает на контроллерах доменов.
- Учетной записи клиента должно быть разрешено делегирование.
- Учетной записи внешнего сервера должно быть разрешено делегирование.
Forwarded Tickets
Итак, в нашем случае будет использоваться метод передачи билета TGT промежуточному серверу. Поэтому остановимся на нем подробнее.
Если клиент желает делегировать задачу получения билетов для одного или нескольких конечных серверов некоему промежуточному серверу, он должен попросить у KDC специальный билет — передаваемый билет (forwardable TGT). По большому счету, это обычный TGT билет, в котором установлен флаг FORWARDABLE. После получения такого билета от KDC клиент вправе передать его промежуточному серверу.
Когда промежуточному серверу необходим билет доступа к службе (Service Ticket) на конечном сервере, он может запросить его, используя TGT, полученный от клиента. В итоге он получит такой билет, словно его запрашивал сам клиент. Процесс обмена сообщениями при этом представлен на рисунке 2.
- Клиент запрашивает TGT. Билет запрашивается как FORWARDABLE.
- KDC возвращает запрошенный билет. Билет помечен как FORWARDABLE.
- Клиент использует TGT для запроса билета доступа к службе для промежуточного сервера.
- KDC возвращает билет доступа к службе для промежуточного сервера.
- Клиент использует билет доступа к службе, чтобы подключиться к промежуточному серверу, и запрашивает взаимную аутентификацию.
- Клиент аутентифицирует промежуточный сервер. В этой статье не рассматриваются различные специфичные аспекты протокола, в частности взаимная аутентификация, поэтому пояснение к данному пункту опустим.
- Вплоть до этой точки обмен был аналогичен обмену при обычной аутентификации.
- После прохождения взаимной аутентификации клиент передает серверу свой TGT и сессионный ключ, которые будут использоваться в дальнейшем для запроса билетов к другим службам. Для доставки этих данных применяется сообщение формата KRB_CRED.
- Промежуточный сервер теперь обладает правильными TGT и сессионным ключом пользователя. Таким образом, он может запрашивать билеты доступа к другим службам.
- Промежуточный сервер запрашивает и получает билет доступа к необходимым службам на конечном сервере. Для этого он использует TGT и сессионный ключ пользователя.
- Промежуточный сервер шлет билет доступа к службе конечному серверу. Билет содержит информацию о пользователе.
- Конечный сервер получает запрос на аутентификацию и аутентифицирует промежуточный сервер. С его точки зрения аутентифицируется пользователь, который представлен промежуточным сервером. Затем конечный сервер создает маркер доступа пользователя, основываясь на информации в билете.
- Производятся дополнительные действия, в зависимости от флагов в билетах, например взаимная аутентификация.
Слово о маркерах доступа
Давайте рассмотрим, чем все же отличаются серверный поток, созданный при аутентификации NTLM, и поток Kerberos. Общий алгоритм серверной обработки подключающихся клиентов одинаков для всех SSP. Универсальность обеспечивает SSPI. На конечном этапе серверный поток, обрабатывающий процесс прохождения аутентификации, вызывает функцию ImpersonateSecurityContext и в результате получает маркер доступа аутентифицирующегося пользователя. В обоих случаях маркеры доступа являются маркерами олицетворения (impersonating tokens). Однако в каждом из них уровень олицетворения (см. врезку «Уровни олицетворения») различен. В случае Kerberos он равен SecurityDelegation, а при NTLM — SecurityImpersonation. Этим объясняются возможности олицетворенного потока по доступу к сетевым ресурсам.
Настройка на примере IIS + SQL Server
Наконец пришло время применить полученные знания на практике. Рассмотрим ситуацию, в которой действуют три участника: клиент, промежуточный Web-сервер и база данных SQL Server. Надо сказать, достаточно типичная ситуация. Итак, какие же действия, основываясь на полученных знаниях, необходимо предпринять?
С точки зрения Web-приложения, прежде всего, нужно, чтобы в web.config было указано, что это приложение будет использовать механизм олицетворения:
Кроме того, следует указать, какой механизм аутентификации будет применяться при работе с SQL Server. Это достигается указанием в строке подключения параметра integrated security = SSPI.
Для настройки используем тестовое приложение для проверки работы делегирования. Это простое Web-приложение, которое будет подключаться к серверу баз данных и исполнять там запрос select suser_sname (), который вернет имя текущего пользователя, подключенного к базе. Если подключение будет успешным и запрос выполнится, приложение выдаст имя пользователя, под которым был совершен вход в локальную систему.
Следующим этапом будет создание Web-сайта, который будет исполнять наше приложение. Первоначально сайт будет создан с настройками по умолчанию. Для этого на сервере IIS создаем Web-сайт. Сайт должен использовать исключительно аутентификацию Windows. Настройка готового сайта представлена на экранах 1–4. Кроме того, для корректного доступа к сайту с использованием указанного в настройках заголовка необходимо создать запись в DNS, указывающую на Web-сервер, на котором расположено тестовое Web-приложение (см. экран 5). Еще одной необходимой настройкой является создание учетной записи пользователя домена, которая будет использоваться для доступа к приложению и базе данных. Таким образом, необходимо создать учетную запись пользователя и предоставить ей доступ на подключение и работу с базой данных. В нашем случае учетную запись пользователя в Active Directory добавляем командой dsadd user cn=client, cn=users, dc=test, dc=local –pwd * и указываем ему подходящий пароль, а также предоставляем ему доступ к базе данных. Для простоты я дал ему роль sysadmin (см. экран 6).
На клиентской рабочей станции необходимо настроить Internet Explorer таким образом, чтобы он использовал аутентификацию Windows (см. экран 7), а также добавить адрес тестового сайта в зону локальной сети, поскольку для зоны Internet браузер не использует аутентификацию Windows (см. экран 8). Теперь при попытке обратиться с клиентской рабочей станции к Web-приложению мы получим ошибку, согласно которой Web-сервер пытается подключиться к серверу баз данных анонимно и получает отказ (см. экран 9).
Используем Kerberos
Приступаем к настройке делегирования. Прежде всего, необходимо создать учетную запись пользователя, которая будет применяться для запуска нашего приложения на Web-сервере. Для этого введем простую команду: user cn=KerbIIS, cn=users, dc=test, dc=local –pwd *. Для того чтобы будущий пул приложений IIS мог использовать для старта эту запись, ее необходимо добавить в группу IIS_WPG (см. экран 10). Для того чтобы делегирование работало, одним из необходимых условий также является то, что учетная запись пользователя, под которой работает приложение, была доверенной для делегирования. Таким образом, необходимо дать ей это право (см. экран 11). Теперь создаем новый пул приложений IIS, для которого в качестве учетной записи, используемой для старта, указываем только что созданную учетную запись пользователя (см. экран 12), и настраиваем Web-приложение так, чтобы оно использовало для своей работы вновь созданный пул (см. экран 13).
Следующим необходимым условием является наличие у клиента права на делегирование. Предоставим ему это право, см. экран 14.
Итак, у нас есть клиент и промежуточный сервер с правом на делегирование. Клиент имеет право на доступ к Web-приложению и серверу баз данных. Остается только собрать это все воедино. Для этого необходимо создать недостающие имена spn. Поскольку в нашем сценарии используется два сервера, Web-сервер и сервер баз данных, то нужны соответственно два имени spn. Одно, связывающее Web-приложение с учетной записью, под которым оно будет запускаться, и второе, связывающее сервер баз данных и его учетную запись. Сначала проверим, какие spn уже зарегистрированы (см. экран 15). Как видно из рисунка, сервер баз данных зарегистрировал идентификатор самостоятельно. Этот идентификатор расположен в объекте самого сервера, значит, сервер запущен с локальной учетной записью. Не хватает только одного — идентификатора для учетной записи KerbIIS, который бы связал Web-приложение и данную учетную запись. Регистрируем этот spn (см. экран 16). В итоге все компоненты системы настроены, и можно проверить результат. Он не заставит себя долго ждать (см. экран 17).
Андрей Вернигора (eosfor@gmail.com) — администратор баз данных и системный администратор на одном из предприятий компании «Укртранснафта». Имеет сертификат MCP
Рисунок 1. Структура интерфейса SSPI
Рисунок 2. Процесс обмена сообщениями при делегировании
Экран 1. Настройка заголовков сайта
Экран 9. Ошибка доступа к базе данных
Экран 10. Настройка членства в группах для учетной записи пользователя пула приложений
Экран 11. Настройка делегирования для учетной записи пользователя пула приложений
Экран 12. Настройка пула приложений IIS
Экран 13. Настройка пула для приложения
Экран 14. Настройка делегирования для клиента
Экран 15. Список SPN серверов
Экран 16. Регистрация spn для учетной записи пула приложений
Экран 17. Результаты настройки
Таблица. Втроенные модули аутентификации
Таблица. Формат SPN
Таблица. Параметры командной строки setspn
Таблица. Уровни олицетворения
За билеты отвечает KDC
KDC (key distribution center) — служба, работающая на каждом контроллере домена и отвечающая за выдачу билетов клиентам. На самом деле в спецификации роль KDC разделена на две части, которые теоретически могут не находиться на одной физической системе. Однако в текущей реализации они исполняются в одном процессе на контроллерах доменов Active Directory.