Share via


Прохождение теста Works with SQL Server 2008. Требования 4-6.

Требование 4. Приложение должно быть способно успешно соединяться с SQL Server.

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

Требование 5. Должна быть выключена xp_cmdshell.

Расширенная хранимая процедура xp_cmdshell позволяет выполнять команды операционной системы из-под SQL Server и оттого представляет собой потенциальную угрозу для безопасности. Злоумышленник может использовать ее как служебный ход и попытаться с ее помощью захватить контроль, в том числе на уровне ОС. В случае ее вызова членом серверной роли sysadmin она выполняется от имени учетной записи, под которой работает сервис SQL Server. В случае вызова другими пользователями - от имени посредника ##xp_cmdshell_proxy_account##. Учетная запись посреднику назначается хранимой процедурой sp_xp_cmdshell_proxy_account. По умолчанию, xp_cmdshell на сервере отключена. Ее включение/отключение выполняется через sp_configure на SQL Server или через политики (смотрите фасет, который называется Surface Area Configuration, у него есть св-во XPCmdShellEnabled). Пример отключения xp_cmdshell:

exec sp_configure 'xp_cmdshell', 0

reconfigure with override

Скрипт 1

На одном из семинаров задавался вопрос: как быть, если xp_cmdshell реально нужна приложению? Что, в этом случае пройти тест не светит? Я ответил, что, по-видимому, все-таки нужна не xp_cmdshell, а возможность вызова из SQL Server команды ОС. Требования теста ничего не говорят про то, что вы не можете использовать эту возможность, они только запрещают прибегать для этого к xp_cmdshell, поскольку она давно всем известна и каждый кулхацкер в первую очередь стремится найти ее (равно как и логин sa). Отключите xp_cmdshell и напишите для своего сервера CLRную процедуру какую-нибудь MyCmdShell, которая будет делать ровно то же самое.

В VS создаем проект обычной библиотеки классов и пишем:

using System;

using System.Data;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using Microsoft.SqlServer.Server;

using System.Diagnostics;

public class Class1

{

    [Microsoft.SqlServer.Server.SqlProcedure]

    public static void ExecCmd(SqlString commandToRun, SqlString args)

    {

        Process p = new Process();

        p.StartInfo.UseShellExecute = false;

        p.StartInfo.RedirectStandardOutput = true;

        p.StartInfo.FileName = commandToRun.Value;

        p.StartInfo.Arguments = args.Value;

        p.Start();

        SqlContext.Pipe.Send(p.StandardOutput.ReadToEnd());

        p.WaitForExit();

    }

}

Скрипт 2

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

if object_id('CmdShell', 'PC') is not null drop proc CmdShell

if exists(select 1 from sys.assemblies where name = 'MyAssembly') drop assembly MyAssembly

create assembly MyAssembly from 'C:\Temp\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll' with permission_set = unsafe

go

create proc CmdShell @cmd nvarchar(max), @args nvarchar(max) as external name MyAssembly.Class1.ExecCmd

go

Скрипт 3

Собственно, все. Можно юзать. Если ее еще назвать понеприметней, то, в отличие от xp_cmdshell, про вашу процедуру, по крайней мере, будет знать не весь белый свет, а только те, кто будет непосредственно с ней работать (и те, кому они эту инфу сольют).

image

рис.1

Требование 6. Объекты таблиц и индексов, создаваемыe прикладной программой, должны использовать ROW Level сжатие. Данное требование является опциональным, но рекомендуемым к использованию.

Итак, единственное требование, имеющее отношение к новой функциональности SQL Server 2008, носит опциональный характер. Тем не менее, возможность достаточно интересна, чтобы сказать про нее несколько слов. При рутинной работе со здоровыми таблицами, там, где нет суперсложных математических вычислений, основная нагрузка приходится на I/O. Следовательно, чем больше данных мы прокачаем за одну операцию ввода-вывода, тем быстрее будет работать приложение. Чтобы уместить больше данных, их приходится сжимать. Да, на сжатие тратятся какие-то ресурсы, в том числе процессорные, но это копейки. Суммарно получается достаточно приличный выигрыш по скорости.

В 2008 используется сжатие постраничное и позаписьное. Грубо говоря, позаписьное, это как если бы мы перед каждым типом поставили приставку var. Типы varchar существовали всегда. В 2005, дай бог памяти, SP2 появился vardecimal. Ну вот теперь по тому же принципу можно упаковать вообще все. Только var писать не надо, надо включить компрессию на уровне записей. Сжатие на уровне страницы называют еще префиксно-словарным сжатием. Сначала в каждой колонке определяются наиболее частые префиксы (ну, например, название округа или города в юр.адресе), которые вытаскиваются в заголовок страницы, а затем вся страница ищется на предмет общих значений независимо от колонки, которые тоже вытаскиваются в заголовок. Лежит-то все один хрен в виде бинарщины. По типу колонки ее потом можно обратно превратить во что-то осмысленное. Какой вид сжатия более оптимален, зависит каждый раз от данных, поэтому чего ребята в тесте привязались только к row, надо спрашивать у них. Вот пример, где страничное сжатие оказывается выигрышней - http://blogs.msdn.com/alexejs/archive/2009/07/07/var.aspx. Просто потому, что я там в качестве примера взял табличку DimCustomer, где большинство полей и так имеют тип varchar. Паковать varcharы позаписьным сжатием - все равно, что сжимать zip zipом. Выигрыш будет, но небольшой. В то же время, в таблице присутствует, например, колонка Address, с тучей одинаковых префиксов, колонки Education, Occupation и пр. с кучей повторяющихся значений, так что ничего удивительного в том, что постраничное сжатие оказывается в данном случае более эффективным.

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

 

Алексей Шуленин, Microsoft