cat_mucius (
cat_mucius) wrote2016-04-30 01:51 pm
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Немного о трёхглавых собаках
Нашёл недавно довольно интересную штуку:
Положим, у нас есть сайт, использующий "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 тут вполне в тему, на мой взгляд.
Положим, у нас есть сайт, использующий "Windows Integrated Authentication" - то есть Kerberos или NTLM. И допустим, что юзер, пытающийся на него зайти - относится к другому, недоверяемому домену, или же он локальный юзер на доменном компе, а то и вовсе на стэнд-элоне. Так или иначе, попытка автоматического, прозрачного для юзера логина проваливается. Что произойдёт?
Ответ: зависит от браузера. Firefox просто выдаст сообщение об ошибке. А вот Chrome или IE поступят по другому - выкинут стандартное окошко username & password. А самое интересное, что если username указать в полной форме - к примеру, me@mydomain.com, - то они пошлют запросы DNS-серверу на две записи SRV, стремясь обнаружить керберосовский центр раздачи ключей (KDC) для указанного домена:
и получив ответ, попытаются запросить по его адресу керберосовский билетик для сайта. Каковой затем и предъявят сайту как доказательство юзерской личности.
(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 или Хромом, может логиниться на сайт. Возможно, также и юзеры других доменов, у которых есть отношения доверия с доменом сайта - не проверял.
Достоинства:
Существует библиотека на Java, умеющая извлекать SID-ы групп из PAC - может быть полезна для всевозможных серверов JavaEE.
Недостатки:
Вот такие пироги с собачками. Для полноценного сайта, предназначенного для общей публики, это, конечно, не решение - но если задача в том, чтобы корпоративный сайтик из серверной комнаты куда-нибудь на Амазон перенести, то Kerberos тут вполне в тему, на мой взгляд.