Существуют ли какие-либо особые риски безопасности или производительности при использовании CLR в SQL Server?
Существуют ли какие-либо особые риски безопасности или производительности при использовании CLR в SQL Server?
Ответы:
Вопрос, как указал Ремус, слишком общий, чтобы получить ответ, так как ответ зависит от контекста того, какая функциональность будет использоваться и как она будет использоваться.
Относительно "безопасности":
Если вы спрашиваете о чем-либо, что можно сделать в сборке, помеченной значком PERMISSION_SET = SAFE
, то я не смог найти никаких проблем, которые когда-либо могли бы найти. И SQLCLR "безопаснее", чем использование xp_cmdshell
или замечательных (это был сарказм) процедур sp_OA*
(или даже расширенных хранимых процедур, но, надеюсь, никто из них больше не создаст).
Если вы хотите получить представление о том, что «SAFE» означает в практическом плане, см. Эту статью: Лестница к SQLCLR Уровень 3: Безопасность (Общие и SAFE сборки) (требуется бесплатная регистрация).
Если вы спрашиваете обо всем, что можно сделать в сборке, помеченной значком PERMISSION_SET = EXTERNAL_ACCESS
, то, безусловно, существуют риски, опять же, в зависимости от того, какая функциональность используется. Если вы пишете подпрограмму для чтения каталогов и имен файлов (то есть только для чтения), то это просто вопрос того, что следует видеть, а не видеть. Если вы пишете код, позволяющий удалить файл, риск возрастает. Но то, что можно сделать с этими внешними ресурсами, контролируется:
Если вы спрашиваете о чем-либо, что может быть сделано в сборке, отмеченной PERMISSION_SET = UNSAFE
это довольно открытый. Многие функциональные возможности считаются пригодными только для сборок UNSAFE, поскольку они представляют собой проблемы стабильности и / или согласованного поведения, а не безопасности или производительности. Например, в сборке UNSAFE возможно иметь доступную для записи статическую переменную. Обычно это не очень хорошая вещь, так как классы SQLCLR совместно используются всеми сеансами. Если вы намереваетесь обмениваться данными в памяти по всем сеансам и запланировали условия гонки (и провели много испытаний), то вы должны быть в порядке, ожидая такого поведения. Но если вы просто хотели, чтобы доступная для записи статическая переменная кэшировала значение для определенного сеанса, чтобы не приходилось искать его снова или вычислять снова, и не знали, что другие сеансы читают это значение и, возможно, перезаписывают его, ну, это было бы проблемой.
Но если вы беспокоитесь о том, что кто-то пишет в Реестр, но при этом у вас нет кода, который действительно пишет в Реестр, то вам, вероятно, не нужно беспокоиться об этом ;-).
Если вы хотели бы получить представление о том, как EXTERNAL_ACCESS и UNSAFE работают в практическом плане, и разницу между настройкой TRUSTWORTHY ON
(не желательно) и использованием асимметричного входа на основе ключа или сертификата, см. Эту статью: Лестница к SQLCLR уровня 4: Безопасность (ВНЕШНИЕ и БЕЗОПАСНЫЕ сборки) (требуется бесплатная регистрация).
Относительно «Производительности»:
Это все зависит от того, что вы пытаетесь сделать и как вы это делаете. Есть некоторые вещи, которые намного быстрее в SQLCLR, и некоторые вещи, которые медленнее. Но, как и в случае с T-SQL, можно взять несколько простых и / или эффективных задач и сделать их сложными и / или неэффективными из-за неправильного выполнения действий. Но использование SQL CLR по своей природе не медленнее.
SQLCLR сборка может быть установлена с тремя уровнями безопасности доступа: SAFE | EXTERNAL_ACCESS | UNSAFE
. Это в полной мере документированы см CREATE ASSEMBLY
и Проектирование Ассамблей :
Управление безопасностью сборки
Вы можете контролировать, насколько сборка может обращаться к ресурсам, защищенным .NET Code Access Security, когда она запускает управляемый код. Это можно сделать, указав один из трех наборов разрешений при создании или изменении сборки: SAFE, EXTERNAL_ACCESS или UNSAFE.
SAFE
SAFE - это набор разрешений по умолчанию, и он является наиболее строгим. Код, запускаемый сборкой с разрешениями SAFE, не может получить доступ к внешним системным ресурсам, таким как файлы, сеть, переменные среды или реестр. БЕЗОПАСНЫЙ код может обращаться к данным из локальных баз данных SQL Server или выполнять вычисления и бизнес-логику, которые не требуют доступа к ресурсам за пределами локальных баз данных.
Большинство сборок выполняют задачи вычислений и управления данными, не имея доступа к ресурсам вне SQL Server. Поэтому мы рекомендуем SAFE в качестве набора разрешений на сборку.
EXTERNAL_ACCESS
EXTERNAL_ACCESS позволяет сборкам получать доступ к определенным внешним системным ресурсам, таким как файлы, сети, веб-службы, переменные среды и реестр. Только учетные записи SQL Server с разрешениями EXTERNAL ACCESS могут создавать сборки EXTERNAL_ACCESS. Сборки SAFE и EXTERNAL_ACCESS могут содержать только код, который может быть проверен на безопасность. Это означает, что эти сборки могут получать доступ к классам только через четко определенные точки входа, действительные для определения типа. Следовательно, они не могут произвольно обращаться к буферам памяти, не принадлежащим коду. Кроме того, они не могут выполнять операции, которые могут отрицательно повлиять на надежность процесса SQL Server.
UNSAFE
UNSAFE предоставляет сборкам неограниченный доступ к ресурсам как внутри, так и за пределами SQL Server. Код, который выполняется из сборки UNSAFE, может вызывать неуправляемый код. Кроме того, указание UNSAFE позволяет коду в сборке выполнять операции, которые считаются небезопасными для верификатора CLR. Эти операции могут потенциально обращаться к буферам памяти в пространстве процессов SQL Server неконтролируемым образом. UNSAFE-сборки также могут потенциально подорвать систему безопасности SQL Server или общеязыковой среды выполнения. Разрешения UNSAFE должны предоставляться только опытным разработчикам или администраторам только для сборок с высоким уровнем доверия. Только члены предопределенной роли сервера sysadmin могут создавать сборки UNSAFE.
Существуют дополнительные ограничения на допустимые атрибуты CLR, и поддерживается только подмножество сборок .Net Framework. Опять же, обратитесь к связанной документации.
Что касается производительности, самое важное - помнить, что SQL Server - это многозадачная среда для совместной работы, а CLR - нет. Код SQLCLR должен вызываться Thread.BeginThreadAffinity()
каждый раз, когда он загружает ЦП в течение любой продолжительности (включая блокировку). Адам Мачаник имеет отличную презентацию на эту тему, смотрите Data, Faster: Microsoft SQL Server Performance Techniques с SQLCLR .
Тема обширная и вопрос расплывчатый. SQLCLR может выполнять некоторые уникальные задачи, с которыми не может сравниться ни одна другая функция. А SQLCLR - это еще одно оружие в арсенале SQL Server, с которым вы можете застрелиться, с производительностью или безопасностью. Прочитайте документацию.