016 Системный Администратор 03 2004

97

Upload: dmitry-ushakov

Post on 17-Mar-2016

262 views

Category:

Documents


6 download

DESCRIPTION

32 88 Ошибки переполнения буфера извне и изнутри как обобщенный опыт реальных атак Уважаемые читатели! Рады сообщить вам, что с 1 апреля открыта подписка на II полугодие 2004 года. Более подробная информация на нашем сайте www.samag.ru Программное управление ADSI: LDAP С Юниксом на vi 1 2 АНДРЕЙ БЕШКОВ администрирование 4 администрирование 5 6

TRANSCRIPT

Page 1: 016 Системный Администратор 03 2004
Page 2: 016 Системный Администратор 03 2004

1№3(16), март 2004

оглавление

АДМИНИСТРИРОВАНИЕ DeviceLock

Андрей Бешков[email protected] 38

А ты что видишь?Удаленное управление посредствомrdesktop, RAdmin, VNC

Антон Борисов[email protected] 12

Свободная ДОС для свободных людей,или Не Linux единым жив человек

Андрей Маркелов[email protected] 20

С Юниксом на vi

Сергей Супрунов[email protected] 24

Свободный антивирусОбзор Clam AntiVirus – антивирусной программы для UNIX-систем.

Сергей Яремчук[email protected] 32

БЕЗОПАСНОСТЬ

Запуск Windows-приложений под Linuxс помощью CrossOver OfficeЧасть 2

Андрей Бешков[email protected] 4

Три поросёнка Snort:«Ниф-ниф», «Нуф-нуф» и «Наф-наф».(Настройка нескольких сенсоров Snortс помощью SnortCenter)

Павел Закляков[email protected] 42

Ошибки переполнения буфераизвне и изнутри как обобщенный опытреальных атак

Крис Касперски[email protected] 64

HARDWARE

Реализация низкоуровневой поддержкишины PCI в ядре операционной системыLinux

Владимир Мешков[email protected] 74

ОБРАЗОВАНИЕ

Программное управление ADSI: LDAP

Иван Коробко[email protected] 88

Уважаемые читатели!Рады сообщить вам, что с 1 апреля открыта подписка на II полугодие 2004 года.

Подписной индекс 81655 по каталогу агентства «Роспечать».

Подписной индекс 87836 по каталогам:Объединенный каталог «Пресса России» 2004/2

Каталог стран СНГ 2004/2Каталог Казахстана 2004/2

Адресный каталог «Подписка за рабочим столом» 2004/2Адресный каталог «Библиотечный каталог» 2004/2

ООО «Интер-почта» по тел. (095) 500-00-60 (Курьерская доставка по Москве).

Более подробная информация на нашем сайте www.samag.ru

Page 3: 016 Системный Администратор 03 2004

2

Впервые организованная в 1989 году, выставка НеделяИнформационных Технологий «IT Week Russia», изве-стная в прошлом как Comtek, за пятнадцать лет своегосуществования пережила и взлеты и падения. В преды-дущие годы в Неделю Информационных Технологий вхо-дила выставка Сomtek, которая состояла из несколькихнаправлений, и конференция E-Business. Развитие выс-тавки в течение последних лет привело к необходимос-ти выделить отдельные разделы в самостоятельные вы-ставки. С этого года в Неделю Информационных Техно-логий будут входить пять самостоятельных выставок идве конференции. Этот шаг позволил расширить масш-таб выставки, объединяющей все аспекты компьютер-ного бизнеса, что, в свою очередь, дает возможностьпривлечь к участию в выставке большее число компа-ний, занятых во всех сферах индустрии информацион-ных технологий.

Давид Патеишвили, директор выставки, сказал: «Вэтом году мы расширили темы, представленные на экс-позиции, которые теперь охватывают все области компь-ютерной индустрии. Это дает превосходную возможностьи участникам, и посетителям выставки принять участие иознакомиться сразу с пятью выставками и двумя конфе-ренциями, проходящими в одно время и в одном месте.Это также позволит нам улучшить маркетинговую и рек-ламную кампании для каждой из выставок и конферен-ций, проходящих в рамках Недели Информационных Тех-нологий, с учетом целевой аудитории, специфичной длякаждой из них. Хочется добавить, что некоторые выстав-ки, которые будут проходить в рамках Недели Информа-ционных технологий, не имеют аналогов в России, явля-ясь тем самым уникальными».

В рамках Недели Информационных Технологий прой-дут следующие выставки и конференции:1. Personal Computing Expo – общая, неспециализиро-

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

2. Hardware & Peripherals Expo – специализированнаявыставка, на которой представлены: компьютеры, мо-ниторы, периферийные устройства, комплектующие,накопители, коммуникационное оборудование и услу-ги, т.е. весь спектр hardware, ориентированного на ве-дение бизнеса.

3. Международная конференция eLearning Russia (Инфор-мационные технологии в образовании), на которой бу-дут освещены последние достижения образовательныхтехнологий в школах, вузах, а также рассмотрены воп-росы дистанционного и бизнес-образования.

4. Software Expo – специализированная выставка, ори-ентированная на программные продукты для систембухгалтерского и складского учета, комплексного ПОуправления предприятием, систем управления доку-ментооборотом, систем распознавания документов,разработку ПО, защиту информации. В рамках этойвыставки будет подготовлен цикл тематических семи-наров, посвященных актуальным вопросам в областиразработки экономических программ и систем управ-ления бизнесом.

5. Специализированная выставка CAD/CAM/CAE пред-ставляет системы автоматизированного проектиро-вания. Для большинства российских производителейнеобходимость использования САПР для оптимиза-ции работы предприятия стала очевидной. Особенноярко это проявляется в таких отраслях, как авиастро-ение, автомобилестроение, тяжелое машиностроение,архитектура, строительство, нефтегазовая промыш-ленность.

6. eLearn Expo – специализированная выставка, на ко-торой будут демонстрироваться новейшие продуктыи технологии в сфере электронного обучения, пред-назначенные для коллективного и индивидуальногопользования. Дистанционное обучение через сетиInternet и Intranet, получившее широкое распростра-нение в развитых странах, становится все более ак-туальным и для России.

7. eBusiness Russia (Электронный бизнес в России) –международная конференция, посвященная вопросамавтоматизации бизнес-процессов, развития электрон-ной коммерции, подбора ИТ-персонала.

Выставка IT-week остается ведущей международнойвыставкой информационных технологий в России и стра-нах СНГ. Это уникальное место для проведения перего-воров с первыми лицами сразу нескольких крупных фирм-поставщиков оборудования и решений. Практически всекрупные западные вендоры присутствуют на выставке не-посредственно или при посредстве своих российских парт-неров.

В соответствии с растущими потребностями рынка иувеличением числа участников экспозиция расширилаплощадь, которая в этом году составит 8 000 кв. м. В выс-тавках, которые пройдут в течение 4 дней, примут учас-тие 250 ведущих компаний отрасли из 25 стран мира.Ожидается, что число посетителей выставки превысит75 000 человек, включая руководителей верхнего и сред-него звена, технических специалистов и IT-администра-торов, из более 500 городов России и СНГ.

«IT Week 2004», 15-ая Международная Выставка Ин-формационных Технологий пройдет в «Экспоцентре» наКрасной Пресне в Москве с 26 по 29 апреля 2004 года.

УНИКАЛЬНЫЕ СОБЫТИЯНА КОМПЬЮТЕРНОМ РЫНКЕ

Page 4: 016 Системный Администратор 03 2004
Page 5: 016 Системный Администратор 03 2004

4

администрирование

АНДРЕЙ БЕШКОВ

В первой статье о CrossOver Office мы обсудили, как выполнить инсталляцию этого программногопакета. Затем поговорили о том, как с помощью него запускать под управлением Linux программы,написанные для Windows. В качестве примера было рассказано об успешной работе с MicrosoftOffice 2000, The Bat!, Microsoft Internet Explorer, Mplayer и Outlook Express. Тем, кто пропустилпервую статью, рекомендую обязательно ознакомиться с ней. Сделать это можно либо в февральскомвыпуске этого журнала, либо на моем сайте http://onix.opennet.ru. Ну а я потихоньку продолжулинию нашего повествования.

ЗАПУСК WINDOWS-ПРИЛОЖЕНИЙПОД LINUX C ПОМОЩЬЮ CROSSOVER OFFICE

ЧАСТЬ 2

Page 6: 016 Системный Администратор 03 2004

5№3(16), март 2004

администрирование

Задача на сегодня довольно проста. Нужно изучить теориюфункционирования и глубинные механизмы CrossOver Office.В дальнейшем это поможет нам правильно идентифициро-вать проблемы, возникающие при инсталляции Windows-про-грамм, а, как говорят врачи, правильный диагноз – полови-на лечения. Как было отмечено в первой статье, все Windows-программы делятся на два вида. Официально поддержива-емое обеспечение скорее всего легко установится и будетгладко работать под управлением CrossOver Office, навеваяна вас мысли о невыносимой легкости бытия Linux-пользо-вателя. К сожалению, список этих программ не так уж ве-лик. Ознакомиться с ним можно по следующему адресу:http://www.codeweavers.com/site/compatibility/browse/cat.

Кстати, стоит отметить, что в него входят только те при-ложения, за стабильную работу которых сотрудники ком-пании Codeveawers могут поручиться на все сто процен-тов. К сожалению, сотрудников в компании не так уж и мно-го, поэтому они не могут знать о всех используемых вамиWindows-приложениях. Впрочем, даже если они и будутзнать, это не очень изменит положение вещей. Ведь на те-стирование каждого приложения нужно потратить немаловремени. Таким образом, получается, что приложения, неподвергшиеся тестированию под CrossOver Office, не по-лучают официальной поддержки. Ничего страшного в этомнет. Возможно, при работе с нашими Windows-программа-ми все будет хорошо, и нам никогда не придется прибегатьк поддержке персонала Сodeveawers. Например, я доволь-но легко установил Remote Administrator, QuickTime Player,Acrobat Reader и Microsoft Visio и весьма успешно работаюс этими приложениями. Все вышесказанное означает толь-ко то, что, начав работать с неподдерживаемыми програм-мами, надеяться нам не на кого и мы, как кошки, начинаемгулять сами по себе. Впрочем, это ни в коем случае не дол-жно страшить нас.

В связи с тем, что CrossOver Office основан на коде, унас-ледованном от Wine, практически все, о чем я буду расска-зывать в этой статье, может вполне успешно применятьсяпри работе с Wine. Итак, начнем с самых основ и посмотрим,что происходит в системе во время запуска Windows-прило-жений. Сам по себе процесс загрузки программы в памятьнесложен. Проблема в том, что нужно найти и загрузить всетребуемые DLL. Затем провести импортирование из DLL тре-буемых функций и правильно найти точки входа в каждуюиз них. Предполагается, что каждое нормально написанноеприложение, как и любые небазовые DLL, не станет пытать-ся использовать напрямую системные функции, а вместо это-го будет импортировать все требуемые механизмы из ос-новных системных библиотек. Соответственно для того, что-бы Wine смогла нормально загружать Windows-приложения,нужно как минимум заменить своими собственными реали-зациями основные системные DLL, в число которых входятUSER/USER32, GDI/GDI32, KERNEL/KERNEL32 и NTDLL.

Кстати, стоит отметить, что многие функции, реализован-ные изначально в KERNEL32 и ADVAPI32, постепенно былиперенесены в NTDLL. Динамические библиотеки, зановореализованные для Wine, называются «встроенными», а те,что перенесены из Windows без каких-либо изменений, на-зываются «родными». Соответственно в тот момент, когдаWindows-приложение заявляет о своем желании импорти-

ровать какую-либо DLL, Wine сначала смотрит в список встро-енных DLL, если там найти нужное не удалось, то начинает-ся поиск на жестком диске родного Windows DLL-файла.

Сердцем системы эмуляции служит Wine-сервер, еслиговорить по существу, то он необходим для правильной орга-низации межпроцессорных коммуникаций между всеми за-пущенными Windows-приложениями и является отдельнымоднопоточным процессом с бесконечным циклом выборки иобработки сообщений, приходящих от системы и клиентс-ких процессов. Из-за отсутствия многопоточности внутрисвоего процесса Wine-сервер не может выполнять задачи,требующие существенных временных затрат. Впрочем пе-редача сообщений и событий между клиентскими процес-сами и основной системой действительно не является тру-доемкой работой. Также в целях безопасности Wine-серверне имеет доступа к адресному пространству своих клиен-тов. Если в момент старта первого клиентского Wine-про-цесса процесс Wine-сервера еще не работает, то он будетнезамедлительно запущен. Сразу же после начала работыWine-сервер создает UNIX-сокет, предназначенный для об-щения с клиентами, отвечающими за выполнение Windows-приложений. Обычно сокет находится в директории $HOME/.wine либо там, куда указывает переменная окруженияWINEPREFIX. Ну а если мы используем CrossOver Office, тосокет возникнет в директории /tmp/wine-<имя пользователя>.После того как все клиентские Wine-процессы будут завер-шены, закончит свою работу и Wine-сервер. Методы работыс приложениями win32 и win16 довольно сильно отличаются.Для программ с архитектурой win16, доставшихся нам в на-следство от старых версий Windows, характерно функцио-нирование в едином адресном пространстве и использова-ние кооперативной многозадачности. Исходя из таких тре-бований, удобнее всего было сделать так, чтобы все запу-щенные win16-программы выполнялись не как отдельныепроцессы, а стали нитями в рамках одного процесса. Идеяподобного механизма работы с устаревшими приложения-ми была позаимствована из Windows NT, поэтому так же,как и в системе-прародителе, сущность, обеспечивающаяфункционирование приложений win16, называется WOW-процессом. Внутри него разные нити, олицетворяющие от-дельные приложения, синхронизируются друг с другом с по-мощью мьютекса. Нить, работающая в данный момент, зах-ватывает мьютекс в эксклюзивное владение и соответствен-но не позволяет работать остальным нитям. Как только ак-тивная нить посчитает, что выполнила достаточно действий,мьютекс будет освобожден и начнет подавать сигналы, ука-зывающие на его холостятский статус. В результате этогоон будет вновь захвачен следующей нитью, стоящей в оче-реди на выполнение. Таким образом реализуется коопера-тивная многозадачность. Ну а WOW-процесс будет существо-вать до тех пор, пока внутри него работает хотя бы одна нить.Приемы, используемые для работы с win32-программами,выглядят совершенно иначе. Для каждого выполняемоговнутри Wine приложения win32 создается свой собственныйпроцесс, так как программы такого типа написаны в расчетена вытесняющую многозадачность и отдельное виртуальноеадресное пространство для каждого экземпляра. Каждыйклиентский процесс Wine имеет в своем составе специаль-ную сервисную нить, выполняющуюся наравне с остальны-

Page 7: 016 Системный Администратор 03 2004

6

администрирование

ми нитями этого процесса. Ее функция состоит в том, чтобывыполнять задачи, которые нельзя поручить Wine-серверу.Например, с помощью него удается реализовать для каждо-го процесса отдельную очередь ожидания событий, исходя-щих от системы и других Wine-процессов. По приходу собы-тия сервисная нить процесса выходит из состояния сна, об-рабатывает поступившее событие и передает сообщение онем другим нитям процесса. Любые компоненты ядра wineмогут устанавливать свои собственные обработчики в сер-висную нить, если есть необходимость выполнять какие-либодействия вне зависимости от цикла выборки сообщений эму-лируемого приложения.

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

А это значит, что в случае необходимости мы легко смо-жем добавлять или удалять данные в этот импровизиро-ванный реестр с помощью обычного текстового редактора.Текстовый формат хранения данных не единственное отли-чие реестра, используемого Wine, от настоящего Windows-реестра. Дело в том, что под Wine реестр хранится не водном, а сразу в нескольких отдельных файлах. Сразу жепосле инсталляции CrossOver Office ветви реестра, обес-печивающие базовую функциональность Windows, будут за-писаны в файл system.reg, находящийся в директории$HOME/.cxoffice/dotwine. Дабы не испортить системныйреестр, все изменения, вносимые в него во время установ-ки и последующего жизненного цикла пользовательскихпрограмм, записываются в отдельный файл user.reg.

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

CrossOver Office хранит все эти директории в $HOME/.cxoffice/dotwine/fake_windows/. Создаются они автомати-чески и так же легко наполняются всеми необходимымифайлами сразу же после запуска программы /opt/cxoffice/bin/officesetup.

Вот теперь, когда мы уже разобрались со многими ню-ансами работы эмулятора, пришло время посмотреть, каквыглядит изнутри главный конфигурационный файл. ДляWine этот файл называется $HOME/.wine/wine.conf, а дляCrossOver соответственно $HOME/.cxoffice/dotwine/config.Формат обоих файлов почти ничем не отличается в обеихреализациях. Первые несколько секций отвечают за оп-ределение виртуальных дисков для Windows-системы.Проблема состоит в том, что в UNIX-подобных операци-онных системах, в отличие от Windows, файловая систе-ма не разбита на отдельные диски, обозначаемые латин-скими буквами от A до Z, а представлена единым дере-вом. Ну а вторая досадная неувязка кроется в том, чтотрадиционная файловая система Windows не различаетстрочные и прописные буквы в именах файлов и директо-рий. Соответственно файл с именем MyDOCUMENT иmydocument для Windows являются одним и тем же. Та-ким образом, перед нами стоит задача сделать так, что-бы Windows считала некоторые директории файловой си-стемы UNIX своими виртуальными дисками. Кстати, сто-ит отметить, что те строки, которые начинаются знаком«;», воспринимаются эмулятором как комментарии.

[AINF0008\\0.map] 1069188705"008cc782b199a527"=",33,HKCR,Interface\\ ↵↵↵↵↵

{56a868b5-0ad4-11ce-b03a-0020af0ba770}\\Distributor,,"i"140e1cba790e4932"=",33,HKLM,Software\\Microsoft\\ ↵↵↵↵↵

Multimedia\\DirectXMedia,.Prog,"

# Èìÿ âèðòóàëüíîãî äèñêà.  äàííîì ñëó÷àå ýòî äèñê A:[Drive A]# Ïóòü ê äèðåêòîðèè, êîòîðàÿ õðàíèò â ñåáå ôàéëû. Ïî óìîë÷àíèþ# ñêðèïò èíñòàëëÿöèè âïèñûâàåò ñþäà äèðåêòîðèþ /mnt/floppy/,# íî äëÿ ìåíÿ ýòî íå ïîäõîäèò â ñâÿçè ñ òåì, ÷òî â ìîåé# ñèñòåìå ðàáîòàåò äåìîí autofs, êîòîðûé ìîíòèðóåò óñòðîéñòâî# äèñêîâîäà /dev/floppy â äèðåêòîðèþ /mnt/floppy/auto/.# Ïîýòîìó ïðèøëîñü ïîïðàâèòü ïóòü âðó÷íóþ."Path" = "/mnt/floppy/auto"# Òèï óñòðîéñòâà. Äóìàþ, âñåì ïîíÿòíî, ÷òî äëÿ Windows îíî# áóäåò âûãëÿäåòü êàê ãèáêèé äèñê. Ýòà ïåðåìåííàÿ ìîæåò# ïðèíèìàòü çíà÷åíèÿ hd, cdrom, network, floppy ñîîòâåòñòâåííî# îáîçíà÷àþùèå æåñòêèé äèñê, CD-ROM, ñåòåâàÿ ïàïêà,# ãèáêèé äèñê."Type" = "floppy"# Ìåòêà òîìà. Îáû÷íî íóæíà òîëüêî äëÿ ïðîãðàìì, êîòîðûå# ïûòàþòñÿ çàùèùàòüñÿ îò êîïèðîâàíèÿ ñ ïîìîùüþ ÷òåíèÿ ýòîé# ìåòêè."Label" = "Floppy A"# Èìÿ ôèçè÷åñêîãî óñòðîéñòâà îáû÷íî èñïîëüçóåòñÿ äëÿ# íèçêîóðîâíåâîãî ÷òåíèÿ è çàïèñè. Ýòó îïöèþ ìîæíî ïðèìåíÿòü# òîëüêî ê ãèáêèì äèñêàì è CD-ROM.# Åñëè ïîïûòàòüñÿ ïðèìåíèòü òàêóþ îïöèþ ê ëþáîìó äðóãîìó# óñòðîéñòâó, òî ðåçóëüòàòû áóäóò î÷åíü íåïðèÿòíûå.# Íèçêîóðîâíåâàÿ çàïèñü ñêîðåå âñåãî ïîâðåäèò ðîäíóþ UNIX# ôàéëîâóþ ñèñòåìó."Device" = "auto"# Îïèñàíèå äèñêà Ñ: [Drive C]"Path" = "fake_windows"# Ñóäÿ ïî òèïó óñòðîéñòâà, Windows áóäåò ñ÷èòàòü, ÷òî ýòî# æåñòêèé äèñê."Type" = "hd""Label" = "fake_windows"# Òèï ôàéëîâîé ñèñòåìû, ïîâåäåíèþ êîòîðîé Wine áóäåò# ïîäðàæàòü. Ìîæåò ïðèíèìàòü çíà÷åíèÿ: win95, msdos, unix.# Ñîîòâåòñòâåííî â ñëó÷àå îïöèè win95 ýìóëèðóåìàÿ ñèñòåìà áóäåò# äóìàòü, ÷òî ýòî FAT32 ñ ïîääåðæêîé äëèííûõ èìåí. Ðåãèñòð# ñèìâîëîâ â èìåíàõ ôàéëîâ íå ðàçëè÷àåòñÿ. Åñëè èñïîëüçîâàòü# òèï msdos, òî íà èìåíà ôàéëîâ íàêëàäûâàåòñÿ îãðàíè÷åíèå,# ñîîòâåòñòâóþùåå ôàéëîâîé ñèñòåìå MS-DOS. Îïöèÿ unix# îòîáðàæàåò ôàéëîâóþ ñèñòåìó òî÷íî òàê æå, êàê îíà âûãëÿäèò# äëÿ UNIX. Ýòà îïöèÿ ïðàêòè÷åñêè íå ïðèìåíÿòñÿ, òàê êàê# Windows íå óìååò ðàáîòàòü ñ òàêèìè ôàéëîâûìè ñèñòåìàìè."Filesystem" = "win95"

Page 8: 016 Системный Администратор 03 2004

7№3(16), март 2004

администрирование

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

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

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

Разобравшись с понятием подмены загружаемых биб-лиотек, идем дальше по файлу конфигурации к секции, от-вечающей за работу с графическими драйверами. Драй-вер X11, используемый в Wine для работы с графикой, позамыслу разработчиков должен заниматься отрисовкойэлементов графического интерфейса только внутри окон,предоставляемых системным оконным менеджером, и неболее того. А менеджер, в свою очередь, не вторгается натерриторию окон, предоставленных Wine, и всего лишь уп-равляет их взаимоотношениями с основной системой.

# Îïöèÿ, îòâå÷àþùàÿ çà ïåðåêîäèðîâàíèå èìåí ôàéëîâ# è äèðåêòîðèé â ðîäíóþ êîäèðîâêó."Codepage" = "0"# Îïèñàíèå äèñêà M: [Drive M]# Ýòî ïåðâûé CD-ROM â ñèñòåìå. Êàê îáû÷íî, èç-çà äåìîíà# autofs ïðèøëîñü ïîìåíÿòü ïóòü ñ /mnt/cdrom íà /mnt/cdrom/auto"Path" = "/mnt/cdrom/auto""Type" = "cdrom""Label" = "CD-ROM M""Filesystem" = "win95""Device" = "auto"# Îïèñàíèå äèñêà N: [Drive N]# Âòîðîé CD-ROM. Âñå óñòàíîâêè ñäåëàíû àíàëîãè÷íî äèñêó M."Path" = "/mnt/cdrom1/auto""Type" = "cdrom""Label" = "CD-ROM N""Filesystem" = "win95""Device" = "auto"# Îïèñàíèå äèñêà Y:[Drive Y]# Çäåñü â êà÷åñòâå äèñêà Y ìîíòèðóåòñÿ äîìàøíÿÿ äèðåêòîðèÿ# ïîëüçîâàòåëÿ."Path" = "%HOME%"# À âîò òàêîé òèï óñòðîéñòâ â ñòàíäàðòíîì Wine íå âñòðå÷àåòñÿ,# îí õàðàêòåðåí òîëüêî äëÿ CrossOver Office. Âïðî÷åì, äëÿ Windows# ýòî óñòðîéñòâî âñå ðàâíî âûãëÿäèò, êàê îáû÷íûé æåñòêèé äèñê."Type" = "%CXOFFICE_DRIVE_TYPE_HACK%""Label" = "Home""Filesystem" = "win95""Codepage" = "0"# Îïèñàíèå äèñêà Z: [Drive Z]# À òóò ìîíòèðóåòñÿ êîðåíü âñåé ôàéëîâîé ñèñòåìû."Path" = "/""Type" = "%CXOFFICE_DRIVE_TYPE_HACK%""Label" = "Root""Filesystem" = "win95""Codepage" = "0"

[wine]# Èìåíà ñèñòåìíûõ äèðåêòîðèé"Windows" = "c:\\Windows""System" = "c:\\Windows\\system""Temp" = "c:\\Windows\\Temp"# Ñèñòåìíàÿ ïåðåìåííàÿ PATH óêàçûâàåò, ãäå è â êàêîì ïîðÿäêå# çàãðóæàåìûå ïðîãðàììû äîëæíû èñêàòü íåîáõîäèìûå äëÿ ðàáîòû# áèáëèîòåêè è óòèëèòû."Path" = "c:\\Windows;c:\\Windows\\system;y:\\"# Äàííàÿ îïöèÿ óêàçûâàåò, ãäå äîëæíû õðàíèòüñÿ ïîëüçîâàòåëüñêèå# ïðîôèëè, íî â ñâÿçè ñ òåì, ÷òî ó íàñ âñåãî îäèí ïîëüçîâàòåëü,# îíà íèêîãäà íå èñïîëüçóåòñÿ è ïîýòîìó çàêîììåíòèðîâàíà.;;"Profile" = "c:\\Windows\\Profiles\\Administrator"# Êàêóþ ãðàôè÷åñêóþ ïîäñèñòåìó íóæíî èñïîëüçîâàòü äëÿ ðèñîâàíèÿ# ýêðàííûõ îáúåêòîâ."GraphicsDriver" = "x11drv"# Äîëæíû ëè Windows-ïðîãðàììû âèäåòü ôàéëû, ó êîòîðûõ ïåðâûì# ñèìâîëîì èìåíè ÿâëÿåòñÿ òî÷êà. Îáû÷íî òàêèå ôàéëû ñ÷èòàþòñÿ# ñêðûòûìè.;;"ShowDotFiles" = "1"# Ìîæíî ëè ïîêàçûâàòü ñèìâîëè÷åñêèå ññûëêè íà äèðåêòîðèè?# Îáû÷íî ýòî ïðèâîäèò ê çàâèñàíèþ Windows-ïðîãðàìì,# ïûòàþùèõñÿ äåëàòü ðåêóðñèâíûé îáõîä äèðåêòîðèé. ×àùå âñåãî# â ýòó ëîâóøêó ïîïàäàþòñÿ ðàçíîîáðàçíûå àâòîìàòè÷åñêèå# èíñòàëëÿòîðû.;;"ShowDirSymlinks" = "1"# Óêàçàíèå íà ñêðèïò, îòâå÷àþùèé çà ñîçäàíèå è óñòàíîâêó# ïðàâèëüíûõ èêîíîê äëÿ Windows-ïðîãðàìì âíóòðè âàøåãî îêîííîãî# ìåíåäæåðà.  êà÷åñòâå ìåíåäæåðîâ, ê ïðèìåðó, ìîãóò âûñòóïàòü# GNOME, KDE èëè CDE."ShellLinker" = "wineshelllink"# Ïðîãðàììà, îòâå÷àþùàÿ çà ñîçäàíèå è îáñëóæèâàíèå ìåíþ

# ïðîãðàìì îêîííîãî ìåíåäæåðà"LinkProcessor" = "winemenubuilder.exe"# Òóò íàõîäÿòñÿ èêîíêè. Êñòàòè, ñòîèò îòìåòèòü, ÷òî# äëÿ óäîáñòâà îáðàùåíèÿ îíè àâòîìàòè÷åñêè êîíâåðòèðóþòñÿ# èç ôîðìàòà ico â xpm."IconsDir" = "c:\\Windows\\Icons"# Íó à çäåñü ëåæèò áèáëèîòåêà, îòâå÷àþùàÿ çà ðàáîòó# ñ FreeType-øðèôòàìè."FreeTypeLib" = "libcxfreetype.so"

[Restart]# Ïðîãðàììà ïî èäåå äîëæíà îòâå÷àòü çà ïåðåçàãðóçêó Windows.# Èíòåðåñíî, ÷òî òàêîãî ôàéëà íà äèñêå íå ñóùåñòâóåò.# À åãî ôóíêöèè âûïîëíÿåò ñêðèïò /opt/cxoffice/bin/cxreboot.# Âèäèìî, êòî-òî èç ðàçðàáîò÷èêîâ äîïóñòèë òóò îøèáêó."Boot" = "c:\\Windows\\System\\reboot.exe"# [wineconf][Version]# Êàêóþ âåðñèþ Windows äîëæåí èìèòðèðîâàòü ýìóëÿòîð?# Îïöèÿ ìîæåò ïðèíèìàòü çíà÷åíèÿ: win95, win98, winme, nt351,# nt40, win2k, winxp, win2k3, win20, win30, win31. Íåêîòîðûå# ïðîãðàììû áóäóò ðàáîòàòü òîëüêî ïîä îïðåäåëåííîé âåðñèåé."Windows" = "win98"# Âåðñèÿ MS-DOS. Íóæíà äëÿ íåêîòîðûõ ñòàðûõ ïðîãðàìì.;;"DOS" = "6.22"

[DllOverrides]"ole2" = "native, builtin""ole2nls" = "native, builtin""*comctl32" = "builtin""*ICWCONN1.EXE" = "builtin""*IEINFO5.OCX" = "builtin"

[x11drv]# Êîëè÷åñòâî öâåòîâ, âûäåëÿåìûõ èç ñèñòåìíîé ïàëèòðû äëÿ íóæä# Windows-ïðîãðàìì. Äåéñòâóåò òîëüêî â òîì ñëó÷àå, êîãäà

Page 9: 016 Системный Администратор 03 2004

8

администрирование

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

Вот тут у нас расписаны опции, необходимые для нор-мальной работы LPT-порта и принтера, если он, конечно,к нему присоединен. Ну и конечно же, описан стандарт-ный механизм работы с файлом подкачки и фильтрамипринтера.

Кстати, стоит отметить, что работа с принтером вCrossOver Office сделана очень удобно. Несмотря на точто в моей системе для печати используется CUPS, при-ложения Windows автоматически опознали все доступныесистеме принтеры и без каких-либо дополнительных на-строек стали отлично с ними работать.

Следующая сессия указывает, какой стиль иконок, кно-пок и прочего оформления использовать для рисованиявнутри эмулируемых приложений. Доступны стили Win31,Win95 и Win98.

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

Итак, закончив с изучением внутреннего строенияCrossOver Office, перейдем к решению насущных проблем.В первой статье мы столкнулись с одним досадным не-удобством. При пользовании программой /opt/cxoffice/bin/officesetup было замечено, что на вкладке «Menus» естьсписок меню, созданных установленными приложениямии выглядящий вот так.

Соответственно с помощью нажатия на кнопку«Recreate menu entry» мы могли бы автоматически со-здавать пункты меню для отображения в оконном ме-неджере. Но, к сожалению, с русскими названиями менюCrossOver Office дружить не захотел и при каждой по-пытке создать то или иное меню выводил вот такуюошибку.

[serialports]"Com1" = "/dev/ttyS0""Com2" = "/dev/ttyS1""Com3" = "/dev/ttyS2""Com4" = "/dev/modem"

[parallelports]"Lpt1" = "/dev/lp0"[spooler]"FILE:" = "tmp.ps""LPT1:" = "|lpr""LPT2:" = "|gs -sDEVICE=bj200 -sOutputFile=/tmp/fred -q -""LPT3:" = "/dev/lp3

[Tweak.Layout]"WineLook" = "Win95"

# ãðàôè÷åñêàÿ ïîäñèñòåìà ðàáîòàåò â ðåæèìå ãëóáèíû öâåòà# 8 áèò íà îäèí ïèêñåëü èëè 256 öâåòîâ."AllocSystemColors" = "100""PrivateColorMap" = "N"# Ïûòàòüñÿ ëè èñïîëüçîâàòü áîëåå ìåäëåííûå îïåðàöèè âìåñòî# áûñòðûõ äëÿ óëó÷øåíèÿ êà÷åñòâà îòðèñîâêè. Ëè÷íî ìíå# ïîêàçàëîñü, ÷òî â áîëüøèíñòâå ñëó÷àåâ ðàçíèöà íå áóäåò çàìåòíà."PerfectGraphics" = "N"# Óêàçûâàåò, êàêóþ ãëóáèíó öâåòà íåîáõîäèìî èñïîëüçîâàòü.# Èìååò ñìûñë òîëüêî äëÿ äèñïëååâ, óìåþùèõ ðàáîòàòü â ðåæèìå# multi-depth. Ïî óìîë÷àíèþ îòêëþ÷åíî, òàê êàê èñïîëüçóåòñÿ# êðàéíå ðåäêî.;;"ScreenDepth" = "16"# Èìÿ äèñïëåÿ, íà êîòîðûé íóæíî âûâîäèòü ãðàôèêó.;;"Display" = ":0.0"# Äàííàÿ îïöèÿ ïîêàçûâàåò, ðàçðåøåíî ëè îêîííîìó ìåíåäæåðó# óïðàâëÿòü îêíàìè Wine"Managed" = "Y"#  ñëó÷àå åñëè ïðåäûäóùàÿ îïöèÿ àêòèâèðîâàíà, ìîæíî ëè# ïîçâîëèòü ìåíåäæåðó ðèñîâàòü ðàìêè îêîí è ïðî÷èå ýëåìåíòû.# Ýòè äâå îïöèè óëó÷øàþò èíòåãðàöèþ ýìóëèðóåìîãî ïðèëîæåíèÿ# ñ îñòàëüíûìè ïðîãðàììàìè, íî íå âñå çàäà÷è ìîãóò íîðìàëüíî# ðàáîòàòü â òàêîì ðåæèìå.; WMFrames = "Y"# Äàííûé ðåæèì âûñòóïàåò êîíêóðåíòîì äëÿ äâóõ ïðåäûäóùèõ îïöèé# è ïîçâîëÿåò ðàáîòàòü Wine òàê, ñëîâíî ýòî íå ïðîñòî îêíî,# à âèðòóàëüíûé äåñêòîï. Ñîîòâåòñòâåííî âñå Windows-ïðèëîæåíèÿ# áóäóò ðèñîâàòü ñâîè îêíà òîëüêî âíóòðè ýòîãî äåñêòîïà, òàê êàê# èì ýòî áîëüøå âñåãî ïîäõîäèò. Çà óïðàâëåíèå îêíàìè âíóòðè# âèðòóàëüíîãî äåñêòîïà îòâå÷àåò Wine. Òàêîé ðåæèì ïîçâîëÿåò# èçáåæàòü âçàèìîäåéñòâèÿ Windows-ïðèëîæåíèé ñ ñèñòåìíûì# îêîííûì ìåíåäæåðîì, ïîýòîìó îí íàèáîëåå ñîâìåñòèì c ìîäåëüþ# ðèñîâàíèÿ, èñïîëüçóåìîé íàñòîÿùåé Windows.;;"Desktop" = "640x480"# Íóæíî ëè, ÷òîáû ïðèëîæåíèÿ, ðàáîòàþùèå ñ DirectDraw, ìîãëè# âîñïîëüçîâàòüñÿ ïðåèìóùåñòâàìè ðàáîòû ñ ãðàôè÷åñêîé ïîäñèñòåìîé# â ðåæèìå DGA (XFree86 Direct Graphic Architecture). Îáÿçàòåëüíî# óáåäèòåñü, ÷òî ó âàñ åñòü äîñòóï ê óñòðîéñòâó /dev/mem"UseDGA" = "Y"# Åñëè ñ DGA ïîðàáîòàòü íå ïîëó÷èëîñü, òî ìîæíî ïîïðîáîâàòü# çàñòàâèòü DirectX èñïîëüçîâàòü ðàçäåëÿåìóþ ïàìÿòü äëÿ îáìåíà# äàííûìè ñ âèäåîïîäñèñòåìîé. Êîíå÷íî, ýòî áóäåò ðàáîòàòü# ìåäëåííåå, ÷åì DGA, íî âñå æå áûñòðåå, ÷åì ïðèìåíÿåìûé# ñòàíäàðòíî îáìåí äàííûìè ñ X11 ÷åðåç ñîêåò."UseXShm" = "Y"# Ðàçðåøåíèå èñïîëüçîâàòü äëÿ îòðèñîâêè ðåæèì XVideo"UseXVidMode" = "Y"# Óëó÷øåííîå óïðàâëåíèå îêíîì, ïîëó÷èâøèì ôîêóñ ââîäà."UseTakeFocus" = "Y"# Îïöèÿ äëÿ âêëþ÷åíèÿ ïðîäâèíóòîãî ñïîñîáà êîíòðîëÿ çà ìûøüþ.# Î÷åíü ïîëåçíà äëÿ ïðèëîæåíèé, èñïîëüçóþùèõ DirectX"DXGrab" = "N"# Âêëþ÷àåò äâîéíóþ áóôåðèçàöèþ îêíà, â êîòîðîì îòðèñîâûâàåòñÿ# äåñêòîï. Ïðèìåíÿåòñÿ òîëüêî âìåñòå ñ îïöèåé Desktop, îïèñàííîé# âûøå. Î÷åíü ïîìîãàåò ïðè ðàáîòå ñ ïðèëîæåíèÿìè, èíòåíñèâíî# èñïîëüçóþùèìè OpenGL ."DesktopDoubleBuffered" = "N"# Íîìåð ïîðòà äëÿ ðåæèìà XVideo. Íóæíî èñïîëüçîâàòü òîëüêî â# ñëó÷àå, åñëè ó íàñ íåñêîëüêî ïîðòîâ.;; "XVideoPort" = "43"# Îïöèÿ, óêàçûâàþùàÿ, íóæíî ëè ðàáîòàòü â ñèíõðîííîì ðåæèìå.# Îáû÷íî èñïîëüçóåòñÿ äëÿ îòëàäêè ïðîáëåì ñ X11.;;"Synchronous" = "Y"

Page 10: 016 Системный Администратор 03 2004

9№3(16), март 2004

администрирование

Для исправления данной проблемы, мешающей намсоздавать меню, нужно открыть файл $HOME/.gnome2/vfolders/applications.vfolder-info, найти в нем все словосо-четания, содержащие следующий набор букв «яПЕДЯР-БЮ» и удалить эти странные символы. Такое непонятноеслово получается, если неправильно перевести слово«средства», содержащееся в названии меню «СредстваMicrosoft Office» из кодировки cp1251 в koi8-r. После тогокак мы выкорчевали все встречные слова «яПЕДЯРБЮ»,создание пунктов меню для оконного менеджера должнозаработать так, как и положено. После этого конвертиру-ем файл-заготовку в нужную кодировку и обновляем сис-темное меню.

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

Кстати, это всего лишь малый список Windows-приложе-ний, используемых мною повседневно. Разобравшись с этойпроблемой, давайте двинемся дальше. Беда в том, что мно-гие современные приложения для правильного функциони-рования очень сильно опираются на компоненты, предостав-ляемые Microsoft Internet Explorer. И все было бы здорово,если бы не вечная гонка за новизной. После инсталляцииMicrosoft Office 2000 или Microsoft Office XP в системе ужеприсутствует Microsoft Internet Explorer версии 5.0, но мно-гим устанавливаемым программам этого, к сожалению, не-достаточно, им на блюдечке подай шестую версию. Каза-лось бы, проблема не стоит выеденного яйца, обновить вер-сию вышеуказанного продукта с помощью CrossOver Office

$ iconv -f cp-1251 -t utf-8 $HOME/.menu/cxoffice > ↵↵↵↵↵$HOME/.menu/cxoffice

$ update-menus �n �u

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

Поэтому нам нужно будет скачать шестую версию вруч-ную и установить ее самостоятельно. Делается это довольнопросто.

Для начала убедимся, что версия Windows, под которуюмаскируется CrossOver, называется win98. Для тех, кто за-был, как это сделать, напоминаю, что нужно посмотреть вфайл config и найти в нем секцию [Version]. На отдельноймашине или используя VMWare, запускаем операционнуюсистему Windows 98. Данная машина может быть подклю-чена к Интернету через прокси-сервер или напрямую. Ска-чиваем первую часть инсталлятора, соответствующую язы-ку используемого у вас браузера: http://www.microsoft.com/windows/ie/downloads/critical/ie6sp1/default.asp. После запус-ка инсталляции используем опцию выборочной установкикомпонентов.

В дереве компонентов я выбрал следующие пункты:

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

Page 11: 016 Системный Администратор 03 2004

10

администрирование

После того как установка завершится, файлы, скачан-ные из Сети, будут лежать в директории c:\Windows\Windows Update Setup Files либо c:\Windows\Файлы уста-новки Windows Update. Думаю, все понимают, что назва-ние директории зависит от языковой локализации Windows,использованной для скачивания. В директории скореевсего будут лежать файлы с такими именами:

Жизненно необходимы нам только вот эти файлы:

Но все же лучше перестраховаться и на всякий случайскопировать все имеющиеся файлы во временную дирек-торию Windows, которая у нас находится в $HOME/.cxoffice//dotwine/fake_windows/Temp. Распаковываем все файлы срасширением .CAB с помощью утилиты cabextract вот та-ким образом.

Утилита cabextract существует практически в каж-дом дистрибутиве Linux. Не стоит пытаться распаковатьза один раз больше 3 файлов, иначе будете получатьошибки «Segmentation fault».

Закончив с распаковкой, скопируйте файл nashbase.stfв файл acmsetup.stf и через программу officesetup, какобычно, начинаем инсталляцию Internet Explorer. Выбира-ем пункт Advanced install и указываем, где у нас находит-ся файл acmsetup.exe. В ответ получаем вот такое весьмаприятное для нас изображение.

Несколько раз нажимаем кнопки «ОК» и «Далее», на-чинаем любоваться на индикатор установки. Иногда мо-жет случиться, что язык устанавливаемых компонентовотличается от того, что было в старых файлах.

Бояться этого не стоит, просто нажмите кнопку «Да» ина следующий вопрос ответьте «Заменить все такие ком-поненты». Инсталляция весело побежит дальше и весьмаблагополучно доберется до этого момента:

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

ADVAUTH.CAB FONTCORE.CAB ie6setup.exeIELPKAD.CAB IE_S4.CAB iesetup.iniREADME.CAB TS95.CAB BRANDING.CABFONTSUP.CAB IEDOM.CAB IE_S1.CABIE_S5.CAB MOBILE95.CAB SCR56EN.CABVGX.CAB CRLUPD.CAB HELPCONT.CABIEEXINST.CAB IE_S2.CAB IE_S6.CABMPLAYER2.CAB SETUPW95.CAB Ýòó ïàïêó ìîæíî óäàëèòü.txtfilelist.dat HHUPD.CAB IE_EXTRA.CABIE_S3.CAB iesetup.dir OAINST.CABSWFLASH.CAB

IE_S1.CAB IE_S2.CAB IE_S3.CABIE_S4.CAB IE_S5.CAB IE_S6.CABIEDOM.CAB SCR56EN.CAB

#cabextract IE_S1.CAB IE_S2.CAB IE_S3.CAB

Page 12: 016 Системный Администратор 03 2004

11№3(16), март 2004

администрирование

И так будет продолжаться бесконечно. Дабы разор-вать этот порочный круг, принудительно закрываем окнос работающей инсталляцией. Теперь нужно перезагру-зить Windows, делается это с помощью пункта менюSimulate Windows Reboot или вызовом программы /opt/cxoffice/bin/cxreboot. На экране будут наблюдаться сле-дующие явления.

После окончания этого процесса можно будет спокой-но работать с обновленным Internet Explorer.

Последним шагом нужно будет установить DCOM98, тре-бующийся для запуска большинства новых программ. По-этому берем его тут: http://www.microsoft.com/com/dcom/dcom98/download.asp и проводим стандартную инсталляцию.

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

циями. В следующей статье мы рассмотрим методы и сек-реты борьбы с некоторыми особо упорными приложениями.

Page 13: 016 Системный Администратор 03 2004

12

администрирование

Время идет, ваша фирма развивается. Появилась ЛВС, сначала одноранговая, затем с выделеннымисерверами. Хорошо, когда сеть однородная, все работают в однотипной среде. Но жизнь диктуетсвои законы, в силу определенных причин ЛВС получилась гетерогенной. И не только гетерогенной,но и распределенной. Представьте себе машиностроительный завод или фирму с филиалами по всемугороду. Что делать, как управлять всем этим IT-богатством?

Время идет, ваша фирма развивается. Появилась ЛВС, сначала одноранговая, затем с выделеннымисерверами. Хорошо, когда сеть однородная, все работают в однотипной среде. Но жизнь диктуетсвои законы, в силу определенных причин ЛВС получилась гетерогенной. И не только гетерогенной,но и распределенной. Представьте себе машиностроительный завод или фирму с филиалами по всемугороду. Что делать, как управлять всем этим IT-богатством?

... сейчас мы нажимаем на контактыи перемещаемся к вам, но если эта машинка

не сработает, тогда уж вы с нами переместитесь,куда мы вас переместим...

х/ф «Кин-Дза-Дза»

... сейчас мы нажимаем на контактыи перемещаемся к вам, но если эта машинка

не сработает, тогда уж вы с нами переместитесь,куда мы вас переместим...

х/ф «Кин-Дза-Дза»

Можно бегать, как горная лань, по этажам и цехам, объяс-нять, разъяснять, учить. Можно нанять дополнительныйперсонал. Научить бегать его. Однако запомните, что есливы лично претендуете на звание системного администра-тора, то главная черта, которая вам должна быть прису-ща – это лень! В хорошем смысле этого слова (см. статьюВячеслава Калошина «Каким видится хороший системныйадминистратор» в июльском номере журнала за 2003 г.).Рассмотрим, как снизить расходы «на перемещение в про-странстве и времени» бренного тела администратора.

Объяснять, как получить удаленное управление наUNIX-машинах я не буду. Считаю, что это известный факт.Цель этой статьи – показать, с помощью чего управлять сUNIX-машины парком серверов и рабочих станций с уста-новленной ОС Windows.

Начнем, пожалуй, с серверов. По всей видимости, увас установлены следующие семейства – Windows NTTerminal Server 4.0, Windows 2000 Server/Advanced Server,Windows 2003 Server, Datacenter и т. п. Отлично, это даженам на руку. Проверим, что установлены терминальныеслужбы удаленного доступа (terminal services).

АНТОН БОРИСОВ

А ТЫ ЧТО ВИДИШЬ?УДАЛЕННОЕ УПРАВЛЕНИЕПОСРЕДСТВОМ RDESKTOP, RADMIN, VNC

А ТЫ ЧТО ВИДИШЬ?УДАЛЕННОЕ УПРАВЛЕНИЕПОСРЕДСТВОМ RDESKTOP, RADMIN, VNC

bash-2.05b# nmap -v -sS compaq

bash-2.05b# nmap -v -sS fuji

Page 14: 016 Системный Администратор 03 2004

13

администрирование

Теперь пакет rdesktop установлен. Осуществляем со-единение с удаленным сервером.

Стоит отметить, что в некоторых случаях соединениеможет не заработать, а в ответ получим вот такую ошибку:

Проблема в том, что по умолчанию используется 5-я вер-сия RDP-протокола, а некоторые сервера, не обращая вни-мания на все заплатки и обновления, продолжают говоритьна 4-й версии. В таком случае нужно подать команду:

На что выдается окно MSGINA для ввода имени пользо-вателя, пароля, домена (если таковой имеется).

Войдя в систему, мы работаем, как за родным Windows-терминалом. Есть некоторые специфические моменты,когда нельзя использовать удаленный вход (но об этом вдругой раз). В общем, аскетично, т.к. только 256 цветов,но вы ведь не играть пришли, верно?

Чтобы узнать, какой именно порт отвечает за терми-нальные службы, поступим следующим образом:

А тем, у кого нет nmap, можно посмотреть весь списокпортов вот тут: http://www.iana.org/assignments/port-numbers.При установленной службе он будет присутствовать в си-стеме.

Можете на самом Windows-сервере запустить cmd.exeи посмотреть порты, которые использует сервер в данныймомент:

Если портов с номером 3389 нет, то стоит добавитьслужбу следующим образом: Пуск →→→→→ Настройка →→→→→ До-бавление/Удаление Программ (Добавление Windows-компонентов).

В итоге получили работающую терминальную службу.Что дальше, спросит любопытный читатель?

Дальше сходим на сайт http://www.rdesktop.org и забе-рем исходники программы rdesktop. Она использует про-токол RDP (т.е. протокол терминальной службы). После-дняя версия 1.3 (на момент написания статьи). Настройкапроста.

rdesktop �4 rubin

bash-2.05b$ cat /usr/share/nmap/nmap-services | grep Remote\ Display

netstat -na | more (èëè netstat -na > netstat.txt)

bash-2.05b$ ./configure --prefix=/usr/local/rdesktopbash-2.05b$ makebash-2.05b# make install

rdesktop rubin

Page 15: 016 Системный Администратор 03 2004

14

администрирование

Во времена, когда администраторы были еще белымии пушистыми, активную популярность приобрел пакетRemote Administrator.

Стоит отметить, что программа на момент своего по-явления на свет затмила свои аналоги. Одна из причин,из-за чего программу устанавливают, – это возможностьпоказать оператору, работающему за удаленной маши-ной, что именно у него нажимается не так, ибо перехва-тывается управление как клавиатурой, так и мышкой.Среди дополнительных возможностей программы – нали-чие в некоторой степени аналога ftp-сервиса. Авторизо-вавшись на удаленной машине, появляется возможностьперебросить туда файл с нашей локальной машины.

Еще один немаловажный момент – при нарушениинастроек, например, swap-файл не прописался, удален-ный/локальный пользователь не может зайти, т.к. окноприглашения не появляется. Что делать? Выбираем ре-жим работы с удаленной машиной «File transfer» и удаля-ем неправильный swap-файл.

Но! Данный продукт написан под Windows-платформу.По заявлениям самих разработчиков, версию под UNIX-системы они разрабатывают, но как скоро она появится ипоявится ли вообще – неизвестно. Переустанавливать навсех клиентах что-то альтернативное, чтобы администра-тор мог со своей машины без затруднений управлять всемпарком, – лишняя беготня. Нужна ли она? Как увидим чутьдалее – нет.

Что нам потребуется для запуска?Windows-эмулятор, он же wine. Пакет, если у вас его

нет, заберем на http://www.winehq.com. Настройка анало-гична настройке rdesktop.

Никаких дополнительных опций я не задавал. Префикспути, где будет лежать пакет:

Обращаю ваше внимание, что пакет громоздкий – по-требуется для сборки порядка 500 Мб. Плюс еще 260 Мбдля готового к употреблению изделия.

Итак, собрали пакет, научились его запускать на про-стейших Windows-играх, например, «Сапер», «Паук» и т. д.Теперь устанавливаем у себя на Linux-машине RemoteAdministrator.

Несколько слов об установке. Цель – получить у себякаталог, например, «RAdmin» со следующими файлами:

Теперь приступим непосредственно к запуску rad-min.exe. В домашей директории есть каталог, относящий-ся к wine – ~/.wine, где лежит файл конфигурации «config».Для того чтобы в дальнейшем не было проблем с фокуси-ровкой мышки и клавиатурного ввода, добавим следую-щие строчки:

Строка «Desktop» = «700x500» означает, что для при-ложения radmin.exe необходимо использовать окно с гео-метрией 700 на 500 точек. Облегчает поиск нашего при-ложения radmin.exe, когда используется разный тип изме-нения фокуса в оконном менеджере. Из рисунка видно,что открываемое приложение не будет максимизированооконным менеджером, а будет открыто с указанными раз-мерами «горизонталь на вертикаль».

Строка «Managed» = «N» приводит к тому, что изме-нить размеры не получится. В любом случае смотрите до-кументацию к wine.

Теперь мы готовы к запуску.

Подразумевается, что мы установили пакет в каталогRAdmin. Далее введем регистрационный ключ и, вуаля,далее вопрос техники – заполнить имена хостов. С этогомомента у нас полноценный доступ к другим машинам сустановленной radmin-службой.

Скажу несколько слов об обратной связи. Запустив наLinux-машине radmin-сервис:

с Windows-машин мы можем видеть рабочий экран Linux-машины. Правда, управлять нельзя, можно только наблю-дать. Это лирическое отступление. Замечены некоторыепроблемы с клавиатурой, а именно при нажатии комби-наций клавиш Shift+Key проявляется эффект «залипания»Shift. С чем это связано, неизвестно. Известно, как от этогоизбавиться. Нажать на настройке окна radmin.exe«Options», и залипание пропадет.

И напоследок посмотрим, что такое VNC.VNC – Virtual Network Computing, пакет разрабатывал-

ся в лаборатории AT&T, сейчас доступен в свободнойформе на сайте http://www.realvnc.com. Богатый ассор-тимент настроек, автоматическое определение необхо-

--prefix=/usr/local/wine

/usr/local/wine/bin/wine ~/RAdmin/radmin.exe

/usr/local/wine/bin/wine ~/RAdmin/r_server.exe

[AppDefaults\\radmin.exe\\x11drv]"Desktop" = "700x500""Managed" = "N"

Page 16: 016 Системный Администратор 03 2004

15

администрирование

димой ширины канала для передачи информации и т. п.Например, в любой момент времени можно переключить-ся из TrueColor-режима в режим 256 цветов. Экономияна трафике.

Работа с использованием VNC-клиента с сервероманалогична двум предыдущим рассмотренным пакетам.

Нажимая F8, получаем возможность изменить на ходунастройки. Нажатие первый раз обрабатывает наш VNC-клиент, которого мы запустили у себя, второй раз уже об-рабатывает сервер, где запущена VNC-служба. Службуможно определить по открытым портам 5800, 5900.

В качестве эксперимента я поставил VNC у себя в ло-кальной сети на Linux-сервер под своим аккаунтом. Такчто при перезагрузке вторая моя машина запускает авто-матически VNC-сервис. Повторю, что поставил в качествеэксперимента, ибо никто не отменял комбинацию со вто-рым X-сервером и перенаправлением ввода с удаленнойUNIX-машины на этот второй X-сервер.

Тем не менее опишу, как я провел сию операцию. Обемашины в локальной сети работают под slackware linux,поэтому настройки, которые я добавлял, находятся в ка-талоге /etc/rc.d/. Добавляю туда скрипт rc.vnc.

Для запуска нового сервиса сделаем упоминание так-же в файле /etc/rc.d/rc.local. Добавим строчки:

Появляющийся сервис запускается с правами пользо-вателя anthony, который присутствует в системе. Экспор-тирование пути необходимо, т.к. при запуске «su» авто-матически переменная PATH заполняется значениями из/etc/login.defs. Мы же чуть-чуть увеличим путь, т.к. длязапуска Xvnc необходимо, чтобы vncserver знал, где егонайти, а также некоторые дополнительные программы.Сервис запускается с виртуальным экраном номер 10,поэтому для его обслуживания видим сразу 3 открытыхдля нужд VNC порта – это 5810, 5910 и 6010. Полная кар-та открытых портов на этой машине приведена ниже.

#!/bin/sh# Start the Virtual Networking Communication (VNC) serverBINDIR=/usr/local/vncDAEMON=vncservercase "$1" in 'start')

su - anthony -c "export PATH=$PATH:/usr/X11R6/bin:/usr/ ↵↵↵↵↵local/bin; $BINDIR/$DAEMON :10 -geometry 800x600"

;; 'stop') $BINDIR/$DAEMON -kill :10 ;; 'restart') $0 stop; $0 start ;; *) echo "usage $0 start|stop|restart" ;;esac

echo "***** Starting RealVNC server *****"/etc/rc.d/rc.vnc start

bash-2.05b# nmap -v -sS fuji -p 1-10000

Page 17: 016 Системный Администратор 03 2004

16

администрирование

Чтобы запустить клиента, пишу следующую строчку:

где fuji:10 – linux-box, где установлен VNC-сервис на 10 вир-

туальном экране, с помощью параметра «-geometry 600x400»указываю, что клиент надо запустить с разрешением 600 на400 точек. Параметр «-passwd ~/.vnc/passwd» означает, чтопароль можно не вводить, а брать по указанному месту. Кста-ти, он скопирован с машины, где запущен VNC-сервис.

Вот вроде бы и все. Работа с помощью VNC немногоудобнее по сравнению с остальными. Хотя это мой субъек-тивный взгляд. В качестве примера рассмотрим, как по-считать трафик, используемый каждым приложением. Яопишу, как на стомегабитной сетевой карте добиться ско-рости 9600 байт в cекунду. Сия скоростная планка взятаиз желания посмотреть, насколько устойчиво будут рабо-тать рассмотренные приложения.

Не секрет, что до сих пор в некоторых местах исполь-зуются телефонные линии с не очень хорошим качествомсвязи. Вы можете указать свою скорость, отличную от ука-занной, и проанализировать ситуацию. Считаю, что дан-ный опыт будет полезен в случае, когда организация сто-ит перед выбором, какой тип соединения использовать длясвязи филиалов – ТФОП (телефонные линии общего дос-тупа), беспроводной доступ или иной вид связи. Проана-лизировав на локальной сети центрального филиала, чтоименно подходит под ваши условия, вы делаете свой вы-бор. Чтобы «зажать» скорость в указанных пределах, явоспользовался traffic shaper – rshaper. Взять можно поуказанному адресу: http://ar.linux.it/software/#rshaper. Сбор-ка происходит через подачу команды make && make install.Пакет устанавливается в каталог /usr/local/sbin как модульк ядру и программа управления трафиком.

vncviewer fuji:10 -passwd ~/.vnc/passwd -geometry 600x400

Page 18: 016 Системный Администратор 03 2004

17

администрирование

В целом происходит следующее – данный модуль со-здает сетевой буфер, где пакеты задерживаются опреде-ленное время, в результате чего создается эффект «про-стаивания в очереди», т.е. создается определенная ско-рость. В нашем случае 9600 б/с на прием.

Нам еще потребуется, чтобы у вас в системе также былпростейший брандмауэр, точнее настроены правила дляiptables. Например, взятый здесь: http://www.faqs.org/docs/iptables/examplecode.html.

Сначала подгружаем shape-модуль:

Модуль загружен, далее указываем, с каким хостоммы соединяемся, с какой скоростью и размер простаива-ния в буфере (в секундах):

Затем выставляем правила для iptables для подсчетапрошедшего трафика. Для входящего от хоста трафика:

Для исходящего к хосту трафика:

Пролистать показания счетчика:

С теорией достаточно. Ближе к практике. Для этих це-лей составлен простейший скрипт, в котором задается ско-рость для shaper, происходит обнуление/показ прошедше-го трафика.

modprobe rshaper.o

rshaperctl HOST SPEED TIME

iptables -N MyRDP_INiptables -I INPUT -j MyRDP_IN -s HOSTiptables -I MyRDP_IN -j INPUT

iptables -N MyRDP_OUTiptables -I OUTPUT -j MyRDP_OUT -d HOSTiptables -I MyRDP_OUT -j OUTPUT

iptables -L MyRDP_IN -v

MyRDPTest.sh#!/bin/shIPTL=/usr/sbin/iptablesSHAPER=/usr/local/sbin/rshaperctlMODE=9600HOST=rubinTIME=10

if [ "$1" = "zero" ]; thenecho "Zeroing IN & OUT counters for $HOST";$IPTL -L MyRDP -Z 2>/dev/null 1>/dev/null$IPTL -L MyRDPOut -Z 2>/dev/null 1>/dev/null

fiecho "Setting Shaping MODE as $MODE bytes to host $HOST"$SHAPER $HOST $MODE $TIME$SHAPERecho "Incoming traffic from host"IN=`$IPTL -L MyRDP -v -n | grep ACCEPT`INpkts=`echo $IN | awk '{ print $1 }'`INbytes=`echo $IN | awk '{ print $2 }'`echo "pkts = $INpkts, bytes = $INbytes";

echo "Outcoming traffic to host"OUT=`$IPTL -L MyRDPOut -v -n | grep ACCEPT`OUTpkts=`echo $OUT | awk '{ print $1 }'`OUTbytes=`echo $OUT | awk '{ print $2 }'`echo "pkts = $OUTpkts, bytes = $OUTbytes";

Page 19: 016 Системный Администратор 03 2004

18

администрирование

Если скрипт вызван с параметром «zero», то счетчикидля входящего (MyRDP) и исходящего (MyRDPOut) тра-фика будут обнулены. Вот какие цифры получились у меняпосле недолгой работы по разным протоколам с серве-ром по имени RUBIN. Скорость на прием – 9600 байт всекунду.

Проводились типизированные действия. В частности,был запущен MPEG-клип через Media Player. Что следуетотметить – при работе с RDP передавался n-ый кадр с за-метными паузами для перерисовки. Остальные протоко-лы автоматически пропускали прорисовку кадров, просто-напросто ничего не рисовали, т.е. старались не заниматьканал «тяжелым» содержимым. Это касается только ви-део. В остальном субъективно было заметно, что RADMIN

и VNC легче держат канал. Первый даже лучше, нежелиVNC. Может на других скоростях получатся другие циф-ры, но это испытание мы оставим пытливому читателю.

Я специально не стал освещать решения от компанииCitrix, поскольку это отдельный серьезный разговор, т.к.заложенных возможностей в данный продукт хватит на-долго и намного.

P.S. Всегда были и будут разговоры об эффективнос-ти и применимости удаленного доступа и открытых дляэтих целей дверей в системе. Приходится чем-то жертво-вать, либо потенциально открыто, либо потенциально зак-рыто. Запомните, самый оптимальный с точки зрения бе-зопасности стиль работы – держать администрируемуюмашину всегда выключенной.

В статье были упомянуты программы со следующихресурсов:1. http://www.rdesktop.com2. http://www.radmin.com3. http://www.winehq.com4. http://www.realvnc.com5. http://ar.linux.it/software/#rshaper6. http://www.faqs.org/docs/iptables/examplecode.html

Òàáëèöà 1. Èíôîðìàöèÿ î ïðîøåäøåì òðàôèêå çà 5-ìèíóòíûéïåðèîä ïî ðàçíûì ïðîòîêîëàì

RDP ïðîòîêîë Incoming traffic from host pkts = 2604, bytes = 1039K Outcoming traffic to host pkts = 3563, bytes = 474KVNC ïðîòîêîë Incoming traffic from host pkts = 6277, bytes = 804K Outcoming traffic to host pkts = 5413, bytes = 321KRADMIN ïðîòîêîë Incoming traffic from host pkts = 2739, bytes = 472K Outcoming traffic to host pkts = 3610, bytes = 267K

Page 20: 016 Системный Администратор 03 2004

19

администрирование

Page 21: 016 Системный Администратор 03 2004

20

администрирование

СВОБОДНАЯ ДОС ДЛЯ СВОБОДНЫХ ЛЮДЕЙ,ИЛИ НЕ LINUX ЕДИНЫМ ЖИВ ЧЕЛОВЕК

АНДРЕЙ МАРКЕЛОВ

Когда говорят об операционной системе, обозначаемой аббревиатурой DOS, мало кто задумывается –о какой же Дисковой Операционной Системе (Disk Operation System) идет речь. Обозначение целогокласса операционных систем для большинства людей стало синонимом лишь одного-единственногоего представителя – MS DOS фирмы Microsoft. Кто-то, может быть, вспомнит PC DOS, отличающуюсяв основном лишь названием и именами некоторых файлов. Может, кому-то придет в голову и DR-DOSот компании Digital Research – создателя предшественницы DOS от Microsoft, операционнойсистемы CP/M. Но в целом почти для всех DOS – это MS-DOS, последняя версия которой вышлавот уже десять лет назад, и которая давно завершила свое развитие.

Page 22: 016 Системный Администратор 03 2004

21№3(16), март 2004

администрирование

Однако до сих пор в эксплуатации остается огромноечисло программ, работающих в среде и написанных подэту нетребовательную к ресурсам ОС, и не меньшее чис-ло морально устаревших компьютеров, прекрасно ра-ботающих под ней. Как же быть? Ведь MS-DOS давноне поддерживается и не продается. Я бы посоветовалобратить внимание на FreeDOS, изначально написан-ную Джимом Холлом, а сейчас развивающуюся при уча-стии целой команды разработчиков из разных концовсвета.

Свободная ОС FreeDOS была анонсирована ее созда-телем Джимом Холлом (Jim Hall) 28 июня 1994 года пер-воначально под именем PD-DOS. Уже в июле приставка«PD-» была заменена на «Free-». Знак «дефис» междудвумя составляющими названия операционная системапотеряла в 1996 году при достаточно курьезных обстоя-тельствах. В этом году издательство «R+D Books» выпус-кало книгу под названием «Free-DOS Kernel», и редакториздательства выбросил знак «дефис» в названии исклю-чительно из дизайнерских соображений.

Основной причиной, вызвавшей появление проекта,Джим называет прекращение компанией Microsoft поддер-жки операционной системы MS-DOS. Итак, вот уже 10 летмы имеем реальную альтернативу операционной системеMS-DOS, но под лицензией GNU. «FreeDOS Project» не ис-пользует код, созданный Microsoft. Согласно открытымспецификациям команда пишет свой код, обладающийаналогичным функционалом.

Ядром FreeDOS является DOS-C, изначально написан-ное Pat Villani как DOS-ядро для встраиваемых систем.Первоначальное название – DOS/NT. DOS/NT содержала32 000 строк кода, была написана на Cи и ассемблере ираспространялась как shareware.

FreeDOS работает на устаревшем железе (начинаяот 5МГц IBM PC XT с 640К оперативной памяти), встро-енных системах, различных виртуальных машинах, в томчисле DOSEmu, VMWare и Bochs. FreeDOS – идеальное,лицензионно чистое решение для создания «спасатель-ной» загрузочной дискеты. Другое применение – средадля исполнения ваших программ или обновлений. Кли-енту достаточно загрузиться с полученной от вас диске-ты или компакт-диска, и вот вам (или вашей службе под-держки) уже не приходится часами висеть на телефоне,объясняя бухгалтеру, находящемуся за несколько сотенкилометров, как найти диск C:\.

FreeDOS обладает отличной совместимостью с DOS-программами, в том числе со старыми добрыми играми:DOOM, Quake, Warcraft 2. А небезызвестная фирма Dellдаже продает свои десктопы, с предустанавливаемой наних одной из версий этой операционной системы.

Из особенностей FreeDOS я хочу отметить: поддерж-ку FAT-32 дисков объемом до 128 Гб, поддержку сети (выможете поставить на FreeDOS ftp- и HTTP-сервер), но от-сутствие встроенной поддержки NTFS и USB. ОднакоFreeDOS вполне нормально работает и с USB-клавиату-рами, USB-мышами, Serial-ATA-дисками, если их поддер-живает BIOS компьютера.

При помощи дополнительных драйверов возможнаработа с длинными именами.

УстановкаИтак, вы решили познакомиться с новой для себя опера-ционной системой. Прекрасно! Пятидесятимегабайтныйдистрибутив «FreeDOS Beta9 pre-release 3» (последний намомент написания статьи) скачан в виде ISO-образа с сай-та http://www.freedos.org и записан на «болванку». Встав-ляем полученный загрузочный CD в лоток вашего CD-ROM, и перезагружаем компьютер. Не забудьте попутнов качестве устройства для загрузки выбрать привод ком-пакт-дисков.

Я буду описывать установку FreeDOS на «чистую» ма-шину, однако никто не мешает использовать так называе-мую «двойную загрузку». Я успешно ставил на один компь-ютер одновременно MS-DOS, FreeDOS, Linux и Windows 2000.Причем в качестве загрузчика использовал штатный BootLoader из Windows 2000. При помощи отличной утилитыBootPart 2.50 вы можете сохранить образ 512-байтного заг-рузочного сектора с загрузчиком FreeDOS, Lilo или GRUBв файл, а далее просто прописать на него ссылку вC:\BOOT.INI.

За подробностями отсылаю вас на домашнюю странич-ку программы – http://ourworld.compuserve.com/homepages/gvollant/bootpart.htm. Кроме того, всегда можно попробо-вать запустить FreeDOS в среде виртуальной машины.Нужно заметить, что для DOSEmu рассматриваемая опе-рационная система и так является «официальной» и ре-комендуемой к использованию.

Загрузившись с дистрибутивного диска, мы попадаемв меню инсталлятора. Нажимаем «1» для старта. Далеевыбираем установку с использованием драйвера CD-ROMи XMS – «2». На машинах с процессорами 8086 – 80286нужно выбрать «1».

В следующем меню имеется несколько вариантов:! «1» – установка;! «2» – переход в командную строку;! «3» – создать загрузочную дискету.

Выбираем «1» и еще раз «1», чтобы подтвердить уста-новки по умолчанию.

Теперь мы попадаем в меню «FreeDOS Partition Mana-gement». Eсли жесткий диск не был разбит на логическиедиски, то сейчас имеется возможность разбить его ана-логом MS-DOS-утилиты FDISK. Кроме того, можно запус-

Page 23: 016 Системный Администратор 03 2004

22

администрирование

тить известную всем линуксоидам утилиту для измененияразмеров партиций – FIPS, а также отформатировать диск.Замечу, что утилита FORMAT дистрибутива содержитошибки (которые исправлены в более поздней версии, невошедшей в ISO-образ), и при наличии ошибок во времяформатирования лучше выполнить данную операцию издругой ОС, а FORMAT после инсталляции заменить бо-лее свежей версией с сайта проекта. Еще один вариантрешения этой проблемы – выполнить «быстрое» форма-тирование FORMAT из FreeDOS.

Если уже имеется отформатированный диск, то про-сто выбираем его клавишами со стрелками и нажимаем«Enter». После инсталлятор предлагает выбрать вариантустановки – графический или текстовый. Выбрав, жмем«Enter» и в случае с графикой оказываемся в интер-фейсе, напоминающем интерфейс установки обычногоWindows-приложения. Принимаем лицензионное соглаше-ние GNU GPL, указываем путь для установки (C:\FDOS\)и набор устанавливаемых пакетов. Теперь остается толь-ко следить за ходом инсталляции. После завершения ко-пирования файлов будут запущены несколько конфигу-рационных скриптов, а затем мы попадаем в команднуюстроку, получив напоминание о необходимости записатьзагрузочный сектор командой BOOT. Набираем «boot»,жмем «Enter». Теперь можно перезагрузить машину, уда-лив при этом CD из дисковода.

Настраиваем среду обитанияВначале кратко о структуре каталогов и файлах, входя-щих в дистрибутив. После установки FreeDOS в корнедиска C:\ мы имеем:! autoexec.bat, config.sys – расширенные по синтаксису

аналоги конфигурационных файлов MS-DOS;! fdosboot.bin – загрузочный сектор FreeDOS в виде фай-

ла;! command.com – интерфейс командной строки;! kernel.sys – ядро операционной системы (аналог

msdos.sys).

Сами служебные файлы и утилиты по умолчанию ус-танавливаются в C:\FDOS. Внутри каталога существуютследующие подкаталоги:! APPINFO – файлы формата lsm с кратким описанием

утилит дистрибутива;! BIN – утилиты и драйверы;! DOC, HELP – документация ;! INSTBASE – логи инсталляции всех пакетов;! NLS – файлы локализации для нескольких языков.

Первым делом я бы рекомендовал обновить файлыоперационной системы. Главные кандидаты на обновле-ние (из тех, что были доработаны по сравнению с«FreeDOS Beta9 pre-release 3») – это новая версия ядрапод номером 2033, FreeCOM shell – интерфейс команд-ной строки, EMM386, Format, Shsucdx, Undelete, Edit. Ссыл-ки на утилиты и файлы для скачивания можно найти насайте проекта. Для обновления, как правило, достаточнопросто заменить старые файлы новыми из скачанного zip-архива. Когда будете обновлять файлы ядра, заметьте,

что бинарники ядра распространяются в двух вариантах:keXXXX_32.zip – с поддержкой FAT-32 и keXXXX_16.zip –только с поддержкой FAT-16.

Затем убедимся, что доступен привод компакт-дисков.Файл config.sys должен содержать строку:

Как видно, синтаксис этих команд не отличается отсинтаксиса команд Microsoft DOS. Отличия только в име-нах файлов.

Drugim vagnjm voprosom jvljaetsja russifikazcija. В теку-щей версии отсутствует поддержка COUNTRY, но дляподдержки 866 кодовой страницы можно воспользовать-ся GRAFTABL. С другой стороны, самым простым реше-нием будет использование (до появления полноценнойподдержки русского языка «из коробки») одного из руси-фикаторов: Keyrus или rc. Они прекрасно служили нам вMS-DOS, с таким же успехом послужат и во FreeDOS.

Следующая часто возникающая задача – доступ к то-мам NTFS. В ядре FreeDOS отсутствует поддержка NTFS,но по ссылке http://www.sysinternals.com/ntw2k/freeware/ntfs-dos.shtml можно скачать бесплатную версию NTFSDOS –драйверов, работающих под FreeDOS и предоставляющихдоступ к томам NTFS в режиме «только для чтения». Су-ществует также платная Professional-версия с возможно-стью записи.

Использовать программу крайне просто. Добавьте вы-зов файла ntfsdos.exe в файл autuexec.bat и утилита самапросканирует доступные диски и, если на них будут найде-ны тома NTFS, подключит их без вашего вмешательства.

Теперь перейдем к «длинным», выходящим за рамкиформулы 8+3 именам файлов, которые впервые появи-лись в ОС Windows 95 SR2. Существует несколько ути-лит, созданных для поддержки длинных имен. Например,пакет DOSLFN, который можно скачать по адресу http://www-user.tu-chemnitz.de/~heha/hs_freeware/freew.html. Про-писываем в autoexec.bat вызов TSR-модуля doslfn.com,который занимает 16 Кб в оперативной памяти, и на этомвся установка закончена. Потенциальной проблемой мо-жет стать то, что поддерживаются длинные имена не навсех приводах CD-ROM. В случае возникновения таких про-блем можно попробовать еще один пакет, выполняющийаналогичные функции, – LFN Tools (http://www.odi.ch/).

Графические оболочкиЛюбые задачи в FreeDOS можно выполнить, не выходя зарамки командной строки. Но, конечно, намного удобнее ис-пользовать одну из многих так называемых «оболочек» –shells. Хочу напомнить, что та же MS Windows вплоть доверсии Windows 3.11 for Workgroups являлась ничем иным,как оболочкой для MS-DOS. И лишь Windows 95 присвои-ла себе гордое имя операционной системы.

Говоря об оболочках, в первую очередь упомяну оболоч-ку – бессмертный файловый менеджер Norton Commander иего многочисленные клоны, например, миниатюрныйVolkov Commander и менеджер с открытым исходным ко-дом Dos Navigator (http://www.ritlabs.com/dn/).

DEVICE=C:\FDOS\bin\atapicdd.sys /D:FDCD0001À autoexec.bat êîìàíäó:

C:\FDOS\bin\Shsucdx /D:FDCD0001

Page 24: 016 Системный Администратор 03 2004

23№3(16), март 2004

администрирование

Вышеперечисленные программы имеют текстовый ин-терфейс на основе псевдографики. Гораздо интереснеепознакомиться с по-настоящему графическими оболочка-ми. Часть из тех оболочек, что работают в среде FreeDOS,перечислена в таблице.

Очень кратко рассмотрим некоторые из них.SEAL – тридцатидвухразрядная оболочка, напомина-

ющая по интерфейсу MS Windows. В составе пакета име-ется некий минимальный набор приложений, включая тек-стовый редактор, среду разработки, графический редак-тор, файловый менеджер, CD-плейер, программу снятияобраза с дискет, более десятка игр. Для инсталляции до-статочно разархивировать скачанный с сайта http://sealsystem.sourceforge.net/ архив и запустить install.exe.Оболочка запускается командой C:\seal2\seal.exe.

OpenGEM – развитие Digital Research GEM под откры-той лицензией GPL. OpenGEM достаточно большой па-

кет – на жестком диске требуется почти 10 Мб. Есть вер-сия, помещающаяся на дискете – GEMini.

Кратко по установке. После того как дистрибутив ска-чан и разархивирован, запускаем install.bat. Программаустановщика задаст несколько вопросов: куда ставитьпакет и имеется ли на компьютере установленная Windows.После отработки «батника» добавляем строки из файлаC:\fgconfig.sys в config.sys. Запускается оболочка коман-дой C:\gem.bat. Интерфейс OpenGEM изображен на сле-дующем рисунке:

В состав пакета входит более 30 приложений. В томчисле текстовый процессор, электронные таблицы, HTML-браузер, игры.

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

Page 25: 016 Системный Администратор 03 2004

24

администрирование

С ЮНИКСОМ НА vi

СЕРГЕЙ СУПРУНОВ

Page 26: 016 Системный Администратор 03 2004

25№3(16), март 2004

администрирование

Так уж исторически сложилось, что операционные систе-мы UNIX считаются очень сложными и недружественны-ми по отношению к пользователям. И одним из олицет-ворений этого часто называют редактор vi. По мере того,как набирает обороты Linux, позиционируемый как сис-тема более дружественная, среди его пользователей всебольшую популярность приобретают более привычныередакторы, особенно тот, который встроен в MidnightCommander (поскольку всегда под рукой), и старый доб-рый vi начинает забываться. Тем не менее, этот редак-тор обладает непревзойденной на сегодняшний деньмощью, функциональностью, универсальностью и удоб-ством работы, а кроме того, разработан в полном соот-ветствии с идеологией UNIX. Чтобы не быть голословным,приведу несколько примеров (синтаксис команд редак-тора, которые в них встретятся, будет подробнее рассмот-рен ниже):! Задача: в середину некоторой статьи нужно вставить

вывод команды «ipfw show» (или любой другой). По-пробуйте сделать это, используя ваш любимый редак-тор, а затем посмотрите, как это делается в vi.Конечно же, будучи квалифицированным пользова-телем, вы не стали вбивать результат вручную, а пе-ренаправили вывод в файл, который объединили сфайлом статьи:

после чего, воспользовавшись функциями редакти-рования блоков (ваш же редактор позволяет это?),перенесли блок в нужное место. Конечно, с помо-щью Midnight Commander можно сделать то же са-мое проще:

Идем в точку, в которую нужно вставить блок, затемжмем F9 и выбираем в меню «Файл» пункт «Вставитьфайл…», указываем путь к файлу buffer.Ну а с помощью vi это выполняется одной командой:

! Предположим, что у вас есть пронумерованный спи-сок из 12 пунктов. Вам нужно вставить два пункта,начиная с третьей позиции, и соответственно попра-вить номера всех нижележащих пунктов.Наверняка решать эту задачу вам придется руками.Vi позволяет сократить число операций до миниму-ма. Для первого пункта списка, номер которого нуж-но поменять, ставим курсор на его номер и даем ко-манду «2#+», после чего на номере каждого последу-ющего пункта просто давим символ «.».

! Двадцать четыре строки в тексте нужно сдвинутьвправо символом табуляции.Конечно, не проблема минутку пощелкать «Tab –Стрелка вниз – Home», но vi предлагает более эле-гантный способ: «23>j» над первой строкой. И все.

Надеюсь, мне удалось убедить вас в том, что vi – одиниз лучших текстовых редакторов для систем UNIX. Нижемы более подробно рассмотрим его особенности, син-таксис некоторых команд, коротко коснемся режимов exи view. Чтобы учесть интересы читателей с разным уров-нем подготовки, данная статья будет разбита на следу-ющие подразделы:! основы редактора vi;! команды перемещения и поиска;! команды редактирования и форматирования;! работа с блоками и буфером;! команды режима редактирования;! прочие команды режима visual;! команды режима ex;! установки редактора;! заключение.

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

Основы редактора viИтак, vi – текстовый редактор, входящий в поставку прак-тически всех операционных систем семейства UNIX. За-пуск его осуществляется командой:

Помимо основного (visual) режима он может быть за-пущен в командном режиме, называемом ex (от англ.execute), ориентированном на работу со строками, и врежиме view (только для чтения). Запуск этих режимовосуществляется с ключами –e и –R, или командами ex иview соответственно:

Если файл с таким именем существует в текущей ди-ректории, то он будет открыт для редактирования. Ну аесли его нет, то будет создан новый файл. Если командаvi дана без параметров, будет запущено редактирова-ние нового файла, создаваемого во временном катало-ге, заданном переменной окружения TMPDIR (обычно этопапка /tmp) с именем типа vi.L14259 (часть после точкисоздается случайным образом, чтобы обеспечить уни-кальность создаваемого файла). В дальнейшем вы смо-жете сохранить набранный файл под любым именем.

Если вы последовали моей рекомендации и сразу про-веряете все на практике, то первое, чему вы должны на-учиться, это выходить из редактора. Дело в том, что в viвам не помогут ни <escape>, ни <Alt+X>, ни даже <Ctrl+C>.Нет в нем и так любимой народом верхней строчки, име-нуемой «Главное меню». Также он не будет отображатьто, что вы попытаетесь набрать (хотя, если в панике на-чать беспорядочно стучать по клавиатуре, то может слу-читься «чудо» и ваш набор станет появляться на экране,однако выйти из редактора это вам все равно не помо-

# ipfw show > buffer# cat article buffer > temp# mv temp article

# ipfw show > buffer# mcedit article

!lipfw show

# vi [filename]

# {vi �e | ex} [filename]# {vi �R | view} [filename]

Page 27: 016 Системный Администратор 03 2004

26

администрирование

жет). Так что абсолютно черный экран с одинокими тиль-дами по левому краю, никак не реагирующий на нажа-тия клавиш и не позволяющий вернуться в оболочку ина-че, как «килянием» процесса из соседнего терминала(если вы, конечно, умеете пользоваться командой kill –иначе только Reset), может надолго отбить охоту запус-тить этот редактор еще раз. Поэтому сначала ознакомь-тесь со следующей таблицей, которая поможет вам по-верить в то, что vi – это действительно редактор:

Команды, начинающиеся с символа «:», будут отобра-жаться в нижней строке. Остальные выполняются «мол-ча». Редактор vi имеет два режима работы – режим ко-манд и режим редактирования.

Запускается он в командном режиме, так что все на-жатия на клавиши трактуются как команды. Нажатие кла-виш «i», «a», «o», «O» и ряд других переводят vi в режимвставки, когда набираемые символы трактуются кактекст и отображаются на экране.

Возврат к режиму команд выполняется клавишей<escape> или в некоторых случаях автоматически, на-пример, при попытке передвинуть курсор левее первогосимвола в строке (в редакторе vim, являющемся модер-низированным вариантом vi и часто заменяющем его вLinux, в этом случае редактор остается в режиме встав-ки). Автоматический переход в командный режим обыч-но сопровождается звуковым сигналом, как и ошибоч-ная команда.

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

Далее нажмите «i», чтобы перейти в режим вставки.Теперь все нажатия на клавиши будут трактоваться какввод текста, и символы будут отображаться на экране спозиции курсора.

Наберите «Hello, world!». Постарайтесь не ошибать-ся, поскольку исправление ошибок, как и все остальное,имеет здесь свои особенности, о которых мы поговоримниже. Нажмите <escape> для возврата в командный ре-жим. Наберите «:wq» и нажмите <enter>. Убедитесь, чтофайл test.txt действительно создался. После этого не-большого задания вам будет проще представлять то, очем пойдет речь далее.

Аналогично команде «i», в режим вставки можно пе-рейти, нажав клавишу «a». Единственное отличие – текстбудет вставляться не перед символом, на котором нахо-

дится курсор, а после него. Кроме того, режим вставкиможет быть вызван командами «o» и «O». Первая из нихдобавляет пустую строку после, а вторая – перед теку-щей строкой, и дальнейший ввод символов трактуется какввод текста.

Чтобы удалить символ, нужно перейти в режим команди над удаляемым символом нажать клавишу «x». В режи-ме вставки удалить только что введенный ошибочно сим-вол можно клавишей <backspace>, однако в vi таким об-разом может быть удалена только последняя непрерывновведенная последовательность символов. То есть если выоткроете для редактирования наш тестовый файл со стро-кой «Hello, world», и добавите между словами слово «my»:«Hello, my world», то, используя клавишу <backspace>, высможете удалить только что введенные символы « my», авот запятую и последующие символы удалить таким об-разом уже не удастся. В этом случае придется использо-вать команду «x».

Удалить целиком строку, на которой находится кур-сор, можно командой «dd» (просто нажмите два разаклавишу <d>). Помните, что в vi строкой считается неэкранная строка, а последовательность символов до пе-ревода строки (\n). Если строка больше 80 символов (зна-чение по умолчанию), то она переносится на новую ли-нию (строку экрана). Используя «dd», вы удалите всюстроку вне зависимости от того, на скольких экранныхлиниях она размещается.

Чтобы определить, где находится конец строки, нажми-те клавишу «$» (вы, должно быть, уже заметили, что кла-виши <Home>, <End> и т. п. тут не работают). При навига-ции по экрану ( можно пользоваться стрелками, хотя естьи более «правильный» способ) курсор перемещается непо экранным линиям, а по строкам текста.

Если вы что-то сделали не так, то отменить после-днюю операцию можно командой «u». Эта команда от-меняет только последнее действие, то есть ее повтор-ное применение отменит только что сделанную отмену.Конечно, отсутствие истории операций – один из серь-езных недостатков vi, однако если работать вдумчиво ивнимательно, то он почти незаметен. Собственно, идео-логия UNIX-систем такова, что они не особо балуют поль-зователя подсказками и возможностью отката выполнен-ных операций, так что сразу настраивайтесь на ответ-ственную работу.

Учтите, что по команде «u» отменяется вся командацеликом. Например, если вы дали команду «i», набили 3-йтом «Войны и мира» и вернулись в режим команд, то «u»отменит весь этот ввод. Если ошибок получилось слиш-ком много, можно выйти из редактора без сохранениясделанных изменений (команда «:q!»).

В принципе этих сведений достаточно, чтобы отредак-тировать файл. Однако вряд ли вы поверили, что vi – удоб-ный редактор. Понимаю, как вам хочется нажать <F4> всвоем любимом mc, но все же найдите в себе силы дочи-тать статью до конца и попрактиковаться с vi хотя бы парунедель. Думаю, ваше мнение изменится.

В дальнейшей части статьи некоторые команды и ихприменение будут рассмотрены более подробно. За опи-санием всех остальных команд отсылаю читателя к стра-

# vi test.txt

Page 28: 016 Системный Администратор 03 2004

27№3(16), март 2004

администрирование

ницам справочного руководства «man vi», в полном соот-ветствии с идеологией UNIX.

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

В общем случае по тексту можно перемещаться, ис-пользуя клавиши со стрелками. Но vi разработан такимобразом, чтобы в процессе работы руки не покидали ос-новной рабочей зоны клавиатуры. Те, кто владеет мето-дом «слепой» печати, по достоинству оценят эту особен-ность. Кроме того, это позволяет не заботиться о совмес-тимости клавиатур и терминалов – vi будет полностьюфункционален даже на самых тупых терминалах.

Команды навигации и поиска представлены ниже. За-пись «№» означает число, которое набирается перед вво-дом команды (при этом на экране оно не отображается) изадает число повторений команды или в некоторых случа-ях номер строки, к которой команда должна быть примене-на. Если число не задано, команда выполняется один раз.

Команды перемещения курсора! [№]h – перемещает курсор влево на № символов;! [№]k – перемещает курсор на № символов вверх;! [№]j – перемещает курсор вниз на № символов;! [№]l, [№]<пробел> – перемещает курсор на № симво-

лов вправо;! [№]$ – переход на последний символ строки, №-й пос-

ле текущей;! 0 (ноль) – переход на первый символ текущей строки;! ^ – перемещает курсор на первый символ текущей

строки, отличный от пробельного;! [№]- – переход на первый непробельный символ №-й

перед текущей строки;! [№]+ – переход на первый непробельный символ №-й

после текущей строки;! [№]_ – переход на первый непробельный символ (№-1)-й

после текущей строки.

Также существует масса команд для перемещения пословам, группам символов, предложениям, параграфам.При этом под «словом» будет пониматься последователь-ность символов, разделенных пробельными символами.Термином «группа символов» будем именовать после-довательность символов, не разделенных специальны-ми символами (такими как дефис, точка, запятая и т. д.).В терминах vi эти две единицы именуются «большим сло-вом» (bigword) и «словом» (word) соответственно. Пред-ложение – последовательность слов, ограниченная точ-кой или пустой строкой. Параграф – часть текста, обрам-ленная пустыми строками.

Чтобы вы знали, что искать, просто перечислю эти ко-манды: B, W, E, b, w, e, (, ), {, }, <Ctrl-F>, <Ctrl-B>, <Ctrl-D>,<Ctrl-U>, <Ctrl-E>, <Ctrl-Y>. Познакомиться с ними можно

на страницах «man vi» или методом «научного тыка». На-пример, команда «5<Ctrl-Y>» прокрутит экран на 5 строквниз, не перемещая курсор (очень полезна, если вам нуж-но увидеть несколько строк выше и затем продолжитьредактирование текущей строки).

Еще несколько полезных команд навигации:! z. – прокручивает текст так, что текущая строка стано-

вится в центре экрана;! [№]G – перемещает курсор на №-ю строку от начала

файла, если № не задано – на конец файла;! [№]H – перемещает курсор на №-ю сверху строку, ви-

димую на экране;! [№]L – перемещает курсор на №-ю снизу строку, ви-

димую на экране;! M – перемещает курсор на строку, расположенную в

центре экрана.

С помощью следующих двух команд вы сможете рас-ставлять «маркеры» в тексте, и затем быстро переходитьна эти метки:! m<симв.> – запоминает текущую позицию курсора как

символ <симв.>;! `<симв.> – возвращает курсор на позицию, запомнен-

ную как <симв.>.

Например, запомнив начало второго параграфа как«m2», вы в дальнейшем сможете возвращаться к нему ко-мандой «`2».

Команды поискаС поиском вроде все понятно, ничего пояснять не буду:! /<образец поиска> – поиск в тексте по образцу;! / – повторный поиск по предыдущему образцу (найти

далее);! ?<образец поиска> – поиск по образцу в обратном на-

правлении;! ? – повтор поиска по предыдущему образцу в обрат-

ном направлении.

Предыдущие четыре команды должны обязательнозавершаться нажатием клавиши <Enter>.! [№]<Ctrl-A> – поиск №-го слова, совпадающего с тем,

на котором стоит курсор, начиная с позиции курсора всторону конца документа;

! [№]f<char> – перемещает курсор на №-й после курсо-ра символ <char> в строке;

! [№]t<char> – перемещает курсор на символ, стоящийперед №-м после курсора символом <char> в строке;

! [№]F<char> – перемещает курсор на №-й перед курсо-ром символ <char> в строке;

! [№]T<char> – перемещает курсор на символ, стоящийпосле №-го перед курсором символа <char> в строке.

Команды редактированияи форматированияПомимо рассмотренных выше команд «i» и «a», полезныбудут и следующие:! [№]I – включает режим вставки текста. Текст будет вво-

диться с начала строки;

Page 29: 016 Системный Администратор 03 2004

28

администрирование

! [№]A – включает режим вставки текста. Текст будетвводиться после последнего символа в текущейстроке;

! [№]o – вставка новой строки после текущей. Текстбудет вводиться с начала новой строки;

! [№]O – вставка новой строки выше текущей. Текстбудет вводиться с начала новой строки.

Рассматривая две предыдущие команды, необходимоуказать на одну особенность.

Использование оных со счетчиком № не добавляет №пустых строк, как следовало бы ожидать. Добавляетсяодна, редактор переходит в режим ввода, а затем, послевозврата в командный режим, введенный блок текста бу-дет повторен № раз. Кстати, и команды вставки ведут себяаналогичным образом – сначала вы получаете возмож-ность вставить или добавить текст, начиная с соответству-ющей позиции курсора, после чего, в момент возврата врежим команд, введенный вами текст будет продублиро-ван № раз.

Выполните команду «5i», введите текст «echo », вер-нитесь в режим команд (<escape>) и посмотрите, что изэтого получится. Данный комментарий относится и к рядукоманд, перечисленных ниже.! [№]r<char> – заменяет символ в точке нахождения

курсора (и №-1 последующих символов) символом<char>;

! [№]~ – заменяет текущий и следующие №-1 симво-лов этими же символами в другом регистре;

! [№]s – заменяет № символов в строке, начиная с те-кущего, вводимым далее текстом. Вводимые симво-лы после №-го добавляются после замененных. Гра-ница области замены отмечается символом «$».

Поясним эту команду. Пусть у нас есть строка с тек-стом «This is a big string».

Мы хотим слово «big» заменить более справедли-вым «small». Поставим курсор на букву «b» (естествен-но, используя команду «fb» – мы же уже не маленькие,чтобы стрелочками по тексту скакать). Заменить намнужно три символа, поэтому: «3s». Теперь просто вво-дим наше «small» – первые три символа введутся в ре-жиме замены, последующие добавятся, не затирая то,что нам нужно. Теперь <escape>, и любуемся на делонаших рук, не забывая при этом громко восхищатьсяредактором.! [№]R – включает режим замены (вводимые символы

будут замещать текущие до конца строки, затем сим-волы будут добавляться);

! [№]S – очищает строку и переходит в режим встав-ки текста (аналогичный результат достигается пос-ледовательным выполнением двух команд «[№]dd»и «O»). Обратите особое внимание, что № в данномслучае относится к удалению, то есть № строк будутудалены, и вместо них можно будет ввести один блоктекста.

! [№]C – удаляет символы от текущей позиции курсорадо конца строки и переходит в режим вставки текста.№ также относится к удалению.

! [№]c<направление> – удаляет символы в указанномнаправлении, которое задается командами перемеще-ния курсора (№ отдельных символов для направлений«влево» и «вправо» и № строк для «вверх» и «вниз»)и переводит редактор в режим вставки текста.

Все вышеприведенные команды переводят vi в режимвставки текста, то есть весь последующий ввод будет ото-бражаться на экране начиная с указанной позиции. Длявозврата в командный режим используется комбинация<Ctrl-C> или клавиша <escape>.! [№]x – удаляет № символов после курсора (начиная с

позиции курсора);! [№]X – удаляет № символов перед курсором;! [№]d <направление> – удаляет № символов/строк от-

носительно курсора в указанном направлении. На-правление задается командами управления курсором«h», «j», «k», «l» или стрелками. Если выбрано «вле-во» или «вправо», то удаляются № символов соот-ветственно перед курсором или после него. Направ-ление, заданное как «вверх» или «вниз», позволяетудалить № строк соответственно выше или ниже те-кущей строки (включая текущую);

! [№]D – удаляет символы начиная с позиции курсорадо конца строки;

! [№]J – объединяет текущую строку с № следующими водну;

! [№]> <направление> – сдвигает № строк вправо насимвол табуляции;

! [№]< <направление> – сдвигает № строк влево на сим-вол табуляции.

В предыдущих двух командах (впрочем, как и в осталь-ных) направление задается командами управления кур-сором «h», «j», «k», «l» или стрелками. Так, если выбрано«вправо» или «влево», то команда сдвига действует толькона текущую строку, № игнорируется. Если «вверх» или«вниз», то сдвигается данная строка и № предыдущих илипоследующих соответственно.! [№]#{#|+|-} – инкремент/декремент числа. Если дать

эту команду, когда курсор стоит под числом, то эточисло будет увеличено на № (если задан параметр«#» или «+») или уменьшено на № (если задан пара-метр «-»). Например, чтобы увеличить число 52 на7, ставим курсор на символ «5» или «2» (он можетбыть установлен на любую цифру числа), после чегонабираем последовательно «7#+». В результате «52»изменится на «59». В vim эта функция не поддержи-вается.

! [№]!<направление><команда shell> – заменяет в до-кументе начиная с позиции курсора в заданном направ-лении № строк выводом команды оболочки. Если вамнужно вставить вывод, можно сначала создать две пу-стые строки, а затем выполнить данную команду, на-пример: «2o», <escape>, «!kwho».

Работа с блоками и буферомVi предоставляет пользователю весьма мощные функциипо работе с блоками.

Page 30: 016 Системный Администратор 03 2004

29№3(16), март 2004

администрирование

! [№]yy – копирует в буфер № строк, начиная с текущей;! [№]Y – копирует № строк в буфер (аналогична «yy»);! [№]y<направление> – копирует текст в буфер в ука-

занном направлении. № трактуется в зависимости отнаправления (впрочем, как и в остальных подобных ко-мандах): количество копируемых символов для «впра-во» и «влево» и число строк (дополнительно к теку-щей) для «вверх» и «вниз». Например, «2yk» скопиру-ет в буфер текущую строку и еще две, расположенныевыше (итого – три). Если вам нужно скопировать толь-ко текущую строку, следует использовать команду «yy»или «Y»;

! [№]p – вставляет текст из буфера № раз после курсо-ра;

! [№]P – вставляет текст из буфера № раз перед курсо-ром.

Используя команды расширенного (ex) режима, мож-но работать с несколькими блоками. Где изучить эти воз-можности, вы, думаю, уже знаете. Конечно же, в «man vi».

Команды режима редактированияНаходясь в режиме редактирования, редактор все вводи-мые символы будет отображать на экране как часть тек-ста. Однако существует несколько последовательностей,которые трактуются как специальные команды и для кото-рых выполняется автоматическая замена введенных сим-волов последовательности результатом выполнения коман-ды. Наиболее полезные из них следующие:! <escape> – завершает режим ввода текста и перево-

дит редактор в командный режим;! <Ctrl-C> – также возвращает редактор в режим команд

(при «слепой» печати эта команда более удобна);! <backspace> – удаление только что введенного символа;! <Ctrl-W> – удаление только что введенного слова;! <Ctrl-X>[0-9A-Fa-f] – вставка символа, имеющего код,

выраженный шестнадцатеричным числом (например,«<Ctrl-X>30» отобразится на экране как «^X30» и ав-томатически заменится символом «0», ASCII-код кото-рого – 30h).

Прочие команды режима visualОсталось рассмотреть еще несколько команд, которыетрудно выделить в ту или иную категорию, но которыевесьма полезны при работе.! [№]. – повтор последней команды для текущей пози-

ции курсора № раз;! u – отменяет последнее действие;! U – восстанавливает текущую строку, отменяя все из-

менения, сделанные в ней;! Q – переключение в интерфейс ex (см. далее);! <Ctrl-G> – выводит информацию о редактируемом фай-

ле (состояние – modified/unmodified, отражающее, естьли в файле несохраненные изменения; номер текущейстроки и общее количество строк в файле);

! <Ctrl-R> – перерисовывает экран (может пригодитьсяна плохом канале связи или для восстановления экра-на после вывода на него системных сообщений, есливы работаете с физической консоли);

! <Ctrl-Z> – временное прерывание сессии редактиро-вания и выход в командную оболочку. Чтобы вернуть-ся назад в редактор, нужно воспользоваться систем-ной командой «fg», которая переводит фоновый про-цесс в активный. Номер задачи (job), соответствующийотложенному процессу редактирования, который по-требуется ввести как параметр команды «fg», можноуточнить командой «jobs». При попытке выйти из обо-лочки командой «exit» вы получите предупреждение,что у вас остались незавершенные задачи:

Здесь test – имя редактируемого файла. Нужно заме-тить, что если вы вызываете vi из Midnight Commander,то в списке приостановленных заданий вместо «vi test»будет отображаться «midc» («mc» для Linux). После этихдействий вы вернетесь назад в vi и сможете завершитьредактирование. Если отложенное задание только одно,можно вернуться к нему командой fg без параметров.

! ZZ – выход из редактора с сохранением изменений(аналог команды «:wq»).

Команды режима exРедактор vi имеет помимо рассмотренного еще один ин-терфейс, или режим, – ex. Запустить редактор в этом ре-жиме можно одной из следующих команд:

Кроме того, вы можете перейти в него из режима visualпо команде «Q». Данный интерфейс предоставляет рядрасширенных возможностей для обработки текста, такихкак работа с несколькими буферами, открытие другихфайлов в текущем сеансе, изменение настроек редакто-ра и т. д. В данном разделе будут рассмотрены лишь наи-более полезные из них.

В отличие от интерфейса vi, ex ориентирован на коман-дную работу со строками. Редактирование идет как бы всле-пую. Редактируемый текст на экране по умолчанию не ото-бражается, вам придется специально вызывать на экрантребуемые строки. Почти все ex-команды можно исполнитьиз vi-интерфейса, предварив команду двоеточием. Наибо-лее характерный пример: команда – выход из редактора:«:q». Ниже приведено лишь несколько полезных команд:! :!<команда> – выполняет команду оболочки (резуль-

тат просто выводится на экран);! :[<start>] # [№] – выводит на экран № строк начиная со

<start> (в режиме ex);! :s/<текст1>/<текст2> – замена в текущей строке

<текст1> на <текст2>;! :s – повтор предыдущей замены для текущей строки;! :%s/<текст1>/<текст2> – замена во всем файле

<текст1> на <текст2>;! :next – переход к редактированию следующего файла

из списка параметров, с которым был вызван редактор.! :prev – возврат к редактированию предыдущего файла.

$ exitYou have stopped jobs.$ jobs[1] 34336 Suspended vi test$ fg 34336

# vi �e# ex

Page 31: 016 Системный Администратор 03 2004

30

администрирование

Например, если вы вызываете редактор командой «vifile1 file2», то в процессе редактирования вы сможете пе-реходить между файлами указанными выше командами.При этом содержимое буферов обмена будет сохранять-ся, и вы сможете вставлять в файл фрагменты, скопиро-ванные из другого файла. Заметьте, что редактор не по-зволит вам перейти к другому файлу, пока изменения втекущем не будут сохранены или отменены (отменить всеизменения можно командой «:e!», которая перечитаетредактируемый файл с диска).! :edit <file> – открыть для редактирования файл <file>;! :w[ <filename>] – уже знакомая вам команда сохранения

редактируемого файла. Опциональный параметр<filename> превращает команду в команду «Сохранитькак…» для записи изменений в файл с другим именем.

Еще одно пояснение – очень часто бывает, что, отре-дактировав тот или иной файл (например, squid.conf), припопытке сохранить сделанные изменения вы получаетесообщение, что файл недоступен для записи. Причинапонятна – или вы забыли войти как root, или файл имеетправа «r--r--r--». Выходить без сохранения, менять праваи редактировать снова – жалко… А вот сохранить файлпод другим именем, а затем, обретя требуемые права, за-менить им оригинал – как раз то решение, которое насустраивает. Конечно, можно с другого терминала поме-нять права на сохраняемый файл и снова провести опе-рацию записи. Но при удаленной работе открыть новуюssh-сессию не всегда проще, чем поступить описаннымвыше образом. Да и удаленный доступ к нескольким тер-миналам иногда запрещают из соображений безопаснос-ти. Кроме того, если вы внесли изменения в системныйфайл (скажем, /etc/crontab), будучи зарегистрированнымкак простой пользователь, то вряд ли безопасно менять кнему права доступа, пусть и кратковременно. Кроме того,статья рассматривает редактор vi, а потому примеры при-званы прежде всего показать его пригодность для реше-ния тех или иных задач, пусть и не всегда оптимальнымобразом.! :g /<шаблон>/ <команда> – указанная команда, кото-

рой может быть одна из ex-команд, применяется к стро-кам, которые соответствуют шаблону. Например, ко-манда «:g /qwerty/ delete» удалит все строки, в которыхприсутствует последовательность символов «qwerty»;

! :v /<шаблон>/ <команда> – работает аналогично пре-дыдущей, но команда применяется к тем строкам, ко-торые не соответствуют шаблону;

! :vi – переход в интерфейс visual.

Опции и параметры редактораБыло бы странно, если бы оказалось, что столь мощ-ный редактор не позволяет настраивать себя под тре-бования и предпочтения конкретного пользователя.Однако не следует думать, что настройкой можно пре-вратить vi в редактор ee или что-то подобное. Следую-щие опции позволяют лишь добавить «удобства», неменяя общих принципов работы. Все они устанавлива-ются с помощью ex-команды «:set». «no» перед именемопции отключает ее.

! :set [no]list – включает режим отображения служебныхсимволов (таких как конец строки, который будет ото-бражаться символом «$», и т. д.);

! :set [no]nu – включает отображение номеров строк;! :set [no]showmode – включает отображение режима

(command, insert, append, replace) в нижнем правом углуэкрана, в котором редактор находится в данный момент;

! :set [no]verbose – включает режим расширенных сооб-щений (на каждое ошибочное действие будет выда-ваться соответствующее пояснение).

За остальными настройками, как всегда, – «man vi»,соответствующий раздел.

Увековечить сделанные настройки можно в exrc-фай-лах. Данные файлы применяются в следующей последо-вательности:! /etc/vi.exrc – глобальный файл настроек редактора;! $HOME/.exrc – пользовательский файл настроек;! .exrc – локальный файл настроек для текущей дирек-

тории.

Действовать будут те настройки, которые примененыпоследними. В эти файлы следует занести те ex-коман-ды, которые должны быть исполнены при открытии редак-тора. Например, если вы хотите, чтобы редактор всегдаработал с включенным отображением режима и расши-ренными сообщениями, то создайте в своем домашнемкаталоге файл .exrc следующего содержания:

Теперь каждый раз при вызове редактора эти коман-ды будут отрабатываться автоматически.

ЗаключениеИтак, вы в общих чертах познакомились с редактором vi.Приведу еще несколько преимуществ редактора vi, поми-мо его функциональности:! способность работать практически на любых терминалах;! обязательное наличие в любой UNIX-системе;! надежная работа даже на самых плохих линиях;! используется в некоторых системных командах (напри-

мер, vipw), следовательно, умение в нем работать потре-буется в любом случае;

! а сможете ли вы просмотреть файл, являющийся ката-логом (в UNIX каталог – это специальный файл), с помо-щью «ee» или «mcedi»? Хотя редактировать такой файлвам и vi не позволит, но посмотреть для интереса – мож-но (например, «view /etc»).

Попытайтесь с ним подружиться!P.S. Если вы все же отважились сделать vi вашим основ-

ным редактором, для этого установите значение перемен-ной $EDITOR=vi (например, для оболочки sh нужно попра-вить файл .profile в вашем домашнем каталоге, для csh – этофайл .cshrc). Также в настройках Midnight Commander отме-ните использование встроенного редактора (пункт меню«Настройки» – «Конфигурация…»), и по <F4> будет вызы-ваться тот редактор, который задан в переменной $EDITOR.

set showmodeset verbose

Page 32: 016 Системный Администратор 03 2004
Page 33: 016 Системный Администратор 03 2004

32

безопасность

СЕРГЕЙ ЯРЕМЧУК

СВОБОДНЫЙ АНТИВИРУСДо недавнего времени об установке антивируса подUNIX-системы никто сильно, пожалуй, и не думал,но события последних лет изменили кореннымобразом подход к этому вопросу. Теперь антивируспод эти системы ставят не только для обезвреживаниявирусов при использовании UNIX-систем в качествеплатформы для почтовых и файловых серверовлокальных сетей и т. д., но и для локальной защитыпользовательских данных от деструктивных действийвирусов. При этом антивирусы должны обладатьвозможностью обнаруживать все существующиена данный момент вирусы как для UNIX, так и дляWindows-систем, а также макровирусы.

Page 34: 016 Системный Администратор 03 2004

33№3(16), март 2004

безопасность

Наибольшей популярностью среди антивирусов пользу-ется DrWeb от ЗАО «ДиалогНаука»: http://www.drweb.ru,обладающий действительно хорошими характеристика-ми и эвристическим анализатором, позволяющим иног-да обнаружить неизвестный вирус. Все, в общем, хоро-шо, но, собрав полностью сервер из бесплатных компо-нентов, выбить финансы для того, чтобы платить за ли-ценцию, под конец года не получилось. А ограниченияознакомительной версии, в частности невозможностьпроверки архивов, мне не совсем подходят. Плюс зацик-ливание на одном продукте обычно мешает увидеть егослабые и сильные стороны, все, как говорится, познает-ся в сравнении. Тем более что в Интернете я постояннонатыкался на другие антивирусы, и мне захотелось по-искать замену (или убедиться в отсутствии таковой, чтотоже хорошо). В результате я вышел на несколько до-вольно интересных проектов, о которых речь пойдет вэтой и следующей статьях.

Clam AntiVirus (http://clamav.sourceforge.net/ или http://www.clamav.net/) представляет собой антивирусный ком-плект для UNIX-систем. Главная цель продукта – интег-рация с почтовыми серверами для проверки вложенийна предмет наличия вирусов. В настоящий момент под-держивается широкий спектр операционных систем:Linux, Solaris, FreeBSD, OpenBSD, NetBSD, AIX, Mac OS X,BeOS, HPUX, SCO UNIX и Windows/Cygwin на несколь-ких архитектурах: Intel, Alpha, Sparc, Cobalt MIPS boxes,PowerPC, RISC 6000, что уже вызывает уважение. Рас-пространяется по лицензии GPL, POSIX-интерфейс и об-щедоступные библиотеки позволяют быстро адаптиро-вать его с другими приложениями. Работает с архивамии сжатыми файлами, в настоящее время встроена под-держка RAR, Zip, Gzip, Bzip2. Также встроена поддерж-ка защиты от mail-бомб, которые периодически любятзакидывать в пользовательские ящики, и поддержива-ется milter-интерфейс к программе Sendmail. Обнаружи-вает, по данным разработчиков, более 20 000 вирусов,червей и троянов (хотя программа при запуске выдаетсообщение о чуть больше 10 000, остальное в дополни-тельных базах). Конечно, по сравнению с другими подоб-ными продуктами число получилось небольшое, но ведьмы знаем, что количество можно считать по-разному,хотя сама программа при запуске выдает сообщение о10 000 вирусов. При необходимости можно воспользо-ваться он-лайн-сканером, позволяющим протестироватьфайлы на жестком диске. Для этого заходим по адресу:http://www.gietl.com/test-clamav и указываем на файл.Если же вы имеете вирус, который не обнаруживаетсяClamAV с обновленными базами, то по адресу: http://www.nervous.it/~nervous/cgi-bin/sendvirus.cgi или http://www.clamav.net/cgi-bin/sendvirus.cgi можно заполнитьформу, где нужно обязательно указать свой e-mail, имяи место расположения зараженного файла, опциональ-но можно также проставить антивирус, обнаружившийзаразу. Другой вариант: послать zip-архив с паролем virusпо адресу [email protected]. После чего вирус будет про-анализирован и добавлен в базу данных. Об остальныхвозможностях поговорим, когда посмотрим на его рабо-ту в действии.

УстановкаИз библиотек требуются zlib и bzip2, которые имеются вбольшинстве систем. Если привычнее пользоваться ужескомпилированными пакетами, то зайдите на страницу http://clamav.sourceforge.net/binary.html и выберите нужнуюссылку: на момент написания статьи это Debian, RedHat –Fedora, PLD (Polish(ed) Linux Distribution), Mandrake, AIX,FreeBSD, OpenBSD и MS Windows, на установке в этомслучае останавливаться не буду. В остальных случаях нуж-но компилировать самому, хотя ничего особо сложногоразработчики не придумали.

Единcтвенная задержка возникает при конфигуриро-вании и выглядит это так:

Дело в том, что разработчики в целях безопасностирекомендуют запускать утилиту от лица пользователяclamav, а не root, и не устанавливать ни в коем случаеSUID или SGID.

Избежать этого сообщения можно двумя способами:добавить параметр --disable-clamav при конфигурирова-нии или просто создать этого пользователя.

По умолчанию ClamAV устанавливается в /usr/local, и,соответственно, конфигурационный файл будет лежать в/usr/local/etc, его месторасположение на /etc можно изме-нить, добавив опцию --sysconfdir=/etc.

Если конфигурирование завершилось без ошибок, ком-пилируем и устанавливаем.

После окончания установки в нашем распоряжениибудет несколько исполняемых файлов:! clamscan – утилита командной строки, предназначен-

ная для проверки файлов и каталогов на предмет на-личия вирусов.

! clamd – антивирусный демон, прослушивающий под-ключения к UNIX или TCP-сокетам и сканирующий ка-талоги по требованию. Обеспечена возможность on-access просмотра (только Linux) при применении ути-литы clamuko.

! clamdscan – простой интерфейс к демону clamd, по-зволяет также сканировать файлы и каталоги, при этомиспользуются те же параметры, что и в clamscan, и мо-жет полностью заменить clamscan.

! clamav-milter (при конфигурировании с опцией --enable-milter) – представляет собой антивирусный интерфейск sendmail, использует для просмотра почты clamd.

#tar xzvf clamav-0.65.tar.gz# cd clamav-0.65

#./configure.../dev/(u)random detected.Checking /etc/passwd...ERROR: User "clamav" (and/or group "clamav") doesn't exist.

Please create it. You can omit this check with the --disable-clamav option.

# groupadd clamav# useradd -g clamav -s /bin/false -c "Clam AntiVirus" clamav

# make# su -c "make install"

Page 35: 016 Системный Администратор 03 2004

34

безопасность

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

! sigtool – генерирует вирусную сигнатуру, используя вне-шний антивирусный сканер, который способен обна-ружить вирус. Может создавать шестнадцатиричныйдамп и формировать и распаковывать CVD-базу дан-ных (ClamAV Virus Database).

Теперь по порядку и поподробней. Проверить текущийкаталог на наличие вирусов можно, просто набравclamscan без каких-либо параметров. В результате полу-чим список проверенных файлов и отчет. Список проска-нированных файлов позволяет проверить работу утили-ты с различными типами файлов на начальном этапе, нов большинстве случаев лучше добавить параметр -i длявывода только зараженных файлов. Указать на файлы,находящиеся в другом каталоге, можно, перечислив их встроке запуска, или, если проверяется каталог, то указатьпуть к нему, не забыв опцию -r для рекурсивного обхода(для проверки работы антивируса с пакетом поставляет-ся несколько тестовых файлов).

Опция --database= позволяет указать место располо-жения дополнительной антивирусной базы. Также по умол-чанию пограмма не ведет никаких логов, при работе с cronэто не совсем удобно, т.к. теряется контроль над работойпрограммы, при помощи --log= можно указать, в какойфайл их заносить. При необходимости проверки отдель-ных файлов каталога можно воспользоваться опциями -exclude=PATT и -include=PATT. Первая позволяет указатьшаблоны файлов, которые не надо проверять, а вторая,наоборот, только те, которые надо просканировать в по-иске вирусов. Опция -mbox включает сканирование почто-вых каталогов и файлов.

Или можно проверять выход другой программы на на-личие вирусов.

Кроме вывода информации об обнаружении вируса мож-но удалить (--remove) или переместить (--move=DIRECTORY)такие файлы в другой каталог. Обычно при работе с ар-хивами программа сама находит нужную утилиту для рас-

паковки, и дополнительных указаний ей не надо, но еслипоявляются сообщения вроде:

то указываем на необходимость проверки архивов, и еслине видно нужного архиватора в переменной $PATH, тоуказываем также местонахождение такой программы. На-пример, для rar: -unrar[=FULLPATH]. Так, для zip-архивастрока запуска может выглядеть так:

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

Каталог /tmp забивается таким образом очень быст-ро, т.е., закинув большой архив, можно провести DOS-атаку. Чтобы избежать этого, можно указать при помощи-tempdir= на другой каталог, в котором побольше свобод-ного места, или установив максимальное количество из-влекаемых за один раз файлов (-max-files=#n), или извлечьсначала #n Кб архива (использовав nM или nm, можноуказать на количество Мб) при помощи –max-space=#n.Можно просто указать на максимальный уровень рекур-сии обхода архива: -max-recursion=#n.

В следующем примере используем новую антивируснуюбазу и ограничиваем размер временных файлов в 50 Мб,плюс проверяем архивы.

Я надеюсь, по clamscan все понятно. Переходим к де-мону clamd. Главное отличие демона от сканера заключа-ется в том, что он один раз при старте загружает все не-обходимые базы и настройки и находится в оперативнойпамяти постоянно готовым выполнить работу. В своей ра-боте он использует конфигурационный файл clamav.conf.Если запустить программу без дополнительного редакти-рования (в том случае, если установка происходила изисходных текстов), то демон откажется работать.

Файл хорошо комментирован, и опции описаны в man,чтобы заставить работать демон в конфигурации по умол-чанию, достаточно убрать или закомментировать строкуExample в самом начале файла. Пример (ненужные пара-метры достаточно закомментировать):

# /usr/local/bin/clamscan -r -i /home/sergej/work/clamav-0.65/

#clamscan -r --mbox /var/spool/mail

#cat testfile | clamscan -

# clamscan �unzip /mnt/test/test.zip

#clamscan -d /tmp/newclamdb �tgz �deb �unrar ↵↵↵↵↵--max-space=50m -r /home

# /usr/local/sbin/clamd

#Example# Ïóòü ê ëîã-ôàéëóLogFile /var/log/clamav/clamd.log# Áëîêèðîâêà çàïèñè â ëîã-ôàéë (íåîáõîäèìà ïðè çàïóñêå# íåñêîëüêèõ äåìîíîâ îäíîâðåìåííî)â òîì ÷èñëå è âî èçáåæàíèå# ðàáîòû ñ îäèíàêîâîé êîíôèãóðàöèåé#LogFileUnlock

Page 36: 016 Системный Администратор 03 2004

35№3(16), март 2004

безопасность

И далее в файле вы найдете несколько строк для ра-боты с Clamuko. Это интерфейс к модулю Dazuko (http://dazuko.org), обеспечивает (только для Linux) работу clamdв режиме on-access через устройство /dev/dazuko. Этопока еще экспериментальная разработка, пока я не убе-дился в необходимости пользоваться ею, поэтому, есликто-то заинтересовался, за подробностями обращайтесьв документацию, в ней все понятно расписано.

Запущенный демон ничего не делает. Для указаниятого, чем именно сейчас ему заниматься, необходимо по-слать сигнал:! PING – проверка связи, в ответ демон посылает PONG,

и закрывает соединение.! VERSION – вывод версии.! RELOAD – перезагрузка антивирусных баз.! QUIT – остановка демона.! SCAN file/directory – рекурсивный обход указанных ка-

талогов в поисках вирусов с поддержкой архивов (еслине запрещено в конфигурационном файле).

! RAWSCAN file/directory – то же, только без поддержкиработы с архивами.

! CONTSCAN file/directory – то же, что и SCAN, но приобнаружении вируса программа не прерывает свою ра-боту, а продолжает обход каталога дальше.

! STREAM – просмотр потока, при этом демон выдастномер порта, в который необходимо посылать сигнал.

С сигналами понятно, только вот как их посылать, вдокументации сказано довольно невнятно. Оказалось, всезамешано на межпроцессорном взаимодействии или под-ключении к сетевому порту. Например, команду «проска-нировать каталог» можно дать таким образом (при сете-вом режиме работы демона):

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

Для автоматического запуска clamd вместе с системойнеобходимо положить файл clamd.sh в каталог /etc/init.d/и прописать путь для запуска в /etc/rc.d/rc.local или создатьсимволическую ссылку в каталоге соответствующемууровню запуска системы.

Хотя все в этом вопросе зависит от используемой опе-рационной системы или дистрибутива Linux.

С clamav-milter все просто. Если антивирус устанавли-вался при помощи rpm-пакетов, то необходимо доустано-вить пакет clamav-milter-0.65-4.i386.rpm, в котором прак-тически все уже настроено, и в каталоге /usr/share/doc/clamav-milter-0.65/ лежат документы RPM-clamav-milter.txtи HOWTO-logwathch.txt, в которых все расписано по ша-гам. При установке из исходников также ничего сложно-го. Добавляем в файл /etc/mail/sendmail.mc строку:

И запускаем утилиту:

При необходимости ограничить число процессов до-бавляем опцию -max-children=, если сlamd работает всетевом режиме, то дополнительно используется опция-server= с указанием IP-адреса, последним аргументом вэтом случае проставляется номер порта.

# ìàêñèìàëüíûé ðàçìåð ëîã-ôàéëà (0 � áåç îãðàíè÷åíèé)LogFileMaxSize 0# Èñïîëüçîâàíèå syslogLogSyslog# Ïîäðîáíûé îò÷åò#LogVerbose# Ôàéë äëÿ ñîõðàíåíèÿ èäåíòèôèêàòîðà ïðîöåññàPidFile /var/run/clamav/clamd.pid# Ïóòü ê àíòèâèðóñíûì áàçàì (ïî óìîë÷àíèþ /usr/local/share/clamav)DataDirectory /var/lib/clamav# Äåìîí ìîæåò ðàáîòàòü â ñåòåâîì èëè ëîêàëüíîì ðåæèìå,# â öåëÿõ áåçîïàñíîñòè ðåêîìåíäóåòñÿ ïîêà ïîñëåäíèé, íî âîò# ïîñûëàòü ñèãíàëû ìíå ïîêàçàëîñü áîëåå óäîáíûì èìåííî# â ñåòåâîì. Íåñêîëüêî ñëåäóþùèõ ñòðîê íåîáõîäèìû äëÿ# íàñòðîéêè ñåòåâîãî ðåæèìà.#LocalSocket /var/run/clamav/clamd.sock#FixStaleSocket#TCPSocket 3310#TCPAddr 127.0.0.1#MaxConnectionQueueLength 30# Ïðåäâàðèòåëüíàÿ çàïèñü ïîòîêàStreamSaveToDisk# Ïðåäåë äëÿ ïîòîêà, ïîñëå êîòîðîãî ñîåäèíåíèå çàêðûâàåòñÿ#StreamMaxLength 10M# Ìàêñèìàëüíîå êîëè÷åñòâî îäíîâðåìåííî âûïîëíÿåìûõ çàäà÷MaxThreads 10# Ìàêñèìàëüíàÿ ðåêóðñèÿ êàòàëîãàMaxDirectoryRecursion 15# Ñëåäîâàíèå ñèìâîëè÷åñêèì ññûëêàì äëÿ êàòàëîãîâ è ôàéëîâ#FollowDirectorySymlinks#FollowFileSymlinks# Ïðîâåðêà öåëîñòíîñòè áàç (ïî óìîë÷àíèþ 1 ÷àñ)#SelfCheck 600# Êîìàíäà, êîòîðàÿ äîëæíà âûïîëíèòüñÿ ïðè îáíàðóæåíèè âèðóñà.# Ïðè ýòîì èñïîëüçóþòñÿ ïîäñòàíîâêè %f � èìÿ èíôèöèðîâàííîãî# ôàéëà, %v � íàçâàíèå âèðóñà. Äîëæåí èñïîëüçîâàòüñÿ ïîëíûé# ïóòü ê êîìàíäå#VirusEvent /usr/local/bin/send_sms 123456789 "VIRUS ALERT: %f: %v"# Èìÿ ïîëüçîâàòåëÿ, îò êîòîðîãî çàïóñêàåòñÿ äåìîí, îí äîëæåí# èìåòü ïðàâà íà èçìåíåíèå âñåõ ïåðå÷èñëåííûõ ôàéëîâ è êàòàëîãîâ.User clamav# Ðàáîòà ñ ïî÷òîé è àðõèâàìè, äëÿ RAR íóæíà îòäåëüíàÿ ñòðîêàScanMailScanArchiveScanRAR# Óñòàíîâêà ìàêñèìàëüíûõ çíà÷åíèé äëÿ àðõèâîâ äëÿ çàùèòû# îò mail-áîìá (0 � áåç îãðàíè÷åíèé).ArchiveMaxFileSize 10MArchiveMaxRecursion 5ArchiveMaxFiles 1000ArchiveLimitMemoryUsage

# telnet localhost 3310

#clamdscan /home

#ln -s /etc/init.d/clamd.sh /etc/rc.d/rc5.d/S50clamd

INPUT_MAIL_FILTER(`clmilter',`S=local:/var/run/clmilter.sock,F=, T=S:4m;R:4m')dnldefine(`confINPUT_MAIL_FILTERS', `clmilter')À â clamav.conf ïðîâåðÿåì íàëè÷èå òàêèõ ñòðîê.LocalSocket /var/run/clamd.sockScanMailStreamSaveToDisk

#/usr/local/sbin/clamav-milter -blo /var/run/clmilter.sock

Page 37: 016 Системный Администратор 03 2004

36

безопасность

Утилита автоматического обновления антивирусныхбаз может запускаться в двух режимах: интерактивном –из командной строки, и как демон. Утилита используетбазу http://database.clamav.net для автоматического вы-бора зеркала. В комплекте имеется также список такихбаз, занесенный в файл mirror.txt, утилита пробует попорядку соединиться с первым в списке и в случае не-удачи далее следует по списку. Можно подобрать длясебя оптимальный вариант и поставить его первым. Дляначала следует запустить утилиту без параметров, есливсе нормально, то следующим создать лог-файлы, не-обходимые для работы.

Для запуска в режиме демона используется опция -d:

Параметр -с указывает на промежуток времени об-новления базы в днях (число от 1 до 50). Для указанияотличной от установленной по умолчанию директории, вкоторую должны помещаться обновления, используйтеопцию -datadir=. Прокси можно указать двумя способа-ми: либо задать в командной строке параметры -http-proxy=hostname[:port] и при необходимости указания па-роля для доступа -proxy-user=user:password; второй вари-ант – установить нужное значение переменной http_proxy:

Для контроля за обновлениями можно воспользо-ваться параметрами: -on-error-execute=COMMAND и -on-update-execute=COMMAND. Первая позволяет задать ко-манду, которая будет выполнена при неудачном обновле-нии баз, вторая – наоборот, при успешном проведении об-новления. Для одноразового запуска утилиты в случае не-обходимости немедленного обновления она запускаетсябез опции -d (да и -с смысла не имеет). Остальные пара-метры при этом остаются теми же. В rpm-пакете лежитфайл-шаблон /etc/sysconfig/freshclam, в котором можно за-полнить соответствующие поля для установки всех выше-перечисленных параметров, а запускать утилиту при по-мощи скрипта /etc/init.d/freshclam. Можно для запуска ис-пользовать и cron, занеся в /etc/сrontab для еженедельно-го обновления примерно такую строку:

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

морфного варианта. В документе «Creating signatures forClamAV», который поставляется вместе с архивом, рас-писано, как получить сигнатуру из тестовых «вирусов»,поставляемых вместе в ClamAV. Мне повезло чуть боль-ше. Погоняв чуть дольше недели антивирус в боевом ре-жиме, удалось найти вирус который ClamAV не обнару-жил, а Dr.Web по его поводу сказал следующее:

Другой антивирус F-prot, о котором речь пойдет в сле-дующий раз, выдал сообщение:

Очевидно, разработчики ориентируются в первую оче-редь на новые, недавно появившееся вирусы, и антиви-рус пока плохо знаком со старой гвардией. Сначала про-буем создать такую сигнатуру при помощи clamscan:

Опция -с говорит, какую команду запускать, здесь дол-жен быть один из установленных в системе антивирусов,-f задает инфицированный файл, а -s – уникальная стро-ка, которую вывел антивирус, обнаруживший вирус, вбольшинстве случаев сюда пишем имя обнаруженного ви-руса. Как видите, при помощи clamscan обнаружить егоне получилось, поэтому пробуем Dr.Web.

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

# touch /var/log/clam-update.log# chmod 600 /var/log/clam-update.log# chown clamav /var/log/clam-update.log

# freshclam -d -c 3 -l /var/log/clam-update.log

#export http_proxy="proxy.server:8080"

0 00 * * 07 /usr/local/bin/freshclam --quiet ↵↵↵↵↵-l /var/log/clam-update.log

#drweb /mnt/dos.ext.1/virus_test/

# sigtool -c "clamscan --stdout" ↵↵↵↵↵-f /home/sergej/virus_test/test.exe -s

# sigtool -c "drweb" -f -f /home/sergej/virus_test/test.exe ↵↵↵↵↵-s "Win32.HLLP.Underscore.36864"

Page 38: 016 Системный Администратор 03 2004

37№3(16), март 2004

безопасность

се. Этот вирус, например, переименовывает файлы и со-здает в системном каталоге файл mc42.exe. Поэтому припомощи Midnight Commander, или дав такую команду:

или двоичный дамп для анализа:

а лучше, воспользовавшись двоичным редактором, нахо-дим специфические для данного вируса строки (рис. 1) изаносим их в отдельный файл. Но этот метод хоть интере-сен и работает на ура, мне созданная таким образом сиг-натура позволила найти все файлы на зараженном ком-пакте, в том числе и упрятанные в архив (куда не смогзаглянуть Dr.Web), но все-таки этот процесс может занятьзначительный промежуток времени, особенно при боль-шом исходном файле. Можно попробовать разбить исход-ный файл на меньшие по размеру, в котором(ых) внешнийантивирус будет еще находить вирус, и затем повторитьоперацию. Разбить файл на части можно, воспользовав-шись, например, split. Мне удалось, немного повозившись,создать такой файл в 10 Кб и в результате:

В результате в файле xaf.sig будет примерно такаястрока.

Добавляем в ее начало:

Теперь осталось добавить сигнатуру вируса в базуданных.

Распаковываем одну из установленных баз, их имеетсядве – main.cvd и daily.cvd. Первая – постоянная, вторая –для ежедневных обновлений. Распаковываем нужную:

после чего в текущем каталоге появится файл viruses.db2,если его открыть в любимом редакторе, то увидим, что онсостоит из подобных строк. Добавляем в него сигнатуру ипросчитываем новую контрольную сумму:

Теперь можно пользоваться обновленной базой, ука-зав на нее параметром -d или поместив обратно в ката-лог /var/lib/clamav или /usr/local/share/clamav/ к старымбазам, после чего добавленный таким образом вирус бу-дет обнаруживаться ClamAV. К сожалению, антивирусные

# strings test.exe | less

#cat test.exe | sigtool --hex-dump > virus.sig

компании не очень любят делиться своими наработками,поэтому как-то приделать внешние базы пока не получа-ется, но некоторые сигнатуры в удобочитаемом виде мож-но взять, например, на Sophos http://www.us.sophos.com/downloads/ide/, по крайней мере Bagle появился там быс-тро, а простота операции позволила также оперативно за-нести информацию о нем в свою базу. В документациипоказано, как можно затем обратно упаковать базу, вос-пользовавшись опцией --build, но для этого необходимоиметь доступ к специальному серверу, для подписи, по-этому дальше я не пошел, оставил все как есть.

Предвидя некоторую критику, сразу отвечу: да, не делосисадмина собирать по всему свету сигнатуры. Но, с дру-гой стороны, так можно среагировать все-таки побыстрее,чем антивирусные компании (ну, по крайней мере, такаявозможность греет душу), плюс новые сигнатуры добав-ляются в базу данных ClamAV ежедневно, поэтому, я ду-маю, эта проблема будет решена в скором времени. Мнеэтот антивирус в общем-то понравился и не в последнююочередь разнообразием инструментов и удобством рабо-ты. Также одним из положительных моментов знакомствас ним отмечаю именно открытость продукта, позволившуюнаконец разобраться с технологией и понять реальныймеханизм работы антивирусов. Для сомневающихся в сле-дующих статьях продолжим поиск. Успехов!

# sigtool -c "drweb" -f -f /home/sergej/work/xaf ↵↵↵↵↵-s "Win32.HLLP.Underscore.36864"

Win32.HLLP.Underscore.36864 (Clam)=

#sigtool --unpack-current daily.cvd

#cat xaf.sig >> viruses.db2#md5sum viruses.db2 > viruses.md5

Ðèñóíîê 1

Page 39: 016 Системный Администратор 03 2004

38

безопасность

В последнее время все больше людей, работающих всфере ИТ, задумываются о безопасности. Все же недав-ние вирусные эпидемии и постоянные взломы тех илииных сайтов поневоле привлекают к себе внимание. Всвязи с этим очень четко прослеживается тенденция ро-ста рынка услуг, тем или иным образом связанных с бе-зопасностью. Больше всего бросается в глаза разнооб-разие видов брандмауэров и антивирусных систем. Прак-тически каждое печатное и электронное издание, при-частное к ИТ-тематике, посчитало необходимым расска-зать либо о первом, либо о втором виде продуктов. Бла-годаря такому мощному потоку информации методыборьбы с внешними злоумышленниками всеми нами за-учены практически наизусть. Любой мало-мальски све-дущий в этом вопросе человек расскажет, что для защи-ты внутренней сети лучше всего вынести сервера, пре-доставляющие публичные сервисы, в демилитаризован-ные сети. А на всех шлюзах в корпоративную сеть и Ин-тернет в зависимости от денежных средств, выделенныхнам для этих целей, нужно обязательно поставить бран-дмауэр аппаратной или программной реализации. Ну ас вирусами мы будем бороться, проверяя, где возможно,потоки данных с помощью антивирусного программногообеспечения. Кроме описанных выше, существует ещенекоторое количество добавочных мероприятий, позво-

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

За всем этим валом правдивой, иногда не очень, абывает, и откровенно рекламной информации скрывает-ся один интересный факт – большинство описываемыхсредств предназначены для защиты от внешних злоумыш-ленников. На первый взгляд это естественно, но если по-дойти к вопросу без излишней спешки и проанализиро-вать доступные факты, то получится, что, в соответствиис последней статистикой, восемьдесят процентов инци-дентов происходят по вине людей, находящихся внутриохраняемой сети, и только двадцать процентов приходит-ся на внешние угрозы.

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

АНДРЕЙ БЕШКОВ

DEVICELOCK

Page 40: 016 Системный Администратор 03 2004

39№3(16), март 2004

безопасность

равно у обычного пользователя остается довольно боль-шой простор для злонамеренных действий, направленныхна локальную систему и системы, находящиеся рядом. Не-которые особо продвинутые реализации брандмауэров мо-гут менять свою схему действий в зависимости от даты ивремени. Такой подход, к примеру, помогает реализоватьполитики, при которых определенным IP-адресам разре-шено работать с теми или иными сервисами только побудним дням с 9 часов утра до 17 часов вечера. Основнаяпроблема подобного решения заключается в том, что наодном и том же компьютере могут работать одновремен-но или поочередно несколько пользователей, и большин-ство брандмауэров не обучены принимать в расчет этотфакт. Так что не стоит считать такой подход панацеей,спасающей от внутренних злоумышленников.

Сегодня я хотел бы рассказать о программе DeviceLock,созданной компанией SmartLine. Эта программа помога-ет решить часть проблем с безопасностью рабочих мести, таким образом, повысить общую защищенность сетиизнутри. К сожалению, многие пользователи имеют при-вычку приносить на свое рабочее место программы и дан-ные из посторонних источников. В этом случае никто неможет поручиться за отсутствие в них троянских программи вирусов. Самым простым способом, конечно, было быизъять все потенциально опасные устройства. Но я думаю,что руководство не одобрит тотального демонтированияCD-ROM, DVD, дисководов и прочих устройств, способ-ных переносить данные между компьютерами в обходлокальной сети. Да и большинство пользователей не оце-нит таких нововведений и запишет вас в черный списокзаклятых друзей. К тому же есть желание работать спо-койно, а не тратить все силы на войну с пользователями,поэтому нужно искать какой-то другой путь. Мне, как имногим другим администраторам, хотелось бы иметь воз-можность более аккуратно и гибко управлять доступомпользователей к устройствам, установленным в компью-тере, чем это позволяет делать административный интер-фейс, встроенный в Windows-системы. Также очень хо-чется, чтобы система безопасности автоматически меня-ла свои настройки в зависимости от даты и времени. Врешении именно таких проблем нам должен помочьDeviceLock. Судя по документации, поставляемой вместес программой, она может контролировать и разграничи-вать доступ пользователей к следующим устройствам:! Дисководы гибких дисков.! Магнито-оптические дисководы.! CD-ROM.! DVD.! ZIP.! Все виды устройств, подключаемых через USB.! Инфракрасный порт.! Устройства, подключаемые через FireWire.! Серийные или параллельные порты.! BlueTooth и WiFi-адаптеры .! Накопители на магнитных лентах.

Заинтересовавшись этой программой, я отправился насайт http://www.protect-me.com/ru/dl/download.html и скачал30 дневную пробную версию. От платной она ничем не

отличается, кроме временного ограничения и изредкапоявляющегося на экране напоминания с предложениемзарегистрироваться. Итак, дистрибутив размером в 1.6 Мббыл довольно быстро скачан. После чтения документации,которую можно взять на том же сайте, было выяснено, чтопрограмма предназначена для работы в системах WindowsNT/2000/XP/2003. Для машин, функционирующих под уп-равлением версий Windows 9x и Windows Millenium, тре-буется DeviceLock Millennium Edition. Для проведения тес-тов были выбраны две машины: одна с Windows 2000Professional, а вторая с Windows Server 2003. Пришло вре-мя пробовать, какова на вкус эта новинка. Инсталляцияпрошла легко и без каких-либо проблем. КомплектDeviceLock состоит из двух частей:! DeviceLock Service – сервис, предоставляющий интер-

фейс локального или удаленного управленияDeviceLock.

! DeviceLock Manager – программа, позволяющая сис-темному администратору управлять всем комплексом.

Поэтому стоит обратить внимание на один интересныймомент: если во время установки выбрать вариант«custom», то появится возможность поставить на машинутолько DeviceLock Service без DeviceLock Manager. Такимобразом, на пользовательских машинах можно расставитьтолько сервис, отвечающий за разграничение полномо-чий, а управлять всем этим хозяйством через сеть с по-мощью менеджера. Также доступен режим с автоматичес-кой локальной инсталляцией. Чтобы воспользоваться этойвозможностью, нужно положить в директорию с дистри-бутивом файл devicelock.ini и запустить программу уста-новки с ключом –s. Такой подход позволит поручить про-цедуру обхода пользовательских машин и установку про-граммы младшему администратору без риска, что он мо-жет случайно сделать что-то не так. Более подробно по-читать о том, каков формат файла devicelock.ini и что нуж-но в него записать, можно в прилагаемой к программе идоступной на сайте документации. Ну а для тех, кто умеетработать с Microsoft Systems Management Server (SMS),есть вариант автоматической установки программногообеспечения на целевые машины через сеть.

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

Page 41: 016 Системный Администратор 03 2004

40

безопасность

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

Первый запуск утилиты особых сюрпризов не приносит,так как интерфейс программы понятен и прост: слева –дерево машин, справа – список устройств.

Ну что же, давайте для начала запретим пользовате-лю «Петров» работать с CD-ROM в обеденный перерывпо будним дням и на весь день по субботам и воскресень-ям. Делается это просто: выбираем нужное устройство инажимаем на значок ключа с биркой. В ответ получаемдиалог с настройками безопасности для данного устрой-ства. Жмем кнопку «+ Add» и в появившемся списке вы-бираем нужных пользователей поодиночке или группами.

На следующем экране слева список групп и пользова-телей, для которых в наборе правил безопасности есть за-

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

Также обратите внимание на опцию «Allow eject» – сее помощью можно запретить пользователю выниматьдиск из CD-привода. Для устройств, на которые можно за-писывать данные, доступна опция «Allow Format», позво-ляющая запретить пользователю выполнять действия поформатированию устройства. Таким образом, можно за-щитить данные от случайного уничтожения не в меру лю-бопытными пользователями. Закончив раздавать права,можно посмотреть, как только что выставленный запретбудет выглядеть с точки зрения подопытного пользовате-ля. Говорим системе, что сегодня «Суббота», или уста-навливаем часы на обеденное время и пытаемся получитьдоступ к CD-ROM от имени пользователя «Петров».

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

Также, кроме всего прочего, хотелось бы отметить

Page 42: 016 Системный Администратор 03 2004

41№3(16), март 2004

безопасность

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

Наигравшись вдоволь с разными комбинациями правил,я решил проверить, насколько удобным будет применениеDeviceLock в масштабе предприятия. Часто случается так,что в организации есть некоторое количество машин, ко-торыми пользуется определенный круг работников, и всеони должны быть настроены примерно одинаково. Для ма-лой сети из нескольких машин описать все правила длявсех пользователей на каждом компьютере – процедуране особенно приятная, хотя ради обеспечения собственно-го дальнейшего спокойствия можно и потерпеть. В край-нем случае это неблагодарное занятие можно поручитьтому же младшему администратору. А вот в средних илибольших сетях такое мероприятие может превратиться впродолжительную пытку. И самое главное неудобство кро-ется в повседневном обслуживании такой системы. С те-чением времени одни люди увольняются, а других нанима-ют на освободившиеся должности. Неужели из-за этого при-дется удалять или модифицировать вручную на всех ком-пьютерах правила, касающиеся конкретного пользовате-ля? Вот тут-то на сцену выходит одна из самых мощныхспособностей DeviceLock, называемая batch permissions. Сее помощью мы за несколько минут решим эту проблему.Для того чтобы воспользоваться этой возможностью, жмемкнопку с изображением двух ключей или проходим черезменю File →→→→→ Batch Permission. В появившемся диалоге до-бавляем в список компьютеры, на которые нужно скопиро-вать создаваемые правила.

Стоит отметить, что список машин можно создать с по-мощью графического интерфейса или загрузить из пред-варительно созданного файла. Следующим шагом созда-ем список пользователей, на которых будут распростра-няться наши правила. Затем помечаем галочками нуж-ные устройства, настраиваем временные интервалы, раз-решения и прочие опции. Нажав кнопку «Set permissions»,наслаждаемся процессом. Обратите внимание на опцию«Install/Update Service», она очень полезна для нас, есливо время копирования правил на целевой машине будетнайдена устаревшая версия DeviceLock Service, то про-грамма выполнит всю черную работу за нас, и нужныйкомпонент будет обновлен до текущей версии.

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

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

В целом можно считать, что программа показалась мнедовольно приятным в обращении и полезным инструмен-том. Используя ее с умом, системный администратор смо-жет добавить в структуру безопасности предприятия удоб-ный в обращении, достаточно надежный и простой в об-служивании слой защиты. Надеюсь, короткий экскурс, пред-принятый мной с целью изучения и описания возможнос-тей DeviceLock, был вам интересен.

Page 43: 016 Системный Администратор 03 2004

42

безопасность

ТРИ ПОРОСЁНКА Snort:«НИФ-НИФ», «НУФ-НУФ» И «НАФ-НАФ».

ТРИ ПОРОСЁНКА Snort:«НИФ-НИФ», «НУФ-НУФ» И «НАФ-НАФ».

ПАВЕЛ ЗАКЛЯКОВ

НАСТРОЙКА НЕСКОЛЬКИХ СЕНСОРОВ SnortС ПОМОЩЬЮ SnortCenter

НАСТРОЙКА НЕСКОЛЬКИХ СЕНСОРОВ SnortС ПОМОЩЬЮ SnortCenter

Èëëþñòðàöèÿ Ì.ß.Ðóäà÷åíêî

Page 44: 016 Системный Администратор 03 2004

43№3(16), март 2004

безопасность

Прежде чем перейти к практическим вопросам использо-вания нескольких сенсоров на базе IDS Snort, рассмотримтеоретические аспекты этой задачи. Для этого оценим труд-ности, возникающие при различных способах реализации,и создадим модель, по большей части лишённую замечен-ных недостатков.

«Одна голова хорошо, а две лучше», – подумал змейГорыныч, убегая от Ильи Муромца. Так и в вопросах обна-ружения атак: информация лишней не бывает, больше сен-соров – меньше вероятность пропуска атаки. Конечно, эф-фективность подключения новых сенсоров, начиная с не-которого числа, не даст такого прироста эффективности,как вначале, но это уже другой вопрос.

При использовании нескольких сенсоров наиболееудобным способом ведения логов будет использованиеодной или нескольких БД. Подробнее об этом можно про-читать в [4]. Задача заставить два сенсора вносить своизаписи в одну БД не представляет из себя никакой слож-ности. Об этом не было рассказано ранее, но можно дога-даться, что необходимо в третьей секции конфигурацион-ного файла snort.conf, отвечающей за вывод данных, про-писать всего лишь в одной строчке другое имя хоста сБД, номер порта, логин и пароль. Далее, если доступ к БДне закрыт каким-нибудь пакетным фильтром или МЭ попути, то никаких проблем быть не должно. Даже ACID бу-дет исправно показывать статистику от двух и более сен-соров. Работа такой системы только на первый взгляд ка-жется прозрачной и беспроблемной. По мере увеличениявремени эксплуатации системы неизбежно возникнут раз-личные вопросы. Вот некоторые из них, которые видноневооружённым глазом сразу до начала эксплуатации:! Обновления сигнатурной БД, в нашем примере это

правила, по которым обнаруживаются атаки.! Совместный анализ данных. Данные в БД заносятся

из разных мест, а при анализе этот факт никак не учи-тывается.

! Доверенность сенсоров и устойчивость самой систе-мы обнаружения атак к атакам на неё.

! Контроль за сенсорами.

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

Давайте остановимся и частично рассмотрим пробле-мы и пути решения первого вопроса.

При отсутствии каких-либо целенаправленных решенийпоставленный вопрос решается неудобно, но просто. Ад-министратор подключается к компьютеру стандартнымисредствами администрирования, например, с помощью sshили telnet. Руками вносит изменения в конфигурационныйфайл и перезапускает snort. Потом подключается к друго-му хосту, где установлен другой сенсор и повторяет опера-цию. Согласитесь, что при большом количестве узлов си-туация не очень удобная. Поэтому администратор, чтобыизбавить себя от подобной рутинной работы, один раз ав-томатизирует процесс – пишет скрипт на bash, который пе-риодически запускается через cron, скачивает c помощьюwget новые правила с сайта www.snort.org и устанавливает

их в систему. Благо правила всё время находятся в одноми том же месте на сайте, а имя файла с последними прави-лами остаётся неизменным. Либо http://www.snort.org/dl/rules/snortrules-stable.tar.gz (* см.ниже) – стабильная ветка,либо http://www.snort.org/dl/rules/snortrules-current.tar.gz (* см.ниже) – активно развивающаяся. Во время процесса уста-новки в систему правила разархивируются, распаковыва-ются, возможно, как-то проверяются, помещаются на мес-то старых правил, в конфигурационный файл, возможно,вносятся изменения и происходит перезапуск демона snort,чтобы внесённые изменения вступили в силу.

Таким образом, система работает с завидной стабиль-ностью, присущей Linux/*BSD, некоторое, возможно, и про-должительное время. Позже планомерно появляются но-вые хосты с сенсорами, меняются правила и происходятдругие мелкие события. В общем, всё работает.

Но вот наступает тот самый момент, когда в алгоритмеработы системы наступает сбой либо вероятность его воз-никновения велика. Нет, это не правила неверно скачались.И не изменилось их местоположение, хотя и такое частень-ко бывает. По этой причине вверху у ссылок стоят звёздоч-ки, ссылки уже не действительны. Так, недавно обновилисьадреса и форматы правил для Snort после выхода версии2.1.1-RC1 из серии 2.1.x. Сейчас для разных серий надоскачивать разные правила, в результате имеем следующиереальные ссылки для скачивания:! ht tp://www.snort.org/dl/rules/snortrules-snapshot-

CURRENT.tar.gz! http://www.snort.org/dl/rules/snortrules-snapshot-2_1.tar.gz! http://www.snort.org/dl/rules/snortrules-snapshot-2_0.tar.gz

Старые же правила переехали в поддиректорию: http://www.snort.org/dl/rules/old. При этом на сайте даже нет мяг-ких ссылок для обратной совместимости на новое место-положение старых правил. При попытке загрузить файлыпо ссылкам выше со звёздочками выдаётся ошибка о том,что нет таких файлов.

В ситуации выше будем считать, что система проверкиправил их не установила и послала письмо-уведомление ад-министратору о возникшей ошибке. Это будет не у всех, по-добную обратную связь каждому придётся налаживать вруч-ную. Но что же произошло, если даже и не система отказалаиз-за сбоев в электропитании? А просто в самой IDS Snortнашли очередную ошибку, например, для временного реше-ния которой необходимо отключение того или иного препро-цессора в системе обработки трафика. То есть просто-на-просто надо внести изменения в конфигурационные файлы,например, закомментировать одну строчку. И вот ситуацияповторяется, администратор залезает и вручную правит пра-вила на каждом из сенсоров. А тут ситуация усугубляетсятем, что раньше он работал один, а к моменту сбоя штатыразрослись, и администраторов стало много. Так что для ус-тановки всего лишь одного знака комментария необходимовсем знать пароль суперпользователя и прочие неудобства.

Какой же может быть выход? Наиболее оптимальнымрешением для данного случая было бы использование не-кой единой конфигурационной БД с правилами для всех сен-соров. Удобно, когда все правила в одном месте, соответ-ственно, для внесения изменений уже требуются права толь-

Page 45: 016 Системный Администратор 03 2004

44

безопасность

ко на доступ к конфигурационной БД с правилами, то естьнет того случая, когда выдаются излишние права и пользо-ватель может сильно повредить работоспособность систе-мы. Всё, казалось бы, хорошо, но только за любое удобствоприходится чем-то расплачиваться. В данном случае нам при-дётся решать проблемы связи сенсоров с центральной кон-фигурационной БД. Проблем здесь не меньше, а именно:! выбор того, кто с кем будет связываться: база данных

с сенсорами или сенсоры с БД;! защита от пассивных атак (прослушивание трафика);! защита от активных атак, подмена правил и пр.

На наше счастье, нет необходимости придумывать дан-ную систему с нуля, так как уже имеется пакет SnortCenter[1], изучением и настройкой которого мы займёмся далее.

КороткоОсновная идея SnortCenter – упростить конфигурирование(в том числе обновление правил) и диагностику работос-пособности большого числа сенсоров. При необходимостимогут конфигурироваться сенсоры на базе Windows NTплатформы. Под диагностикой понимается информация отом, запущен и работает демон Snort или нет. Анализом исбором данных SnortCenter не занимается, поэтому всё, чтобыло рассказано в [4] о внесении записей сенсорами в еди-ную БД и о том, как эту БД просматривать, нам пригодится.SnortCenter – это не зависимое от средств анализа реше-ние, скорее – дополняющее его. Для удобства пользовате-лей имеется SnortCenter ACID Plugin, позволяющий краси-во интегрировать веб-интерфейсы SnortCenter и ACID.

Из чего состоит SnortCenter?1. Из управляющей консоли SnortCenter Management Con-

sole – программы, написанной на PHP и осуществляю-щей взаимодействие:! с сенсорами посредством агентов;! с правилами посредством БД;! с пользователем посредством веб-интерфейса.

2. Из агентов SnortCenter Sensor Agents, запускаемых накомпьютерах-сенсорах с установленным Snort. Агенты –это автономные (не требуют наличия веб-сервера) CGI-программы на Perl, которые позволяют пользователюили SnortCenter Management Console через веб-интер-фейс взаимодействовать со Snort и его файлами кон-фигурации. Для защиты соединений от прослушиванияиспользуется SSL-библиотека для perl SSLeay [5].

Если попытаться наглядно представить работу даннойсистемы, должна получиться примерно следующая схема(см. рис. 1). Данная система не является безопасной с точ-ки зрения атак на неё и поэтому требует использованиядополнительных средств. Наиболее простым и эффектив-ным средством снижения опасности атак на систему мо-жет быть использование пакетных фильтров (на схеме онине изображены), например, iptables. В этом случае можноизбежать большинства атак, осуществляемых без подме-ны IP-адреса. Несколько подробнее о вышеописанномспособе и его недостатках написано далее.

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

Ðèñóíîê 1. Íàãëÿäíàÿ ñõåìà âçàèìîäåéñòâèÿ ñåíñîðîâ ñ öåíòðîì

Page 46: 016 Системный Администратор 03 2004

45№3(16), март 2004

безопасность

подходит или данная реализация всё же лучше, чем её от-сутствие, то давайте приступим к её установке и настройке.

Установка SnortВыберем три узла, которые будут сенсорами, назовём их,например, «Ниф-Ниф», «Нуф-Нуф» и «Наф-Наф» и попро-буем создать схему, аналогичную приведённой выше, дляэтого, как и ранее, нам потребуется скачать и установитьSnort с поддержкой ведения логов в БД (подробнее см. [4])на каждый из узлов-сенсоров. Те, у кого Snort уже уста-новлен, могут пропустить несколько шагов, со всеми ос-тальными скачиваем последнюю версию Snort:

Сравниваем значение хеша выданного командами:

Распаковываем содержимое архива snort-2.1.1.tar.gzкуда-нибудь, например, в уже имеющуюся директорию /progi:

После заходим в /progi/snort-2.1.1:

и запускаем конфигурирование с опцией --with-mysql, незабыв о том, что для осуществления этого шага нам необ-ходимо, чтобы в системе уже стояла библиотека libpcap,например, licpcap-0.6.2-12, и часть файлов от MySQL, в час-тности пакеты mysql-3.23.58-1.73 и mysql-devel-3.23.58-1.73.Подробнее см. [4].

Замечание. В процессе обновления Snort на одном изсенсоров с версии 2.0.4 до версии 2.1.1 во время запускакоманды конфигурации новой версии выдалась следующаяошибка об отсутствии библиотеки pcre (Perl CompatibleRegular Expressions [9]).

В то время как на другом компьютере конфигурация про-шла без проблем. Первая мысль, что пришла в голову –поискать на нём файл pcre.h, запустив:

В результате поиска были получены две строки:

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

которая и сообщила, что нужный нам пакет – это pcre-devel-3.9-2, который успешно нашёлся на втором дискеRedHat 7.3 и был установлен командой:

после чего конфигурирование, запущенное повторно, про-шло без проблем.

После конфигурирования необходимо скомпилироватьSnort командой:

И установить командой:

В процессе установки, если вы не задавали дополни-тельных ключей, у вас будет установлено всего лишь 2файла: /usr/local/bin/snort – сама программа и man-стра-ница к ней /usr/local/man/man8/snort.8. Далее следует со-здать директорию /etc/snort, если вы ставите Snort на дан-ный компьютер в первый раз, или удалить все файлы иподдиректории оттуда, если они у вас остались от преды-дущих версий. То же самое следует сделать с директори-ей /var/log/snort. В целом нам эта директория не понадо-бится, но если вдруг не получится вести логи в БД, то онаможет нам пригодиться в процессе отладки.

Аналогичным образом следует установить Snort на всебудущие сенсоры.

Следующим шагом мы осуществим установку агентов(SnortSensor Agent) на наши сенсоры. После того как мыубедимся, что они работают, мы установим и настроимконсоль управления SnortSensor (SnortCenter ManagementConsole), через которую загрузим на все сенсоры их фай-лы конфигурации и осуществим дополнительную отладкуагентов, если это понадобится.

Установка SnortSensor AgentПеред установкой агента скачиваем необходимый для егоработы модуль для perl Net::SSLeay [5]. (Если модуля нет –не будет поддерживаться закрытое SSL-соединение сагентом.)

# wget http://www.snort.org/dl/snort-2.1.1.tar.gz# wget http://www.snort.org/dl/snort-2.1.1.tar.gz.md5

# cat snort-2.1.1.tar.gz.md5# md5sum snort-2.1.1-RC1.tar.gz

# tar -zxvf snort-2.1.1.tar.gz -C /progi

# cd /progi/snort-2.1.1

# ./configure --with-mysql

# find / -name pcre.h

/usr/include/pcre/pcre.h/progi/snort/snort-2.1.1/src/win32/WIN32-Includes/pcre.h

# rpm -qf /usr/include/pcre/pcre.h

# rpm -ihv pcre-devel-3.9-2.i386.rpm

# make

# make install

Page 47: 016 Системный Администратор 03 2004

46

безопасность

Распаковываем содержимое архива Net_SSLeay.pm-1.21.tar.gz куда-нибудь, например, в уже имеющуюся ди-ректорию /progi:

После заходим в появившуюся директорию по имении номеру версии модуля:

и запускаем

либо

Запущенный perl-скрипт проверяет наличие в системеOpenSSL и его версию, создаёт необходимые для дальней-шей установки Makefile файлы. OpenSSL необходим длянормальный работы Net_SSLeay. В случае необходимостивыдаются рекомендации по обновлению версии.

Замечание 1. Следует отметить, что не всегда лучшеиметь самый последний номер того или иного пакета, в каж-дом конкретном случае следует разбираться отдельно. Так,например, тот же Red Hat очень любит выпускать исправле-ния к старым версиям. В результате получается, что номерверсии пакета остаётся старый, а ошибок в пакете уже нет.

Замечание 2. Для компиляции модуля Net_SSLeay не-обходимо, чтобы также был установлен пакет openssl-devel,хотя его наличие не проверяется. Сделать это можно, на-пример, командой:

Если пакет openssl-devel у вас не будет установлен, тов процессе компиляции вы получите следующую ошибку:

Для компиляции запускаем:

После успешной компиляции запускаем:

для установки модулей и man к ним. Для того чтобы убе-

диться, что модуль SSL установился правильно, запустите:

Если не будет никаких сообщений об ошибках, то этозначит, что SSL-модуль установился правильно.

После того как модули установлены, можно приступитьк непосредственной установке SnortSensor Agent. Для это-го скачиваем последнюю версию из [2].

Скорее всего версия у вас будет та же самая, так какуже более года не обновляются новости и не выпускают-ся новые версии. В процессе отладки продукта мы встре-тимся с некоторыми проблемами, часть которых попро-буем решить своими силами. К сожалению, попыткисвязаться с автором («Stefan Dens» <[email protected]>),чтобы скоординировать усилия и, возможно, способ-ствовать выходу новой версии без замеченных недо-статков, не привели к успеху. На форуме от Snort воп-росами SnortCenter не интересуются. В российской час-ти, например на sysadmins.ru, поиск чего-нибудь по клю-чевому слову snortcenter абсолютно бесполезен. Можноконстатировать, что проект «не отполирован до конца».Несмотря на подобное равнодушие к нему, в нём можнонайти некоторые полезные свойства, о которых можнопрочитать ниже.

После скачивания архив необходимо куда-нибудь рас-паковать, например в /progi:

После запуска команды следует зайти в появившуюсядиректорию /progi/sensor:

Далее следует запустить скрипт setup.sh для конфигу-рации сенсора посредством ответов на вопросы:

Появится следующая картинка (см. рис. 2, 3).На запрос «Config file directory» вместо /progi/sensor/

conf следует указать /etc/snort / – то место, где будут рас-полагаться и куда будут записываться конфигурационныефайлы, необходимые для запуска Snort.

На запрос «Log file directory» вместо /progi/sensor/logследует указать /var/log/snort – это место, куда будут вес-тись логи.

На запрос расположения интерпретатора Perl «Full pathto perl» нажмите просто {ENTER}, если вы не меняли егоместорасположение и имя на отличные от приведённыхпо умолчанию /usr/bin/perl.

То же самое и по поводу Snort – нажмите просто {ENTER}.На запрос о пути к правилам Snort «Snort Rule config

file directory» введите /etc/snort вместо предлагаемых /progi/sensor/rules/.

# wget http://symlabs.com/Net_SSLeay/Net_SSLeay.pm-1.21.tar.gz

# tar -zxvf Net_SSLeay.pm-1.21.tar.gz -C /progi

# cd /progi/Net_SSLeay.pm-1.21

# perl Makefile.PL

# ./Makefile.PL

# rpm -ihv openssl-devel-0.9.6b-35.7.i386.rpm

# make

# make install

# perl -e 'use Net::SSLeay'

# wget http://users.pandora.be/larc/download/ ↵↵↵↵↵snortcenter-agent-v1.0-RC1.tar.gz

# tar -zxvf snortcenter-agent-v1.0-RC1.tar.gz -C /progi

# cd /progi/sensor

# ./setup.sh

Page 48: 016 Системный Администратор 03 2004

47№3(16), март 2004

безопасность

Ðèñóíîê 2. Êîíôèãóðèðîâàíèå ïîñðåäñòâîì îòâåòîâ íà âîïðîñû setup.sh

Page 49: 016 Системный Администратор 03 2004

48

безопасность

Замечание. Несмотря на то что в предыдущих настрой-ках мы располагали правила в /etc/snort/rules, сейчас, ис-ходя из соображений удобства, мы этого делать не будем.

Далее задаются вопросы, необходимые для настрой-ки собственного веб-сервера.

Уточняется порт, на котором будет веб-сервер агента«Sensor port», лучше всего его оставить без изменений,если у вас нет других соображений на этот счёт, нажав{ENTER}. (По умолчанию 2525).

Далее спрашивается, какой IP-адрес следует прослу-шивать. Это нужно на тот случай, если у вас несколько IP-адресов на одном интерфейсе или более сложная схема.По умолчанию следует оставить «any», и тогда будут про-слушиваться только те адреса, которые связаны с конк-ретным интерфейсом. Это первое неудобство агентов, чтоих следует привязывать к интерфейсам. Это не самоестрашное неудобство, и об этом мы поговорим чуть ниже.Пока же на запрос «If this host has multiple IP addresses,the server can be configured to listen on only one address(default any):» нажмём просто {ENTER}.

Далее программа настройки запрашивает логинпользователя, которому будет разрешено в дальнейшемподключаться к веб-серверу. Для начала на запрос «Loginname (default admin)» можно нажать просто {ENTER}, од-нако если вы хотите несколько повысить защищённость,то придумайте своё имя, которое вам придётся соответ-ственно заменить и в других местах самостоятельно, гдеэто понадобится.

Замечание. Реальные пользователи в системе не за-водятся. Заведённые пользователи с хэшами от паролейнаходятся в /etc/snort/sensor.users. В силу особенностейреализации не используйте символы «:» и «@» в логине ипароле во избежание ошибок.

На запросы «Login password:» и «Password again:» при-думайте и введите два раза пароль: ваш_пароль№7 длядоступа вышеобозначенного пользователя к веб-серверу.Будьте внимательны, во время ввода пароля в соответ-ствии с одним из требований безопасности System V звёз-дочки вместо вводимых символов не отображаются. В слу-чае несовпадения паролей программа выдаст ошибку:

и необходимо будет запустить конфигурацию ещё раз:

и ответить на вышеописанные вопросы заново. Послеудачного ввода пароля появится вопрос, как называетсяхост, на котором установлен сенсор. «Sensor host name(default %имя_вашего_хоста%):» Можно оставить то имя,что указано по умолчанию, нажав {ENTER}, а можно на-писать что-то новое, вроде Nif-Nif или Nuf-Nuf, чтобы как-то различать сенсоры в дальнейшем.

На вопрос об использовании SSL отвечаем «y» и жмём{ENTER}.

Далее нас спрашивают о диапазоне IP-адресов, с ко-

# ./setup.sh

Ðèñóíîê 3. Êîíôèãóðèðîâàíèå ïîñðåäñòâîì îòâåòîâ íà âîïðîñû setup.sh (ïðîäîëæåíèå)

Page 50: 016 Системный Администратор 03 2004

49№3(16), март 2004

безопасность

торых можно будет осуществлять доступ к агенту. Это до-полнительная мера защиты, используемая в добавлениек авторизации. При необходимости всё то же самое бо-лее гибко можно сделать с помощью какого-нибудь па-кетного фильтра, вроде iptables, однако одно другому немешает и на запрос «Allowed IP addresses» лучше ввестиIP-адрес или имя центра управления сенсорами. При не-обходимости ввести несколько адресов разделяйте ихпробелами, следуя выведенной подсказке.

Следующим будет вопрос о том, следует ли запускатьагента автоматически при загрузке системы «Start Sensorat boot time (y/n):», то есть необходимо ли создать соответ-ствующие файлы в /etc/rc.d/... Отвечаем на этот вопрос «y»и жмём {ENTER}, в противном случае нам придётся каж-дый раз после перезагрузки системы по тем или иным при-чинам запускать агентов руками, что может быть не оченьудобно. После ответа на все вопросы осуществляется за-пуск агента, и фактически он уже готов работать.

В директории /etc/snort у вас появится 11 файлов и 2директории с необходимыми файлами для работы агента(см. рис. 4). В частности, будут созданы файлы для запус-ка, остановки и деинсталляции, так что совсем не обяза-тельно запускать и останавливать работу агента через /etc/rc.d/init.d/sensor.

Запустив:

можно убедиться, что агент запущен и работает. Если на ком-пьютере будущего центра имеется веб-браузер или вы захо-дите с другого компьютера, указанного в списке разрешён-ных для доступа к веб-серверу, и правила пакетного фильтрапозволяют проходить пакетам, то вы можете запустить брау-зер и подключиться к агенту через защищённый веб-интерфейс,набрав просто адрес «https://адрес_агента:2525». Проверитьработу агента таким образом желательно, чтобы не искать пос-ле ошибку, потратив большее количество времени.

Если вы не позаботились ранее о возможности подклю-чения к агенту с других хостов, хотя бы на время настройкисистемы, то, возможно, вам потребуется дописать разреше-ние на нужный вам хост в файле /etc/snort/miniserv.conf че-рез пробел после того, что написано у параметра «allow=».Удалить лишние разрешённые хосты можно там же.

Для разрешения прохождения пакетов через пакетныйфильтр iptables, настроенный на политику запрета по умол-чанию, следует указать два следующих правила:

Переменные $REMOTE_IP и $SENSOR_IP следует заме-нить нужными значениями. Данные правила не учитываютнаправления установления соединения, но при необходимо-сти их можно подправить, ещё больше «закрутив гайки».

После захода на веб-страничку агента будет запрошенлогин и пароль. И выдастся следующая картинка:

Нам этого вполне достаточно, пытаться что-то запус-тить на данный момент есть бессмысленное занятие, таккак у нас ещё нет конфигурационного файла, с которымбы следовало запускать Snort. Аналогичным образом ус-танавливаются и проверяются SnortSensor Agent на дру-гих узлах.

Для того чтобы создать необходимые конфигурацион-ные файлы и запустить Snort, нам необходимо теперь за-няться центром управления, для этого установить на негонепосредственно консоль управления, так называемуюSnortSensor Management Console, и настроить её на со-вместную работу с БД правил и сенсорами, далее необ-ходимо создать правила для сенсоров, передать их наузлы. После этого на узлах-сенсорах будут созданы соот-ветствующие им файлы конфигурации, и можно будет по-пытаться запустить Snort.

Установка и настройка консоли управленияSnortSensor Management ConsoleПо идее, центр управления лучше установить на отдель-ном компьютере, но так как на сам центр могут также со-вершаться атаки, то лучше и на нём установить сенсордля их обнаружения. В результате получится конфигура-ция, когда центральная консоль управления устанавлива-ется на одном из сенсоров.

Для начала установки скачиваем из [2] последнюю вер-сию SnortSensor Management Console, способную работатьсо Snort v.2.x.

Далее распаковываем содержимое архива туда, где на-ходятся файлы веб-сервера, например, в директорию /var/www/html:

Далее, чтобы не запутаться, распаковавшуюся только

# iptables -I INPUT -p tcp -s $REMOTE_IP --sport 1024:65535 ↵↵↵↵↵-d $SENSOR_IP --dport 2525 -j ACCEPT

# iptables -I OUTPUT -p tcp -s $SENSOR_IP --sport 2525 ↵↵↵↵↵-d $REMOTE_IP --dport 1024:65535 -j ACCEPT

Ðèñóíîê 4. Âèä äèðåêòîðèè /etc/snort ïîñëå óñòàíîâêèSnortSensor Agent

# /etc/rc.d/init.d/sensor status

# wget http://users.pandora.be/larc/download/ ↵↵↵↵↵snortcenter-v1.0-RC1.tar.gz

# tar -zxvf snortcenter-v1.0-RC1.tar.gz -C /var/www/html

Page 51: 016 Системный Администратор 03 2004

50

безопасность

что директорию /var/www/html/www переименуем в /var/www/html/snortcenter:

Затем нам необходимо отредактировать файл config.php,для этого либо запускаем:

либо жмём F4 на нужном файле в mc (midnight commander).Если у вас не установлен mc, то редактируем файл с по-мощью vi:

Предполагается, что на центральном компьютере ужеустановлен ACID и все необходимые для его работы ком-поненты, в частности php, php-mysql и ADODB – абстракт-ный класс доступа к базам данных, написанный на PHP [7].Подробнее об установке ACID см. [4].

В процессе редактирования конфигурационного файланеобходимо правильно определить следующие переменные:! $DBlib_path – переменная отвечает за путь к ADODB,

если следовать установке, описанной в [4], то вместо$DBlib_path = «./adodb/»; следует написать $DBlib_path =«../adodb/»;

! $DBtype – переменная, отвечающая за тип БД, так какмы работаем пока только с БД MySQL, то и оставим еёбез изменения: $DBtype = «mysql»;

! $DB_dbname – переменная, определяющая имя БД, вкоторой находятся все правила наших сенсоров, прижелании имя для БД можно сменить, но тогда и далее,когда мы будем создавать эту БД, придётся ей указатьдругое имя. Поэтому оставляем это значение без из-менения $DB_dbname = «snortcenter»;

! $DB_host – переменная, определяющая имя (адрес) хос-та, на котором стоит БД с правилами. При желании БДможет располагаться не обязательно на том же хосте,где находится SnortSensor Management Console. В слу-чае если хосты будут разными, то помимо удобств этодобавит проблем, а именно необходимо будет дополни-тельно осуществлять защиту соединений от прослуши-вания и навязывания информации между БД и управля-ющей консолью. В нашем случае хосты совпадают, по-этому оставляем без изменений: $DB_host = «localhost»;

! $DB_user – переменная, определяющая, от имени како-го пользователя следует подключаться к базе данных сименем $DB_dbname. По умолчанию в программе пред-полагается использование имени root – суперпользова-теля БД MySQL. Если оставить эту переменную без из-менений, то в качестве пароля в следующей перемен-ной придётся задать ваш_пароль№2 см. [4]. В принци-пе это не очень хорошо, так как SnortCenter ManagementConsole получит излишние права над всеми БД, хотя ейвсего лишь достаточно прав на одну лишь БД snortcenter($DB_dbname). Для того чтобы лишний раз не риско-вать, в качестве $DB_user мы напишем пользователяsnortcenteruser $DB_user = «snortcenteruser»; а потом со-здадим такого пользователя в БД MySQL.

# mv /var/www/html/www /var/www/html/snortcenter

# mcedit /var/www/html/snortcenter/config.php

# vi /var/www/html/snortcenter/config.php

Page 52: 016 Системный Администратор 03 2004

51№3(16), март 2004

безопасность

! $DB_password – переменная, определяющая парольпользователя БД $DB_user. Если ранее вы оставилипользователя root, запишите ваш_пароль№2, в про-тивном случае необходимо придумать ваш_пароль№6и записать: $DB_password = «ваш_пароль№6»;

! $DB_port – переменная определяет порт, на которомработает БД и к которому следует подключаться. Поумолчанию в БД MySQL используется порт 3306, есливы его не меняли, то оставьте значение этой перемен-ной пустым, будет использоваться именно этот порт.

! $hidden_key_num – в эту переменную необходимо запи-сать придуманное вами случайное число. Данное случай-ное число используется в дальнейшем в системе аутен-тификации для шифрования значений, хранящихся вcookies. Насколько я понимаю, в системе применяетсянекоторая нормализующая функция перед использова-нием числа, поэтому его разрядность не имеет большогозначения, так что можно записать хоть «5235763723333».На счёт оптимального числа разрядов в случайном чис-ле сказать что-либо обоснованное мне сложно.

! $snortrules_url – данная переменная определяет URLфайла, из которого будут браться «новые» правила. Дан-ный файл будет скачиваться при выборе в дальнейшемпункта меню «обновление через Интернет». Если бы неменялся формат правил, то данную переменную следо-вало бы оставить без изменения, но так как для новыхверсий Snort нужны правила в новом формате, то еслиеё не поменять, то обновление работать не будет в свя-зи с тем, что новые правила лежат в новом файле, по-этому вместо $snortrules_url = «http://www.snort.org/dl/rules/snortrules-stable.tar.gz»; пишем $snortrules_url =«http://www.snort.org/dl/rules/snortrules-snapshot-2_1.tar.gz». Если вас не устраивает обновление черезИнтернет, например, по соображениям безопасности, тонекоторые рекомендации вы встретите ниже.

! $max_lines – данная переменная отвечает за число пра-вил, помещающихся на одной странице, естественно, прималеньком значении переменной большое число правилведёт к большому числу страниц, что неудобно. Лучшеувеличить это значение, но если канал связи медленный,то делать число правил на странице большим не следу-ет. Однако удобнее вначале сделать его большим, акти-вировать все правила, а после придать параметру какое-нибудь разумное значение, например, $max_lines = 50вместо установленных по умолчанию $max_lines = 12.

В конфигурационном файле встречаются и другие пе-ременные, но для нас они менее существенны, поэтомумы их не рассматриваем. Подробнее обо всех перемен-ных см. [8].

После того как управляющая консоль SnortCenter на-строена, нам необходимо:! создать БД snortcenter;! создать пользователя snortcenteruser;! задать пароль ваш_пароль№6 этому пользователю;! задать необходимые права данному пользователю для

доступа к его БД.Для этого подключаемся к БД MySQL от имени супер-

пользователя этой БД.

На запрос пароля вводим ваш_пароль№2 (см. [4]). Да-лее даём команды:

Третью и пятую команды можно не давать, если у васБД и управляющая консоль стоят на одном компьютере.В результате должно получиться нечто следующее:

Далее начинается всё самое интересное, а именно, ви-зуальная настройка через веб-интерфейс. Для этого захо-дим через любой графический браузер на адрес нашегоцентра, где установлена управляющая консоль SnortCenter(http://адрес_SnortCenter/snortcenter/, а лучше, если ваш веб-сервер поддерживает защищённое соединение https://адрес_SnortCenter/snortcenter/).

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

из которой мы можем узнать логин и пароль для доступак SnortSensor Management Console в дальнейшем.

Если подождать некоторое время либо набрать вышеука-занный URL повторно, то мы попадём на страничку, где будутспрашиваться вышеуказанные login и password. В дальней-шем мы сменим пароль на другой, а пока вводим «change».

После входа нам необходимо записать в БД новыеправила, обычно для этого рекомендуется зайти в менюAdmin →→→→→ Import/Update rules →→→→→ Update from Internet.

# mysql -u root -p

mysql> CREATE DATABASE snortcenter;mysql> grant CREATE,INSERT,SELECT,DELETE,UPDATE ↵↵↵↵↵

on snortcenter.* to snortcenteruser@localhost;mysql> grant CREATE,INSERT,SELECT,DELETE,UPDATE ↵↵↵↵↵

on snortcenter.* to snortcenteruser;mysql> set password for ↵↵↵↵↵

'snortcenteruser'@'localhost'=password('âàø_ïàðîëü¹6');mysql> set password for ↵↵↵↵↵

'snortcenteruser'@'%'=password('âàø_ïàðîëü¹6');mysql> exit

Page 53: 016 Системный Администратор 03 2004

52

безопасность

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

Выходов из этой ситуации два. Первый – скачать прави-ла вручную, проверить и загрузить их на доверенный веб-сервер в том виде, как они были изначально. После подпра-вить $snortrules_url в config.php и, возможно, дописать паруразрешающих правил для iptables и проследовать указани-

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

проверить, создать из них единый текстовый файл. Послеиспользовать этот текстовый файл для записи правил в БДлибо путём копирования всего его содержимого в соответ-ствующую загрузочную область веб-формы (Admin →→→→→Import/Update Rules →→→→→ Copy & Paste), либо путём обычнойзагрузки файла на сервер (Admin →→→→→ Import/Update Rules →→→→→Upload file). Для второго необходимо включить в php под-держку загрузки файлов на сервер.

Замечание. После выхода очередной версии Snort се-рии 2.1.x при попытке загрузить новые правила мной былаобнаружена несовместимость правил от Snort 2.1.x соSnortCenter. Возникла следующая ошибка в процессе заг-рузки (см. рис. 5).

Покопавшись в PHP-файлах SnortCenter, я раскоммен-тировал 293-ю строку:

//echo "$sql<BR>";

Ðèñóíîê 5. Îøèáêà â ïðîöåññå çàãðóçêè

Ðèñóíîê 6. Îøèáêà, ñòðîêà äà¸ò ïîíÿòü ïðè÷èíó îøèáêè

Page 54: 016 Системный Администратор 03 2004

53№3(16), март 2004

безопасность

которая находится перед:

В результате была получена следующая картинка пос-ле запуска (см. рис. 6).

После этого, глядя на «global \», возникла мысль, чтопроблема, скорее всего, связана с переносом длинныхстрок в файлах конфигурации. В разборщике правил дляSnortCenter, видимо, забыли учесть, что, начиная со Snortv.1.8, правила не обязательно должны писаться в одну

строчку, и что теперь они могут переноситься с помощьюуказания обратного слеша «\» в конце строки.

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

Создадим файл /var/www/html/snortcenter/convert_ru-les.pl следующего содержания:

$result = $db->acidExecute($sql);$result_a = $db->acidExecute("SELECT max(id) FROM preprocessor");$myrow = $result_a->acidFetchRow();$update_rule_count[1] = 'add-spp';$update_rule_count[2] = $myrow[0];

Ðèñóíîê 7. Ôðàãìåíò îêíà áðàóçåðà ïîñëå óñïåøíîé çàãðóçêè ïðàâèë

#!/usr/bin/perlwhile ($temp=<STDIN>){if ($temp=~/^[^#].*\\\n$/) { chomp $temp; chop $temp; }print $temp;}

Page 55: 016 Системный Администратор 03 2004

54

безопасность

Не забудем придать атрибут запускаемости этому файлу.

При желании скрипт можно сократить, но тогда он бу-дет менее наглядным. Скрипт делает следующее: читаетпострочно стандартный поток ввода и помещает прочи-танное в переменную $temp.

Далее эта переменная проверяется на наличие в концестроки обратного слеша и что эта строка не есть коммента-рий. Если обратный слеш есть и строка не начинается сознака «#» (какой смысл переносить комментарии), то осу-ществляется отрезание от строки символа её конца и обрат-

ного слеша, что приводит к тому, что последующая строкакак бы приклеивается к текущей в общем потоке символов.

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

Для этого вносим изменения в строки 74 и 78 файлаdb_pars.php, отвечающие за загрузку правил с веб-сервера.Вносить изменения в файлы, загружаемые вручную так-же желательно, но не обязательно, так как в этом случаевы всегда имеете возможность их подправить, придав имнужный вид. Поэтому исправления будут только в двух ме-стах, а не в большем количестве мест.

Вместо:

Ðèñóíîê 8. Ïðàâèëà â ÁÄ, óáåäèìñÿ, ÷òî îíè åñòü

Ðèñóíîê 9. Äîáàâëåíèå ñåíñîðà

# chmod +x convert_rules.pl

Page 56: 016 Системный Администратор 03 2004

55№3(16), март 2004

безопасность

и

пишем

и

После этого правила успешно загружаются, уже не вы-давая сообщения об ошибке. В окошке браузера у вас по-явится примерно следующая картинка (см. рис. 7).

Как видно, во время разгрузки правил выдаются пре-дупреждения о неизвестности некоторых полей с коммен-тариями: Unknown Rule option: msg:«....», однако на рабо-тоспособность snort это не влияет. После загрузки пра-вил можно убедиться, что они оказались в БД snortcenter,для этого выбираем Resources →→→→→ Rules →→→→→ View Rules инаблюдаем правила (см. рис. 8).

Аналогичным образом можно просмотреть переменные(Resources →→→→→ Variables →→→→→ View Variables), препроцессоры(Resources →→→→→ Preprocessors →→→→→ View Preprocessors) и дру-гую информацию. Для просмотра не обязательно исполь-зовать средства SnortCenter, можно воспользоватьсяphpMyAdmin или напрямую использовать клиент mysql [4].

После того как в БД имеются правила, необходимо со-здать конфигурации сенсоров, активировать нужные для

Ðèñóíîê 10. Ñîõðàíåíèå èíôîðìàöèè î íîâîì ñåíñîðå

Ðèñóíîê 11. Âûáîð ïðàâèë äëÿ ïðîñìîòðà/àêòèâàöèè

$fp=popen($curl_path."curl -s $proxyline $snortrules_url | ↵↵↵↵↵gunzip -dcf - | tar -xOf - rules/*.rules rules/*.conf ↵↵↵↵↵rules/*.config | ↵↵↵↵↵/var/www/html/snortcenter/convert_rules.pl", "r");

$fp=popen($curl_path."curl -s $proxyline $snortrules_url 2>/↵↵↵↵↵dev/null | tar xzOf - rules/*.rules rules/*.conf rules/↵↵↵↵↵*.config | /var/www/html/snortcenter/convert_rules.pl", "r");

$fp=popen($curl_path."curl -s $proxyline $snortrules_url | ↵↵↵↵↵gunzip -dcf - | tar -xOf - rules/*.rules ↵↵↵↵↵rules/*.conf rules/*.config", "r");

$fp=popen($curl_path."curl -s $proxyline $snortrules_url ↵↵↵↵↵2>/dev/null | tar xzOf - rules/*.rules rules/*.conf ↵↵↵↵↵rules/*.config", "r");

Page 57: 016 Системный Администратор 03 2004

56

безопасность

каждого сенсора правила и закачать конфигурации насвои места, чтобы конфигурационные файлы сенсоров со-ответствовали записям в БД для каждого сенсора.

Для того чтобы добавить сенсор в БД, выбираем SensorConsole →→→→→ Add Sensor (см. рис. 9).

И далее заполняем поля таблички. В имени сенсоране имеет смысла вводить знак «-», так как он автомати-чески после будет оттуда удалён. Среди параметров ко-мандной строки желательно указать ключ -D, чтобы snortзапустился и стал демоном. В качестве пароля вводимранее придуманный ваш_пароль№7. После того как всеполя заполнены, нажимаем save (см. рис. 10).

Далее необходимо для созданного сенсора активиро-вать правила, для этого выбираем в меню Sensor Config →→→→→Rule Selection (см. рис. 11).

В появившемся окне после списка внизу нажимаем наSelect, после чего все правила выделяются галочками:

далее в падающем меню выбираем пункт Activate и знач-ки около правил изменяются.

Единственный недостаток программы, что All означа-ет не все правила, как может показаться, а всего лишьвсе правила на текущей странице, поэтому не следуетзабывать активировать правила на 2-й, 3-й... и т. д. стра-ницах. Разработчики не позаботились об удобстве, поэто-му нелишним будет вспомнить про наличие переменной$max_lines в файле conig.php. Однако не стоит увлекать-ся, уже на значении $max_lines=1000 в процессе работы справилами может появиться следующая ошибка.

Можно проверить, все ли правила вы активировали илинет, для этого необходимо щёлкнуть на Rule CategoryOverview.

После чего появится табличка, в которой правила бу-дут разбиты по категориям, около каждой категории бу-дет два числа через дробь – числа активированных пра-вил к общему числу правил в категории. Если в категориине все правила активированы, то она для удобства подсве-чивается жёлтым. Те категории, в которых все правила ак-тивированы, подсвечены зелёно-салатовым (cм. рис. 12).

Аналогично, даже чуть более просто активируем пе-ременные, для этого выбираем в меню Sensor Config →→→→→Variable selection и т. д.

Аналогично поступаем с препроцессорами и другими пун-ктами меню RuleType Selection, Classificaton Selection и т. д.

Перед тем как активировать Output Plugin Selection,необходимо создать конфигурации для каждого из сенсо-

Page 58: 016 Системный Администратор 03 2004

57№3(16), март 2004

безопасность

ров, для этого необходимо выбрать Resources →→→→→ OutputPlugins →→→→→ Create Output Plugin (см. рис. 13).

В появившемся падающем меню следует выбрать Databa-se (Log to a variety of databases) и нажать select (см. рис. 14).

Далее появится таблица, которую необходимо запол-нить (см. рис. 15).

В DB Host следует указать имя или адрес сервера, накотором запущена БД, в которую следует вести логи. Ана-логично заполняются и другие параметры. После заполне-ния необходимо нажать на save. После того как будет со-здан хотя бы один output plugin, его можно будет выбрать иактивировать в Sensor Config →→→→→ Output Plugin Selection.После того как все необходимые составляющие правил длянужного сенсора выбраны, можно создать и скинуть итого-

вый конфигурационный файл на выбранный сенсор. Дляэтого следует выбрать Sensor Console →→→→→ View Sensors и унужного сенсора (пока он один) нажать push (см. рис. 16).

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

Казалось бы, что на этом настройка должна быть за-

Ðèñóíîê 13. Âûáîð ïóíêòà ìåíþ «Create Output Plugin»

Ðèñóíîê 12. Ïðîñìîòð àêòèâèðîâàííîñòè ïðàâèë ïî êàòåãîðèÿì

Page 59: 016 Системный Администратор 03 2004

58

безопасность

кончена и достаточно нажать на start, чтобы всё зарабо-тало, но, к сожалению, это не так. Сейчас мы осуществимнекоторые действия, догадка о выполнении которых былаполучена опытным путём. Если попытаться нажать start,то мы получим сообщение об ошибке, не дающее запус-тить snort на сенсоре:

Из чего можно сделать предположение о том, что системене хватает файла unicode.map (находится в файле с правила-

Ðèñóíîê 14. Âûáîð ïóíêòà ìåíþ «Database (Log to a variety of databases)»

Ðèñóíîê 15. Íàñòðîéêà ïàðàìåòðîâ âåäåíèÿ ëîãîâ â ÁÄ

Page 60: 016 Системный Администратор 03 2004

59№3(16), март 2004

безопасность

ми). По идее этот файл не должен меняться так же часто, какправила, поэтому нет смысла править SnortCenter, чтобы онумел его скидывать вместе с файлом конфигурации. Прощеего скинуть один раз руками в директорию /etc/snort. Чтобы вдальнейшем не возникало подобных ошибок, лучше всеговместе с unicode.map скинуть и другие *.map-файлы, а имен-но для текущей версии это sid-msg.map и gen-msg.map.

Далее следует подправить строчки 140-142 в файлеparser.php. Вместо

следует написать:

До того, как это было сделано, разборщик правил не-верно разбирал правила, в результате чего дописывалосьлишнее значение byte_test: и snort не хотел запускаться.Возможно, подобную операцию по корректированию вдальнейшем придётся сделать со строками 136-138, но

пока в этом нет необходимости. Также при визуальномпросмотре было замечено несколько опечаток: в строч-ках 166, 232, 250, 251 файла db_pars.php и строчке 307файла rules.php, скорее всего, вместо Unknown-Catagoryследует написать Unknown-Category.

После этого при нажатии на start snort успешно запус-тился, имя сенсора стало подсвеченным салатово-зелёнымцветом.

Аналогичным образом следует усновить Snort и Snort-Center Agent на другие машины-сенсоры и настроить их насовместную работу со SnortCenter Management Console. (Об-ратите внимание, у разных сенсоров переменная HOME_NETбудет разная).

В результате после запуска Snort на всех сенсорах увас получится примерно следующая картинка консолиуправления, где все запущенные сенсоры окажутся назелёно-салатовом фоне (см. рис. 17).

Если Snort остановлен, то подсветка будет жёлто-оран-жевая, и справа вместо «stop» будет «start», а вот еслисенсор недоступен, то подсветка будет красной, и такжебудет соответствующее сообщение (см. рис. 18).

Теперь, когда всё работает, самое время поговоритьоб удобствах и недостатках.

Ðèñóíîê 17. Óñïåøíî ðàáîòàþùèå ñåíñîðû

elseif ($what == "byte_test") {if ($rule['byte_test']) $rule['byte_test'] ↵↵↵↵↵

[$content_nr] .= "; byte_test: $val";else $rule['byte_test'][$content_nr] = $val;

elseif ($what == "byte_test") {$rule['byte_test'][$content_nr] = $val;

Ðèñóíîê 16. Ñêèäûâàíèå êîíôèãóðàöèîííîãî ôàéëà íà ñåíñîð

Page 61: 016 Системный Администратор 03 2004

60

безопасность

Удобства.SnortCenter + ACIDОбычно SnortCenter и ACID [10] запускаются на одном сер-вере, поэтому возникает логичный вопрос, почему бы неинтегрировать интерфейс одного средства с другим. Ко-нечно, этого можно и не делать, но почему бы не иметьвозможность с помощью мышки из одной страницы с за-писями об атаках попасть путём одного щелчка на стра-ничку состояния сенсоров. В данном случае не надо ниче-го придумывать, так как уже имеется готовое решение ввиде SnortCenter ACID Plugin. Нам необходимо просто ска-чать Plugin и установить в соответствии с прилагаемымик нему инструкциями. (Предполагается, что у пользовате-ля уже стоит ACID и работает, если нет, то его необходи-мо установить, см. [4].) Для этого скачиваем файл acid-0.9.6b23-plugin-v1.tar.gz:

Распаковываем содержимое архива в какую-нибудьдиректорию, например в /progi:

Переименовываем как-нибудь файлы ACIDacid_main.php, acid_output_html.inc, acid_style.css, чтобыони не потерялись, так как на их место будут записаныновые. Например, допишем к ним расширения .bak:

Далее копируем все файлы с учётом поддиректорийиз директории /progi/acid-0.9.6b23_plugin в директорию, гдеустановлен ACID: /var/www/html/acid:

либо с выводом имени каждого копируемого файла:

Далее необходимо подредактировать файл plugin.conf.php,изменив в нём переменную $snortcenter_home таким об-разом, чтобы она указывала путь к файлам snortcenter.

В нашем случае вместо $snortcenter_home = «http://localhost/»; пишем $snortcenter_home = «../snortcenter/»;

Следует заметить, что помимо обычного интерфейсак ACID с полными правами мы также создавали интер-фейс только для просмотра (см. [4]), соответственно, еслиэто необходимо, все вышеописанные действия следуетповторить и по отношению к нему.

После установки в результате запуска ACID обычнымобразом мы получим следующую картинку (см. рис. 19).

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

НедостаткиПервый из них это то, что если произойдёт перезапуск ком-пьютера-сенсора, на котором запущен snort, то после пе-резапуска работу snort, как это мы делали ранее, никто невосстановит. Как вариант необходимо вносить измененияв консоль управления SnortCenter, чтобы она умела запус-кать Snort автоматически и при этом отличала аварийновставшие сенсоры от специально остановленных. Это мо-жет показаться не совсем удобным, несмотря на наличиедовольно удобных средств конфигурирования и мониторин-га, описанных выше. Решение этой проблемы довольнопросто: необходимо, как и ранее, создать файл snortd, по-местить его в директорию /etc/rc.d/init.d и сделать на негоссылки из директорий, соответствующих необходимымуровням запуска. Однако в связи с тем, что имена конфи-гурационных файлов теперь другие, изменится и содержа-ние файла snortd.

Ðèñóíîê 18. Íåêîòîðûå ñåíñîðû íåäîñòóïíû, îñòàíîâëåíû

# wget http://users.pandora.be/larc/download/ ↵↵↵↵↵acid-0.9.6b23-plugin-v1.tar.gz

# tar -zxvf acid-0.9.6b23-plugin-v1.tar.gz -C /progi

# mv /var/www/html/acid/acid_main.php /var/www/html/ ↵↵↵↵↵acid/acid_main.php.bak

# mv /var/www/html/acid/acid_output_html.inc /var/www/ ↵↵↵↵↵html/acid/acid_output_html.inc.bak

# mv /var/www/html/acid/acid_style.css /var/www/html/ ↵↵↵↵↵acid/acid_style.css.bak

# cp -R /progi/acid-0.9.6b23_plugin/* /var/www/html/acid

# cp -Rv /progi/acid-0.9.6b23_plugin/* /var/www/html/acid

Page 62: 016 Системный Администратор 03 2004

61№3(16), март 2004

безопасность

Например, вместо ранее snort.conf теперь может бытьsnort.eth0.conf. В принципе эту проблему можно бы былорешить путём создания соответствующих мягких ссылок,но сделать это невозможно, так как в некоторых случаяхна одном узле может быть запущено несколько демоновsnort, прослушивающих разные интерфейсы. Этот слу-чай наиболее неудобный, но не безысходный.

Первый способ решения – это правка файла ниже и дуб-лирование строк запуска с разными конфигурациями. Од-нако этот путь имеет недостатки, а именно все демоны ра-ботают или не работают одновременно, как остановить илизапустить лишь один из демонов? Написав более сложныйскрипт, можно решить и эту проблему. Возможно, в следую-щих статьях я напишу этот файл и приведу его с коммента-риями, однако он явно понадобится не всем, да и существу-ет более простое решение, как создание нескольких фай-лов запуска/останова, каждый из которых будет отвечатьтолько за свою конфигурацию snort. В этом случае простосоздаём файлы snortd2, snortd3 и т. д., аналогичные файлуsnortd, вносим в них изменения и также делаем необходи-мые ссылки. Листинг файла snortd.(snortd2, snortd3...):

Ðèñóíîê 19. Âèä ACID ïîñëå óñòàíîâêè SnortCenter ACID Plugin

#!/bin/bash## snortd Start/Stop the snort IDS daemon.## chkconfig: 2345 79 11# description: snort is a lightweight network intrusion# detection tool that currently detects more than 1100 host# and network vulnerabilities, portscans, backdoors, and more.## June 10, 2000 -- Dave Wreski <[email protected]># - initial version#

# July 08, 2000 Dave Wreski <[email protected]># - added snort user/group# - support for 1.6.2# Source function library.. /etc/rc.d/init.d/functions# Specify your network interface hereINTERFACE=eth0# See how we were called.case "$1" in

start)echo -n "Starting snort: "# ifconfig eth0 updaemon /usr/local/bin/snort -o -i $INTERFACE -d -D ↵↵↵↵↵

-c /etc/snort/snort.$INTERFACE.conftouch /var/lock/subsys/snortsleep 3if [ -f /var/log/snort/alert ]

thenrm /var/log/snort/alertfi

echo;;

stop)echo -n "Stopping snort: "killproc snortrm -f /var/lock/subsys/snortecho;;

restart)$0 stop$0 start;;

status)status snort;;

*)echo "Usage: $0 {start|stop|restart|status}"exit 1

esacexit 0

Page 63: 016 Системный Администратор 03 2004

62

безопасность

Далее следует дать команду:

и т. д., чтобы в директориях соответствующих уровнейпоявились символические ссылки на этот файл.

Далее следует дать команду:

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

Вторым недостатком в работе SnortCenter можно на-звать слабые возможности по редактированию правил.Через веб-интерфейс нельзя внести существенные изме-нения в правила, а также я не заметил возможности уда-ления правил через веб-интерфейс. Конечно, это не кри-тические недостатки, их можно обойти путём созданиясвоих собственных правил (кстати, свои правила уже уда-ляются), их активации и деактивации ненужных, но в це-лом в этом направлении я бы доработал эту программу вбудущем.

Положительные моментыПомимо отрицательных моментов в работе программыесть и положительные моменты, а именно хорошая «за-щита от дурака» при создании нерабочеспособных кон-фигурационных файлов. Система себя ведёт очень хит-рым образом, а именно на сенсорах всегда после перво-го запуска хранятся две конфигурации – основная и ре-зервная. Когда вы загружаете новый файл конфигура-ции, то перед его запуском система осуществляет тес-тирование файла конфигурации и параметров запуска сопцией «-T». В случае успешного тестирования происхо-дит запуск Snort с новым файлом конфигурации, а ре-зервный файл конфигурации заменяется текущим. Вслучае если же тестовый запуск был неуспешным, сис-тема выдаёт пользователю сообщение об ошибке и наместо неправильного нового файла записывает рабочуюрезервную копию последнего успешного запуска. И за-пускает Snort «в предыдущей» конфигурации. Таким об-разом, даже неумелому администратору будет сложнозаставить Snort не работать ошибочными правилами,если он до этого уже работал.

ЗаключениеОписанное выше средство конфигурирования и диагнос-тики нескольких сенсоров довольно удобно при созданиисети диагностики на базе распределённых сенсоров ипредставляет собой относительно законченный продукт,однако в описанной выше реализации есть ряд недостат-ков разной степени важности, которые в будущем следу-ет попытаться решить, если есть потребность в созданиинадёжной, отказоустойчивой и безопасной системы об-наружения атак. Среди недостатков можно отметить сле-дующие:! Передача данных с сенсоров в центральную БД в от-

крытом виде.

! Данные между сенсорами и консолью управления пе-редаются будучи закрытыми средствами слабой и не-проверенной криптографии, что является защитойтолько от дилетантов и создаёт заведомо ложную за-щищённость канала.

! Все передаваемые в системе данные никак не защи-щаются от подмены.

! Отсутствие ведения логов в системе – кто, когда и чтоисправлял, например, на случай, если в системе име-ется несколько администраторов.

! Отсутствие продуманного взаимодействия с другимисредствами защиты, например, с пакетными фильтра-ми. По большей части написание тех или иных разре-шающих/запрещающих правил на компьютере центраи сенсорах лежит на администраторе и не защищеноот его ошибки.

! Отсутствие продуманных механизмов резервной свя-зи на случай атак на саму систему или её части.

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

Литература, ссылки:1. SnortCenter – Snort management console http://

users.pandora.be/larc/2. SnortCenter: раздел download http://users.pandora.be/

larc/download/3. Snort Enterprise Implemention v.2.0 prepared by Steven

J. Scott, October 2002, http://users.pandora.be/larc/documentation/snort_enterprise.pdf

4. Закляков П. Удобнее, эффективнее, лучше: snort +MySQL. – //Журнал «Системный администратор»№11(12), ноябрь 2003 г. – 62-73 с.

5. Net::SSLeay.pm Home Page http://symlabs.com/Net_SSLeay/

6. ACID: Installation and Configuration http://www.andrew.cmu.edu/~rdanyliw/snort/acid_config.html

7. Матюхин М. Абстрактный доступ к БД с помощьюADODB, http://detail.phpclub.net/2003-08-19.htm

8. Getting started, Management Console Installation, http://users.pandora.be/larc/documentation/chap1.html

9. PCRE – Perl Compatible Regular Expressions, http://www.pcre.org/

10. Analysis Console for Intrusion Databases, http://www.cert.org/kb/acid/.

# chkconfig snortd on

# chkconfig snortd on(# chkconfig snortd2 on)

Page 64: 016 Системный Администратор 03 2004
Page 65: 016 Системный Администратор 03 2004

64

безопасность

ОШИБКИ ПЕРЕПОЛНЕНИЯ БУФЕРА ИЗВНЕИ ИЗНУТРИ КАК ОБОБЩЕННЫЙ ОПЫТ

РЕАЛЬНЫХ АТАК

КРИС КАСПЕРСКИ

Мы живем в суровом мире. Программное обеспечение, окружающее нас, содержит дыры, многиеиз которых размерами со слона. В дыры лезут хакеры, вирусы и черви, совершающие набеги изовсех концов Сети. Червям противостоят антивирусы, заплатки, брандмауэры и другие умные слова,существующие лишь на бумаге и бессильные сдержать размножение червей в реальной жизни.Сеть небезопасна – это факт. Можно до потери пульса закидывать Била Гейтса тухлыми яйцамии кремовыми тортами, но ситуация от этого вряд ли изменится.Анализ показывает, что подавляющее большинство червей и хакерских атак основано на ошибкахпереполнения буфера, которые носят фундаментальный характер и которых не избежалопрактически ни одно полновесное приложение. Попытка разобраться в этой, на первый взгляддовольно скучной и незатейливой проблеме безопасности погружает вас в удивительный мир,полный приключений и интриг. Захват управления системой путем переполнения буфера –сложная инженерная задача, требующая нетривиального мышления и превосходной экипировки.Диверсионный код, заброшенный на выполнение, находится в весьма жестких и агрессивныхусловиях, не обеспечивающих и минимального уровня жизнедеятельности.Если вам нужен путеводитель по стране переполняющихся буферов, снабженный исчерпывающимруководством по выживанию, – эта статья для вас!

Page 66: 016 Системный Администратор 03 2004

65№3(16), март 2004

безопасность

Чудовищная сложность современных компьютерных сис-тем неизбежно приводит к ошибкам проектирования иреализации, многие из которых позволяют злоумышлен-нику захватывать контроль над удаленным узлом или де-лать с ним что-то нехорошее. Такие ошибки называютсядырами или уязвимостями (holes и vulnerability соответ-ственно).

Мир дыр чрезвычайно многолик и разнообразен: это иотладочные люки, и слабые механизмы аутентификации,и функционально-избыточная интерпретация пользо-вательского ввода, и некорректная проверка аргумен-тов и т. д. Классификация дыр чрезвычайно размыта, вза-имно противоречива и затруднена (во всяком случае, сво-его Карла Линнея дыры еще ждут), а методики их поискаи «эксплуатации» не поддаются обобщению и требуюттворческого подхода к каждому отдельному случаю. Былобы наивно надеяться, что одна-единственная публикациясможет описать весь этот зоопарк! Давайте лучше сосре-доточимся на ошибках переполнения буферов как на наи-более важном, популярном, перспективном и приоритет-ном направлении.

Большую часть статьи мы будем витать в бумажныхабстракциях теоретических построений и лишь к концуспустимся на ассемблерную землю, обсуждая наиболееактуальные проблемы практических реализаций. Нет, неподумайте! Никто не собирается в сотый раз объяснять,что такое стек, адреса памяти и откуда они растут! Этапубликация рассчитана на хорошо подготовленную чи-тательскую аудиторию, знающую ассемблер и беглоизъясняющуюся на Си/Си++ без словаря. Как происхо-дит переполнение буфера, вы уже представляете и те-перь хотели бы ознакомиться с полным списком возмож-ностей, предоставляемых переполняющимися буферами.Какие цели может преследовать атакующий? По какомупринципу происходит отбор наиболее предпочтительныхобъектов атаки?

Другими словами, сначала мы будем долго говорить отом, что можно сделать с помощью переполнения, и лишьпотом перейдем к вопросу «как именно это сделать». Влюбом случае эта тема заслуживает отдельной статьи.

Описанные здесь приемы работоспособны на большин-стве процессорных архитектур и операционных систем(например, UNIX/SPARC). Пусть вас не смущает, что при-водимые примеры в основном относятся к Windows NT ипроизводным от нее системам. Просто в момент написа-ния статьи другой операционной системы не оказалосьпод рукой.

Мясной рулет ошибок переполнения,или попытка классификацииСогласно «Новому словарю хакера» Эрика Раймондаошибки переполнения буфера – это «то, что с неизбежно-стью происходит при попытке засунуть в буфер больше,чем тот может переварить». На самом деле, это всего лишьчастный случай последовательного переполнения призаписи. Помимо него существует индексное переполне-ние, заключающееся в доступе к произвольной ячейкепамяти за концом буфера, где под «доступом» понимают-ся как операции чтения, так и операции записи.

Переполнение при записи приводит к затиранию, аследовательно, искажению одной или нескольких пере-менных (включая служебные переменные, внедряемыекомпилятором, такие, например, как адреса возврата илиуказатели this), нарушая тем самым нормальный ход вы-полнения программы и вызывая одно из следующих по-следствий:! нет никаких последствий;! программа выдает неверные данные или, попросту го-

воря, делает из чисел винегрет;! программа «вылетает», зависает или аварийно завер-

шается с сообщением об ошибке;! программа изменяет логику своего поведения, выпол-

няя незапланированные действия.

Переполнение при чтении менее опасно, т.к. «всеголишь» приводит к потенциальной возможности доступа кконфиденциальным данным (например, паролям или иден-тификаторам TCP/IP-соединения).

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

Наибольшую угрозу для безопасности системы пред-ставляют именно указатели, поскольку они позволяют ата-кующему осуществлять запись в произвольные ячейкипамяти или передавать управление по произвольным ад-ресам, например, на начало самого переполняющегосябуфера, в котором расположен машинный код, специаль-но подготовленный злоумышленником и обычно называ-емый shell-кодом.

Буфера, располагающиеся за концом переполняюще-гося буфера, могут хранить некоторую конфиденциаль-ную информацию (например, пароли). Раскрытие чужихпаролей, равно как и навязывание атакуемой програм-ме своего пароля – вполне типичное поведение для ата-кующего.

Скалярные переменные могут хранить индексы (и тог-да они фактически приравниваются к указателям), фла-ги, определяющие логику поведения программы (в томчисле и отладочные люки, оставленные разработчиком),и прочую информацию.

Ëèñòèíã 1. Ïðèìåð ïîñëåäîâàòåëüíîãî ïåðåïîëíåíèÿ áóôåðà ïðèçàïèñèseq_write(char  *p){

char buff[8];�strcpy(buff,  p);

}Ëèñòèíã 2. Ïðèìåð èíäåêñíîãî ïåðåïîëíåíèÿ áóôåðà ïðè ÷òåíèèidx_write(int  i){

char  buff[]="0123456789";�return  buff[i];

}

Page 67: 016 Системный Администратор 03 2004

66

безопасность

В зависимости от своего местоположения буфера де-лятся на три независимые категории:! локальные буфера, расположенные в стеке и часто на-

зываемые автоматическими переменными;! статичные буфера, расположенные в секции (сегмен-

те) данных;! динамические буфера, расположенные в куче. Все они

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

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

Дело даже не в том, что малейшая небрежность и за-бытая или некорректно реализованная проверка коррек-тности аргументов приводит к потенциальной уязвимос-ти программы. Корректную проверку аргументов невоз-можно осуществить в принципе! Рассмотрим функцию,определяющую длину переданной ей строки и посимволь-но читающую эту строку до встречи с завершающим еенулем. А если завершающего нуля на конце не окажет-ся? Тогда функция вылетит за пределы утвержденногоблока памяти и пойдет чесать непаханую целину посто-ронней оперативной памяти! В лучшем случае это закон-чится выбросом исключения. В худшем – доступом к кон-фиденциальным данным. Можно, конечно, передать мак-симальную длину строкового буфера с отдельным аргу-ментом, но кто поручится, что она верна? Ведь этот ар-гумент приходится формировать вручную, и, следова-тельно, он не застрахован от ошибок. Короче говоря,вызываемой функции ничего не остается, как заклады-ваться на корректность переданных ей аргументов, а разтак – о каких проверках мы вообще говорим?!

С другой стороны – выделение буфера возможнолишь после вычисления длины принимаемой структурыданных, т.е. должно осуществляться динамически. Этопрепятствует размещению буферов в стеке, посколькустековые буфера имеют фиксированный размер, зада-ваемый еще на стадии компиляции. Зато стековые бу-фера автоматически освобождаются при выходе из фун-кции, снимая это бремя с плеч программиста и предотв-ращая потенциальные проблемы с утечками памяти. Ди-намические буфера, выделяемые из кучи, намного ме-нее популярны, поскольку их использование уродуетструктуру программы. Если раньше обработка текущихошибок сводилась к немедленному return, то теперь пе-

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

Многие библиотечные функции (например, gets,sprintf) не имеют никаких средств ограничения длины воз-вращаемых данных и легко вызывают ошибки перепол-нения. Руководства по безопасности буквально кишат ка-тегорическими запретами на использование последних,рекомендуя их «безопасные» аналоги – fgets и snprintf,явно специфицирующие предельно допустимую длинубуфера, передаваемую в специальном аргументе. Поми-мо неоправданного загромождения листинга посторон-ними аргументами и естественных проблем с их синхро-низацией (при работе со сложными структурами данных,когда один-единственный буфер хранит много всякойвсячины, вычисление длины оставшегося «хвоста» ста-новится не такой уж очевидной арифметической зада-чей, и здесь очень легко допустить грубые ошибки)программист сталкивается с необходимостью контроляцелостности обрабатываемых данных. Как минимум не-обходимо убедиться, что данные не были варварски об-резаны и/или усечены, а как максимум – корректно об-работать ситуацию с обрезанием. А что мы, собствен-но, здесь можем сделать? Увеличить буфер и повторновызывать функцию, чтобы скопировать туда остаток?Не слишком-то элегантное решение, к тому же всегдасуществует вероятность потерять завершающий нульна конце.

В Си++ ситуация с переполнением обстоит намноголучше, хотя проблем все равно хватает. Поддержка ди-намических массивов и «прозрачных» текстовых строкнаконец-то появилась (и это очень хорошо), но подавля-ющее большинство реализаций динамических массивовработает крайне медленно, а строки тормозят еще силь-нее, поэтому в критических участках кода от них лучшесразу же отказаться. Иначе и быть не может, посколькусуществует только один способ построения динамичес-ких массивов переменной длины – представление их со-держимого в виде ссылочной структуры (например, дву-направленного списка). Для быстрого доступа к произ-вольному элементу список нужно индексировать, а самутаблицу индексов где-то хранить. Таким образом, чте-ние/запись одного-единственненного символа выливает-ся в десятки машинных команд и множество обращенийк памяти (а память была, есть и продолжает оставатьсясамым узким местом, существенно снижающим общуюпроизводительность системы).

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

Page 68: 016 Системный Администратор 03 2004

67№3(16), март 2004

безопасность

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

Так что ошибки переполнения были, есть и будут! Отэтого никуда не уйти, и коль скоро мы обречены на дли-тельное сосуществование с последними, будет нелишнимпознакомиться с ними поближе…

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

Все это так (ведь и на улицу лишний раз лучше не вы-ходить – случается, что и балконы падают), но за всю ис-торию существования компьютерной индустрии не насчи-тывается и десятка случаев широкомасштабного исполь-зования переполняющихся буферов для распространениявирусов или атак. Отчасти потому, что атаки настоящихпрофессионалов происходят бесшумно. Отчасти – пото-му, что настоящих профессионалов среди современныххакеров практически совсем не осталось…

Наличие одного или нескольких переполняющихся бу-феров еще ни о чем не говорит, и большинство ошибокпереполнения не позволяет атакующему продвинутьсядальше банального DoS. Вот неполный перечень ограни-чений, с которыми приходится сталкиваться червям и ха-керам:! строковые переполняющиеся буфера (а таковых сре-

ди них большинство) не позволяют внедрять символнуля в середину буфера и препятствуют вводу некото-рых символов, которые программа интерпретирует осо-бым образом;

! размер переполняющихся буферов обычно оказыва-ется катастрофически мал для вмещения в них дажепростейшего загрузчика или затирания сколь-нибудьзначимых структур данных;

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

! адреса системных и библиотечных функций меняют-ся от одной операционной системы к другой – это раз.Ни на какие адреса уязвимой программы такженельзя закладываться, поскольку они непостоянны(особенно это актуально для UNIX-приложений, ком-пилируемых каждым пользователем самостоятель-но) – а это два;

! наконец, от атакующего требуется глубокое знаниекоманд процессора, архитектуры операционной систе-мы, особенностей различных компиляторов языка, сво-бодное от академических предрассудков мышление,плюс уйма свободного времени для анализа, проекти-рования и отладки shell-кода.

А теперь для контраста перечислим мифы противопо-ложной стороны – стороны защитников информации, скакой-то детской наивностью свято верящих, что от хаке-ров можно защититься хотя бы в принципе:! не существуют никаких надежных методик автомати-

ческого (или хотя бы полуавтоматического) поиска пе-реполняющихся буферов, дающих удовлетворитель-ный результат, и по-настоящему крупные дыры не об-наруживаются целенаправленным поиском. Их откры-тие – игра слепого случая;

! все разработанные методики борьбы с переполняющи-мися буферами снижают производительность (под часочень значительно), но не исключают возможности пе-реполнения полностью, хотя и портят атакующемужизнь;

! межсетевые экраны отсекают лишь самых примитив-нейших из червей, загружающих свой хвост через от-дельное TCP/IP-соединение, отследить же передачуданных в контексте уже установленных TCP/IP-соеди-нение никакой межсетевой экран не в силах.

Существуют сотни тысяч публикаций, посвященныхпроблеме переполнения, краткий список которых был при-веден в предыдущей статье этого цикла. Среди них естькак уникальные работы, так и откровенный «поросячийвизг», подогреваемый собственной крутизной (мол, смот-рите, я тоже стек сорвал! Ну и что, что в лабораторныхусловиях?!). Статьи теоретиков от программирования эле-ментарно распознаются замалчиванием проблем, с кото-рыми сразу же сталкиваешься при анализе полновесныхприложений и проектировании shell-кодов (по сути своейявляющихся высокоавтономными роботами).

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

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

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

Page 69: 016 Системный Администратор 03 2004

68

безопасность

зумеется, с точки зрения межсетевого экрана все портыравноценны и ему абсолютно все равно, что закрывать.Однако пользователи сетевых служб и администраторыпридерживаются другого мнения. Если от 135-порта, ис-пользуемого червем Love San, в подавляющем большин-стве случаев можно безболезненно отказаться (личноавтор статьи именно так и поступил), то без услуг тогоже веб-сервера обойдешься едва ли.

Чем сложнее исследуемое приложение, тем большевероятность обнаружить в нем критическую ошибку. Сле-дует также обращать внимание и на формат представ-ления обрабатываемых данных. Чаще всего переполня-ющиеся буфера обнаруживаются в синтаксических ана-лизаторах, выполняющих парсинг текстовых строк, од-нако большинство этих ошибок уже давно обнаружено иустранено. Лучше искать переполняющиеся буфера там,где до вас их никто не искал. Народная мудрость утвер-ждает: хочешь что-то хорошо спрятать – положи это насамое видное место. На фоне нашумевших эпидемийLove San и Slapper с этим трудно не согласиться. Кажет-ся невероятным, что такие очевидные переполнения допоследнего времени оставались необнаруженными!

Наличие исходных текстов одновременно желатель-но и нежелательно. Желательно – потому что они суще-ственно упрощают и ускоряют поиск переполняющихсябуферов, а нежелательно… по той же самой причине!Как говорится: больше народу – меньше кислороду. Дей-ствительно, трудно рассчитывать найти что-то новое висходнике, зачитанном всеми до дыр. Отсутствие исход-ных текстов существенно ограничивает круг исследова-телей, отсекая многочисленную армию прикладных про-граммистов и еще большую толпу откровенных непро-фессионалов. Здесь, в прокуренной атмосфере ассемб-лерных команд, выживает лишь тот, кто программируетбыстрее, чем думает, а думает быстрее, чем говорит. Тот,кто может удержать в голове сотни структур данных, бук-вально на физическом уровне ощущая их взаимосвязь икаким-то шестым чувством угадывая, в каком направле-нии нужно копать. Собственный программистский опытможет только приветствоваться. Во-первых, так легчевжиться в привычки, характер и образ мышления разра-ботчика исследуемого приложения. Задумайтесь: а какбы вы решили данную задачу, окажись на его месте?Какие бы могли допустить ошибки? Где бы проявилинепростительную небрежность, соблазнившись компак-тностью кода и элегантностью листинга?

Кстати об элегантности. Бытует мнение, что неряш-ливый стиль программного кода неизбежно провоциру-ет программиста на грубые ошибки (и ошибки перепол-нения в том числе). Напротив, педантично причесаннаяпрограмма ошибок скорее всего не содержит, и анали-зировать ее означает напрасно тратить свое время. Какзнать… Автору приходилось сталкиваться с вопиющенебрежными листингами, которые работали как часы,потому что были сконструированы настоящими профес-сионалами, наперед знающими, где подстелить солом-ку, чтобы не упасть. Встречались и по-академически ак-куратные программы, дотошно и не по одному разу про-веряющие все, что только можно проверить, но букваль-

но нашпигованные ошибками переполнения. Тщатель-ность сама по себе еще ни от чего не спасает. Для пре-дотвращения ошибок нужен богатый программистскийопыт, и опыт, оставленный граблями в том числе. Новместе с опытом зачастую появляется и вальяжная не-брежность – своеобразный «отходняк» от юношескогоувлечения эффективностью и оптимизацией.

Признаком откровенного непрофессионализма явля-ется пренебрежение #define или безграмотное использо-вание последних. В частности, если размер буфера buffопределяется через MAX_BUF_SIZE, то и размер копиру-емой в него строки должен ограничиваться им же, а неMAX_STR_SIZE, заданным в отдельном define. Обращай-те внимание и на характер аргументов функций, работа-ющих с блоками данных.

Передача функции указателя без сообщения разме-ра блока – частая ошибка начинающих, равно как и зло-употребление функциями strcpy/strncpy. Первая небезо-пасна (отсутствует возможность ограничить предельнодопустимую длину копируемой строки), вторая ненадеж-на (отсутствует возможность оповещения о факте «об-резания» хвоста строки, не уместившегося в буфер, чтосамо по себе может служить весьма нехилым источни-ком ошибок).

Хорошо, ошибка переполнения найдена. Что дальше?А дальше только дизассемблер. Не пытайтесь выжать изисходных текстов хоть какую-то дополнительную инфор-мацию. Порядок размещения переменных в памяти неопределен и практически никогда не совпадает с поряд-ком их объявления в программе. Может оказаться так, чтобольшинства из этих переменных в памяти попросту нети они размещены компилятором в регистрах либо же вовсеотброшены оптимизатором как ненужные. (Попутно заме-тим, что все демонстрационные листинги, приведенные вэтой статье, рассчитывают, что переменные располага-ются в памяти в порядке их объявления.)

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

Цели и возможности атакиКонечная цель любой атаки – заставить систему сделатьчто-то «нехорошее», чего нельзя добиться легальным пу-тем. Существует по меньшей мере четыре различных спо-соба реализации атаки:! чтение секретных переменных;! модификация секретных переменных;! передача управления на секретную функцию програм-

мы;! передача управления на код, переданный жертве са-

мим злоумышленником.

Чтение секретных переменных. На роль секретныхпеременных в первую очередь претендуют пароли навход в систему, а также пароли доступа к конфиденци-альной информации. Все они так или иначе содержатсяв адресном пространстве уязвимого процесса, зачастуюрасполагаясь по фиксированным адресам (под «входомв систему» здесь подразумеваются имя пользователя и

Page 70: 016 Системный Администратор 03 2004

69№3(16), март 2004

безопасность

пароль, обеспечивающие удаленное управление уязви-мым приложением).

Еще в адресном пространстве процесса содержатсядескрипторы секретных файлов, сокеты, идентификато-ры TCP/IP-соединений и многое другое. Разумеется, внетекущего контекста они не имеют никакого смысла, номогут быть использованы кодом, переданном жертве зло-умышленником, и осуществляющим, например, установ-ку «невидимого» TCP/IP-соединения, прячась под «кры-шей» уже существующего.

Ячейки памяти, хранящие указатели на другие ячей-ки, «секретными» строго говоря не являются, однако, зна-ние их содержимого значительно облегчает атаку. В про-тивном случае атакующему придется определять опор-ные адреса вслепую. Допустим, в уязвимой программесодержится следующий код:

где p – указатель на буфер, содержащий секретный па-роль. Допустим так же, что в программе имеется ошиб-ка переполнения, позволяющая злоумышленнику читатьсодержимое любой ячейки адресного пространства. Весьвопрос в том: как этот буфер найти? Сканировать всюкучу целиком не только долго, но и небезопасно, т.к.можно легко натолкнуться на невыделенную страницупамяти и тогда выполнение процесса аварийно завер-шится. Автоматические и статические переменные в этомотношении более предсказуемы. Поэтому атакующийдолжен сначала прочитать содержимое указателя p, ауже затем – секретный пароль, на который он указыва-ет. Разумеется, это всего лишь пример, которым возмож-ности переполняющего чтения не ограничиваются.

Само же переполняющее чтение реализуется по мень-шей мере четырьмя следующими механизмами: «поте-рей» завершающего нуля в строковых буферах, моди-фикаций указателей (см. «Указатели и индексы»), индек-сным переполнением (см. там же) и навязыванием фун-кции printf (и другим функциям форматированного вы-вода) лишних спецификаторов.

Модификация секретных переменных. Возможностьмодификации переменных дает значительно больше воз-можностей для атаки, позволяя:! навязывать уязвимой программе «свои» пароли, дес-

крипторы файлов, TCP/IP-идентификаторы и т. д.;! модифицировать переменные, управляющие ветвле-

нием программы;! манипулировать индексами и указателями, передавая

управление по произвольному адресу (и адресу, содер-жащему код, специально подготовленный злоумыш-ленником в том числе).

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

ячейку памяти на свой выбор (за исключением ячеек,явно защищенных от модификации, например кодовойсекции или секции .rodata, разумеется).

Передача управления на секретную функцию про-граммы. Модификация указателей на исполняемый кодприводит к возможности передачи управления на любуюфункцию уязвимой программы (правда, с передачей ар-гументов имеются определенные проблемы). Практичес-ки каждая программа содержит функции, доступныетолько root, и предоставляющие те или иные управлен-ческие возможности (например, создание новой учетнойзаписи, открытие сессии удаленного управления, запускфайлов и т. д.). В более изощренных случаях управле-ние передается на середину функции (или даже на се-редину машинной инструкции) с таким расчетом, что-бы процессор выполнил замысел злоумышленника,даже если разработчик программы не предусматривалничего подобного.

Передача управления обеспечивается либо за счетизменения логики выполнения программы, либо за счетподмены указателей на код. И то, и другое опираетсяна модификацию ячеек программы, кратко рассмотрен-ную выше.

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

Жертвы переполнения или объекты атакиПереполнение может затирать ячейки памяти следую-щих типов: указатели, скалярные переменные и буфе-ра. Объекты языка Си++ включают в себя как указате-ли (указывающие на таблицу виртуальных функций,если таковые в объекте есть), так и скалярные данные-члены (если они есть). Самостоятельной сущности онине образуют и вполне укладываются в приведеннуювыше классификацию.

Указатели и индексыВ классическом Паскале и других «правильных» языкахуказатели отсутствуют, но в Си/Си++ они вездесущи.Чаще всего приходится иметь дело с указателями на дан-ные, несколько реже встречаются указатели на испол-няемый код (указатели на виртуальные функции, указа-тели на функции, загружаемые динамической компонов-кой и т. д.). Современный Паскаль (раньше ассоциируе-мый с компилятором Turbo Pascal, а теперь еще иDELPHI) также немыслим без указателей. Даже если вявном виде указатели и не поддерживаются, на них дер-

char *p = malloc(MAX_BUF_SIZE);

Page 71: 016 Системный Администратор 03 2004

70

безопасность

жатся динамические структуры данных (куча, разряжен-ные массивы), используемые внутри языка.

Указатели удобны. Они делают программированиепростым, наглядным, эффективным и естественным. В тоже время указатели во всех отношениях категорическинебезопасны. Попав в руки хакера или пищеварительныйтракт червя, они превращаются в оружие опустошитель-ной мощности – своеобразный аналог BFG-900 или, покрайней мере, плазмогана. Забегая вперед, отметим, чтоуказатели обоих типов потенциально способны к переда-че управления на несанкционированный машинный код.

Вот с указателей на исполняемый код мы и начнем.Рассмотрим ситуацию, когда следом за переполняющим-ся буфером buff, расположен указатель на функцию, ко-торая инициализируется до и вызывается после перепол-нения буфера (возможно, вызывается не сразу, а спустянекоторое время). Тогда мы заполучим аналог функцииcall или, говоря другими словами, инструмент для пере-дачи управления по любому (ну или почти любому) ма-шинному адресу, в том числе и на сам переполняющийсябуфер (тогда управление получит код, переданный зло-умышленником).

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

Другая популярная мишень – указатели на объекты. ВСи++ программах обычно присутствует большое количе-ство объектов, многие из которых создаются вызовомоператора new, возвращающим указатель на свежесоз-данный экземпляр объекта. Невиртуальные функции-чле-ны класса вызываются точно так же, как и обычные Си-функции (т.е. по их фактическому смещению), поэтому онинеподвластны атаке. Виртуальные функции-члены вызы-ваются намного более сложным образом через цепочкуследующих операций: указатель на экземпляр объекта →→→→→указатель на таблицу виртуальных функций →→→→→ указательна конкретную виртуальную функцию. Указатели на таб-лицу виртуальных функций не принадлежат объекту ивнедряются в каждый его экземпляр, который чаще всегосохраняется в оперативной памяти, реже – в регистровыхпеременных. Указатели на объекты так же размещаютсялибо в оперативной памяти, либо в регистрах, при этомна один и тот же объект может указывать множество ука-зателей (среди которых могут встретиться и такие, кото-

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

Давайте для простоты рассмотрим приложения с вир-туальными таблицами в секции .data. Если злоумышлен-нику удастся модифицировать один из элементов вирту-альной таблицы, то при вызове соответствующей вирту-альной функции управление получит не она, а совсем дру-гой код! Однако добиться этого будет непросто! Виртуаль-ные таблицы обычно размещаются в самом начале сек-ции данных, т.е. перед статическими буферами и доста-точно далеко от автоматических буферов (более конкрет-ное расположение указать невозможно, т.к. в зависимос-ти от операционной системы стек может находиться какниже, так и выше секции данных). Так что последователь-ное переполнение здесь непригодно и приходится уповатьна индексное, все еще остающееся теоретической экзо-тикой, робко познающей окружающий мир.

Модифицировать указатель на объект и/или указательна виртуальную таблицу намного проще, поскольку онине только находятся в области памяти, доступной для мо-дификации, но и зачастую располагаются в непосред-ственной близости от переполняющихся буферов.

Модификация указателя this приводит к подмене вир-туальных функций объекта. Достаточно лишь найти в па-мяти указатель на интересующую нас функцию (или вруч-ную сформировать его в переполняющемся буфере) иустановить на него this с таким расчетом, чтобы адресследующей вызываемой виртуальной функции попал наподложный указатель. С инженерной точки зрения этодостаточно сложная операция, поскольку кроме вирту-альных функций объекты еще содержат и переменные,которые более или менее активно используют. Переус-тановка указателя this искажает их «содержимое» иочень может быть, что уязвимая программа рухнет рань-ше, чем успеет вызвать подложную виртуальную функ-цию. Можно, конечно, сымитировать весь объект цели-ком, но не факт, что это удастся. Сказанное относится ик указателю на объект, поскольку с точки зрения компи-лятора они скорее похожи, чем различны. Однако нали-чие двух различных сущностей дает атакующему свобо-ду выбора – в некоторых случаях предпочтительнее за-тирать указатель this, в некоторых случаях – указательна объект.

Ëèñòèíã 3. Ôðàãìåíò  ïðîãðàììû,  ïîäâåðæåííîé  ïåðåïîëíåíèþñ çàòèðàíèåì óêàçàòåëÿ íà èñïîëíÿåìûé êîäcode_ptr(){

char buff[8]; void (*some_func) ();�printf("passws:");  gets(buff);�some_func();

}

Page 72: 016 Системный Администратор 03 2004

71№3(16), март 2004

безопасность

Рассмотрим ситуацию, когда следом за переполняю-щимся буфером идет указатель на скалярную перемен-ную p и сама переменная x, которая в некоторый моментвыполнения программы по данному указателю и записы-вается (порядок чередования двух последних переменныхнесущественен, главное, чтобы переполняющийся буферзатирал их всех). Допустим также, что с момента пере-полнения ни указатель, ни переменная не претерпеваютникаких изменений (или изменяются предсказуемым об-разом). Тогда, в зависимости от состояния ячеек, затира-ющих оригинальное содержимое переменных x и p, мысможем записать любое значение x по произвольномуадресу p, осуществляя это «руками» уязвимой програм-мы. Другими словами, мы получаем аналог функций POKEи PatchByte/PatchWord языков Бейсик и IDA-Си соответ-ственно. Вообще-то, на выбор аргументов могут быть на-ложены некоторые ограничения (например, функция getsне допускает символа нуля в середине строки), но это неслишком жесткое условие и имеющихся возможностейвполне достаточно для захвата управления над атакуе-мой системой.

Индексы являются своеобразной разновидностью ука-зателей. Грубо говоря, это относительные указатели, ад-ресуемые относительно некоторой базы. Смотрите, p[i]можно представить и как *(p+i), практически полностьюуравнивая p и i в правах.

Модификация индексов имеет свои слабые и сильныестороны. Сильные – указатели требуют задания абсолют-ного адреса целевой ячейки, который обычно неизвестен,в то время как относительный вычисляется на ура. Ин-дексы, хранящиеся в переменных типа char, лишены про-блемы нулевых символов. Индексы, хранящиеся в пере-менных типа int, могут беспрепятственно затирать ячей-ки, расположенные «выше» стартового адреса (т.е. лежа-щие в младших адресах), при этом старшие байты индек-са содержат символы FFh, которые значительно более ми-ролюбивы, чем символы нуля.

Однако, если обнаружить факт искажения указателейпрактически невозможно (дублировать их значение в ре-зервных переменных не предлагать), то оценить коррект-ность индексов перед их использованием не составляет

Ëèñòèíã 6. Ôðàãìåíò ïðîãðàììû, ïîäâåðæåííîé ïîñëåäîâàòåëüíîìóïåðåïîëíåíèþ ïðè çàïèñè è çàòèðàíèåì ñêàëÿðíîé ïåðåìåííîéè óêàçàòåëÿ íà äàííûå, ïîãëîùàþùèìè çàòåðòóþ ïåðåìåííóþdata_ptr(){

char buff[8]; int x; int *p;printf("passws:");  gets(buff);�*p = x;

}

.text:00401051 mov ecx,  [ebp+var_4]

.text:00401051 ; ïåðåäàåì ôóíêöèè óêàçàòåëü this

.text:00401051  ;

.text:00401054 call dword ptr [eax]; âûçûâàåì âèðòóàëüíóþ ôóíêöèþ � ïåðâóþ ôóíêöèþ âèðòóàëüíîé; òàáëèöû.text:00401054.text:00401054  ;.text:00401056 mov esp, ebp.text:00401058 pop ebp.text:00401059 retn.text:00401059  main endp

Ëèñòèíã 4. Ôðàãìåíò ïðîãðàììû, ïîäâåðæåííîé ïîñëåäîâàòåëüíîìóïåðåïîëíåíèþ ïðè çàïèñè, ñ çàòèðàíèåì óêàçàòåëÿ íà òàáëèöóâèðòóàëüíûõ  ôóíêöèéclass A{public:

virtual void f() { printf("legal\n");};};main(){

char buff[8]; A *a = new A;printf("passwd:");gets(buff);  a->f();

}Ëèñòèíã 5. Äèçàññåìáëåðíûé  ëèñòèíã  ïåðåïîëíÿþùèéñÿ  ïðîãðàì-ìû ñ êðàòêèìè êîììåíòàðèÿìè; CODE XREF: start+AF↓↓↓↓↓p.text:00401000  main proc near.text:00401000.text:00401000  var_14 = dword ptr -14h ; this.text:00401000  var_10 = dword ptr -10h ; *a.text:00401000  var_C = byte ptr -0Ch.text:00401000  var_4 = dword ptr -4.text:00401000.text:00401000 push ebp.text:00401001 mov ebp, esp.text:00401003 sub esp, 14h; îòêðûâàåì êàäð ñòåêà è ðåçåðâèðóåì 14h ñòåêîâîé ïàìÿòè.text:00401003.text:00401003  ;.text:00401006 push 4.text:00401008 call operator  new(uint).text:0040100D add esp, 4; âûäåëÿåì ïàìÿòü äëÿ íîâîãî ýêçåìïëÿðà îáúåêòà A è ïîëó÷àåì; óêàçàòåëü.text:0040100D.text:0040100D  ;.text:00401010 mov [ebp+var_10],  eax; çàïèñûâàåì óêàçàòåëü íà îáúåêò â ïåðåìåííóþ var_10.text:00401010.text:00401010  ;.text:00401013 cmp [ebp+var_10],  0.text:00401017 jz short  loc_401026.text:00401017 ; ïðîâåðêà óñïåøíîñòè âûäåëåíèÿ ïàìÿòè.text:00401017  ;.text:00401019 mov ecx,  [ebp+var_10].text:0040101C call A::A.text:0040101C ; âûçûâàåì êîíñòðóêòîð îáúåêòà A.text:0040101C  ;.text:00401021 mov [ebp+var_14],  eax; çàíîñèì âîçâðàùåííûé óêàçàòåëü this â ïåðåìåííóþ var_14.text:00401021.text:00401021  ;�.text:0040102D  loc_40102D: ; CODE XREF: main+24↑↑↑↑↑j.text:0040102D mov eax,  [ebp+var_14].text:00401030 mov [ebp+var_4],  eax; áåðåì óêàçàòåëü this è ïåðåïðÿòûâàåì åãî â ïåðåìåííóþ var_4.text:00401030.text:00401030  ;; "passwd:".text:00401033 push offset aPasswd.text:00401038 call _printf.text:0040103D add esp, 4.text:0040103D ; âûâîäèì ïðèãëàøåíèå ê ââîäó íà ýêðàí.text:0040103D  ;.text:00401040 lea ecx,  [ebp+var_C]; ïåðåïîëíÿþùèéñÿ áóôåð ðàñïîëîæåí íèæå óêàçàòåëÿ íà îáúåêò; è ïåðâè÷íîãî óêàçàòåëÿ this, íî âûøå ïîðîæäåííîãî óêàçàòåëÿ; this, ÷òî äåëàåò ïîñëåäíèé óÿçâèìûì.text:00401040.text:00401040.text:00401040.text:00401040 ;.text:00401043 push ecx.text:00401044 call _gets.text:00401049 add esp, 4.text:00401049 ; ÷òåíèå ñòðîêè â áóôåð.text:00401049  ;.text:0040104C mov edx,  [ebp+var_4]; çàãðóæàåì óÿçâèìûé óêàçàòåëü this â ðåãèñòð EDX.text:0040104C.text:0040104C  ;.text:0040104F mov eax, [edx].text:0040104F ; èçâëåêàåì àäðåñ âèðòóàëüíîé òàáëèöû.text:0040104F  ;

Page 73: 016 Системный Администратор 03 2004

72

безопасность

никакого труда, и многие программисты именно так и по-ступают (правда, «многие» еще не означает «все»). Дру-гой слабой стороной индексов является их ограниченная«дальнобойность», составляющая ±128/256 байт (для ин-дексов типа signed/unsigned char) и -2147483648 байт дляиндексов типа signed int.

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

Рассмотрим случай, когда вслед за переполняющим-ся буфером расположена переменная buks, инициализи-руемая до переполнения, а после переполнения исполь-зуемая для расчетов количества денег, снимаемых со сче-та (не обязательно счета злоумышленника). Допустим,программа тщательно проверяет входные данные и недопускает использования ввода отрицательных значений,однако, не контролирует целостность самой переменнойbuks. Тогда, варьируя ее содержимым по своему усмот-рению, злоумышленник без труда обойдет все проверкии ограничения.

При всей своей искусственности приведенный примерчрезвычайно нагляден. Модификация скалярных перемен-ных только в исключительных случаях приводит к захватууправления системой, но легко позволяет делать из чи-сел винегрет, а на этом уже можно сыграть! Но что же этоза исключительные случаи? Во-первых, многие програм-мы содержат отладочные переменные, оставленные раз-работчиками, и позволяющие, например, отключить сис-тему аутентификации. Во-вторых, существует множествопеременных, хранящих начальные или предельно допус-тимые значения других переменных, например, счетчиковцикла – for (a =b; a < c; a++) *p++ = *x++; очевидно, что мо-

дификация переменных b и c приведет к переполнениюбуфера p со всеми отсюда вытекающими последствиями.В-третьих… да мало ли что можно придумать – всего и неперечислишь! Затирание скалярных переменных при пе-реполнении обычно не приводит к немедленному обруше-нию программы, поэтому такие ошибки могут долго оста-ваться не обнаруженными. Будьте внимательными!

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

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

ЗаключениеИзначально статья задумывалась как исчерпывающее ру-ководство, снабженное большим количеством листингови избегающее углубляться в академические теоретизи-рования. Теперь, вычитывая статью перед заключитель-ной правкой и внося в нее мелкие, косметические улуч-шения, я с грустью осознаю, что выполнить свой замыселмне так и не удалось… До практических советов разго-вор вообще не дошел, и львиная часть подготовленногоматериала осталась за кадром. Ох, и не следовало мнепытаться объять необъятное…

Надеюсь, что следующие статьи этого цикла исправятположение. В первую очередь планируется рассказать о пе-редовых методиках переполнения кучи, приводящих к зах-вату управления удаленной машиной, обсудить техническиеаспекты разработки shell-кода (приемы создания позицион-но-независимого кода, проблема вызова системных функ-ций, оптимизация размера и т. д.), затем можно будет пе-рейти к разговору о способах поиска переполняющихся бу-феров и о возможных мерах по заблаговременному предот-вращению оных. Отдельную статью хотелось бы посвятитьцеликом червям Love Sun и Slapper, поскольку их дизассем-блерные листинги содержат очень много интересного.

Ëèñòèíã 7. Ôðàãìåíò ïðîãðàììû, ïîäâåðæåííîé ïîñëåäîâàòåëüíîìóïåðåïîëíåíèþ ïðè çàïèñè, ñ çàòèðàíèåì èíäåêñàindex_ptr(){

char *p; char buff[MAX_BUF_SIZE]; int i;p = malloc(MAX_BUF_SIZE); i = MAX_BUF_SIZE;�printf("passws:");  gets(buff);�// if ((i < 1) || (i > MAX_BUF_SIZE)) îøèáêàwhile(i--) p[i] = buff[MAX_BUF_SIZE � i];

}

Ëèñòèíã 8. Ôðàãìåíò  ïðîãðàììû,  ïîäâåðæåííûé  ïåðåïîëíåíèþñ çàòèðàíèåì ñêàëÿðíîé ïåðåìåííîévar_demo(float  *money_account){

char buff[MAX_BUF_SIZE]; float buks = CURRENT_BUKS_RATE;printf("input  money:");  gets(buff);if (atof(buff)<0) îøèáêà! ââåäèòå ïîëîæèòåëüíîå çíà÷åíèå�*money_account -= (atof(buff) * CURRENT_BUKS_RATE);

}

Ëèñòèíã 9. Ôðàãìåíò ïðîãðàììû, ïîäâåðæåííîé ïîñëåäîâàòåëüíîìóïåðåïîëíåíèþ ïðè çàïèñè ñ çàòèðàíèåì ïîñòîðîííåãî áóôåðàbuff_demo(){

char  buff[MAX_BUF_SIZE];char  pswd[MAX_BUF_SIZE];�fgets(pswd,  MAX_BUF_SIZE,  f);�printf("passwd:");  gets(buff);if (strncmp(buff, pwsd, MAX_BUF_SIZE))

// íåïðàâèëüíûé ïàðîëüelse

// ïðàâèëüíûé ïàðîëü}

Page 74: 016 Системный Администратор 03 2004
Page 75: 016 Системный Администратор 03 2004

74

hardware

РЕАЛИЗАЦИЯ НИЗКОУРОВНЕВОЙ ПОДДЕРЖКИ ШИНЫ PCIВ ЯДРЕ ОПЕРАЦИОННОЙ СИСТЕМЫ LINUX

ВЛАДИМИР МЕШКОВ

В данной статье на примере решения простой задачи – определения MAC-адреса сетевой карты –рассмотрена реализация низкоуровневой поддержки (low-level support) шины PCI в ядреоперационной системы Linux.

Page 76: 016 Системный Администратор 03 2004

75№3(16), март 2004

hardware

Постановка задачи и исходные данныеИсходные данные – имеется компьютер, функционирую-щий под управлением ОС Linux, версия ядра 2.4.24. В PCI-слот установлен сетевой адаптер на чипсете RTL8139C(далее – адаптер RTL8139C).

Задача – определить MAC-адрес этого адаптера.Путей решения этой задачи несколько. Можно восполь-

зоваться командами dmesg или ifconfig:

Можно написать небольшое приложение следующеговида:

Можно извлечь MAC-адрес из самого адаптераRTL8139C. Рассмотрим, как это делается.

Согласно спецификации на сетевой адаптер RTL8139C,MAC-адрес занимает первые 6 байт в пространстве пор-тов ввода/вывода (I/O), отведенного адаптеру. Задаваясмещение относительно базового порта I/O, можно про-читать все 6 байт MAC-адреса.

Пример функции, выполняющей процедуру чтенияMAC-адреса, приведен ниже:

Функция get_mac_addr() принимает в качестве пара-метра адрес порта I/O адаптера RTL8139C и в цикле про-изводит считывание данных MAC-адреса из пространства

I/O, выделенного адаптеру. При выходе из цикла в буфе-ре mac[] будет находиться искомый MAC-адрес.

Теперь вся задача сводится к определению значениябазового адреса порта I/O адаптера RTL8139C. Как найтиэтот адрес? Чтобы ответить на этот вопрос, давайте по-знакомимся поближе с шиной PCI.

Общая характеристика шины PCIРазработка шины PCI началась весной 1991 года как внут-ренний проект корпорации Intel (Release 0.1). Специалис-ты компании поставили перед собой цель разработать не-дорогое решение, которое бы позволило полностью реа-лизовать возможности нового поколения процессоров 486/Pentium/P6. Особенно подчеркивалось, что разработкапроводилась «с нуля», а не была попыткой установки но-вых «заплат» на существующие решения. В результатешина PCI появилась в июне 1992 года (R1.0). Разработчи-ки Intel отказались от использования шины процессора иввели еще одну «антресольную» (mez-zanine) шину.

Благодаря такому решению шина получилась, во-пер-вых, процессорно-независимой, а во-вторых, могла рабо-тать параллельно с шиной процессора, не обращаясь кней за запросами и тем самым снижая её загрузку. Стан-дарт шины был объявлен открытым и передан PCI SpecialInterest Group (www.pcisig.com), которая продолжила ра-боту по совершенствованию шины. В настоящее времядействует спецификация PCI версии 2.3.

Основные возможности шины следующие:! Синхронный 32- или 64-разрядный обмен данными. При

этом для уменьшения числа контактов (и стоимости)используется мультиплексирование, то есть адрес иданные передаются по одним и тем же линиям.

! Поддержка 5V и 3.3V логики. Частота 66 МГц поддер-живается только 3.3V логикой.

! Частота работы шины 33 МГц или 66 МГц позволяетобеспечить широкий диапазон пропускных способно-стей (с использованием пакетного режима):! 132 Мб/сек при 32-бит/33 МГц;! 264 Mб/сек при 32-бит/66 МГц;! 264 Mб/сек при 64-бит/33 МГц;! 528 Мб/сек при 64-бит/66 МГц.

При этом для работы шины на частоте 66 МГц необхо-димо, чтобы все периферийные устройства работалина этой частоте.

! Полная поддержка multiply bus master (например, не-сколько контроллеров жестких дисков могут одновре-менно работать на шине).

! Автоматическое конфигурирование карт расширенияпри включении питания.

! Спецификация шины позволяет комбинировать до вось-ми функций на одной карте (например, видео + звук).

! Шина позволяет устанавливать до 4 слотов расшире-ния, однако возможно использование моста PCI-PCIдля увеличения количества карт расширения.

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

root@bob~/# dmesg | grep eth0eth0: RealTek RTL8139 at 0xc000, 00:02:44:72:5e:4e, IRQ 11eth0: Identified 8139 chip type 'RTL-8100B/8139D'root@bob~/# ifconfig | grep eth0eth0 Link encap:Ethernet HWaddr 00:02:44:72:5E:4E

/* get_mac.c */#include <stdio.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <linux/if.h>int main() {

int fd;struct ifreq ifr;unsigned char mac[6];fd=socket(AF_INET,SOCK_DGRAM,0);memset(&ifr,0,sizeof(struct ifreq));memcpy(ifr.ifr_name,"eth0",4);ioctl(fd,SIOCGIFHWADDR,&ifr);memcpy(mac,(char *)&(ifr.ifr_hwaddr.sa_data), ↵↵↵↵↵sizeof(struct sockaddr));

printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);

return 0;}

void get_mac_addr(u32 base_addr){

u8 mac[6];/** Ïîñëåäîâàòåëüíî ÷èòàåì áàéòû èç ïîðòà base_addr* è ñîõðàíÿåì èõ â ìàññèâå mac[]

*/for(int i = 0; i < 6; i++)

mac[i] = inb(base_addr + i);/** Îòîáðàæàåì ðåçóëüòàò

*/printf("%02X:%02X:%02X:%02X:%02X:%02X\n",

mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);}

Page 77: 016 Системный Администратор 03 2004

76

hardware

Шина поддерживает метод передачи данных, называ-емый «linear burst» (метод линейных пакетов). Этот методпредполагает, что пакет информации считывается (илизаписывается) «одним куском», то есть адрес автомати-чески увеличивается для следующего байта, при этомувеличивается скорость передачи данных за счет умень-шения числа передаваемых адресов.

На одной шине PCI может присутствовать несколькоустройств, каждое из которых имеет свой номер (devicenumber). В системе может присутствовать несколько шинPCI, каждая из которых имеет свой номер (PCI bus number).Шины нумеруются последовательно; шина, подключённаяк главному мосту, имеет нулевой номер.

В каждой транзакции (обмене по шине) участвуют дваустройства – инициатор (initiator) обмена, он же мастер(master) или ведущее устройство, и целевое (target) уст-ройство, оно же ведомое (slave). Шина PCI все транзак-ции трактует как пакетные: каждая транзакция начинает-ся фазой адреса, за которой может следовать одна илинесколько фаз данных.

Конфигурационное пространствоустройства PCIСогласно спецификации, каждое устройство PCI имеетконфигурационное пространство (configuration space) раз-мером 256 байт, в котором содержится информация о са-мом устройстве и о ресурсах, занимаемых устройством.Это пространство не приписано ни к пространству памя-ти, ни к пространству ввода-вывода. Доступ к нему осу-ществляется по специальным циклам шины ConfigurationRead и Configuration Write. После аппаратного сброса (илипо включении питания) устройства PCI доступны толькодля операций конфигурационного чтения и записи. В этихоперациях устройства выбираются по индивидуальнымсигналам IDSEL и сообщают о потребностях в ресурсах ивозможных вариантах конфигурирования. После распре-деления ресурсов, выполняемого программой конфигури-рования (во время теста POST), в конфигурационные ре-гистры устройства записываются параметры конфигури-рования. Только после этого к устройству становится воз-можным доступ по командам обращения к памяти и пор-там ввода-вывода. Для того чтобы всегда можно былонайти работоспособную конфигурацию, все ресурсы, за-нимаемые картой, должны быть перемещаемыми в своихпространствах. Для многофункциональных устройств каж-дая функция должна иметь свое конфигурационное про-странство.

Конфигурационное пространство, формат которогопредставлен на рис. 1, состоит из трех областей:! область, не зависимая от устройства (device-independent

header region);! область, определяемая типом устройства (header-type

region);! область, определяемая пользователем (user-defined

region).

Подробное описание полей конфигурационного про-странства приведено в спецификации [4]. Рассмотримкратко основные поля.

Vendor_ID, Device_ID, Class_CodeПоля Vendor_ID, Device_ID и Class_Code содержат кодфирмы-изготовителя устройства, код устройства и кодкласса устройства. Классификация устройств и указаниекода класса в его конфигурационном пространстве явля-ется важной частью спецификации PCI.

Код изготовителя, код устройства и код класса приме-няются в процессе поиска заданного устройства. Еслинеобходимо найти конкретное устройство, то поиск вы-полняется по кодам устройства и его изготовителя; еслинеобходимо найти все устройства определенного типа, топоиск выполняется по коду класса устройства. После тогокак устройство найдено, при помощи регистров базовыхадресов можно определить выделенные ему области вадресном пространстве памяти и пространстве ввода-вывода (I/O).

Header_TypeПоле Header_Type определяет формат header-type облас-ти, а также является ли устройство многофункциональ-ным. Идентификатором многофункционального устрой-ства является бит 7 поля: если бит установлен в 1 – уст-ройство поддерживает несколько функций, если сброшенв 0 – устройство выполняет только функцию.

Биты 0 – 6 определяют собственно формат header-typeобласти: если эти биты обнулены (содержат код 0x00), тоформат области header-type соответствует формату, пред-ставленому на рис. 1; значение 0x01 идентифицирует уст-ройство как мост PCI-to-PCI, и формат header-type области

Ðèñóíîê 1. Ôîðìàò êîíôèãóðàöèîííîãî ïðîñòðàíñòâà PCI

Page 78: 016 Системный Администратор 03 2004

77№3(16), март 2004

hardware

описан в спецификации PCI-to-PCI Bridge ArchitectureSpecification; значение 0x02 идентифицирует устройство какмост CardBus. Остальные значения зарезервированы.

CommandКомандный регистр (поле Command) содержит средствауправления устройством. Назначение отдельных бит это-го регистра:! бит 0 – определяет реакцию устройства на обращение

к нему через пространство портов I/O. Если бит сбро-шен в 0, устройство игнорирует попытки доступа к немучерез порты I/O;

! бит 1 – определяет реакцию устройства на обращениек нему через адресное пространство. Если бит установ-лен в 1, устройство отвечает на обращения к нему че-рез адресное пространство; если бит сброшен в 0, тоустройство на попытки доступа к нему не реагирует;

! бит 2 – установленный в 1 бит разрешает устройствуработать в режиме Bus Master.

Base Address RegistersРегистры базовых адресов (Base Address Registers) содер-жат выделенные устройству области в адресном простран-стве и пространстве портов I/O. Бит 0 во всех регистрахбазовых адресов определяет, куда будет отображен ре-сурс – на пространство портов I/O или на адресное про-странство. Регистр базового адреса, отображаемый напространство портов, всегда 32-разрядный, бит 0 установ-лен в 1. Регистр базового адреса, отображаемый на ад-ресное пространство, может быть 32- и 64-разрядным, бит0 сброшен в 0.

Программный доступк конфигурационному пространству PCI

Configuration Mechanism #1Поскольку конфигурационное пространство не имеет при-вязки к какой-либо определенной области адресного про-странства, для доступа к нему применяется специальныймеханизм, названый в спецификации ConfigurationMechanism #1. Для работы этого механизма в простран-стве портов I/O зарезервированы два 32-разрядных пор-та, входящих в главный мост: CONFIG_ADDRESS с адре-сом 0xCF8 и CONFIG_DATA с адресом 0xCFC. ФорматCONFIG_ADDRESS представлен на рис. 2.

Установленный в 1 бит 31 разрешает обращение к кон-фигурационному пространству через порт CONFIG_DATA,биты 30 – 24 зарезервированы (read-only), при чтении дол-жны возвращать 0, биты 23 – 26 содержат номер шины,биты 15 – 11 – номер устройства, биты 10 – 8 – номерфункции и биты 7 – 2 – номер регистра, к которому вы-полняется обращение (смещение в конфигурационномпространстве).

Порядок работы Configuration Mechanism #1 следую-щий – в порт CONFIG_ADDRESS (0xCF8) заносится ад-рес, соответствующий формату, приведенному на рис. 2;обращением к порту CONFIG_DATA (0xCFC) производит-ся чтение или запись данных в требуемый регистр конфи-гурационного пространства.

PCI BIOSДля взаимодействия с устройствами PCI имеются допол-нительные функции BIOS, доступные как из реального,так и защищенного режима работы процессора. Эти фун-кции предназначены для работы с конфигурационнымпространством и генерации специальных циклов PCI.

Функции PCI BIOS для 16-битного реального режимавызываются через прерывание int 0x1A. Номер функциизадается в регистре AX. Признаком нормального выпол-нения являются значения флага CF = 0 и ноль в регистреAH (AH = 0x00, SUCCESFUL). Если CF = 1, то регистр AHсодержит код ошибки:! 0x81 – неподдерживаемая функция (FUNC_NOT_SUP-

PORTED);! 0x83 – неправильный идентификатор производителя

(BAD_VENDOR_ID);! 0x86 – устройство не найдено (DEVICE_NOT_FOUND);! 0x87 – неправильный номер регистра PCI (BAD_REGIS-

TER_NUMBER), т.е. неправильно задано смещение вконфигурационном пространстве.

Перечислим некоторые функции PCI BIOS (полныйперечень содержится в [6]):! 0xB101 – проверка присутствия PCI BIOS;! 0xB102 – поиск устройства по коду фирмы-изготови-

теля;! 0xB103 – поиск устройства по коду класса;! 0xB108 – чтение байта конфигурационного простран-

ства устройства PCI;! 0xB109 – чтение слова конфигурационного простран-

ства устройства PCI;! 0xB10A – чтение двойного слова конфигурационного

пространства устройства PCI.

При чтении информации из конфигурационного простран-ства в регистры процессора заносятся следующие значения:! AX – номер функции;! BH – номер шины, к которой подключено устройство

(от 0 до 255);! BL – номер устройства в старших 5 битах и номер фун-

кции в трех младших;! DI – смещение в конфигурационном пространстве.

После этого следует вызов прерывания int 0x1A, в ре-зультате которого в регистрах процессора будут размеще-ны следующие значения:! ECX – считанная информация (байт/слово/двойное

слово);! AH – код возврата (SUCCESFUL/BAD_REGISTER_NUM-

BER);! CF – статус возврата (0 – функция успешно выполне-

на, 1 – ошибка).

Ðèñóíîê 2. Ôîðìàò ðåãèñòðà CONFIG_ADDRESS

Page 79: 016 Системный Администратор 03 2004

78

hardware

BIOS32При работе в 32-разрядном защищенном режиме для дос-тупа к функциям PCI BIOS используются средства BIOS32.Процедура проверки наличия BIOS32 предполагает обра-щение к физическим адресам памяти, поэтому обычнопроизводится из реального режима, до переключения взащищенный. Если BIOS32 поддерживается, то в облас-ти памяти BIOS, расположенной в диапазоне 0xE0000 –0xFFFFF, должна присутствовать специальная 16-байтнаяструктура данных – служебный каталог (BIOS32 ServiceDirectory). Структура каталога приведена в таблице 1.

Процесс поиска служебного каталога BIOS32 заключа-ется в сканировании памяти ПЗУ BIOS: производится по-иск сигнатуры «_32_» в диапазоне 0xE0000 – 0xFFFFF по16-байтным параграфам (начало служебного каталога вы-ровнено на границу 16 байт). После обнаружения сигнату-ры производится вычисление и проверка контрольной сум-мы: если сумма совпадает, то служебный каталог найден.

Для доступа к PCI BIOS в 32-разрядном режиме требу-ется выполнить дальний вызов через точку входа BIOS32.Перед выполнением вызова в регистры записывается сле-дующая информация:! в EAX – идентификатор запрашиваемого сервиса, ко-

торый для PCI BIOS имеет значение «$PCI»(0x49435024);

! в EBX – селектор функции (значение должно быть рав-но нулю).

После выполнения вызова в регистре AL будет возвра-щен код результата:! 0 – операция успешно завершена;! 0x80 – некорректный идентификатор сервиса;! 0x81 – недопустимое значение селектора функции.

Если вызов завершен успешно, в регистрах процессо-ра будет размещена следующая информация:! в EBX – физический адрес базы сервиса BIOS;! в ECX – размер сегмента сервиса BIOS;! в EDX – точка входа в сервис BIOS (смещение относи-

тельно базы, возвращенной в EBX).

Адрес точки входа в сервис определяется путем сло-жения физического адреса базы сервиса и смещения от-носительно базы. Дальнейший порядок обращения к фун-кциям сервиса PCI BIOS не отличается от реального ре-жима, за исключением того, что вместо вызова прерыва-ния int 0x1A необходимо выполнить дальний вызов черезточку входа в сервис.

Алгоритм чтения MAC-адресаИтак, вернемся к решению нашей задачи – определениюMAC-адреса сетевого адаптера RTL8139C. Для этого нам

был необходим базовый адрес в пространстве I/O, и этозначение, как мы уже установили, находится в конфигу-рационном пространстве устройства. Чтобы извлечь егооттуда, можно воспользоваться сервисом BIOS32 либо ра-ботать с устройством напрямую, при помощи ConfigurationMechanism #1.

Алгоритм решения задачи при использовании серви-са BIOS32 следующий:! определяем адрес точки входа в BIOS32. Для этого вы-

полняем поиск служебного каталога BIOS32 в диапа-зоне 0xE0000 – 0xFFFFF;

! определяем адрес точки в сервис BIOS32 – PCI BIOS.Для этого выполняем дальний вызов через точку вхо-да в BIOS32, задав в регистре EAX идентификатор зап-рашиваемого сервиса ($PCI);

! используя PCI BIOS, выполняем поиск сетевого адап-тера и определяем его координаты – номер шины, но-мер устройства и номер функции. Поиск производимпо коду класса. Код класса сетевого контроллера ра-вен 0x00020000 (см. [4]);

! из конфигурационного пространства сетевого адапте-ра считываем значение базового адреса порта I/O и,задавая смещение относительно этого адреса, считы-ваем MAC-адрес адаптера RTL8139C.

При использовании Configuration Mechanism #1 всё го-раздо проще и сводится к последовательной записи ин-формации в порт CONFIG_ADDRESS и чтении её из пор-та CONFIG_DATA. Рассмотрим программную реализациюэтих алгоритмов.

Программная реализация алгоритмачтения MAC-адресаРазработаем модуль ядра, который при загрузке будетвыполнять поиск сетевого адаптера RTL8139C и считы-вать его MAC-адрес. Все исходные тексты, рассмотрен-ные в статье, доступны на сайте журнала.

Начнём с описания заголовочных файлов, переменныхи информационных структур.

Заголовочных файлов у нас два:

Определим код фирмы-изготовителя адаптераRTL8139C, код типа устройства и код класса устройства.

Функции PCI BIOS, которые мы будем использовать(полный перечень приведен в [6]):

Òàáëèöà 1

#include <linux/module.h>#include <linux/pci.h>

// êîä ôèðìû-èçãîòîâèòåëÿ � RealTek#define VENDOR_ID 0x10EC// êîä óñòðîéñòâà � ñåòåâàÿ êàðòà RTL8139C#define DEVICE_ID 0x8139// êîä êëàññà ñåòåâîãî êîíòðîëëåðà ([4])#define CLASS_CODE 0x00020000

// ïðîâåðêà ïðèñóòñòâèÿ PCI BIOS â ñèñòåìå#define PCIBIOS_PCI_BIOS_PRESENT 0xb101// ïîèñê óñòðîéñòâà PCI çàäàííîãî òèïà#define PCIBIOS_FIND_PCI_DEVICE 0xb102// ïîèñê óñòðîéñòâà PCI çàäàííîãî êëàññà#define PCIBIOS_FIND_PCI_CLASS_CODE 0xb103// ïðî÷èòàòü áàéò èç êîíôèãóðàöèîííîãî ïðîñòðàíñòâà

Page 80: 016 Системный Администратор 03 2004

79№3(16), март 2004

hardware

Сигнатура, по которой производится поиск служебно-го каталога BIOS32 (_32_):

Сигнатура для проверки присутствия PCI BIOS в систе-ме (используется функцией PCIBIOS_PCI_BIOS_PRESENT):

Сигнатура, по которой осуществляется поиск сервисаBIOS32:

Определим структуру для хранения информации обустройстве PCI:

Следующие две структуры описывают физическиеадреса точек входа в BIOS32 и в сервис BIOS32 (PCI BIOS).

Физический адрес точки входа в BIOS32 (в форматеселектор:смещение):

Физический адрес точки входа в сервис BIOS32 (PCIBIOS):

__KERNEL_CS – селектор сегмента кода, определен вфайле include/asm-i386/segment.h:

Стандартный служебный каталог BIOS32 имеет сле-дующий вид:

Рассмотрим функцию, которая производит поиск слу-жебного заголовка BIOS32.

Сканируем область памяти BIOS в диапазоне адресов0xe0000 и 0xfffff в поисках сигнатуры «_32_» и служебно-го каталога BIOS32:

Поиск выполняется относительно нижней границы ад-ресного пространства ядра 0xC0000000, на что указыва-ет макрос __va(0xe0000) и __va(0xffff0).

Этот макрос определен в файле include/page.h следу-ющим образом:

Если сигнатура найдена – определяем размер служеб-ного каталога BIOS32 в байтах:

Считываем контрольную сумму и определяем номерверсии реализации:

Если вышли за пределы диапазона сканирования, тоиспользовать BIOS32 мы не сможем:

Если всё в порядке – вычисляем адрес точки входа вBIOS32 и заполняем структуру bios32_indirect:

#define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ↵↵↵↵↵('2' << 16) + ('_' << 24))

#define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ↵↵↵↵↵('I' << 16) + (' ' << 24))

#define PCI_SERVICE (('$' << 0) + ('P' << 8) + ↵↵↵↵↵('C' << 16) + ('I' << 24))

struct pci_dev_struct {// êîä ôèðìû-èçãîòîâèòåëÿ è êîä òèïà óñòðîéñòâàu16 vendor_id, device_id;// êîä êëàññà óñòðîéñòâàu32 class_code;// àäðåñ ïîðòà I/Ou32 base_addr;// êîîðäèíàòû óñòðîéñòâà � íîìåð øèíû, íîìåð óñòðîéñòâà// íà øèíå è íîìåð ôóíêöèè óñòðîéñòâàu8 bus, dev, fn;

};

static struct {u32 address;u16 segment;

} bios32_indirect = { 0, __KERNEL_CS };

static struct {u32 address;u16 segment;

} pci_indirect = { 0, __KERNEL_CS };

#define __KERNEL_CS 0x10

union bios32 {struct {

// ñèãíàòóðà _32_u32 signature;

int pci_find_bios(void){

union bios32 *check; // ñëóæåáíûé êàòàëîã BIOS32u8 sum;int i, length;

for (check = (union bios32 *) __va(0xe0000);check <= (union bios32 *) __va(0xffff0); ++check) {

if (check->fields.signature != BIOS32_SIGNATURE) continue;

// íèæíÿÿ ãðàíèöà àäðåñíîãî ïðîñòðàíñòâà ÿäðà#define __PAGE_OFFSET 0xC0000000#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET))

length = check->fields.length * 16;if (!length) continue;

sum = 0;for (i = 0; i < length ; ++i)

sum += check->chars[i];if (sum != 0)

continue;if (check->fields.revision != 0) {

printk("PCI: unsupported BIOS32 revision %d ↵↵↵↵↵at 0x%p\n", check->fields.revision, check);

continue;}

if (check->fields.entry >= 0x100000) {printk("PCI: BIOS32 entry (0x%p) in high memory, ↵↵↵↵↵

cannot use.\n", check);return 0;

} else {

// óñòðîéñòâà PCI#define PCIBIOS_READ_CONFIG_BYTE 0xb108// ïðî÷èòàòü ñëîâî èç êîíôèãóðàöèîííîãî ïðîñòðàíñòâà// óñòðîéñòâà PCI#define PCIBIOS_READ_CONFIG_WORD 0xb109// ïðî÷èòàòü äâîéíîå ñëîâî èç êîíôèãóðàöèîííîãî ïðîñòðàíñòâà// óñòðîéñòâà PCI#define PCIBIOS_READ_CONFIG_DWORD 0xb10a

// 32-õ áèòíûé ôèçè÷åñêèé àäðåñ òî÷êè âõîäà â BIOS32u32 entry;// íîìåð âåðñèè, Revision level, 0u8 revision;// ðàçìåð ñëóæåáíîãî êàòàëîãà â 16-áàéòíûõ ïàðàãðàôàõu8 length;// êîíòðîëüíàÿ ñóììà, äîïîëíÿåò âñå áàéòû äî 0u8 checksum;// çàðåçåðâèðîâàíî, çàïîëíÿåòñÿ íóëÿìèu8 reserved[5];

} fields;char chars[16];

};

Page 81: 016 Системный Администратор 03 2004

80

hardware

Следующая функция, которую мы рассмотрим, опре-деляет адрес точки входа в сервис BIOS32.

Идентификатор сервиса передается в параметрах фун-кции.

Адрес точки входа в сервис BIOS32 определяется пу-тем дальнего вызова через точку входа в BIOS32. Передвыполнением вызова в регистры процессора заноситсяследующая информация:! EAX – идентификатор сервиса (в нашем случае это $PCI);! EBX – селектор функции (должен быть равен 0);! EDI – адрес точки входа в BIOS32.

После вызова регистры процессора будут содержатьследующую информацию:! AL – код возврата: 0 – запрашиваемый сервис найден,

0x80 – сервис отсутствует (не поддерживается);! EBX – физический адрес базы сервиса;! ECX – размер сегмента сервиса;! EDX – точка входа в сервис BIOS32 (смещение отно-

сительно базы, возвращённой в регистре EBX).

Вот как выполняется данный вызов:

Конструкция типа

используется для защиты критичных участков кода от воз-действия прерываний.

Проанализируем код возврата:

Если код возврата равен 0, то сервиc PCI BIOS присут-ствует, и адрес точки входа в него можно определить, сло-жив значение адреса базы (address) и смещения относи-тельно базы (entry):

Если код возврата равен 0x80, запрашиваемый сер-вис отсутствует:

А теперь рассмотрим порядок обращения к сервису PCIBIOS в защищенном режиме, выполнив проверку присут-ствия PCI BIOS в системе:

pcibios_entry – это точка входа в сервис, назначение осталь-ных переменных рассмотрим ниже. Ищем точку входа в сер-вис PCI путём вызова функции bios32_service(). Параметрфункции – идентификатор сервиса, сигнатура $PCI. Все ад-реса отсчитываются относительно нижней границы адрес-ного пространства ядра (PAGE_OFFSET = 0xC0000000).

Выполняем обращение к функции проверки присутствияPCI BIOS в системе – 0xB101. Для этого выполняем дальнийвызов через точку входа pcibios_entry, предварительно за-полнив регистры процессора следующей информацией:! EAX – запрашиваемая функция сервиса, в данном слу-

чае 0xB101;! EDI – адрес точки входа в сервис.

В результате выполнения вызова в регистрах процес-сора будет находиться следующая информация:! EDX – сигнатура запрашиваемого сервиса (PCI в на-

шем случае);! AH – признак присутствия сервиса (0 – PCI BIOS при-

сутствует, если в EDX правильная сигнатура, любоедругое значение – PCI BIOS отсутствует);

! AL – поддерживаемый аппаратный механизм конфи-гурирования (см. «Configuration Mechanism #1»);

! BH – номер версии интерфейса;

unsigned long bios32_entry = check->fields.entry;bios32_indirect.address = bios32_entry + ↵↵↵↵↵

PAGE_OFFSET; // àäðåñ òî÷êè âõîäà â BIOS32printk(KERN_INFO "PCI: BIOS32 entry point at ↵↵↵↵↵

0x%08x\n", bios32_indirect.address);}break;/* Hopefully more than one BIOS32 cannot happen... */

}return 0;

}

static u32 bios32_service(u32 service){

u8 return_code; /* %al, êîä âîçâðàòà */u32 address; /* %ebx, àäðåñ áàçû ñåðâèñà*/u32 length; /* %ecx, ðàçìåð ñåãìåíòà ñåðâèñà */u32 entry; /* %edx, òî÷êà âõîäà â ñåðâèñ */u32 flags;

__save_flags(flags); __cli();__asm__("lcall (%%edi); cld"

: "=a" (return_code),// ôèçè÷åñêèé àäðåñ áàçû ñåðâèñà"=b" (address),// ðàçìåð ñåãìåíòà ñåðâèñà"=c" (length),// òî÷êà âõîäà â ñåðâèñ BIOS32 (ñìåùåíèå îòíîñèòåëüíî// áàçû, âîçâðàùåííîé â EBX)"=d" (entry)// èäåíòèôèêàòîð çàïðàøèâàåìîãî ñåðâèñà ($PCI): "0" (service),// ñåëåêòîð ôóíêöèè, äîëæåí áûòü ðàâåí íóëþ"1" (0),// àäðåñ òî÷êè âõîäà â BIOS32"D" (&bios32_indirect));

__restore_flags(flags);

__save_flags(flags);__cli();/* This code runs with interrupts disabled */__restore_flags(flags);

switch (return_code) {

case 0:// èñêîìûé àäðåñ òî÷êè âõîäà â ñåðâèñ BIOS32 (PCI BIOS)return address + entry;

case 0x80: /* Not present */printk(KERN_WARNING "bios32_service(0x%08x): ↵↵↵↵↵

not present\n", service);return 0;

default: /* Shouldn't happen */printk(KERN_WARNING "bios32_service(0x%08x): returned ↵↵↵↵↵

0x%x -- BIOS bug!\n", service, return_code);return 0;

}}

int check_pcibios(void){

u32 signature, eax, ebx, ecx;u8 status, major_ver, minor_ver, hw_mech;u32 flags,u32 pcibios_entry;

if ((pcibios_entry = bios32_service(PCI_SERVICE))) {pci_indirect.address = pcibios_entry + PAGE_OFFSET;

Page 82: 016 Системный Администратор 03 2004

81№3(16), март 2004

hardware

! BL – подномер версии интерфейса;! CL – номер последней шины PCI в системе.

Итак, выполняем вызов:

и обрабатываем полученные результаты:

Если сервис присутствует, переменная status будет рав-на 0. Проверяем это, а заодно и полученную сигнатуру:

Функция pci_bios_find_device() выполняет поиск устрой-ства заданного типа при помощи PCI BIOS и возвращаетего координаты – номер шины, к которой подключено ус-тройство, номер устройства на шине и номер функции ус-тройства:

Функция принимает следующие параметры:! vendor – код фирмы-изготовителя устройства PCI;! device_id – код типа устройства;! index – порядковый номер устройства заданного типа.

Если устройство одно, то его порядковый номер равен 0.

Параметры bus, dev и fn, соответствующие координа-там устройства PCI (номер шины, номер устройства на

шине и номер функции), передаются по ссылке и будутизменены на реальные значения.

Для поиска устройства выполняем дальний вызов че-рез точку входа в сервис BIOS32, задав в регистрах про-цессора соответствующие параметры:! EAX – запрашиваемая функция сервиса, в данном слу-

чае 0xB102.! ECX – код типа устройства.! EDX – код фирмы-изготовителя устройства.! ESI – индекс (порядковый номер) устройства заданно-

го типа.! В регистр EDI занесем адрес точки входа в сервис.

В результате выполнения вызова в регистрах процес-сора будет находиться следующая информация:! BH – номер шины, к которой подключено устройство;! BL – номер устройства в старших пяти битах и номер

функции в трёх младших;! AH – код возврата (может принимать значения BAD_VEN-

DOR_ID, DEVICE_NOT_FOUND и SUCCESFUL).

Выполняем дальний вызов:

Обрабатываем полученный результат:

Функция поиска устройства заданного классаpci_bios_find_class() практически не отличается от функ-ции поиска устройства по типу:

В параметрах функции передается указатель на инфор-мационную структуру struct pci_dev_struct *pd.

Перед выполнением дальнего вызова в регистры за-носятся следующие данные:! EAX – запрашиваемая функция сервиса – 0xB103.! ECX – код класса устройства.! ESI – индекс (порядковый номер) устройства заданно-

го типа.! В регистр EDI занесем адрес точки входа в сервис.

Результаты выполнения вызова аналогичны предыду-щим:! в регистре BH – номер шины;

__save_flags(flags); __cli();__asm__(

"lcall (%%edi); cld\n\t""jc 1f\n\t""xor %%ah, %%ah\n""1:"// â EDX âîçâðàùàåòñÿ ñèãíàòóðà "PCI": "=d" (signature),// â AH � ïðèçíàê ïðèñóòñòâèÿ, â AL � àïïàðàòíûé ìåõàíèçì

"=a" (eax),// â BH - íîìåð âåðñèè èíòåðôåéñà PCI, BL � ïîäíîìåð// âåðñèè èíòåðôåéñà

"=b" (ebx),// ECX � íîìåð ïîñëåäíåé øèíû PCI â ñèñòåìå

"=c" (ecx)// 0xB101 � ôóíêöèÿ ïðîâåðêè ïðèñóòñòâèÿ PCI BIOS// â ñèñòåìå: "1" (PCIBIOS_PCI_BIOS_PRESENT),// òî÷êà âõîäà â ñåðâèñ BIOS32

"D" (&pci_indirect): "memory");

__restore_flags(flags);

// ïðèçíàê ïðèñóòñòâèÿ ñåðâèñà ñ ñèñòåìåstatus = (eax >> 8) & 0xff;// ïîääåðæèâàåìûé àïïàðàòíûé ìåõàíèçìhw_mech = eax & 0xff;// íîìåð âåðñèèmajor_ver = (ebx >> 8) & 0xff;// íîìåð ïîäâåðñèèminor_ver = ebx & 0xff;

if (status || signature != PCI_SIGNATURE) {printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] ↵↵↵↵↵

found\n", status, signature);return 0;

}printk(KERN_INFO "PCI: PCI BIOS revision %x.%02x entry ↵↵↵↵↵

at 0x%08x\n", major_ver, minor_ver, pcibios_entry);return 1;

}return 0;

}

static int pci_bios_find_device(u16 vendor, u16 device_id, ↵↵↵↵↵u16 index, u8 *bus, u8 *dev, u8 *fn)

{u16 bx;u16 ret;

__asm__("lcall (%%edi); cld\n\t""jc 1f\n\t""xor %%ah, %%ah\n""1:": "=b" (bx),

"=a" (ret): "1" (PCIBIOS_FIND_PCI_DEVICE),

"c" (device_id),"d" (vendor),"S" ((int) index),

// àäðåñ òî÷êè âõîäà â ñåðâèñ"D" (&pci_indirect));

*bus = (bx >> 8) & 0xff; // íîìåð øèíû*dev = (bx & 0xff) >> 3; // íîìåð óñòðîéñòâà íà øèíå*fn = bx & 0x3; // íîìåð ôóíêöèèreturn (int) (ret & 0xff00) >> 8;

}

static int pci_bios_find_class(u32 class_code, u16 index, ↵↵↵↵↵struct pci_dev_struct *pd)

{u16 bx;u16 ret;

Page 83: 016 Системный Администратор 03 2004

82

hardware

! в BL – номер устройства в старших пяти битах и номерфункции в трёх младших;

! в AH – код возврата (DEVICE_NOT_FOUND илиSUCCESFUL):

Заносим в структру struct pci_dev_struct *pd координа-ты устройства:

После того как устройство заданного типа найдено,необходимо получить данные, находящиеся в его конфи-гурационном пространстве (см. «Конфигурационное про-странство устройства PCI»). Сделаем это при помощифункции pci_bios_read():

Параметрами функции являются координаты устрой-ства (bus – номер шины, dev – номер устройства, fn – но-мер функции), смещение в конфигурационном простран-стве (reg) и размер данных для считывания (len, байт/сло-во/двойное слово). В последний параметр мы поместимсчитанное из конфигурационного пространства значение,поэтому этот параметр передается по ссылке.

Проверяем правильность переданных параметров:

Для чтения информации из конфигурационного про-странства устройства PCI BIOS предоставляет следующиефункции [6]:! 0xB108 – чтение байта;! 0xB109 – чтение слова;! 0xB10A – чтение двойного слова.

Эти функции отличаются только размером считывае-мых данных – байт, слово или двойное слово. Перед вы-зовом функции в регистры процессора помещается сле-дующая информация:! EAX – код функции;! BH – номер шины, к которой подключено устройство;! BL – номер устройства в старших пяти битах и номер

функции в трёх младших битах;! DI – смещение в конфигурационном пространстве.

После выполнения функции в регистре ECX будут нахо-диться считанные данные, а регистр AH будет содержать кодвозврата. Подготовим значение для загрузки в регистр BX ипрочитаем информацию из конфигурационного простран-ства устройства, учитывая размер запрашиваемых данных:

Помимо средств BIOS32 для работы с конфигурацион-ным пространством устройства PCI в защищенном режиметакже используется Configuration Mechanism #1. Его поря-док работы был рассмотрен в «Configuration Mechanism #1»:в порт CONFIG_ADDRESS (0xCF8) заносится адрес, соот-ветствующий формату, приведенному на рис. 2; обраще-нием к порту CONFIG_DATA (0xCFC) производится чте-ние или запись данных в требуемый регистр конфигура-ционного пространства.

Формировать адрес установленного формата будетмакрос PCI_CONF1_ADDRESS():

Самый старший бит установлен в 1 – это позволит намполучить данные из порта CONFIG_DATA.

После того как адрес сформирован, записываем его впорт CONFIG_ADDRESS.

Функция pci_direct_read() выполняет обращение к уст-ройству PCI при помощи Configuration Mechanism #1:

__asm__("lcall (%%edi); cld\n\t""jc 1f\n\t""xor %%ah, %%ah\n""1:": "=b" (bx),

"=a" (ret): "1" (PCIBIOS_FIND_PCI_CLASS_CODE),

"c" (class_code),"S" ((int) index),

// àäðåñ òî÷êè âõîäà â ñåðâèñ"D" (&pci_indirect));

// íîìåð øèíûpd->bus = (bx >> 8) & 0xff;// íîìåð óñòðîéñòâà íà øèíåpd->dev = (bx & 0xff) >> 3;// íîìåð ôóíêöèèpd->fn = bx & 0x03;return (int) (ret & 0xff00) >> 8;

}

static int pci_bios_read(int bus, int dev, int fn, int reg, ↵↵↵↵↵int len, u32 *value)

{u32 result = 0;u32 bx;

if (bus > 255 || dev > 31 || fn > 7 || reg > 255)return -EINVAL;

bx = ((bus << 8) | (dev << 3) | fn);switch (len) {case 1: // ñ÷èòûâàåì áàéò

__asm__("lcall (%%esi); cld\n\t""jc 1f\n\t""xor %%ah, %%ah\n""1:": "=c" (*value),

"=a" (result): "1" (PCIBIOS_READ_CONFIG_BYTE),

"b" (bx),"D" ((long)reg),

// òî÷êà âõîäà â ñåðâèñ"S" (&pci_indirect));

break;case 2: // ñ÷èòûâàåì ñëîâî

__asm__("lcall (%%esi); cld\n\t""jc 1f\n\t""xor %%ah, %%ah\n""1:": "=c" (*value),

"=a" (result): "1" (PCIBIOS_READ_CONFIG_WORD),

"b" (bx),"D" ((long)reg),

// òî÷êà âõîäà â ñåðâèñ"S" (&pci_indirect));

break;case 4: // ñ÷èòûâàåì äâîéíîå ñëîâî

__asm__("lcall (%%esi); cld\n\t""jc 1f\n\t""xor %%ah, %%ah\n""1:": "=c" (*value),

"=a" (result): "1" (PCIBIOS_READ_CONFIG_DWORD),

"b" (bx),"D" ((long)reg),

// òî÷êà âõîäà â ñåðâèñ"S" (&pci_indirect));

break;}return (int)((result & 0xff00) >> 8);

}

#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) | ↵↵↵↵↵(0x80000000 | (bus << 16) | (dev << 11) | ↵↵↵↵↵(fn << 8) | (reg & ~3))

Page 84: 016 Системный Администратор 03 2004

83№3(16), март 2004

hardware

Параметры функции – номер шины bus, номер устрой-ства на шине dev, номер функции fn, смещение в конфи-гурационном пространстве reg, длина запрашиваемыхданных (байт/слово/двойное слово). Результат помещает-ся в параметр value, который передается по ссылке.

Проверяем правильность переданных параметров:

Формируем адрес при помощи макроса PCI_CONF1_ADDRESS() и записываем его в порт CONFIG_ADDRESS:

Считываем значение из порта CONFIG_DATA:

Функция pci_direct_find_class() выполняет поиск устрой-ства заданного класса, используя Configuration Mechanism#1, и возвращает его координаты – номер шины, номерустройства на шине и номер функции:

Параметры функции – код класса устройства и струк-тура struct pci_dev_struct *pd, в которую необходимо запи-сать координаты устройства.

Переменная idx – это смещение в конфигурационномпространстве устройства, и указывает оно на поле RevisionID, за которым следуют три байта поля Class Code. Длясчитывания Class Code достаточно считать двойное сло-во, находящееся по смещению idx, и сдвинуть результатна 8 бит в сторону младших разрядов.

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

Считываем двойное слово, находящееся по смещениюidx, и получаем код класса:

Сравниваем полученный код класса с искомым. Присовпадении сохраняем координаты устройства

Все функции, которые мы рассмотрели, будут вызва-ны во время процедуры инициализации модуля:

Напомню, что наша задача – прочитать MAC-адрес се-тевого адаптера RTL8139C, и для этого нам необходимополучить его базовый адрес в пространстве I/O. Ищем слу-жебный заголовок BIOS32, вычисляем адрес точки входа вBIOS32 и производим проверку присутствия PCI BIOS:

Выполняем поиск устройства (сетевого адаптераRTL8139C) по коду типа устройства. В результате мы по-лучим его координаты – номер шины, номер устройствана шине и номер функции:

Повторим процедуру, но в этот раз будем искать уст-ройство по коду класса:

static int pci_direct_read(int bus, int dev, int fn, ↵↵↵↵↵int reg, int len, u32 *value)

{

if (bus > 255 || dev > 31 || fn > 7 || reg > 255)return -EINVAL

outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);

switch (len) {case 1: // ñ÷èòûâàåì áàéò

*value = inb(0xCFC + (reg & 3));break;

case 2: // ñ÷èòûâàåì ñëîâî*value = inw(0xCFC + (reg & 2));break;

case 4: // ñ÷èòûâàåì äâîéíîå ñëîâî*value = inl(0xCFC);break;

}return 0;

}

int pci_direct_find_class(u32 class_code, ↵↵↵↵↵struct pci_dev_struct *pd)

{

int bus, dev, fn = 0, idx = 0x08;u32 config_dword, code;

printk(KERN_INFO "Looking for device with class code ↵↵↵↵↵0x%X\n", class_code);

memset(pd, 0, sizeof(struct pci_dev_struct));// ñêàíèðóåì âñå øèíûfor(bus = 0; bus < 256; bus++) {

// ñêàíèðóåì âñå óñòðîéñòâà íà êàæäîé øèíå

pci_direct_read(bus, dev, fn, idx, 4, &config_dword);code = config_dword >> 8;

if(code == class_code) {printk(KERN_INFO "OK. Device found.\n");printk(KERN_INFO "bus - %d, dev - %d, ↵↵↵↵↵

fn - %d\n", bus, dev, fn);pd->bus = bus;pd->dev = dev;pd->fn = fn;return 0;

}}

}}return 0x80;

}

static int __init pcidev_on(void){

// ñòðóêòóðà ñ ïàðàìåòðàìè PCI-óñòðîéñòâàstruct pci_dev_struct pdev;// ñìåùåíèå ê äàííûì â êîíôèãóðàöèîííîì ïðîñòðàíñòâå// óñòðîéñòâà PCIint idx = 0;// êîîðäèíàòû óñòðîéñòâàu8 bus = 0, dev = 0, fn = 0;// êîìàíäíûé ðåãèñòðu16 command_reg = 0;u32 config_dword = 0;

pci_find_bios();check_pcibios();

if(pci_bios_find_device(VENDOR_ID, DEVICE_ID, idx, ↵↵↵↵↵&bus, &dev, &fn) == PCIBIOS_SUCCESSFUL)printk(KERN_INFO "Device found by type, bus - %d, ↵↵↵↵↵

dev - %d, fn - %d\n", bus, dev, fn);

for(dev = 0; dev < 32; dev++) {// ñêàíèðóåì âñå ôóíêöèèfor(fn = 0; fn < 8; fn++) {

memset((void *)&pdev, 0, sizeof(struct pci_dev_struct));if(pci_bios_find_class(CLASS_CODE, idx, ↵↵↵↵↵&pdev) == PCIBIOS_SUCCESSFUL)printk(KERN_INFO "Device found by class, bus - %d, ↵↵↵↵↵

dev - %d, fn - %d\n", pdev.bus, pdev.dev, pdev.fn);else {

Page 85: 016 Системный Администратор 03 2004

84

hardware

Итак, устройство найдено. Считываем из конфигура-ционного пространства код фирмы-производителя и за-носим это значение в структуру struct pci_dev_struct pdev:

То же самое – для кода типа устройства и для кодакласса устройства:

Считываем значение командного регистра:

Считываем значение базового адреса в пространствеI/O. Предварительно проверяем, чтобы бит 0 командногорегистра был установлен в единицу. Если это так, то вы-полняем поиск базового адреса устройства:

Базовый адрес найден. Отобразим информацию обустройстве и прочитаем MAC-адрес адаптера RTL8139C:

Функции display_pcidev_info() и get_mac_addr() выгля-дят следующим образом:

Теперь давайте выполним процедуру чтения MAC-ад-реса сетевого адаптера RTL8139C, используя ConfigurationMechanism #1 для доступа к конфигурационному простран-ству устройства.

Пытаемся найти устройство по коду класса:

Считываем код фирмы-производителя, код типа уст-ройства и код класса устройства:

Считываем содержимое командного регистра и зна-чение адреса порта I/O:

/* Read VENDOR ID */idx = 0x00;if(pci_bios_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵↵↵↵↵2, &config_dword) == PCIBIOS_SUCCESSFUL)pdev.vendor_id = (u16)config_dword;

/* Read DEVICE ID */idx = 0x02;if(pci_bios_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵↵↵↵↵2, &config_dword) == PCIBIOS_SUCCESSFUL)pdev.device_id = (u16)config_dword;

/* Read Class Code */idx = 0x08;if(pci_bios_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵↵↵↵↵4, &config_dword) == PCIBIOS_SUCCESSFUL)pdev.class_code = config_dword >> 8;

/* Read Command Register */idx = 0x04;if(pci_bios_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵↵↵↵↵1, &config_dword) == PCIBIOS_SUCCESSFUL)command_reg = config_dword;

/* Read Base Address Registers */idx = 0x10;if(command_reg & 0x01) {

// ñêàíèðóåì Base Address Registers â ïîèñêàõ àäðåñà// ïîðòà I/Ofor(; idx < 0x28 ;) {

if(pci_bios_read(pdev.bus, pdev.dev, pdev.fn, ↵↵↵↵↵idx, 4, &config_dword) == PCIBIOS_SUCCESSFUL) {

// åñëè íóëåâîé áèò ðàâåí 1, òî àäðåñ ïîðòà// I/O íàéäåíif(config_dword & 0x01) {

config_dword &= ~0x1;pdev.base_addr = config_dword;break;

}idx += 4;

}}

} else return 0;

display_pcidev_info(&pdev);get_mac_addr(pdev.base_addr);

void display_pcidev_info(struct pci_dev_struct *pdev){

printk(KERN_INFO "VENDOR ID - 0x%X\n", pdev->vendor_id);printk(KERN_INFO "DEVICE ID - 0x%X\n", pdev->device_id);printk(KERN_INFO "CLASS CODE - 0x%X\n", pdev->class_code);printk(KERN_INFO "BASE ADDRESS - 0x%X\n", pdev->base_addr);

/* Direct read PCI */printk(KERN_INFO "PCI direct access:\n");if(pci_direct_find_class(CLASS_CODE, &pdev) < 0) {

printk(KERN_INFO "Device not found\n");return 0;

}

/* Read VENDOR_ID */idx = 0x00;if(pci_direct_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵↵↵↵↵2, &config_dword) == 0)printk(KERN_INFO "VENDOR_ID - 0x%X\n", config_dword);

/* Read DEVICE_ID */idx = 0x02;if(pci_direct_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵↵↵↵↵2, &config_dword) == 0)printk(KERN_INFO "DEVICE_ID - 0x%X\n", config_dword);

/* Read Class Code */idx = 0x08;if(pci_direct_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵↵↵↵↵4, &config_dword) == 0)printk(KERN_INFO "CLASS_CODE - 0x%X\n", ↵↵↵↵↵

config_dword >> 8);

/* Read Command Register */command_reg = 0;idx = 0x04;if(pci_direct_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵↵↵↵↵2, &config_dword) == 0)command_reg = config_dword;

/* Read Base Address Registers */idx = 0x10;if(command_reg & 0x01) {

for(; idx < 0x28 ;) {if(pci_direct_read(pdev.bus, pdev.dev, pdev.fn, ↵↵↵↵↵

idx, 4, &config_dword) == PCIBIOS_SUCCESSFUL) {if(config_dword & 0x01) {

config_dword &= ~0x1;pdev.base_addr = config_dword;break;

}idx += 4;

}}

printk(KERN_INFO "Device not founf by class\n");return 0;

}return;

}void get_mac_addr(u32 base_addr){

int i = 0;u8 mac[6];memset(mac, 0, 6);

/* Get and display MAC address */for(; i < 6; i++)

mac[i] = inb(base_addr + i);printk(KERN_INFO "MAC address: ↵↵↵↵↵%02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], ↵↵↵↵↵mac[2], mac[3], mac[4], mac[5]);

return;}

Page 86: 016 Системный Администратор 03 2004

85№3(16), март 2004

hardware

Считываем значение MAC-адреса сетевого адаптера.

Выгружает модуль из памяти функция pcidev_off:

Инициализация модуля и выгрузка его из памяти вы-полняется при помощи двух макросов:

Исходные тексты модуля доступны на сайте журналаи находятся в файле pcidev.c. При помощи команды makeполучаем объектный модуль pcidev.o и загружаем его ко-мандой insmod:

Вся информация, полученная от устройства, будет со-брана в файле /var/log/messages.

Пример записи из этого файла сравните с результата-ми, полученными при помощи команд dmesg и ifconfig (см.«Постановка задачи и исходные данные»).

ЗаключениеРассмотренные нами функции являются базовыми в под-системе низкоуровневой поддержки (low-level support)шины PCI ядра ОС Linux. Все эти функции можно найти вфайле arch/i386/kernel/pci-pc.c.

В повседневной практике нет особой необходимостиработать напрямую с шиной, для этих целей целесообраз-но применять функции более высокого уровня, переченькоторых приведён в файле Documentation/pci.txt.

Насчет спецификаций и где их брать – спецификацияна RTL8139C находится на сайте компании RealTek,www.realtek.com.tw, спецификация PCI 3.0 и перевод нарусский язык спецификации PCI 2.0 были найдены на сай-те http://dsp.neora.ru. На сайте Intel (www.intel.com) можновзять спецификацию на сетевые карты Intel 8255x – для это-го в строке поиска задайте 8255X_OpenSDM (OpenSDM –Open Source Software Developer Manual). Также посетитесайт фирмы Phoenix (www.phoenix.com) – материалы поBIOS.

Список кодов классов и подклассов устройств PCI на-ходится в [4], приложение D.

Литература:1. Аппаратные средства IBM PC. Энциклопедия, 2-е изд.

/ М. Гук – СПб.: Питер, 2003. – 923 с.:ил.2. Программирование на аппаратном уровне: специаль-

ный справочник. 2-е изд. / В. Кулаков. – СПб.: Питер,2003. – 848 с.:ил.

3. Шина PCI (Peripheral Component Interconnect bus). Ни-колай Дорофеев, www.ixbt.com.

4. PCI Local Bus Specification. Revision 3.0. August 12, 2002.5. Standard BIOS 32-bit Service Directory Proposal, Revision

0.4 May 24, 19936. PCI BIOS specification. Revision 2.0. 1993.

} else return 0;

get_mac_addr(config_dword);return 0;

}

static void __exit pcidev_off(void){

return;}

module_init(pcidev_on);module_exit(pcidev_off);

insmod pcidev.o

Page 87: 016 Системный Администратор 03 2004
Page 88: 016 Системный Администратор 03 2004
Page 89: 016 Системный Администратор 03 2004

88

образование

ПРОГРАММНОЕ УПРАВЛЕНИЕADSI: LDAP

В предыдущих статьях [1, 2] были рассмотрены теоретические аспекты построения Active Directoryи проведен обзор доступных провайдеров, с помощью которых можно программно управлятьActive Directory, а также описаны основы программирования одного из провайдеров – WinNT.Данный материал содержит основы программирования провайдера LDAP, объектная моделькоторого рассмотрена на примере стандартных утилит, созданных компанией Microsoft.

ИВАН КОРОБКО

Page 90: 016 Системный Администратор 03 2004

89№3(16), март 2004

образование

Объектная модельпровайдера LDAPДля программного управления Active Directory с помощьюпровайдера LDAP необходимо использовать его объектнуюмодель. Объектная модель представляет собой совокуп-ность объектов, которые взаимосвязаны друг с другом иобразуют между собой иерархическую структуру. Каждыйиз этих объектов имеет набор свойств, характерных исклю-чительно для объектов данного типа. Существует несколь-ко типов (идентификаторов) объектов: CN, DС, OU. Рас-шифровка и назначение каждого объекта см. в таблице 1.

Имена LDAP URLИмена LDAP URL (см. RFC 1779, RFC 2247) построены наоснове протокола X.500 и используются для связывания собъектами. Идентификаторы объектов DC, OU, CN обра-зуют полное составное имя (Distinguished Name, DN), а имясамого объекта – относительное составное имя (RelativeDistinguished Name, RDN). Полное составное имя объектавключает в себя имя объекта и всех его родителей, начи-ная с корня домена (см. рис. 1).

Существуют две формы доступа к ADSI: развернутая исокращенная. Рассмотрим принципы построения путей кресурсу двумя способами на примере домена domain.com(см. рис. 1).

Развернутая формаПри использовании этого вида формы строка связыванияначинается с описания верхнего элемента структуры. За-тем происходит переход вниз по иерархии. Важно помнить,что при написании пути к объекту необходимо исключатьпробелы.

В качестве шаблона может служить выражение вида:

где DC=Domain_name1/DC=Domain_name2/DC=Domain_na-me3 образуют полное имя контроллера домена, элементы

OU=OU_Name_Level1/OU=OU_Name_Level2…/OU=OU_Na-me_Levelµ представляют собой вложенные друг в другаэлементы. В развернутой форме доступа объект CN яв-ляется «дном колодца» в иерархии.

Пример: запрос к объекту CN=User3 с помощью раз-вернутой формы доступа выглядит следующим образом(см. рис. 1):

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

Соответственно запрос к объекту CN=User3 с помощьюсокращенной формы доступа выглядит следующим образом:

Инструменты, обеспечивающие доступк объектной модели каталогаСуществует несколько программ, предназначенных дляпросмотра объектной модели каталога. Остановимся лишьна двух из них: Active Directory Viewer (Microsoft) и LDAPBrowser 2.5.3 (Softerra).

Active Directory Viewer (Microsoft)Active Directory Viewer (ADV) является графической ути-литой, позволяющей выполнять операции чтения, моди-фицирования, осуществлять поиск в любых совместимыхкаталогах, таких как Active Directory, Exchange Server,Netscape Directory, Netware Directory.

Active Directory Viewer входит в состав SDK для ActiveDirectory Services Interface, который можно бесплатно заг-рузить с сайта Microsoft: http://www.microsoft.com/ntserver/nts/downloads/other/adsi25.

После установки SDK for ADSI утилита Active DirectoryViewer (AdsVw.exe) будет находиться в c:\Program Files\Microsoft\ADSI Resource Kit, Samples and Utilities\ADsVw\.

Программа работает в двух режимах: ObjectViewer иQuery (см. рис. 2). Для просмотра объектной модели ка-кого-либо провайдера необходимо использовать режимObjectViewer. Режим Query используется для осуществ-ления поиска объектов в выбранной объектной модели. Вданной статье режим Query рассматриваться не будет.

Òàáëèöà 1

Set obj = GetObject ("LDAP://DC=Domain_name1/ ↵↵↵↵↵DC=Domain_name2/DC=Domain_name3/OU=OU_Name_Level1/ ↵↵↵↵↵OU=OU_Name_Level2�/OU=OU_Name_Levelµ/CN=CN_Name")

Set obj = GetObject ("LDAP://DC=RU/DC=Domain1/OU=Group1/ ↵↵↵↵↵OU=Group4/CN=User3")

Set obj=GetObject("LDAP://CN=User3,OU=Group4, ↵↵↵↵↵OU=Group3,DC=Domain1,dc=RU")

Set obj=GetObject("LDAP://CN=CN_Name,OU=OU_Name_Levelµ�, ↵↵↵↵↵OU=OU_Name_Level2,OU=OU_Name_Level1/DC=�")

Ðèñóíîê 1

Ðèñóíîê 2

Page 91: 016 Системный Администратор 03 2004

90

образование

Просмотр и редактирование объектной моделипрограммой ADV в режиме ObjectViewerПосле выбора режима работы ObjectViewer появится диа-логовое окно (см. рис. 3). Для получения доступа к ката-логу необходимо указать путь к каталогу и параметрыучетной записи, обладающей правами администратора(имя и пароль). Путь к каталогу должен быть построен всоответствии со следующим шаблоном:

Обратите внимание на две особенности в этом шаб-лоне: в шаблоне не должно быть пробелов, «слэши» дол-жны быть прямыми – «/». Невыполнение хотя бы одногоиз перечисленных условий приведет к ошибке в соедине-нии с каталогом. Для доступа к серверу server доменаdomain.ru с помощью протокола LDAP используется сле-дующий запрос:

После соединения с каталогом на экране будет ото-бражена его иерархическая структура (см. рис. 4). В ле-вой части экрана отображается иерархическая структуракаталога. В правой части отображаются характеристикиобъекта, на котором установлен курсор. Список свойствобъекта и соответствующих им значений приведен в«Properties» и «Property Value».

С помощью кнопок «Change», «Clear», «Append»,«Delete» можно изменять объектную модель каталога: из-менять, удалять, добавлять поля в свойствах объектов.

LDAP Browser 2.5.3 (Softerra)LDAP Browser 2.5.3 является бесплатной программой (http://www.ldapadministrator.com).

По своим возможностям программа превосходит ActiveDirectory Viewer, в использовании LDAP Browser гораздоудобнее. В процессе создания соединения с каталогоммогут быть заданы фильтры, параметры административ-

<Provider_Name:>//<Server_Name>/<Full_Domain_Name>

Ðèñóíîê 3

LDAP://server/DC=domain,DC=ru;

Ðèñóíîê 4

Page 92: 016 Системный Администратор 03 2004

91№3(16), март 2004

образование

ной учетной записи, порт TCP, по которому имеет местосоединение, и другие параметры. Общий вид программыприведен на рис. 5.

Различия в функционалепровайдеров LDAP и WinNTОб одном из отличий речь велась в предыдущей статье[2] – провайдер LDAP (Lightweight Directory Access Protocol)рассматривает принтер как сетевое устройство, в то вре-мя как провайдер WinNT рассматривает принтер исклю-чительно как локальное устройство. Использование обо-их провайдеров при работе с принтерами позволяет пол-ностью управлять принтерами. Наглядный пример управ-ления принтерами домена рассмотрен в статье «Управ-ление сетевыми принтерами домена» [3].

Вторым принципиальным отличием провайдеров явля-ются расширенные возможности поиска провайдераLDAP. Используя провайдер WinNT, можно было осуще-ствлять поиск, пользуясь фильтром, который позволял осу-ществлять поиск всех объектов, принадлежащих к одно-му из классов – computer, user, service и др. Провайдерпозволяет искать объект, при этом не обязательно указы-вать класс, к которому относится объект. Найдя объект,осуществляем чтение его свойств, включая местоположе-ние объекта в AD, класс, к которому относится объект, идругие параметры.

Поиск объектов осуществляется с помощью OLEDistributed Query (DB) интерфейса, который вызывается пря-мо из интерфейса службы активного каталога (Active DirectoryService Interface – ADSI). Поиск осуществляется на основа-нии запроса и его параметров. В качестве параметров зап-роса могут быть: уровень поиска, диапазон поиска, ограни-

чение по размеру, сортировка и т. д. Форма запроса(Distributed Query) заимствована из Microsoft SQL Server.

Запрос строится по шаблону:

где путь – путь к интересующему объекту AD в форматеLDAP URL.

На практике поиск объектов осуществляется следую-щим образом:

В приведенном примере осуществляется поиск всехзарегистрированных в AD-принтеров. У найденных прин-

Ðèñóíîê 5

SELECT ïîëå11,ïîëå21,ïîëån1 FROM ïóòü ↵↵↵↵↵WHERE objectClass="òèï_îáúåêòà"

Ïðèìåð 1:Set objNameSpace = GetObject("WinNT:")

For Each Domain in objNameSpaceDomainName=Domain.Name

NextSet objConnection = CreateObject("ADODB.Connection")Set objCommand = CreateObject("ADODB.Command")objConnection.Provider = "ADsDSOObject"objConnection.Open "Active Directory Provider"Set objCommand.ActiveConnection = objConnectionobjCommand.CommandText = "SELECT printerName, serverName ↵↵↵↵↵

FROM " _ & " 'LDAP://"& DomainName & "' ↵↵↵↵↵WHERE objectClass='printQueue'"

objCommand.Properties("Cache Results") = FalseSet objRecordSet = objCommand.ExecuteobjRecordSet.MoveFirstDo Until objRecordSet.EOF

temp=temp & "Printer Name: " ↵↵↵↵↵& objRecordSet.Fields("printerName").Value ↵↵↵↵↵& " Server Name: " ↵↵↵↵↵& objRecordSet.Fields("serverName").Value & chr(13)

objRecordSet.MoveNextLoopwscript.echo temp

Page 93: 016 Системный Администратор 03 2004

92

образование

теров происходит чтение двух полей: название принтераи название сервера печати.

Поиск объектов с помощью провайдера LDAP осуще-ствляется по следующему шаблону:! устанавливается соединение с Active Directory Provider

через ADODB;! составляется запрос, на основе которого будет осуще-

ствляться поиск;! осуществляется поиск по заданным критериям.

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

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

Таким образом, основываясь на приведенном приме-ре, вместо objRecordSet.Fields(«serverName»).Value мож-но записать objRecordSet.Fields(1).Value.

Третье отличие – это управление коммерческими про-дуктами, поддерживающими LDAP. Множество коммер-ческих продуктов использует каталог LDAP для храненияинформации. Используя ADSI, можно управлять коммер-ческими продуктами, в число которых входят: MicrosoftWindows 2000, 2003; Microsoft Exchange 5.5, 2000, 2003;Microsoft Site Server 3.0 + SP2; Netscape Directory Server идр. Кроме того, компании Cisco и Microsoft предложилистандарт сети на основе каталога, в котором описывает-ся интеграция сетевых устройств в каталоге LDAP.

В настоящей статье будет рассмотрен вопрос, касаю-щийся управления Microsoft Windows 200х, а именно ActiveDirectory. Рассмотрим следующие вопросы, касающиесяуправления AD через провайдер LDAP: просмотр атрибу-тов записи от анонимной и конкретной учетной записи;изменение атрибутов учетной записи; создание и удале-ние учетной записи.

Просмотр атрибутов записиот анонимной и конкретнойучетной записиПросмотр атрибутов объектов осуществляется с помощьюфункции Get(), вызову которой предшествует вызов функ-ции GetObject(). Для получения анонимного доступа к объек-там необходимо указать путь к объекту, начиная с контрол-лера домена. В приведенном примере читается идентифи-кационный номер учетной записи User3 (см. рис. 2) – UserID,которому соответствует поле uid. Объектная модель провай-дера LDAP будет рассмотрена позже. Необходимо отметить,что свойства имеют все типы объектов – OU, CN и другие.

В том случае если доступ анонимным пользователямк записям блокирован, то необходимо читать свойстваобъектов от имени учетной записи, которая имеет правана чтение свойств. Пусть пользователь User1 имеет пра-во на чтение всех полей объектов. Пароль пользователяUser1 – 1234567. Осуществим чтение идентификационногономера учетной записи User3 от имени User1. Чтение па-раметров от имени другого пользователя осуществляет-ся с помощью функции OpenDSObject():

Изменение атрибутовучетной записиМодификация атрибутов учетной записи осуществля-ется с помощью функции Put() и метода SetInfo, служа-щего для сохранения внесенных изменений в ActiveDirectory. В приведенном ниже примере атрибут учет-ной записи User3 – Canonical Name (CN) будет измененс User3 на User4.

InetOrgPerson – тип учетной записи.

Создание и удалениеучетной записиДля создания учетной записи в Active Directory необхо-димо задать несколько обязательных параметров, от-носящихся к учетной записи и ее родительскому кон-тейнеру:! создание учетной записи должно выполняться пользо-

вателем, имеющим административные привилегии;! путь к родительскому контейнеру, в котором необходи-

мо создать учетную запись;! класс создаваемого объекта;! соответствующие свойства создаваемого класса объек-

та записи.

Ïðèìåð 2:Set obj=GetObject("LDAP://CN=User3, OU=Group1, ↵↵↵↵↵OU=Users, o=domain.ru")For Each U_obj In obj

wscript.echo "UserUID: " & U_obj.Get("uid")Next

Ïðèìåð 3:Set PreObj= GetObject("LDAP:")

Set obj= PreObj.OpenDSObject("LDAP://CN=User3, OU=Group1, ↵↵↵↵↵OU=Users, o=domain.ru", "CN=User1","1234567",0)For Each U_obj In obj

wscript.echo "UserUID: " & U_obj.Get("uid")Next

Ïðèìåð 4:Set PreObj= GetObject("LDAP:")

Set obj= PreObj.OpenDSObject("LDAP://CN=User3, OU=Group1, ↵↵↵↵↵OU=Users, o=domain.ru", "CN=User1","1234567",0)

Set U_obj=obj.GetObject("InetOrgPerson","CN=User3")U_obj.Put "CN","User4"U_obj.SetInfoMsgBox "Ïàðàìåòð CN èçìåíåí."

Ïðèìåð 5:Set PreObj= GetObject("LDAP:")

Set obj= PreObj.OpenDSObject("LDAP:// OU=Group1, OU=Users, ↵↵↵↵↵o=domain.ru", "CN=User1","1234567",0)

Set U_obj=obj.Create("InetOrgPerson","CN=User3")ClassArray=Array("InetOrgPerson","person","top","organizationPerson")U_obj.Put "objectClass", ClassArrayU_obj.Put "cn", "User_Name_3"U_obj.Put "sn", "Second_Name_3"U_obj.SetInfoMsgBox "Ó÷åòíàÿ çàïèñü ñîçäàíà."

Page 94: 016 Системный Администратор 03 2004

93№3(16), март 2004

образование

Для удаления учетных записей используется методDelete («InetOrgPerson», object_name).

ЗаключениеНа практике управление Active Directory преимуществен-но осуществляется с помощью провайдера WinNT или всовокупности WinNT с LDAP. В «чистом» виде програм-мирование LDAP используется очень редко. Основнаяпричина заключается в том, что для доступа к любомуобъекту с помощью провайдера LDAP необходимо знатьполный путь к этому объекту. Эта проблема легко реша-ется: происходит осуществление поиска объекта, затемчтение его свойств. Приведем пример чтения поляFullName для пользователя USER1 с помощью провайде-ров LDAP и WinNT.

Ïðèìåð 6 a) - WinNT:Set obj=GetObject("WinNT:")

For Each str In objDomainName=str.NameNext

Set UserName="Value"Set element=GetObject("WinNT://" & DomainName & "/ USER1")Msgbox "FullName: "+ cstr(element.FullName)Ïðèìåð 6 á) - LDAP:set rootDSE_ = GetObject("LDAP://RootDSE")DomainName = rootDSE_.Get("defaultNamingContext")UserLogonName="USER1"Const ADS_SCOPE_SUBTREE = 2Set objConnection = CreateObject("ADODB.Connection")Set objCommand = CreateObject("ADODB.Command")objConnection.Provider = "ADsDSOObject"objConnection.Open "Active Directory Provider"Set objCommand.ActiveConnection = objConnectionobjCommand.CommandText = "SELECT name, sAMAccoutName ↵↵↵↵↵

FROM " _ & " 'LDAP://"& DomainName & "' ↵↵↵↵↵WHERE objectClass='users'"

objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREEobjCommand.Properties("Cache Results") = FalseSet objRecordSet = objCommand.Execute

objRecordSet.MoveFirstDo Until objRecordSet.EOFIf objRecordSet.Fields("sAMAccoutName").Value=UserLogonNamemsgbox "FullName: "+ objRecordSet.Fields("name").Valueend ifLoop

Как видно, листинг примера 6 б) в несколько раз больше,чем листинг примера 6 а). За счет того, что в примере 6 б)«просматривается» весь массив пользователей, сценарийбудет отрабатываться в несколько раз медленнее, чем сце-нарий 6 а). Скорость выполнения сценария напрямую зави-сит от количества объектов в просматриваемом массиве.Очевидно, что чем больше размер массива, тем медленнеебудет работать скрипт.

Многократное использование данного механизма в од-ном скрипте дополнительно уменьшит скорость выполненияскрипта и увеличивает его размер по сравнению с анало-гичным скриптом, в котором доступ к объектам осуществля-ется с помощью провайдера WinNT. Однако отказаться отдоступа к AD с помощью провайдера LDAP невозможно, по-скольку существует много функций, которые реализованытолько в провайдере LDAP. Оптимальным вариантом явля-ется совместное использование провайдеров LDAP и WinNT.Ярким примером является чтение свойств сетевого принте-ра: с точки зрения провайдера WinNT принтер – локальноеустройство, с точки зрения LDAP – сетевое.

Литература:1. Коробко И. Active Directory – теория построения. –

// Журнал «Системный администратор», №1(14), ян-варь 2004 г. – 90-94с.

2. Коробко И. Программное управление ADSI: WinNT. –// Журнал «Системный администратор», №2(15), фев-раль 2004 г. – 66-74с.

3. Коробко И. Управление сетевыми принтерами доме-на. – // Журнал «Системный администратор», №10(11),октябрь 2003 г. – 38-46с.

Page 95: 016 Системный Администратор 03 2004
Page 96: 016 Системный Администратор 03 2004

95№3(16), март 2004

подписка

Рады видетьВас нашимичитателями!

Подписнойиндекс:

81655по каталогуагентства«Роспечать»

Открыта подписка на II полугодие 2004 г.Более подробная информация на сайте www.samag.ru

в разделе «Подписка»

подпискаподпискаподпискаподпискаподписка

Page 97: 016 Системный Администратор 03 2004

96

СИСТЕМНЫЙ АДМИНИСТРАТОР№3(16), Март, 2004 год

РЕДАКЦИЯИсполнительный директорВладимир ПоложевецОтветственный секретарьНаталья Хвостова[email protected]Технический редакторВладимир ЛукинРедакторАндрей БешковНаучно-технические консультантыДмитрий ГоряиновВалерий Цуканов

РЕКЛАМНАЯ СЛУЖБАтел./факс: (095) 928-8253Константин Меделянreс[email protected]

Верстка и оформление[email protected][email protected]Дизайн обложкиНиколай Петрочук

103045, г. Москва,Ананьевский переулок, дом 4/2 стр. 1тел./факс: (095) 928-8253Е-mail: [email protected]: www.samag.ru

РУКОВОДИТЕЛЬ ПРОЕКТАПетр ПоложевецУЧРЕДИТЕЛИВладимир ПоложевецАлександр Михалев

ИЗДАТЕЛЬЗАО «Издательский дом«Учительская газета»

Отпечатано типографиейГП «Московская Типография №13»Тираж 6600 экз.Журнал зарегистрированв Министерстве РФ по делам печати,телерадиовещания и средств мас-совых коммуникаций (свидетельствоПИ № 77-12542 от 24 апреля 2002г.)

За содержание статьи ответственностьнесет автор. За содержание рекламно-го обьявления ответственность несетрекламодатель. Все права на опубли-кованные материалы защищены. Ре-дакция оставляет за собой право изме-нять содержание следующих номеров.

ЧИТАЙТЕВ СЛЕДУЮЩЕМНОМЕРЕ:

Transparent proxy.Быть или не быть?Данная статья посвящена проблемампрозрачного проксирования на приме-ре популярного сервера Squid. В каче-стве ОС использовалась стабильнаяверсия FreeBSD 4.7. При работе прокси-сервера в прозрачном режиме (Trans-parent mode) для веб-доступа пользо-вателей в Интернет не требуется на-страивать браузер для взаимодействияс прокси на каждом рабочем месте, асами пользователи могут вообще незнать о существовании прокси-серве-ра. В таком режиме администраторы итехники получают меньше вопросов ижалоб от пользователей по настройкепользовательского ПО. Технически этотрежим реализуется следующим обра-зом. С помощью брандмауэра все со-единения на определённый порт (в слу-чае HTTP – порт 80) внешних серверовперенаправляются на локальный портпрокси сервера (обычно – 3128).

По стандарту протокола HTTP 1.1(RFC2616) каждый запрос клиентадолжен содержать заголовок «Host»,в котором указывается адрес сервера-получателя запроса. Именно с помо-щью этого заголовка прокси-серверопределяет адресата и соединяется сним. Что же касается других популяр-ных протоколов (FTP, HTTPS, и т. д.),то такой возможности в них просто непредусмотрено. На этой «весёлой ноте»можно начать описание проблем.

Работа по расписаниюв FreeBSDСпособность операционной системывыполнять задачи в заданное время(по расписанию) может сделать ад-министрирование существенно про-ще и эффективнее, а в ряде случа-ев такая способность просто необ-ходима.

В данной статье рассмотренысредства отложенной работы и рабо-ты по расписанию, имеющиеся воFreeBSD (на примере FreeBSD 5.1),однако большинство описанных здесьфункций будут доступны вам и в дру-гих ОС семейства UNIX, включаяLinux. Особое внимание уделено ме-ханизмам работы, знание которых не-обходимо для эффективного поискавозможных проблем.

NTP – атомные часына каждом столеКаждый из нас, работая за компью-тером, иногда смотрит на часы. Приэтом кто-то поглядывает на стену, кто-то на руку, а кто-то бросает беглыйвзгляд в угол экрана монитора. Конеч-но, часы могут быть разными, глав-ное – чтобы они шли точно. И если дляобычных часов их точность во многомопределятся фирмой-производите-лем, то для практически любых «ком-пьютерных» высокая точность можетбыть достигнута благодаря синхро-низации времени, например, с помо-щью протокола NTP (Network TimeProtocol), об использовании которо-го и пойдет речь в данной статье.

Создание кластерана Windows 2000/2003.Шаг за шагомВ этой статье я попытаюсь собратьсвой опыт по созданию кластерныхсистем на базе Windows и дать не-большое пошаговое руководство посозданию двухузлового кластера сер-веров с разделяемым хранилищемданных.

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