OpenRowset и связанный сервер - PullRequest
2 голосов
/ 24 июня 2019

Я знаю, что этот тип вопросов возникает часто, но ничто из того, что я могу найти здесь или на других сайтах, кажется, не дает веских оснований для того, чтобы не использовать открытые наборы запросов, кроме «все говорят, что это плохо, поэтому это должно быть плохо, хотяони не могут объяснить, почему ".

У нас есть установка с главным сервером (назовем это ServerMaster), который имеет подключения к ряду дочерних серверов (ServerChild1, ServerChild2 и т. д.).Эти дочерние серверы также имеют доступ для чтения и записи через связанный сервер к ServerMaster.В нашем сценарии обойти это невозможно.По различным причинам существует общее двустороннее взаимодействие между ServerMaster и ServerChildren.Базы данных в ящиках ServerChild (более 1000 баз данных) должны писать в ServerMaster.Этот доступ через связанный сервер использует доверенное соединение, а не конкретную учетную запись.

У нас также есть служба Windows, которая обрабатывает очередь на ServerMaster.Эта служба устанавливает соединение, используя определенную учетную запись для запуска процедуры, которая обслуживает очередь.Когда запрос попадает в эту очередь, служба вызывает другой процесс на ServerMaster, чтобы сгенерировать ряд сценариев для выполнения в базах данных на ServerChild.Proc выполняет несколько запросов к определенному набору таблиц, чтобы получить строки, необходимые для построения сценариев.Это включает проверку набора таблиц в базах данных на каждом ServerChild.Все эти таблицы разные, но в конечном итоге имеют общую базу, а именно Предмет и Версия.В некоторых таблицах эти столбцы существуют.В других они существуют, но с разными именами (например, Part и Revision).В других, тем не менее, они не существуют, но могут быть связаны с резервной копией структуры отношений (т. Е. Таблица деталей имеет Part, Revision и PartID (PK) и связана с этим, это PartAspect, который присоединяется к PartID.

Поскольку данныесвязывается с первичными источниками, которые определены в таблице, которую мы должны присоединить к базовой таблице, Parts, к определенному запросу, который дает нам объединения согласованным образом и ключи для идентификации. Таким образом, для этого у нас есть столбецопределяется для каждой таблицы, которая дает нам этот запрос.

Итак, наша таблица управления выглядит следующим образом:

TableName: Parts
LockQuery: SELECT PartID As ItemID, Revision As Version, PartID FROM Parts

TableName: PartAspects
LockQuery: SELECT p.PartID As ItemID, p.Revision As Version, pa.AspectID FROM Parts p JOIN PartAspects pa ON p.PartID = pa.PartID

Это означает, что когда мы пробегаем каждую из таблиц, мы можем определитьнепротиворечивая структура для доступа к нужному набору данных во всех полях ServerChild.

Из-за особенностей LockQuery мы выполняем это с помощью OPENQUERY. Этот аспект запроса соединяется с временными таблицами, сгенерированными в proc.а также другие физические таблицы на ServerMaster.

Теперь во временной среде разработки(не связанного ни с чем живым), мы использовали простой текстовый пароль, пока мы ожидаем, что наш ИТ-отдел решит некоторые межсерверные проблемы.Это, очевидно, не собирается делать это из этой изолированной временной среды, но это подняло вопрос от наших администраторов баз данных о том, почему мы используем «небезопасный» метод Openquery.Администраторы базы данных признают, что они не знают, почему это «небезопасно», и не могут предоставить никаких приемлемых сценариев относительно того, что делает его небезопасным, но, как говорят все в Интернете, так и должно быть.Конечно, когда наш ИТ-отдел решит проблемы с несколькими серверами, мы будем устанавливать это соединение через доверенное соединение с строго ограниченной учетной записью единой службы, имеющей разрешение только на те объекты, которые ему необходимы.

Обоснование того, чтоДо сих пор было сказано, что это должно быть сделано через связанные серверы, потому что «это то, что Microsoft рекомендует».Ну, насколько я могу судить, это совсем не то, что MS рекомендует.MS ранее включала Ad Hoc запросы при установке, но перестала делать это с 2008 года. Это было не потому, что это изначально было плохо, а потому, что здравый смысл - отключать вещи, которые вам не нужны, если они вам не нужны.Если они нужны опытному разработчику / dba, они могут включить их.

Второй аргумент всегда, MS говорит: «OPENDATASOURCE следует использовать только для ссылки на источники данных OLE DB, к которым редко обращаются. Для любых источников данных, к которым будет осуществляться доступ более нескольких раз, определите связанный сервер».который также кажется всем переведенным как «никогда не используйте это, если только это не единственный запрос, который вы никогда больше не выполните».Редкий это очень открытый термин.Моя интерпретация этого заключается в том, что, поскольку наш код выполняет один оператор выбора из одного процесса, только когда служба обрабатывает эту очередь, это нечасто.Это не обычный процесс, запускаемый несколькими операторами на регулярной основе.

Теперь это «можно» реорганизовать для использования значений замены в запросе и, следовательно, принудительно выполнять запросы на всех связанных серверах.Это потребовало бы, чтобы каждый аспект запроса выполнялся на ServerMaster, а не весь запрос выполнялся на ServerChild, что приводило бы к гораздо менее эффективному процессу (учитывая, что он будет работать с 1000+ базами данных), не говоря уже о том, что это потребовало бы грязного решенияиспользования замещающих строк для его выполнения в нескольких базах данных на нескольких ServerChildren.

Аргумент 3 заключается в том, что это предоставляет большую зону атаки, чем связанные серверы.В некоторой степени это правда.Однако эта область атаки настолько велика, насколько позволяет безопасность.Если учетная запись sysadmin для ServerChild скомпрометирована, то злоумышленник может использовать ServerMaster для выполнения гнусных действий над ServerChild.Тем не менее, они также могут делать это непосредственно на ServerChild, не имея в первую очередь набора скомпрометированных учетных данных для ServerMaster.Это не проблема с запросами AdHoc, это проблема скомпрометированных учетных записей.Точно так же, если учетная запись на ServerMaster скомпрометирована, они имеют доступ только к этой учетной записи.Если у него нет доступа к чему-либо, кроме необходимого на ServerChild, риск не больше, чем через связанный сервер.

Наконец, и это тот, который, кажется, волнует всех, позволяяэто в ServerChild означает, что хакер, взломавший учетную запись в ServerChild, может подключиться к своему собственному серверу из ServerChild и выгрузить все, что хочет.Это опять-таки может быть правдой, если безопасность настроена так плохо, чтобы разрешить это.Но реальность ситуации такова, что все эти коробки находятся в нашей собственной среде.Все они находятся за демилитаризованной зоной, и ни один из них не имеет доступа за пределы домена.Они внутренне скрыты, и поэтому наш «риск» заключается в том, что внутренний злоумышленник получает доступ к данным, которые они не должны.Теперь, если учесть, что данные в этом сценарии уже присутствуют во всех полях ServerChild и не являются чувствительными или даже не имеют никакого значения вне контекста, риск (а) не превышает риск, предоставляемый через связанные серверы, (б) риск, который может быть подвержен только плохо настроенным средствам безопасности (разрешающим доступ к ненужным объектам), или (c) риск, который следует устранять с помощью конфигурации DMZ, а не SQL Server.

Это примерзапрос, который мы выполняем (очевидно, код здесь не динамический, но соединение и запрос выполняются, когда мы его выполняем:

    UPDATE lc
    SET DefinedAspect = pa.SourceDataColumn
    FROM #LocalObjects lc
    JOIN OPENROWSET('ConnectionSettings', 'SELECT p.PartID As ItemID, p.Revision As Version, pa.AspectID FROM Parts p JOIN PartAspects pa ON p.PartID = pa.PartID') clk
    ON lc.ItemID = clk.ItemID
      AND lc.Version = clk.Version
    JOIN PartAspect pa
    ON clk.AspectID = pa.ASpectID

Итак, здесь я ищу кого-то, кто может предоставить подлинный, иПричина, по которой мы должны вырвать текущий код и повторить его менее эффективным и менее элегантным способом для связанных серверов.

Помните, что мы предлагаем изменить модель и использовать репликацию, например, неТаблица здесь. Я хочу доказать, что AdHoc запросы не более рискованны в этом сценарии, чем ссылкаи что при правильной настройке безопасности любые проблемы присутствуют в обоих подходах и могут быть смягчены с помощью надлежащих мер безопасности.

Пожалуйста, не говорите "MS говорят X", потому что это не дает мне однозначного ответа на вопрос, почему один подход лучше, чем другой. Я пытаюсь обосновать это, и в настоящее время я думаю, что если все говорят, что это плохо, то так и должно быть.

Как вы, вероятно, можете сказать, я в лучшем случае скептически отношусь к этому аргументу, но если кто-то может показать мне осязаемую и обоснованную причину, по которой это плохо, я буду более чем счастлив согласиться с ним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...