Дон Кайли (donkiely@computer.org) – старший консультант по технологиям, специализируется на защите приложений, имеет звания MVP, MSCD

Специалисты Microsoft коренным образом переработали систему безопасности в SQL Server 2005 и с тех пор постепенно совершенствовали ее в каждой новой версии. Планомерное развитие продолжено с выпуском версии SQL Server 2012, дополненной новыми интересными функциями, в том числе ролями уровня сервера, новыми алгоритмами хеширования и разрешениями. Добавлены также автономные базы данных, обеспечивающие пользователям подключение к базам данных без проверки подлинности на уровне сервера. Это превосходное решение устраняет проблемы при перемещении баз данных, но внушает опасения в отношении безопасности. Есть и другие новшества безопасности, наряду с улучшениями старых функций. В этом выпуске нет радикальных изменений, просто развитие и адаптация к разнообразным способам использования серверов баз данных в компаниях.

В данной статье рассматриваются некоторые из наиболее удачных новшеств в области безопасности SQL Server 2012. Моя цель — предоставить достаточную информацию, чтобы вы могли самостоятельно решить, улучшится ли защита вашей базы данных благодаря применению SQL Server 2012 или меры безопасности становятся слишком обременительными. В свое время переход на SQL Server 2005 стал обязательным благодаря новшествам безопасности, но, вполне вероятно, одна лишь безопасность — недостаточное основание для перехода на SQL Server 2012.

Итак, что нового в средствах защиты SQL Server 2012? В данной статье мы ограничимся ядром базы данных и рассмотрим наиболее интересные аспекты, которые можно разделить на четыре категории:

* управление безопасностью, в том числе схема по умолчанию для групп и определяемых пользователем ролей сервера;

* проверка подлинности, в частности автономные базы данных и проверка подлинности без учетных данных;

* защита данных, включая изменения в шифровании;

* аудит.

Управление безопасностью

Усовершенствования в управлении безопасностью в SQL Server 2012 не относятся к радикальным изменениям, но сообщество SQL Server ожидало их уже давно. Одна из функций, получивших мощную поддержку через сайт Microsoft Connect — схемы по умолчанию для групп. Они устраняют пробел в работе SQL Server со схемами, исключая неявно созданные схемы и снижая вероятность применения неверных схем в запросах.

Схемы по умолчанию для пользователей появились в SQL Server 2005, чтобы обеспечить использование правильной схемы при запросах, создании объектов и выполнении других операций. У схем по умолчанию есть один побочный эффект: в конечном итоге в базе данных может появиться множество неявно созданных схем. Желающие посмотреть, как это происходит, могут обратиться к файлу The Default Schemas.sql на сайте нашего журнала.

Версия SQL Server 2012 дополнена возможностью определить схемы по умолчанию не только для пользователей, но и для групп. Таким образом в значительной мере решается проблема наличия неявно созданных схем и упрощается управление безопасностью. Схема по умолчанию для группы задается с помощью инструкции CREATE USER или ALTER USER. Например, если Tribe — группа Windows на компьютере Gulkana, связанном с учетными данными сервера того же имени, то с использованием следующей инструкции можно назначить carolSchema схемой по умолчанию группы:

CREATE USER Tribe FROM LOGIN [Gulkana\Tribe]
WITH DEFAULT_SCHEMA = carolSchema;

Еще одна долгожданная функция управления безопасностью — роли сервера, определяемые пользователем. В SQL Server уже давно есть определяемые пользователем роли базы данных для детального назначения разрешений на уровне базы данных. Благодаря пользовательским ролям сервера наконец-то можно назначать детальные разрешения на уровне сервера.

В предыдущих версиях SQL Server единственным способом дать какое-либо разрешение пользователю было назначение встроенной роли сервера, которая обычно получала слишком много разрешений. Каждый сотрудник — системный администратор; это стало, увы, типичной картиной. Хотя такой подход явно противоречит принципу наименьших привилегий, на практике его часто не удается избежать. К счастью, этот недостаток исправлен в SQL Server 2005 и более новых версиях благодаря возможности назначать детальные разрешения. Пользователю можно назначить почти любое разрешение уровня сервера. Однако такие разрешения нельзя сгруппировать в роль сервера. В SQL Server 2012 эта проблема решена благодаря ролям сервера, определяемым пользователем. Для создания новой роли сервера достаточно применить инструкцию CREATE SERVER ROLE:

CREATE SERVER ROLE LimitedDBA;

Затем можно предоставить или отменить любые разрешения на уровне сервера. Например, в следующем программном коде предоставляется разрешение CONTROL SERVER новой роли (подобно предоставлению разрешения системному администратору), а затем отменяется несколько разрешений с целью сузить права роли сервера:

GRANT CONTROL SERVER TO LimitedDBA;
DENY ALTER ANY LOGIN TO LimitedDBA;
DENY ALTER ANY SERVER AUDIT TO LimitedDBA;
DENY ALTER ANY SERVER ROLE TO LimitedDBA;
DENY CREATE SERVER ROLE TO LimitedDBA;
DENY UNSAFE ASSEMBLY TO LimitedDBA.

Это очень гибкий способ предоставления разрешений пользователям — членам группы. Файл User-Defined Server Roles.sql на сайте содержит дополнительный программный код, в котором показаны способы добавления пользователя в роль сервера LimitedDBA.

Проверка подлинности

Еще одно новшество SQL Server 2012, автономная база данных, не относится напрямую к мерам безопасности, но реализует новую проверку подлинности. Благодаря автономной базе данных решается проблема перемещения базы данных между серверами. В прошлом нам приходилось перемещать не только базу данных, но и объекты уровня сервера, такие как учетные данные и сведения о заданиях агента SQL Server. Настройка на сервере назначения — дело трудоемкое, особенно из-за необходимости восстанавливать учетные данные и заново сопоставлять идентификаторы SID. Благодаря автономной базе данных администраторы избавлены от этих хлопот.

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

Чтобы продемонстрировать новый метод проверки подлинности, я подготовил два сценария — PubsContained.sql и Contained Databases.sql, — которые можно найти на сайте журнала. Сначала нужно выполнить PubsContained.sql, чтобы создать автономную версию старой тестовой базы данных pubs. Для создания базы данных PubsContained в сценарии используется следующий исходный текст:

CREATE DATABASE PubsContained CONTAINMENT = PARTIAL;

Если параметру CONTAINMENT присвоено значение PARTIAL, то создается автономная база данных. Значению NONE соответствует обычная база данных. По умолчанию действует режим NONE.

В файле Contained Databases.sql содержится исходный текст для использования автономных баз данных в экземпляре SQL Server. По умолчанию они отключены. В сценарии также показано, как создать учетные данные SQL Server на уровне базы данных. Сделать это, как и следовало ожидать, просто:

CREATE USER floyd WITH PASSWORD = '%5JiD2s^6^Y^$u26q7YL';

Кроме того, в Contained Databases.sql показано, как перенести учетные данные пользователя в автономную базу данных с использованием новой системной хранимой процедуры sp_migrate_user_to_contained.

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

Обратите внимание на схему: если проверка подлинности на уровне базы данных завершается неудачей, проверка на уровне сервера не выполняется, даже при наличии учетных данных сервера с тем же именем. Кроме того, база данных на самом деле лишь частично автономна (в документации Microsoft они именуются как автономными, так и частично автономными), поэтому для нее могут существовать учетные данные на уровне сервера. Диагностика неполадок проверки подлинности при использовании автономных баз данных может заметно усложниться, поскольку требуется проверять много путей.

Защита данных

В SQL Server давно предусмотрены встроенные функции шифрования, такие как хеширование паролей, но, начиная с версии SQL Server 2005, шифрование применяется и для защиты данных (шифрование и хеширование на уровне ячеек). В SQL Server 2008 появились важные улучшения, в том числе прозрачное шифрование данных и усовершенствованные функции хеширования. В SQL Server 2012 внесены небольшие, но полезные изменения в алгоритмы шифрования.

Одно из удачных новшеств заключается в том, что функция HashBytes поддерживает алгоритмы Secure Hash Algorithm-256 (SHA-256) и SHA-512, поэтому хеши стали гораздо надежнее. Сопутствующее изменение — хеширование паролей теперь производится с использованием алгоритма SHA-512 вместо SHA-1. При этом возникает проблема перевода существующих паролей на новый алгоритм при переходе на SQL Server 2012. В основном сервер переводит чисто текстовые пароли в формат SHA-512, например когда пользователь регистрируется в системе в первый раз после модернизации или меняет пароль.

Компания Microsoft благоразумно отказалась от алгоритма шифрования RC4, который поддерживается, только если задан уровень обратной совместимости сервера 90 или 100 (SQL Server 2005 или SQL Server 2008). У RC4 есть несколько уязвимых мест, в частности не добавляются привязки ключа (salting). Вследствие этого при повторном шифровании значения получается одинаковый зашифрованный текст, и взломать шифр гораздо проще. Не используйте RC4, даже если требуется обеспечить совместимость со старыми версиями SQL Server.

При импорте ключей сертификатов из внешнего источника максимальная длина увеличилась с 3456 до 4096 байт. Таким образом, в SQL Server проще использовать ключи от сторонних служб сертификации.

Для главных ключей службы и базы данных используется шифрование AES256 вместо Triple-DES (3DES), что повышает надежность шифрования, в том числе резервных копий. При переводе баз данных на SQL Server 2012 сохраняется шифрование 3DES, но можно регенерировать главные ключи.

Наконец, у инструкции CREATE CERTIFICATE есть параметр FROM BINARY, с помощью которого можно напрямую создать сертификат из метаданных существующего сертификата в SQL Server. Исключается необходимость экспорта сертификата в файл для создания нового сертификата.

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

Аудит

Администраторам базы данных будет приятно услышать, что в версии SQL Server 2012 много внимания уделено аудиту. Основные функции аудита сервера теперь имеются во всех, а не только в передовых редакциях SQL Server. Это значит, что можно создать спецификацию аудита для всех баз данных любой редакции. Однако новшества эти неоднозначные: аудит отдельных баз данных доступен только в редакциях Enterprise, Developer и Evaluation. Поэтому пользователям выпусков Developer и Evaluation следует проверить, располагает ли нужными функциями редакция производственного сервера.

Удобство новых функций аудита заключается в том, что администратор меньше зависит от функций аудита в SQL Trace. Тому есть несколько причин:

* можно подготовить несколько вариантов аудита и целей;

* производительность аудита выше, чем при трассировке;

* аудит перезапускается вместе с экземпляром сервера, поэтому его состояние сохраняется;

* гибкость аудита;

* авторизованные пользователи могут отключить трассировку, но при этом фиксируется, кто остановил аудит.

Важное улучшение аудита — устойчивость к таким отказам, как сбой сетевого соединения. Благодаря буферизации SQL Server будет продолжать попытки сохранять записи аудита до тех пор, пока неполадка не будет устранена.

В прошлом сбои записи могли привести к потере данных аудита. Можно воспользоваться командой ON_FAILURE = SHUTDOWN, но отключение экземпляра сервера — суровая мера, вряд ли подходящая для производственной базы данных. В SQL Server 2012 можно, по крайней мере, указать FAIL_OPERATION, чтобы приложение выдало ошибку и произошла отмена транзакции; выполнение не прошедших аудит операций может быть продолжено. Кажущееся произвольным чередование успешных операций и отказов не всегда приемлемо, но может хорошо работать в экземплярах сервера с высоким уровнем безопасности, где аудит обязателен. Одна из проблем заключается в том, что в случае сбоя инициации аудита запуск экземпляра сервера завершится неудачей, хотя запустить его можно принудительно с помощью параметра -f в командной строке.

В аудите вводится ограничение на количество файлов без переключения. В старых версиях SQL Server число файлов журнала не ограничено, или можно назначить переключение после того, как на сервере создано заранее определенное число файлов. В первом случае может не хватить места на диске. Во втором случае можно потерять данные аудита. На хорошо контролируемом сервере этими параметрами можно управлять, но в SQL Server 2012 предусмотрен другой вариант: ограничение файлов без переключения. Таким образом можно управлять количеством информации, сохраняемой без потери записей аудита.

Чтобы ограничить число файлов без переключения, используйте параметр MAX_FILES в инструкции CREATE SERVER AUDIT. При наличии этого параметра SQL Server блокирует и откатывает любые операции после того, как достигнут предел, пока администратор не очистит файлы. Это оптимальный вариант в некоторых случаях, особенно если нужно сохранить все записи аудита, но, тем не менее, сервер нуждается в тщательном мониторинге.

Файл Auditing.sql на сайте содержит исходный текст, показывающий, как создать объекты аудита и определить, куда направлять подробные сведения. Например, следующий программный код создает объект аудита, который направляет результаты в журнал событий приложения Windows и завершает операции аудита неудачей, если возникают проблемы с записью событий аудита:

CREATE SERVER AUDIT SQLServerAudit
TO APPLICATION_LOG
WITH ( QUEUE_DELAY = 1000, ON_FAILURE = FAIL_OPERATION);
GO

Затем можно создать спецификацию аудита с использованием группы событий аудита, в которой указаны виды событий аудита, подлежащие регистрации. Следующий программный код задает регистрацию неудачных попыток входа:

CREATE SERVER AUDIT SPECIFICATION TestSQLServerAuditSpec
FOR SERVER AUDIT SQLServerAudit ADD (FAILED_LOGIN_GROUP)
WITH (STATE = ON);

Наконец, следующий код включает аудит:

ALTER SERVER AUDIT SQLServerAudit WITH (STATE = ON);

В SQL Server 2012 можно еще создать определяемые пользователем события аудита, то есть вносить в журнал аудита любую информацию по своему усмотрению. Для этого выполните следующие шаги.

1. Создайте и определите аудит с использованием программного кода, похожего на приведенный в листинге 1. Сначала создается объект аудита. Затем создается спецификация аудита, определяющая USER_DEFINED_AUDIT_GROUP как действие для аудита, подлежащее регистрации. Наконец, аудит включается.

2. Добавьте собственную информацию в журнал аудита. Можно воспользоваться системной хранимой процедурой sp_audit_write, например:

EXEC sp_audit_write 9999, 1,
N'Something in Denali succeeded!'

Хранимая процедура принимает три параметра: идентификатор определяемого пользователем события типа smallint; битовый аргумент @succeeded, указывающий, было действие выполнено успешно или нет; и текстовое значение nvarchar(4000) с информацией о событии. Если не включить USER_DEFINED_AUDIT_GROUP, то SQL Server игнорирует sp_audit_write.

Еще одна потенциально удачная новая функция аудита — фильтрация, в которой используется тот же механизм фильтрации, что и в Extended Events. Фильтрация обеспечивает детализированный контроль информации, записываемой в журнал аудита. Сервер генерирует все указанные события аудита, затем с помощью фильтра определяет, следует ли записать событие в журнал. В силу метода работы лучше создать события аудита для определенных объектов, чем фильтровать их, но фильтрация позволяет управлять записываемыми данными.

Например, если нужно создать аудит, регистрирующий все события определенного типа, кроме связанных с некоторыми учетными данными со значением идентификатора server_principal_id, равным 266. Можно воспользоваться исходным текстом в листинге 2, чтобы создать аудит сервера с предложением WHERE для фильтрации событий, участник которых имеет идентификатор 266.

Еще одно полезное новшество аудита: можно использовать информацию кадра стека T-SQL, чтобы указать, выполнен запрос из хранимой процедуры или непосредственно из приложения. В тестовом файле Auditing.sql есть простой пример. Если аудит сервера с именем TSQLStackFrameAudit уже существует, можно создать спецификацию аудита, подобную следующей, чтобы регистрировать события аудита для инструкций SELECT, примененных любым пользователем к таблице dbo.Orders в базе данных Northwind:

CREATE DATABASE AUDIT SPECIFICATION TSQLStackFrameSpec
FOR SERVER AUDIT TSQLStackFrameAudit
ADD (SELECT ON OBJECT::dbo.Orders BY public)
WITH (STATE = ON);

Затем можно применить запросы к таблице Order с использованием следующего программного кода, который обращается к таблице как через хранимую процедуру, так и с прямым запросом:

EXEC dbo.[Sales by Year] '1998-01-01', '1999-12-31';
SELECT * FROM dbo.Orders;

Чтобы увидеть события и кадр стека T-SQL при обращении к таблице Orders через хранимую процедуру, можно открыть журнал аудита в узле \Security\Audits в SQL Server Management Studio (SSMS). Щелкните правой кнопкой мыши узел TSQLStackFrameAudit и выберите пункт View Audit Logs из раскрывающегося списка. Информация кадра стека находится в столбце Additional Information, как показано на экране 1. Здесь мы видим лишь малую часть доступной информации о событии.

В этой статье я уделил внимание в основном способам подготовки программного кода для выполнения различных действий. Многие из этих действий можно выполнить и с использованием SSMS. Например, на экране 2 показано, как создать спецификацию аудита TSQLStackFrameSpec из графического интерфейса.

Эволюция, а не революция

В функциях безопасности SQL Server 2012 мало революционного или радикально нового. Однако в этой версии много полезных улучшений, благодаря которым в безопасности сервера и базы данных можно не сомневаться. Достаточно ли одних улучшений безопасности для перехода на новую версию? Вероятно, нет, если одно из новшеств или улучшений не защищает ваши данные от актуальной угрозы. Однако если ценность данных велика, и вы нуждаетесь в полном арсенале средств защиты, безотлагательно переходите на SQL Server 2012.

Листинг 1. Создание и определение аудита сервера

CREATE SERVER AUDIT SQLServerUserDefinedAudit
TO APPLICATION_LOG
WITH ( QUEUE_DELAY = 1000, ON_FAILURE = CONTINUE);
GO
CREATE SERVER AUDIT SPECIFICATION TestUserDefinedAuditSpec
FOR SERVER AUDIT SQLServerUserDefinedAudit
ADD (USER_DEFINED_AUDIT_GROUP)
WITH (STATE = ON);
GO
ALTER SERVER AUDIT SQLServerUserDefinedAudit
WITH (STATE = ON);
GO

Листинг 2. Создание аудита сервера с фильтром

CREATE SERVER AUDIT FilterAudit
TO APPLICATION_LOG
WITH
(QUEUE_DELAY = 1000
, ON_FAILURE = CONTINUE
)
WHERE server_principal_id <> 266;
ALTER SERVER AUDIT FilterAudit WITH (STATE = ON);
GO
Путь проверки подлинности при включенной автономной базе данных
Рисунок. Путь проверки подлинности при включенной автономной базе данных
Журнал аудита с информацией кадра стека T-SQL
Экран 1. Журнал аудита с информацией кадра стека T-SQL
Создание спецификации аудита с использованием SSMS
Экран 2. Создание спецификации аудита с использованием SSMS