cat_mucius: (Default)
cat_mucius ([personal profile] cat_mucius) wrote2016-04-30 01:51 pm
Entry tags:

Немного о трёхглавых собаках

Нашёл недавно довольно интересную штуку:
Положим, у нас есть сайт, использующий "Windows Integrated Authentication" - то есть Kerberos или NTLM. И допустим, что юзер, пытающийся на него зайти - относится к другому, недоверяемому домену, или же он локальный юзер на доменном компе, а то и вовсе на стэнд-элоне. Так или иначе, попытка автоматического, прозрачного для юзера логина проваливается. Что произойдёт?

Ответ: зависит от браузера. Firefox просто выдаст сообщение об ошибке. А вот Chrome или IE поступят по другому - выкинут стандартное окошко username & password. А самое интересное, что если username указать в полной форме - к примеру, me@mydomain.com, - то они пошлют запросы DNS-серверу на две записи SRV, стремясь обнаружить керберосовский центр раздачи ключей (KDC) для указанного домена:
  • _kerberos._tcp.Default-First-Site-Name._sites.dc._msdcs.mydomain.com
  • _kerberos._tcp.dc._msdcs.mydomain.com

  • и получив ответ, попытаются запросить по его адресу керберосовский билетик для сайта. Каковой затем и предъявят сайту как доказательство юзерской личности.

    (Update: обнаружил, что и клиент Remote Desktop в Win7 тоже так умеет.)

    Почему это так интересно? А потому, что означает, вопреки популярному убеждению, что Kerberos можно использовать в Интернете - а не только в корпоративных сеточках.

    Допустим, у нас есть сайт где-то в облаке, без всякой связи с сетью домена. Допустим, он вовсе не на Windows - например, это бегущий под линуксом Tomcat. Тогда всё, что нам надо сделать:
    1. Создать какой-нибудь аккаунт в домене и сгенерить для него файл keytab - аналог пароля.
    2. Связать URL сайта с этим аккаунтом, определив SPN.
    3. Залить файл keytab на сервер и прописать его в конфигурации - сервер будет им юзерские билетики расшифровывать.
    4. Открыть 88-й порт (TCP и UDP) на доменном контроллере в Интернет - наиболее спорный пункт. На мой взгляд, достаточно безопасный вариант - построить read-only domain controller, разместить его в DMZ, запретить ему держать у себя пароли и разрешить разговаривать с обычным DC. Тогда он превращается в прокси, обвал которого домену никак не вредит.
    Если же это никак неприемлемо, остаётся вариант с VPN - что, конечно, странно, но может и кому-то и подойти, учитывая, что вся система предназначена всё же для людей из определённой организации.
    5. Прописать публичный адрес этого RODC в DNS - под SRV-record _kerberos._tcp.dc._msdcs.mydomain.com.

    Всё. Любой юзер домена, вооружённый IE или Хромом, может логиниться на сайт. Возможно, также и юзеры других доменов, у которых есть отношения доверия с доменом сайта - не проверял.

    Достоинства:
  • Пароли не проходят через сайт ни на каком этапе.
  • Взаимная аутентификация - без нужды в SSL. Ответ сервера на предъявленный билетик доказывает, что он был способен его расшифровать - что сам сервер легитимен.
  • Сайт работает полностью автономно от доменной сети.
  • URL сайта может быть любым, никак с доменом не связаным.
  • В случае взлома сайта выписка любых новых билетов для него прекращается моментально, отключением ассоциированного с ним аккаунта, а уже выписанные билеты протухают по дефолту за 10 часов - но этот срок можно уменьшить и до 10-ти минут.
  • В случае взлома юзера - тем более, баним его аккаунт и конец делу. Время жизни выданного ему TGT с дефолтовых 10-ти часов также можно урезать. Сравните с процессом отмены сертификата!
  • Проще в настройке, чем SAML, оAuth, OpenID и прочее с того же куста, и намного прозрачнее для серверной аппликации.
  • При этом позволяет передавать не только username, но и информацию о группах - микрософтовская имплементация Кербероса присобачивает к билетику поле под названием PAC - оно содержит список групп в Active Directory, к которым относится юзер (причём, что особенно прелестно, не обязательно напрямую - nesting groups там сидят также). Неприятное ограничение в том, что имена групп в PAC не значатся - только их длинные номера SID. Но построив на сервере mapping из SID в имена, можно справиться и с этим, после чего разным группам пораздавать разные права.
    Существует библиотека на Java, умеющая извлекать SID-ы групп из PAC - может быть полезна для всевозможных серверов JavaEE.

    Недостатки:
  • Необходимость доступности контроллера домена в Интернете, пусть даже и read-only и лишь парой керберосовских портов. Я большой проблемы с этим не вижу, но возможно, что люди поумнее таки да.
  • Сами билетики шифрованные, но некоторые поля в пакете Kerberos передаются открытым текстом - например, юзернейм. С трафиком между сидящим вне доменной сети юзером и KDC особо делать нечего (разве что VPN), между юзером и сайтом - включить HTTPS. Лишний слой шифрования не помешает.
  • Отсутствует logout - нет способа сказать сайту, что юзерская сессия закончилась и дальнейшие запросы с тем же билетом приниматься не должны. Неидеальный способ для юзера состоит в том, чтобы закрыть полностью браузер - лишь в заново запущенном браузере процесс логина повторится сначала. Впрочем, с клиентскими сертификатами та же проблема.
  • Как уже сказано, не самый удобный способ передавать информацию о группах - тут ADFS куда круче, конечно, к тому же позволяет передавать массу других атрибутов. Тут же, если дополнительная информация из AD необходима - воленс-ноленс приходится либо запрашивать по LDAP, либо переходить на ADFS или аналог.
  • Какой-либо provisioning юзеров исключается - создавать или убивать их можно лишь через AD. Не через сайт.
  • Использовать таким образом иные методы аутентификации, кроме пароля - проблемно, несмотря на том, что в Windows в целом поддерживается интеграция сертификатов и Кербероса (см. PKINIT).
  • Привязка к конкретным браузерам.

    Вот такие пироги с собачками. Для полноценного сайта, предназначенного для общей публики, это, конечно, не решение - но если задача в том, чтобы корпоративный сайтик из серверной комнаты куда-нибудь на Амазон перенести, то Kerberos тут вполне в тему, на мой взгляд.

  • Post a comment in response:

    You may post here only if cat_mucius has given you access; posting by non-Access List accounts has been disabled.
    If you don't have an account you can create one now.
    HTML doesn't work in the subject.
    More info about formatting