SqlCmd все о SQL технологиях.





Все что необходимо для изучения и работы с СУБД Microsoft SQL Server, MySQL, MariaDB, MongoDB. Авторские статьи, библиотека фрагментов T-SQL кода, сборник полезных инструментов.



MS SQL Server, SQL Server, T-SQL, исходники, сниппеты, статьи, учебники SQL, утилиты SQL, инструменты SQL



Header RSS-подписка на обновления сайта eMail-подписка на обновления сайта

Настройка безопасности для связанных серверов. Часть 2/4.





Опция 1. Be made using the login's current security context

Почему именно эта опция настойчиво рекомендуется при работе с удаленным SQL Server? Потому что процесс выяснения что пользователю можно, а что нет носит здесь характер наиболее прямолинейный: локальный сервер просто «форвардит» данные учетной записи пользователя запросившего выполнение распределенного запроса серверу удаленному. А далее как решит последний: если пользователю разрешено запрошенное им действие то он получит данные, а нет — так получит ошибку. В любом случае пользователь работает «под собой» как на сервере локальном, так и «под собой же» на сервере удаленном. Картина ясна и понятна. При этом если пользователь подключился к локальному серверу в режиме Windows Authentication то на удаленный сервер «форвардится» традиционный для Windows-платформы маркер доступа, то бишь access token. Если же он подключился к тому же серверу в режиме SQL Server Authentication «отфорвардятся» логин и пароль указанные им же в момент подключения.

Это, кстати, приводит нас к заключению что локальный и удаленный сервера должны быть согласованы по типам аутентификации ими поддерживаемыми. Идеальный вариант когда оба находятся в режиме по умолчанию — Windows Authentication mode. Но в любом случае с точки зрения удаленного SQL сервера все выглядит точно так же, как если бы тот же самый пользователь подключался к нему напрямую, и выполнял (ну или по крайней мере пытался выполнить) операции прямо на нем, минуя сервер локальный. Разумеется, при таких раскладах пользователь должен быть известен и серверу локальному, и серверу удаленному, причем если это два физически разных компьютера (а не один, как в нашем тестовом окружении) то вам придется озаботиться вопросом что бы пользователь был известен обоим машинам и на уровне операционной системы (по крайней мере для режима аутентификации Windows Authentication mode). Разумеется, если дело происходит в домене (а на практике чаще всего именно там оно и происходит) и пользователь входит на клиента с доменной учетной записью (опять же, чаще всего он именно с такой и входит) — то эта часть вопроса решена, пользователь известен всему домену и, соответственно, обоим серверам (считаем что все три машины принадлежат одному домену). Но тут нас подстерегают иные «грабли», а именно вот какие.

Сценарий 1: настройки двух SQL серверов абсолютно такие же как в нашем тестовом окружении за исключением того факта, что это не два экземпляра на одном физическом сервере, а два физических сервера. Оба — в одном домене. Пользователь со своей доменной учеткой логинится на тот сервер что в наших экспериментах мы называем локальным (ну вот допустим, что сервер это и его workstation заодно) и с него выполняет распределенный запрос. Нет никаких проблем — токен пользователя «уходит» с локального сервера на удаленный, обрабатывается им и т.д., одним словом механизм завертелся.

Сценарий 2: все то же самое, но пользователь заходит на свою действительную workstation, которая теперь не совпадает с сервером локальным. Подключается с нее к тому же серверу. Пока все хорошо, токен отправлен локальному серверу, принят им и соединение установлено. Теперь пользователь пытается выполнить тот же самый распределенный запрос. Согласно настройкам связанных серверов локальному серверу надлежит «продвинуть» «не свой» токен (в том смысле, что токен выписывался контроллером домена для workstation, а не для локального сервера) в еще одну точку — удаленный сервер. И вот тут-то все успешно «обламывается» — без специальных и дополнительных действий по настройке сетевой безопасности такое продвижение невозможно. В литературе и Интернете данная проблема известна под кодовым именем «проблемы двойного прыжка», она же double hop problem (или issue). Интересно заметить, что если в нашем втором сценарии сервера используют для установления связи между собой режим аутентификации SQL Server Authentication — проблем нет, как нет и второго «прыжка». Но мы то хотим работать в режиме Windows Authentication mode, не правда ли? Так же замечу, что если при тестировании работы ваших связных серверов в доменном окружении вы, при попытке обратиться к удаленному серверу, получаете ошибку

Login failed for user '(null)'. Reason: Not associated with a trusted SQL Server connection.

то это верный признак того что вас настигла упомянутая проблема.

Но вроде как автор заронил искру надежны, что с определенными усилиями реализуем и второй сценарий? Ну — было бы странно если бы он был принципиально исключен, можно, разумеется. Те самые «дополнительные действия по настройке сетевой безопасности» имеют простое и четкое наименование: принудительное делегирование для Kerberos (kerberos constrained delegation, сокращенно KCD). Вот эту самую «штуковину» вам надлежит реализовать в вашем домене дабы заработал второй сценарий. Не знаете как? Отличный документ Word (свободно забираемый отсюда) опишет все по шагам. Более того, он составлялся именно для нас с вами, т.е. администраторов SQL Server 2008, а не для специалистов по сетевой безопасности! Поэтому практичен, компактен и в нем «много картинок». :) Одна «неприятность» — на английском, разумеется.

По счастью в нашем случае все много, много проще. У нас и компьютер-то один, какие уж там «двойные прыжки»... Поэтому мы можем попросту переключиться в frank-студию и попробовать выполнить набранный там однострочный тест-скрипт. Напомню, что пользователь frank подключился к «дефолтному» инстансу и пытается при его посредничестве обратиться к инстансу именованному. Что «он» (а на самом деле мы) имеем на текущий момент?

Msg 18456, Level 14, State 1, Line 1 Login failed for user 'WINR2\frank'.

Ну... логично. Удаленный сервер с «подачи» локального принимает подключение от Фрэнка и не обнаруживает у себя соответствующего логина. OK, к admin-студии, подключаемся к именованному экземпляру (тот что как бы удаленный сервер) и создаем требуемое:

1
2
3
USE master
GO
CREATE LOGIN [WINR2\frank] FROM WINDOWS

Снова frank-студия, снова тест-скрипт:

Msg 916, Level 14, State 1, Line 1
The server principal "WINR2\frank" is not able to access the database "DB1" under the current security context.

Понятно, не завели пользователя базы. Admin-студия, именованный экземпляр:

1
2
3
USE DB1
GO
CREATE USER frank FOR LOGIN [WINR2\frank]

Вновь тест-скрипт из frank-студии:

Msg 229, Level 14, State 5, Procedure usp1, Line 1
The EXECUTE permission was denied on the object 'usp1', database 'DB1', schema 'dbo'.

Понятно, прав не выполнение процедуры не дали. Admin-студия, именованный экземпляр:

1
2
3
USE DB1
GO
GRANT EXECUTE ON SCHEMA::[dbo] TO [frank]

И наконец-то Фрэнк получает свои данные:

LoginName   DB_UserName
WINR2\frank frank

Их беглый анализ не оставляет сомнений: в режиме настройки безопасности «Be made using the login's current security context» пользователь подключается к серверу удаленному ровно так же, как он подключался бы к нему будь тот сервером локальным. Возможность выполнить запрошенную операцию определяется тем набором прав что установлены для нашего пользователя (frank) как на локальном сервере, так и на сервере удаленном. Иными словами пользователь проходит «двойную проверку», по разу в каждой из точек.