div.main {margin-left: 20pt; margin-right: 20pt}
Повышение надежности Windows
2000
Часть 2
В предыдущей статье были рассмотрены характеристики Windows 2000,
способствующие повышению ее надежности. Сегодня я расскажу о новых
свойствах системы реализованных разработчиками Microsoft для того,
чтобы средствами восстановления приходилось пользоваться как можно
реже. К ним относятся: (1) «подпись» драйверов (Driver Signing), (2)
служба защиты системных файлов (System File Protection) и (3)
методика верификации драйвера (Driver Verifier), о которой пойдет
речь в следующий раз в части 3.
«Подпись» драйвера (Driver Signing)
|
Марк Русинович доктор философии в области
вычислительной техники Университета Карнеги-Меллон и один из
соавторов многих популярных утилит для Windows NT, включая
NTFSDOS, Filemon, Regmon и Recover. С ним можно связаться по
электронной почте по адресу mark@sysinternais.com
или через Web-узел http://www.sysinternais.com/ | Как
уже отмечалось в прошлый раз, ошибки, допущенные при написании
драйверов, являются основной причиной нестабильности Windows NT 4.0.
Начиная с самых первых версий Windows NT компания Microsoft
публикует документ Hardware Compatibility List (HCL), где приводится
список устройств и соответствующих им драйверов, которые поставщики
аппаратуры предоставили для тестирования фирме Microsoft. Запись об
устройстве в этом документе означает, что оно успешно прошло целый
ряд тестовых испытаний в среде Windows NT. Хотя указание в HCL того
или иного драйвера не гарантирует отсутствие в нем ошибок,
вероятность столкнуться с ними в работе ниже, чем при использовании
драйверов, не прошедших такие испытания. Однако зачастую при
подключении нового устройства пользователи попросту забывают о
необходимости свериться с этим списком. А бывает и так: стараясь
поддерживать самые последние версии драйвера от производителя,
пользователь обращается к HCL, но оригинальный драйвер устройства
может быть указан в списке, но его новая версия — нет (например,
поставщик создал новую версию драйвера с целью повышения
производительности, но при этом она работает с ошибками). К тому же
иногда администраторам приходится иметь дело с системами, для
которых проведение какой-либо безопасной политики в отношении
установки драйверов фактически нереально. Чтобы помочь системе в
процессе работы следить за тем, какие драйверы используются
(включены ли они в список HCL), Microsoft разработали технологию
«подписи» драйверов (Driver Signing). Программа Microsoft Internet
Explorer (IE) уже на протяжении нескольких лет использует «подпись»
Authenticode для элементов ActiveX, так что IE можно настроить,
чтобы каждый раз перед загрузкой элемента ActiveX программа выдавала
пользователю запрос. Процесс «подписи» драйвера реализует фактически
такую же технологию применительно к файлам драйверов. Поскольку
Microsoft «подписывает» только драйверы, упомянутые в HCL, по
отсутствию «подписи» система «понимает», что данный драйвер не из
списка HCL.
На Экране 1 представлено диалоговое окно Driver Signing Options
(Обращение через Control Panel => System => закладка
Hardware).
|
ЭКРАН 1. Установка действий системы при
проверке «подписи»
драйвера. | Используя настройки,
предлагаемые в этом окне, можно задать действия, которые должна
выполнить система при попытке установить драйвер, отсутствующий в
HCL. Например, указать параметр Ignore, и тогда Windows 2000
позволит устанавливать «неподписанные» драйверы без каких-либо
«замечаний» со своей стороны (именно такой механизм заложен в NT
4.0). Выбирая параметры Warn или Block, можно настроить систему так,
что при попытке установить «неподписанный» драйвер она должна или
предупредить об этом, или же запретить подобную установку.
Что скрывается за словосочетанием «Microsoft подписывает
драйвер»? Во-первых, для файла драйвера генерируется некоторый
цифровой код — хэш-код (hash). Он представляет собой число,
поставленное в соответствие содержимому файла. Это число уникально,
т. е. нет таких двух файлов, для которых хэш-коды были бы
одинаковыми. Затем с помощью технологии шифрования, разработанной
фирмой VeriSign (компанией, предоставляющей услуги цифровой
аутентикации), Microsoft выполняет шифрование хэш-кода открытым
ключом. Зашифрованный хэш-код — это своеобразная «подпись»
(сигнатура) драйвера. Впоследствии и драйвер, и его «подпись»
поставляются вместе. Если известен открытый ключ, то сигнатуру
драйвера в любой момент можно расшифровать. На CD-ROM с Windows 2000
помимо собственно файлов-драйверов содержатся и их сигнатуры. После
установки системы обратите внимание на каталог
%systemroot%system32catroot: именно здесь хранится информация о
сигнатурах установленных драйверов в так называемых catalog-файлах.
Драйверы устройств и их сигнатуры, разработанные OEM-партнерами
Microsoft, после проведения соответствующих испытаний на
совместимость с Windows 2000 (HCL-тестирование) предоставляются
поставщикам системы. В каталоге Catroot имеются два файла с
одинаковым именем sysmast и подкаталог, имя которого состоит из
набора цифр и букв, а длина превышает 8 символов. Sysmast — главный
индекс catalog-файлов. В подкаталоге находятся catalog-файлы для
различных компонентов Windows 2000. Например, fp.cat — это каталог
сигнатур для файлов приложения FrontPage, а nt5.cat и nt5inf.cat
хранят сигнатуры для системных файлов.
Драйверы в Windows 2000 устанавливаются по-разному. Наиболее
общий подход означает, что, когда подсистема Plug-and-Play (PnP)
обнаруживает появление нового устройства, она пытается
проинсталлировать соответствующий драйвер автоматически. При этом
подсистема ядра PnP извещает пользовательский компонент PnP о
появлении нового устройства. Последний (UMPNPMGR) реализован в виде
библиотеки %systemroot%system32umpnpmgr.dll. Когда в систему
добавляется новое устройство, UMPNPMGR начинает поиск
информационного файла инсталляции драйвера (INF-файла). Этот файл
может располагаться или в каталоге %systemroot%INF, или на внешнем
носителе — дискете, или CD-ROM — в случае использования
OEM-драйверов. INF-файлы имеют расширение и представляют собой
обычный текстовый файл, содержащий инструкции по установке драйвера,
той или иной степени сложности. Это могут быть директивы по
копированию файлов — откуда и куда, задания новых значений в
реестре, — в общем, все то, что нужно выполнить в системе при
инсталляции нового драйвера или приложения. Другой способ установки
драйвера состоит в применении мастера установки, Hardware
Installation Wizard (HIW), реализованного в виде
библиотеки %systemroot%system32 newdev.dll. HIW
последовательно, шаг за шагом, проходит тем же путем, что и
UMPNPMGR, когда локализует местонахождение INF-файла.
UMPNPMGR и HIW используют вызовы API, предоставляемые библиотекой
%systemroot%system32 setupapi.dll (SETUPAPI), для работы с
INF-файлом. С помощью вызовов SETUPAPI обрабатываются инструкции по
установке драйвера и проверяется параметр реестра HKEY_
LOCAL_MACHINESOFTWARE MicrosoftDriverSigningPolicy. Если он не
установлен, то проверяется HKEY_CURRENT_USERSoftwareMicrosoft
DriverSigningPolicy. Именно эти параметры реестра устанавливаются
в диалоговом окне Driver Signing Options. Когда во время работы в
данном диалоге выдается директива Apply setting as system default,
то устанавливается параметр реестра HKEY_LOCAL_MACHINE; в противном
случае изменение происходит в HKEY_CURRENT_USER. Компонент UMPNPMGR
сначала проверяет значение Policy в ветви HKEY_LOCAL_MACHINE и если
оно установлено, то система присваивает ему наивысший приоритет, и
индивидуальные установки, заданные в политике «подписи» драйверов не
принимаются во внимание, кем бы они ни были заданы —
администраторами или обычными пользователями. Значение 0 означает,
что инсталляция драйверов будет производиться в системе без
рассмотрения «подписи». Если значение равно 1, то при попытке
установить драйвер без «подписи» будет выполнено обращение к
SetupAPI, и пользователю придется дополнительно подтвердить
необходимость установки такого драйвера. Значение Policy, равное 2,
не позволит установить в системе драйвер без соответствующей
«подписи».
В том случае, когда политика «подписей» диктует SetupAPI, в
обязательном порядке проверять сигнатуры драйверов, с помощью
соответствующего вызова API осуществляется поиск нужного каталожного
файла. Затем SetupAPI обращается к CryptoAPI, в котором реализованы
криптографические функции, для вычисления хэш-кода файла драйвера и
дешифровки сигнатуры каталожного файла на основе открытого ключа от
VeriSign. Если полученные значения не совпадают или для драйвера не
найден catalog-файл, то SetupAPI либо запросит пользователя, нужно
ли продолжать установку драйвера, либо процесс прервется, и будет
выдано сообщение об ошибке.
Windows File Protection
В процессе разработки Windows 2000 Microsoft произвела опрос
пользователей NT с целью выяснить, что, по их мнению, служит
причиной нестабильности NT 4.0. В результатах опроса часто
упоминался так называемый «библиотечный кошмар». Суть «кошмара»
состоит в том, что в комплект поставки многих приложений
разработчики добавляют библиотеки, необходимые для работы и самой
системы NT. Резон разработчиков прост: не зависеть от того, какая
версия библиотеки присутствует в системе. Например, приложения,
написанные с использованием возможностей библиотеки Microsoft
Foundation Classes (MFC) C++, часто поставляются с определенной
копией библиотеки mfc42.dll. Компания Microsoft выпустила несколько
версий этой библиотеки, и возможно, не все они совместимы с той, на
которую рассчитано данное приложение. Проблема множества версий DLL
распространяется даже на библиотеки, с которыми работает ядро
NT.
В Windows 2000 появилась служба защиты от подобных приложений —
Windows File Protection (WFP). До третьей бета-версии эта защита
носила название System File Protector. WFP выполняет функции
обеспечения безопасности системных файлов, в том числе файлов DLL,
драйверов, шрифтов, INF-файлов и исполняемых файлов. Когда WFP
«замечает» изменение в одном из охраняемых файлов, активизируется
механизм защиты и произведенное изменение нейтрализуется
оригинальной копией файла.
Во время активизации подсистемы Windows Logon (%systemroot%
system32winlogon.exe) подгружается одна из библиотек WFP —
%systemroot%system32sfc.dll (System File Checker — SFC). SFC
экспортирует несколько функций для процедуры Winlogon, среди них
SfcInitProt — функция инициализации. SfcInitProt в первую очередь
считывает реестр в части SFC, именно раздел
HKEY_LOCAL_MACHINESOFTWAREMicrosoft WindowsNTCurrentVersion
Winlogon. Сначала анализируется параметр SFCDisable. Если оно не
установлено в 0 и отладчик ядра (WinDbg) активен, то SFC
дезактивирует службу WFP.
Вслед за этим SFC проверяет параметр SFCScan. Если его значение
равно 1, то после завершения инициализации системы будет выполняться
контроль целостности (сканирование) системных файлов. Если же он
равен 2, то после завершения контроля целостности SFCScan имеет
нулевое значение. Оно же задается по умолчанию. При этом
сканирование системных файлов после завершения процедуры Winlogon не
производится, но SFC тем не менее активизируется. В состав Windows
2000 входит утилита sfc.exe, с помощью которой можно задавать
значение параметра SFCScan.
После завершения обработки параметра SFCScan анализируется
параметр реестра SfcDllCacheDir. Последний параметр реестра, который
проверяет служба SFC, — SFCQuota (тип данных DWORD). Значение этого
параметра устанавливает максимальное количество данных (в
мегабайтах), которое SFC должна контролировать. Все упомянутые
параметры реестра необязательны; это означает, что, если они не
заданы, считается, что им присвоено значение 0. Исключение
составляет лишь SFCQuota: если оно явно не задано, то SFC
присваивает ему значение -1. Это означает, что размер данных,
контролируемых SFC, не ограничен.
После того как считаны все установки реестра, SfcInitProt
вызывает функцию SfcInitializeDllLists. Эта функция начинает
обработку списка контролируемых службой SFC файлов. Если Windows
2000 установлена в разделе NTFS, то проверяются права доступа к
системным каталогам и соответствие этих прав рекомендациям SFC по
защите системы. SFC контролирует около 3000 системных файлов.
(Список SFC можно просмотреть на http://www.sysinternals.com/misc.htm.
Библиотека Sfc.dll обеспечивает защиту указанных в списке файлов.)
На Рисунке 1 приведен фрагмент списка системных каталогов, за
которыми SFC устанавливает наблюдение. Не все файлы из обширного
списка SFC присутствуют в каждой установленной Windows 2000.
РИСУНОК 1. Фрагмент списка каталогов, за которыми следит
SFC.%systemroot%
%systemroot%system
%systemroot%system32
%systemroot%system32wbem
%systemroot%system32usrbri
%systemroot%system32spool
prtprocs
%systemroot%system32spool
prtprocsw32x86
%systemroot%system32spool
driversw32x863
%systemroot%system32rpcproxy
%systemroot%system32reminst
%systemroot%system32os2dll
%systemroot%system32npp
%systemroot%system32netmon
%systemroot%system32mui 009
%systemroot%system32mts
%systemroot%system32mtsmtxclex
%systemroot%system32inetsrv
%systemroot%system32export
%systemroot%system32drivers
%systemroot%system32com
%systemroot%system32clients
tsclientnetwin32aСледовательно, реальное число
контролируемых файлов может быть меньше 3000. Копии оригинальных
файлов из списка SFC хранятся в каталоге %systemroot%
system32dllcache, если только в реестре в параметре SfcDllCacheDir
не указано иное. Тем самым Microsoft предусмотрела возможность
хранения архивной копии контролируемых файлов в некотором
общедоступном месте в сети, что особенно целесообразно при
административном (корпоративном) развертывании систем. SFC трактует
значение SfcDllCacheDir (тип данных String), как путь к копии
защищенных файлов. При этом путь может задаваться в формате UNC и
содержать описание сетевого диска. При подготовке к проведению
автоматической инсталляции можно указать в файле unattended.txt
нужный путь. Но надо иметь в виду, что, прежде чем SFC реально
обратится в каталог, заданный параметром SfcDllCacheDir,
пользователь должен иметь права на чтение в этом каталоге. Когда SFC
производит отмену внесенных изменений, то в первую очередь
происходит обращение в каталог Dllcache за оригинальной копией
измененного или удаленного системного файла.
Вслед за SfcInitializeDllLists процедура SfcInitProt вызывает
функцию SfcBuildDirectoryWatchList. Задача этой функции состоит в
том, чтобы каждый раз, когда будет происходить обращение к каталогу,
содержащему защищенные файлы, служба SFC получала уведомление о
модификации (change-notification). SfcBuildDirectoryWatchList
открывает каждый такой каталог и оставляет открытым. В Windows 2000
любое приложение может запросить системное подтверждение для
проведения изменений внутри данного каталога. Если бы такой
возможности не было, то для контроля потенциальных изменений
пришлось бы периодически анализировать файл за файлом в
контролируемом каталоге. Чтобы оценить преимущество
change-notification, нужно открыть один и тот же каталог в Windows
Explorer и окне DOS (с командной строки), затем в окне DOS удалить
или переименовать произвольный файл. Windows Explorer автоматически
начнет выполнять обновление окна, чтобы проведенные в каталоге
изменения были отражены и в его окне.
Если из параметра реестра SFCScan следует, что SFC должна
выполнить сканирование системных файлов, то следующим шагом в
процедуре инициализации службы SFC будет верификация файлов. Эту
задачу выполняет функция SfcScanProtectedDlls. На основе списка
контролируемых файлов, сформированных с помощью
SfcInitializeDllLists, функция SfcValidateDLL выполняет обращение к
каждому из них и проводит верификацию содержимого файла. В
дальнейшем SFC обращается к функции SfcValidateDLL всякий раз, когда
устанавливается факт изменения системных файлов.
Когда начальное сканирование (в общем случае необязательное)
завершено, SFC запускает специальный поток защиты (watchdog thread).
Этот поток находится в состоянии ожидания события
change-notifications, относящегося к каталогам, где хранятся
SFC-файлы. Когда система «сообщает» о том, что приложение произвело
изменение одного или нескольких контролируемых файлов, данный поток
вызывает функцию SfcValidateDLL для каждого такого изменения, и
происходит возврат к оригинальным копиям файлов. SfcValidateDLL
поочередно вызывает функцию SfcGetValidationData и
SfcValidateFileSignature для измененных файлов. С их помощью
устанавливается версия файла и проверяется его цифровая «подпись».
Дополнительно проверяется факт верификации цифровой подписи для
копии файла в каталоге Dllcache. На CD-ROM с Windows 2000 содержатся
все SFC-файлы, а также соответствующие «подписи» от Microsoft.
SfcValidateFileSignature использует несколько функций из состава
CryptoAPI, среди которых есть такая, которая позволяет вычислить
хэш-код файла. С помощью другой импортируемой функции
SfcValidateFileSignature вычисляет ссылку на файл, содержащий
цифровую «подпись» для данного файла.
Итак, SfcValidateFileSignature располагает и хэш-кодом, и ссылкой
на catalog-файл. Вслед за этим выполняется вызов функции
WinVerifyTrust — функции ядра Windows 2000 для верификации цифровой
подписи. WinVerifyTrust на основе открытого ключа от VeriSign
расшифровывает цифровую «подпись» и получает хэш-код catalog-файла
«подписи». Выполняется сравнение хэш-кодов, и если они совпадают, то
WinVerifyTrust регистрирует этот факт. Если файл поврежден, изменен
или отсутствует, функция возвращает код ошибки, а
SfcValidateFileSignature сообщает системе о сбое при проведении
верификации сигнатур.
Проверяя «подписи» обоих файлов, того, который используется
системой, и его оригинальной копии, SfcValidateDLL «узнает»
произошло ли изменение. Если верификация оригинальной копии
завершена с ошибкой, SFC необходимо восстановить архивную копию до
того, как потребуется заменить файл, используемый системой в данный
момент. Для определения пути к установочным файлам Windows 2000
(пути, откуда производилась инсталляция системы), служба SFC
анализирует параметр реестра HKEY_LOCAL_MACHINESOFTWARE
MicrosoftWindowsNTCurrentVersionSourcePath. В качестве источника
архивных копий системных файлов может служить и установочный
носитель, но, если он отсутствует (например, CD-ROM Windows 2000 не
вставлен в устройство для чтения компакт-дисков), SFC предлагает
предоставить этот носитель. Если же SFC не может установить
местонахождение архивных файлов или если пользователь в ответ на
запрос вставить носитель нажимает Cancel, то служба SFC не обновляет
файл, и на экран выводится соответствующее сообщение (см. Экран 2).
SFC использует функции SetupAPI
(%systemroot%system32setupapi.dll), чтобы обнаружить и
скопировать необходимые файлы с инсталляционного носителя.
|
ЭКРАН 2. Сообщение службы
SFC. |
После того как функция SfcValidateDLL установила, что архивная
копия в каталоге Dllcache отвечает всем предъявляемым требованиям
или выполнено копирование архивного файла с установочного носителя,
служба SFC выполняет восстановление измененного системного файла,
используя архивную версию. При этом в системный журнал (System Event
Log) производится запись о системном файле, который был
модифицирован.
Иногда необходимо установить новые версии файлов, которые
контролируются WFP, и Windows 2000 должна предоставить механизм для
выполнения такой операции. Например, установка программных
«заплаток» (hotfixes), пакетов обновлений, установка Windows 2000 в
режиме Upgrade предполагает штатное обновление системных файлов.
Поскольку эти программы изменяют системные файлы, т. е. файлы,
«подписанные» Microsoft, следовательно, изменяются или добавляются
соответствующие catalog-файлы и их сигнатуры. Изменения копируются
поверх существующих версий. WFP обнаруживает эти изменения, но
считает их правомочными, так как хэш-коды системных и catalog-файлов
совпадают. В то же время WFP распознает, что хэш-коды обновленных
файлов отличаются от хэш-кодов одноименных файлов во время самого
последнего проведенного сканирования, и поэтому переписывает каталог
Dllcache, заполняя его новыми файлами. После штатного обновления
системных файлов необходима перезагрузка для того, чтобы внесенные
изменения вступили в силу, и каждый компонент системы стал
использовать новые версии файлов. Не существует никакого иного
способа сообщить приложениям, что нужно работать с обновленными
версиями системных файлов, кроме как перезагрузка системы в
целом.
Специалисты Microsoft надеются, что благодаря WFP, который
обеспечивает защиту системных файлов, пользователи не будут
сталкиваться с неустойчивостью Windows 2000 по причине
«библиотечного кошмара». Тем не менее не надо думать, что WFP — это
своего рода «бронежилет» для системных файлов. Поскольку SFC имеет
буфер ограниченного размера для фиксации изменений в контролируемом
множестве файлов, существует опасность, что буфер может
переполниться. Если это произойдет, SFC просто сбросит его
содержимое. Или, например, если в каталоге %systemroot%system32
вдруг удаляются все системные файлы, то WFP будет не в состоянии
произвести возврат к исходному состоянию, так как заранее
неизвестно, что эти файлы удалены. В таком случае необходимо
сканировать системные файлы с помощью утилиты sfc.exe с ключом
/scannow или же воспользоваться опцией Repair, запустив программу
установки Windows 2000 с CD-ROM для проведения перезаписи системных
файлов.
Три угла атаки
Для решения проблем, связанных с обеспечением должной надежности
новой системы, специалисты компании Microsoft сконцентрировала свои
усилия в трех направлениях. Во-первых, как было рассказано в первой
части настоящей статьи, в Windows 2000 реализованы новые механизмы
для выявления и устранения возникающих проблем. Во-вторых,
предприняты усилия по предотвращению несанкционированного
«расползания» OC через системные файлы и драйверы. В заключительной
части будет рассмотрен последний «угол атаки» на проблему надежности
Windows 2000. Речь пойдет об инструментальных средствах
разработчика, которые должны помочь программисту создавать более
надежные драйверы устройств, а администратору системы — с высокой
точностью локализовать проблемный драйвер.
|