Вы находитесь на странице: 1из 97

оглавление

АДМИНИСТРИРОВАНИЕ
DeviceLock
Запуск Windows-приложений под Linux Андрей Бешков
с помощью CrossOver Office tigrisha@sysadmins.ru 38
Часть 2
Андрей Бешков Три поросёнка Snort:
tigrisha@sysadmins.ru 4 «Ниф-ниф», «Нуф-нуф» и «Наф-наф».
(Настройка нескольких сенсоров Snort
с помощью SnortCenter)
А ты что видишь?
Удаленное управление посредством
rdesktop, RAdmin, VNC Павел Закляков
amdk7@mail.ru 42
Антон Борисов
a.borisov@tesv.tmb.ru 12
Ошибки переполнения буфера
извне и изнутри как обобщенный опыт
Свободная ДОС для свободных людей, реальных атак
или Не Linux единым жив человек
Крис Касперски
Андрей Маркелов kk@sendmail.ru 64
andrew@markelov.net 20

HARDWARE
С Юниксом на vi
Сергей Супрунов Реализация низкоуровневой поддержки
amsand@rambler.ru 24 шины PCI в ядре операционной системы
Linux

БЕЗОПАСНОСТЬ Владимир Мешков


ubob@mail.ru 74
Свободный антивирус
Обзор Clam AntiVirus – антивирусной программы для UNIX-
систем.
ОБРАЗОВАНИЕ

Сергей Яремчук Программное управление ADSI: LDAP


grinder@ua.fm 32
Иван Коробко
ikorobko@prosv.ru 88
Уважаемые читатели!
Рады сообщить вам, что с 1 апреля открыта подписка на II полугодие 2004 года.

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

Подписной индекс 87836 по каталогам:


Объединенный каталог «Пресса России» 2004/2
Каталог стран СНГ 2004/2
Каталог Казахстана 2004/2
Адресный каталог «Подписка за рабочим столом» 2004/2
Адресный каталог «Библиотечный каталог» 2004/2

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

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


№3(16), март 2004 1
УНИКАЛЬНЫЕ СОБЫТИЯ
НА КОМПЬЮТЕРНОМ РЫНКЕ
Впервые организованная в 1989 году, выставка Неделя 4. Software Expo – специализированная выставка, ори-
Информационных Технологий «IT Week Russia», изве- ентированная на программные продукты для систем
стная в прошлом как Comtek, за пятнадцать лет своего бухгалтерского и складского учета, комплексного ПО
существования пережила и взлеты и падения. В преды- управления предприятием, систем управления доку-
дущие годы в Неделю Информационных Технологий вхо- ментооборотом, систем распознавания документов,
дила выставка Сomtek, которая состояла из нескольких разработку ПО, защиту информации. В рамках этой
направлений, и конференция E-Business. Развитие выс- выставки будет подготовлен цикл тематических семи-
тавки в течение последних лет привело к необходимос- наров, посвященных актуальным вопросам в области
ти выделить отдельные разделы в самостоятельные вы- разработки экономических программ и систем управ-
ставки. С этого года в Неделю Информационных Техно- ления бизнесом.
логий будут входить пять самостоятельных выставок и 5. Специализированная выставка CAD/CAM/CAE пред-
две конференции. Этот шаг позволил расширить масш- ставляет системы автоматизированного проектиро-
таб выставки, объединяющей все аспекты компьютер- вания. Для большинства российских производителей
ного бизнеса, что, в свою очередь, дает возможность необходимость использования САПР для оптимиза-
привлечь к участию в выставке большее число компа- ции работы предприятия стала очевидной. Особенно
ний, занятых во всех сферах индустрии информацион- ярко это проявляется в таких отраслях, как авиастро-
ных технологий. ение, автомобилестроение, тяжелое машиностроение,
Давид Патеишвили, директор выставки, сказал: «В архитектура, строительство, нефтегазовая промыш-
этом году мы расширили темы, представленные на экс- ленность.
позиции, которые теперь охватывают все области компь- 6. eLearn Expo – специализированная выставка, на ко-
ютерной индустрии. Это дает превосходную возможность торой будут демонстрироваться новейшие продукты
и участникам, и посетителям выставки принять участие и и технологии в сфере электронного обучения, пред-
ознакомиться сразу с пятью выставками и двумя конфе- назначенные для коллективного и индивидуального
ренциями, проходящими в одно время и в одном месте. пользования. Дистанционное обучение через сети
Это также позволит нам улучшить маркетинговую и рек- Internet и Intranet, получившее широкое распростра-
ламную кампании для каждой из выставок и конферен- нение в развитых странах, становится все более ак-
ций, проходящих в рамках Недели Информационных Тех- туальным и для России.
нологий, с учетом целевой аудитории, специфичной для 7. eBusiness Russia (Электронный бизнес в России) –
каждой из них. Хочется добавить, что некоторые выстав- международная конференция, посвященная вопросам
ки, которые будут проходить в рамках Недели Информа- автоматизации бизнес-процессов, развития электрон-
ционных технологий, не имеют аналогов в России, явля- ной коммерции, подбора ИТ-персонала.
ясь тем самым уникальными».
В рамках Недели Информационных Технологий прой- Выставка IT-week остается ведущей международной
дут следующие выставки и конференции: выставкой информационных технологий в России и стра-
1. Personal Computing Expo – общая, неспециализиро- нах СНГ. Это уникальное место для проведения перего-
ванная выставка, ориентированная на конечных воров с первыми лицами сразу нескольких крупных фирм-
пользователей. В ней представлены производители и поставщиков оборудования и решений. Практически все
дистрибьюторы персональных компьютеров и перифе- крупные западные вендоры присутствуют на выставке не-
рии, компьютерных игр, дистрибьюторы сотовой тех- посредственно или при посредстве своих российских парт-
ники и портативных компьютеров, интернет- и контент- неров.
провайдеры и многие другие. В соответствии с растущими потребностями рынка и
2. Hardware & Peripherals Expo – специализированная увеличением числа участников экспозиция расширила
выставка, на которой представлены: компьютеры, мо- площадь, которая в этом году составит 8 000 кв. м. В выс-
ниторы, периферийные устройства, комплектующие, тавках, которые пройдут в течение 4 дней, примут учас-
накопители, коммуникационное оборудование и услу- тие 250 ведущих компаний отрасли из 25 стран мира.
ги, т.е. весь спектр hardware, ориентированного на ве- Ожидается, что число посетителей выставки превысит
дение бизнеса. 75 000 человек, включая руководителей верхнего и сред-
3. Международная конференция eLearning Russia (Инфор- него звена, технических специалистов и IT-администра-
мационные технологии в образовании), на которой бу- торов, из более 500 городов России и СНГ.
дут освещены последние достижения образовательных «IT Week 2004», 15-ая Международная Выставка Ин-
технологий в школах, вузах, а также рассмотрены воп- формационных Технологий пройдет в «Экспоцентре» на
росы дистанционного и бизнес-образования. Красной Пресне в Москве с 26 по 29 апреля 2004 года.

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

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

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

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

4
администрирование
Задача на сегодня довольно проста. Нужно изучить теорию ровать какую-либо DLL, Wine сначала смотрит в список встро-
функционирования и глубинные механизмы CrossOver Office. енных DLL, если там найти нужное не удалось, то начинает-
В дальнейшем это поможет нам правильно идентифициро- ся поиск на жестком диске родного Windows DLL-файла.
вать проблемы, возникающие при инсталляции Windows-про- Сердцем системы эмуляции служит Wine-сервер, если
грамм, а, как говорят врачи, правильный диагноз – полови- говорить по существу, то он необходим для правильной орга-
на лечения. Как было отмечено в первой статье, все Windows- низации межпроцессорных коммуникаций между всеми за-
программы делятся на два вида. Официально поддержива- пущенными Windows-приложениями и является отдельным
емое обеспечение скорее всего легко установится и будет однопоточным процессом с бесконечным циклом выборки и
гладко работать под управлением CrossOver Office, навевая обработки сообщений, приходящих от системы и клиентс-
на вас мысли о невыносимой легкости бытия Linux-пользо- ких процессов. Из-за отсутствия многопоточности внутри
вателя. К сожалению, список этих программ не так уж ве- своего процесса Wine-сервер не может выполнять задачи,
лик. Ознакомиться с ним можно по следующему адресу: требующие существенных временных затрат. Впрочем пе-
http://www.codeweavers.com/site/compatibility/browse/cat. редача сообщений и событий между клиентскими процес-
Кстати, стоит отметить, что в него входят только те при- сами и основной системой действительно не является тру-
ложения, за стабильную работу которых сотрудники ком- доемкой работой. Также в целях безопасности Wine-сервер
пании Codeveawers могут поручиться на все сто процен- не имеет доступа к адресному пространству своих клиен-
тов. К сожалению, сотрудников в компании не так уж и мно- тов. Если в момент старта первого клиентского Wine-про-
го, поэтому они не могут знать о всех используемых вами цесса процесс Wine-сервера еще не работает, то он будет
Windows-приложениях. Впрочем, даже если они и будут незамедлительно запущен. Сразу же после начала работы
знать, это не очень изменит положение вещей. Ведь на те- Wine-сервер создает UNIX-сокет, предназначенный для об-
стирование каждого приложения нужно потратить немало щения с клиентами, отвечающими за выполнение Windows-
времени. Таким образом, получается, что приложения, не приложений. Обычно сокет находится в директории $HOME/
подвергшиеся тестированию под CrossOver Office, не по- .wine либо там, куда указывает переменная окружения
лучают официальной поддержки. Ничего страшного в этом WINEPREFIX. Ну а если мы используем CrossOver Office, то
нет. Возможно, при работе с нашими Windows-программа- сокет возникнет в директории /tmp/wine-<имя пользователя>.
ми все будет хорошо, и нам никогда не придется прибегать После того как все клиентские Wine-процессы будут завер-
к поддержке персонала Сodeveawers. Например, я доволь- шены, закончит свою работу и Wine-сервер. Методы работы
но легко установил Remote Administrator, QuickTime Player, с приложениями win32 и win16 довольно сильно отличаются.
Acrobat Reader и Microsoft Visio и весьма успешно работаю Для программ с архитектурой win16, доставшихся нам в на-
с этими приложениями. Все вышесказанное означает толь- следство от старых версий Windows, характерно функцио-
ко то, что, начав работать с неподдерживаемыми програм- нирование в едином адресном пространстве и использова-
мами, надеяться нам не на кого и мы, как кошки, начинаем ние кооперативной многозадачности. Исходя из таких тре-
гулять сами по себе. Впрочем, это ни в коем случае не дол- бований, удобнее всего было сделать так, чтобы все запу-
жно страшить нас. щенные win16-программы выполнялись не как отдельные
В связи с тем, что CrossOver Office основан на коде, унас- процессы, а стали нитями в рамках одного процесса. Идея
ледованном от Wine, практически все, о чем я буду расска- подобного механизма работы с устаревшими приложения-
зывать в этой статье, может вполне успешно применяться ми была позаимствована из Windows NT, поэтому так же,
при работе с Wine. Итак, начнем с самых основ и посмотрим, как и в системе-прародителе, сущность, обеспечивающая
что происходит в системе во время запуска Windows-прило- функционирование приложений win16, называется WOW-
жений. Сам по себе процесс загрузки программы в память процессом. Внутри него разные нити, олицетворяющие от-
несложен. Проблема в том, что нужно найти и загрузить все дельные приложения, синхронизируются друг с другом с по-
требуемые DLL. Затем провести импортирование из DLL тре- мощью мьютекса. Нить, работающая в данный момент, зах-
буемых функций и правильно найти точки входа в каждую ватывает мьютекс в эксклюзивное владение и соответствен-
из них. Предполагается, что каждое нормально написанное но не позволяет работать остальным нитям. Как только ак-
приложение, как и любые небазовые DLL, не станет пытать- тивная нить посчитает, что выполнила достаточно действий,
ся использовать напрямую системные функции, а вместо это- мьютекс будет освобожден и начнет подавать сигналы, ука-
го будет импортировать все требуемые механизмы из ос- зывающие на его холостятский статус. В результате этого
новных системных библиотек. Соответственно для того, что- он будет вновь захвачен следующей нитью, стоящей в оче-
бы Wine смогла нормально загружать Windows-приложения, реди на выполнение. Таким образом реализуется коопера-
нужно как минимум заменить своими собственными реали- тивная многозадачность. Ну а WOW-процесс будет существо-
зациями основные системные DLL, в число которых входят вать до тех пор, пока внутри него работает хотя бы одна нить.
USER/USER32, GDI/GDI32, KERNEL/KERNEL32 и NTDLL. Приемы, используемые для работы с win32-программами,
Кстати, стоит отметить, что многие функции, реализован- выглядят совершенно иначе. Для каждого выполняемого
ные изначально в KERNEL32 и ADVAPI32, постепенно были внутри Wine приложения win32 создается свой собственный
перенесены в NTDLL. Динамические библиотеки, заново процесс, так как программы такого типа написаны в расчете
реализованные для Wine, называются «встроенными», а те, на вытесняющую многозадачность и отдельное виртуальное
что перенесены из Windows без каких-либо изменений, на- адресное пространство для каждого экземпляра. Каждый
зываются «родными». Соответственно в тот момент, когда клиентский процесс Wine имеет в своем составе специаль-
Windows-приложение заявляет о своем желании импорти- ную сервисную нить, выполняющуюся наравне с остальны-

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


администрирование
ми нитями этого процесса. Ее функция состоит в том, чтобы CrossOver Office хранит все эти директории в $HOME/
выполнять задачи, которые нельзя поручить Wine-серверу. .cxoffice/dotwine/fake_windows/. Создаются они автомати-
Например, с помощью него удается реализовать для каждо- чески и так же легко наполняются всеми необходимыми
го процесса отдельную очередь ожидания событий, исходя- файлами сразу же после запуска программы /opt/cxoffice/
щих от системы и других Wine-процессов. По приходу собы- bin/officesetup.
тия сервисная нить процесса выходит из состояния сна, об- Вот теперь, когда мы уже разобрались со многими ню-
рабатывает поступившее событие и передает сообщение о ансами работы эмулятора, пришло время посмотреть, как
нем другим нитям процесса. Любые компоненты ядра wine выглядит изнутри главный конфигурационный файл. Для
могут устанавливать свои собственные обработчики в сер- Wine этот файл называется $HOME/.wine/wine.conf, а для
висную нить, если есть необходимость выполнять какие-либо CrossOver соответственно $HOME/.cxoffice/dotwine/config.
действия вне зависимости от цикла выборки сообщений эму- Формат обоих файлов почти ничем не отличается в обеих
лируемого приложения. реализациях. Первые несколько секций отвечают за оп-
Следующей проблемой является поддержка реестра. ределение виртуальных дисков для Windows-системы.
Ведь в любой, даже свежеустановленной Windows-системе Проблема состоит в том, что в UNIX-подобных операци-
в реестре уже записано довольно большое количество дан- онных системах, в отличие от Windows, файловая систе-
ных, поэтому нам необходимо иметь свою собственную реа- ма не разбита на отдельные диски, обозначаемые латин-
лизацию реестра. В отличие от Windows, где реестр хранит- скими буквами от A до Z, а представлена единым дере-
ся в бинарном формате, wine использует для этой цели обыч- вом. Ну а вторая досадная неувязка кроется в том, что
ный текстовый файл. Соответственно ключи реестра запи- традиционная файловая система Windows не различает
сываются примерно в таком формате: строчные и прописные буквы в именах файлов и директо-
рий. Соответственно файл с именем MyDOCUMENT и
[AINF0008\\0.map] 1069188705 mydocument для Windows являются одним и тем же. Та-
"008cc782b199a527"=",33,HKCR,Interface\\ ↵
{56a868b5-0ad4-11ce-b03a-0020af0ba770}\\Distributor,,"i ким образом, перед нами стоит задача сделать так, что-
"140e1cba790e4932"=",33,HKLM,Software\\Microsoft\\ ↵ бы Windows считала некоторые директории файловой си-
Multimedia\\DirectXMedia,.Prog,"
стемы UNIX своими виртуальными дисками. Кстати, сто-
А это значит, что в случае необходимости мы легко смо- ит отметить, что те строки, которые начинаются знаком
жем добавлять или удалять данные в этот импровизиро- «;», воспринимаются эмулятором как комментарии.
ванный реестр с помощью обычного текстового редактора.
Текстовый формат хранения данных не единственное отли- # Èìÿ âèðòóàëüíîãî äèñêà.  äàííîì ñëó÷àå ýòî äèñê A:
[Drive A]
чие реестра, используемого Wine, от настоящего Windows- # Ïóòü ê äèðåêòîðèè, êîòîðàÿ õðàíèò â ñåáå ôàéëû. Ïî óìîë÷àíèþ
реестра. Дело в том, что под Wine реестр хранится не в # ñêðèïò èíñòàëëÿöèè âïèñûâàåò ñþäà äèðåêòîðèþ /mnt/floppy/,
# íî äëÿ ìåíÿ ýòî íå ïîäõîäèò â ñâÿçè ñ òåì, ÷òî â ìîåé
одном, а сразу в нескольких отдельных файлах. Сразу же # ñèñòåìå ðàáîòàåò äåìîí autofs, êîòîðûé ìîíòèðóåò óñòðîéñòâî
после инсталляции CrossOver Office ветви реестра, обес- # äèñêîâîäà /dev/floppy â äèðåêòîðèþ /mnt/floppy/auto/.
# Ïîýòîìó ïðèøëîñü ïîïðàâèòü ïóòü âðó÷íóþ.
печивающие базовую функциональность Windows, будут за- "Path" = "/mnt/floppy/auto"
писаны в файл system.reg, находящийся в директории # Òèï óñòðîéñòâà. Äóìàþ, âñåì ïîíÿòíî, ÷òî äëÿ Windows îíî
# áóäåò âûãëÿäåòü êàê ãèáêèé äèñê. Ýòà ïåðåìåííàÿ ìîæåò
$HOME/.cxoffice/dotwine. Дабы не испортить системный # ïðèíèìàòü çíà÷åíèÿ hd, cdrom, network, floppy ñîîòâåòñòâåííî
реестр, все изменения, вносимые в него во время установ- # îáîçíà÷àþùèå æåñòêèé äèñê, CD-ROM, ñåòåâàÿ ïàïêà,
# ãèáêèé äèñê.
ки и последующего жизненного цикла пользовательских "Type" = "floppy"
программ, записываются в отдельный файл user.reg. # Ìåòêà òîìà. Îáû÷íî íóæíà òîëüêî äëÿ ïðîãðàìì, êîòîðûå
# ïûòàþòñÿ çàùèùàòüñÿ îò êîïèðîâàíèÿ ñ ïîìîùüþ ÷òåíèÿ ýòîé
Следующим условием, необходимым для правильного # ìåòêè.
функционирования Windows-программ, является наличие "Label" = "Floppy A"
# Èìÿ ôèçè÷åñêîãî óñòðîéñòâà îáû÷íî èñïîëüçóåòñÿ äëÿ
на диске строго определенной иерархии директорий. С точ- # íèçêîóðîâíåâîãî ÷òåíèÿ è çàïèñè. Ýòó îïöèþ ìîæíî ïðèìåíÿòü
ки зрения Windows наши директории должны выглядеть так. # òîëüêî ê ãèáêèì äèñêàì è 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"

6
администрирование
# Îïöèÿ, îòâå÷àþùàÿ çà ïåðåêîäèðîâàíèå èìåí ôàéëîâ # ïðîãðàìì îêîííîãî ìåíåäæåðà
# è äèðåêòîðèé â ðîäíóþ êîäèðîâêó. "LinkProcessor" = "winemenubuilder.exe"
"Codepage" = "0"
# Òóò íàõîäÿòñÿ èêîíêè. Êñòàòè, ñòîèò îòìåòèòü, ÷òî
# Îïèñàíèå äèñêà M: # äëÿ óäîáñòâà îáðàùåíèÿ îíè àâòîìàòè÷åñêè êîíâåðòèðóþòñÿ
[Drive M] # èç ôîðìàòà ico â xpm.
# Ýòî ïåðâûé CD-ROM â ñèñòåìå. Êàê îáû÷íî, èç-çà äåìîíà "IconsDir" = "c:\\Windows\\Icons"
# autofs ïðèøëîñü ïîìåíÿòü ïóòü ñ /mnt/cdrom íà /mnt/cdrom/auto
"Path" = "/mnt/cdrom/auto" # Íó à çäåñü ëåæèò áèáëèîòåêà, îòâå÷àþùàÿ çà ðàáîòó
"Type" = "cdrom" # ñ FreeType-øðèôòàìè.
"Label" = "CD-ROM M" "FreeTypeLib" = "libcxfreetype.so"
"Filesystem" = "win95"
"Device" = "auto"
[Restart]
# Îïèñàíèå äèñêà N: # Ïðîãðàììà ïî èäåå äîëæíà îòâå÷àòü çà ïåðåçàãðóçêó Windows.
[Drive N] # Èíòåðåñíî, ÷òî òàêîãî ôàéëà íà äèñêå íå ñóùåñòâóåò.
# Âòîðîé CD-ROM. Âñå óñòàíîâêè ñäåëàíû àíàëîãè÷íî äèñêó M. # À åãî ôóíêöèè âûïîëíÿåò ñêðèïò /opt/cxoffice/bin/cxreboot.
"Path" = "/mnt/cdrom1/auto" # Âèäèìî, êòî-òî èç ðàçðàáîò÷èêîâ äîïóñòèë òóò îøèáêó.
"Type" = "cdrom" "Boot" = "c:\\Windows\\System\\reboot.exe"
"Label" = "CD-ROM N"
"Filesystem" = "win95" # [wineconf]
"Device" = "auto"
[Version]
# Îïèñàíèå äèñêà Y: # Êàêóþ âåðñèþ Windows äîëæåí èìèòðèðîâàòü ýìóëÿòîð?
[Drive Y] # Îïöèÿ ìîæåò ïðèíèìàòü çíà÷åíèÿ: win95, win98, winme, nt351,
# Çäåñü â êà÷åñòâå äèñêà Y ìîíòèðóåòñÿ äîìàøíÿÿ äèðåêòîðèÿ # nt40, win2k, winxp, win2k3, win20, win30, win31. Íåêîòîðûå
# ïîëüçîâàòåëÿ. # ïðîãðàììû áóäóò ðàáîòàòü òîëüêî ïîä îïðåäåëåííîé âåðñèåé.
"Path" = "%HOME%" "Windows" = "win98"
# À âîò òàêîé òèï óñòðîéñòâ â ñòàíäàðòíîì Wine íå âñòðå÷àåòñÿ,
# îí õàðàêòåðåí òîëüêî äëÿ CrossOver Office. Âïðî÷åì, äëÿ Windows # Âåðñèÿ MS-DOS. Íóæíà äëÿ íåêîòîðûõ ñòàðûõ ïðîãðàìì.
# ýòî óñòðîéñòâî âñå ðàâíî âûãëÿäèò, êàê îáû÷íûé æåñòêèé äèñê. ;;"DOS" = "6.22"
"Type" = "%CXOFFICE_DRIVE_TYPE_HACK%"
"Label" = "Home"
"Filesystem" = "win95" Следующая интересная для нас секция конфигураци-
"Codepage" = "0" онного файла управляет порядком загрузки динамических
# Îïèñàíèå äèñêà Z: библиотек. Иногда случается так, что Windows-приложение
[Drive Z] лучше работает с родными библиотеками, чем с теми, что
# À òóò ìîíòèðóåòñÿ êîðåíü âñåé ôàéëîâîé ñèñòåìû.
"Path" = "/" предлагает эмулятор.
"Type" = "%CXOFFICE_DRIVE_TYPE_HACK%"
"Label" = "Root"
"Filesystem" = "win95" [DllOverrides]
"Codepage" = "0" "ole2" = "native, builtin"
"ole2nls" = "native, builtin"
Разобравшись с виртуальными дисками, идем дальше. "*comctl32" = "builtin"
"*ICWCONN1.EXE" = "builtin"
Следующая интересная для нас секция выглядит так: "*IEINFO5.OCX" = "builtin"

[wine] Процедура загрузки библиотек читает опции слева на-


# Èìåíà ñèñòåìíûõ äèðåêòîðèé
"Windows" = "c:\\Windows" право. Соответственно, к примеру, для ole32 ключевое сло-
"System" = "c:\\Windows\\system" во native означает, что эмулятор должен сначала найти на-
"Temp" = "c:\\Windows\\Temp"
стоящую Windows-библиотеку и только в случае неудачи пы-
# Ñèñòåìíàÿ ïåðåìåííàÿ PATH óêàçûâàåò, ãäå è â êàêîì ïîðÿäêå таться подменить ее встроенной версией. Как видите, опи-
# çàãðóæàåìûå ïðîãðàììû äîëæíû èñêàòü íåîáõîäèìûå äëÿ ðàáîòû
# áèáëèîòåêè è óòèëèòû. сание имен библиотек позволяет использовать шаблоны. Ко-
"Path" = "c:\\Windows;c:\\Windows\\system;y:\\" нечно, иногда изменение порядка загрузки тех или иных ком-
# Äàííàÿ îïöèÿ óêàçûâàåò, ãäå äîëæíû õðàíèòüñÿ ïîëüçîâàòåëüñêèå понентов помогает оживить те или иные безнадежные
# ïðîôèëè, íî â ñâÿçè ñ òåì, ÷òî ó íàñ âñåãî îäèí ïîëüçîâàòåëü, Windows-приложения. Но все же стоит отдавать себе отчет,
# îíà íèêîãäà íå èñïîëüçóåòñÿ è ïîýòîìó çàêîììåíòèðîâàíà.
;;"Profile" = "c:\\Windows\\Profiles\\Administrator" что жонглирование библиотеками может запросто довести
систему эмуляции до критических ошибок. Впрочем, особен-
# Êàêóþ ãðàôè÷åñêóþ ïîäñèñòåìó íóæíî èñïîëüçîâàòü äëÿ ðèñîâàíèÿ
# ýêðàííûõ îáúåêòîâ. но пугаться не стоит, как только порядок загрузки библио-
"GraphicsDriver" = "x11drv" тек будет восстановлен, все сразу же вернется на круги своя.
# Äîëæíû ëè Windows-ïðîãðàììû âèäåòü ôàéëû, ó êîòîðûõ ïåðâûì Разобравшись с понятием подмены загружаемых биб-
# ñèìâîëîì èìåíè ÿâëÿåòñÿ òî÷êà. Îáû÷íî òàêèå ôàéëû ñ÷èòàþòñÿ лиотек, идем дальше по файлу конфигурации к секции, от-
# ñêðûòûìè.
;;"ShowDotFiles" = "1" вечающей за работу с графическими драйверами. Драй-
вер X11, используемый в Wine для работы с графикой, по
# Ìîæíî ëè ïîêàçûâàòü ñèìâîëè÷åñêèå ññûëêè íà äèðåêòîðèè?
# Îáû÷íî ýòî ïðèâîäèò ê çàâèñàíèþ Windows-ïðîãðàìì, замыслу разработчиков должен заниматься отрисовкой
# ïûòàþùèõñÿ äåëàòü ðåêóðñèâíûé îáõîä äèðåêòîðèé. ×àùå âñåãî элементов графического интерфейса только внутри окон,
# â ýòó ëîâóøêó ïîïàäàþòñÿ ðàçíîîáðàçíûå àâòîìàòè÷åñêèå
# èíñòàëëÿòîðû. предоставляемых системным оконным менеджером, и не
;;"ShowDirSymlinks" = "1" более того. А менеджер, в свою очередь, не вторгается на
# Óêàçàíèå íà ñêðèïò, îòâå÷àþùèé çà ñîçäàíèå è óñòàíîâêó территорию окон, предоставленных Wine, и всего лишь уп-
# ïðàâèëüíûõ èêîíîê äëÿ Windows-ïðîãðàìì âíóòðè âàøåãî îêîííîãî равляет их взаимоотношениями с основной системой.
# ìåíåäæåðà.  êà÷åñòâå ìåíåäæåðîâ, ê ïðèìåðó, ìîãóò âûñòóïàòü
# GNOME, KDE èëè CDE.
"ShellLinker" = "wineshelllink" [x11drv]
# Êîëè÷åñòâî öâåòîâ, âûäåëÿåìûõ èç ñèñòåìíîé ïàëèòðû äëÿ íóæä
# Ïðîãðàììà, îòâå÷àþùàÿ çà ñîçäàíèå è îáñëóæèâàíèå ìåíþ # Windows-ïðîãðàìì. Äåéñòâóåò òîëüêî â òîì ñëó÷àå, êîãäà

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


администрирование
# ãðàôè÷åñêàÿ ïîäñèñòåìà ðàáîòàåò â ðåæèìå ãëóáèíû öâåòà [serialports]
# 8 áèò íà îäèí ïèêñåëü èëè 256 öâåòîâ. "Com1" = "/dev/ttyS0"
"AllocSystemColors" = "100" "Com2" = "/dev/ttyS1"
"PrivateColorMap" = "N" "Com3" = "/dev/ttyS2"
"Com4" = "/dev/modem"
# Ïûòàòüñÿ ëè èñïîëüçîâàòü áîëåå ìåäëåííûå îïåðàöèè âìåñòî
# áûñòðûõ äëÿ óëó÷øåíèÿ êà÷åñòâà îòðèñîâêè. Ëè÷íî ìíå Вот тут у нас расписаны опции, необходимые для нор-
# ïîêàçàëîñü, ÷òî â áîëüøèíñòâå ñëó÷àåâ ðàçíèöà íå áóäåò çàìåòíà. мальной работы LPT-порта и принтера, если он, конечно,
"PerfectGraphics" = "N"
к нему присоединен. Ну и конечно же, описан стандарт-
# Óêàçûâàåò, êàêóþ ãëóáèíó öâåòà íåîáõîäèìî èñïîëüçîâàòü. ный механизм работы с файлом подкачки и фильтрами
# Èìååò ñìûñë òîëüêî äëÿ äèñïëååâ, óìåþùèõ ðàáîòàòü â ðåæèìå
# multi-depth. Ïî óìîë÷àíèþ îòêëþ÷åíî, òàê êàê èñïîëüçóåòñÿ принтера.
# êðàéíå ðåäêî.
;;"ScreenDepth" = "16"
[parallelports]
# Èìÿ äèñïëåÿ, íà êîòîðûé íóæíî âûâîäèòü ãðàôèêó. "Lpt1" = "/dev/lp0"
;;"Display" = ":0.0"
[spooler]
# Äàííàÿ îïöèÿ ïîêàçûâàåò, ðàçðåøåíî ëè îêîííîìó ìåíåäæåðó "FILE:" = "tmp.ps"
# óïðàâëÿòü îêíàìè Wine "LPT1:" = "|lpr"
"Managed" = "Y" "LPT2:" = "|gs -sDEVICE=bj200 -sOutputFile=/tmp/fred -q -"
"LPT3:" = "/dev/lp3
#  ñëó÷àå åñëè ïðåäûäóùàÿ îïöèÿ àêòèâèðîâàíà, ìîæíî ëè
# ïîçâîëèòü ìåíåäæåðó ðèñîâàòü ðàìêè îêîí è ïðî÷èå ýëåìåíòû. Кстати, стоит отметить, что работа с принтером в
# Ýòè äâå îïöèè óëó÷øàþò èíòåãðàöèþ ýìóëèðóåìîãî ïðèëîæåíèÿ CrossOver Office сделана очень удобно. Несмотря на то
# ñ îñòàëüíûìè ïðîãðàììàìè, íî íå âñå çàäà÷è ìîãóò íîðìàëüíî
# ðàáîòàòü â òàêîì ðåæèìå. что в моей системе для печати используется CUPS, при-
; WMFrames = "Y" ложения Windows автоматически опознали все доступные
# Äàííûé ðåæèì âûñòóïàåò êîíêóðåíòîì äëÿ äâóõ ïðåäûäóùèõ îïöèé системе принтеры и без каких-либо дополнительных на-
# è ïîçâîëÿåò ðàáîòàòü Wine òàê, ñëîâíî ýòî íå ïðîñòî îêíî, строек стали отлично с ними работать.
# à âèðòóàëüíûé äåñêòîï. Ñîîòâåòñòâåííî âñå Windows-ïðèëîæåíèÿ
# áóäóò ðèñîâàòü ñâîè îêíà òîëüêî âíóòðè ýòîãî äåñêòîïà, òàê êàê Следующая сессия указывает, какой стиль иконок, кно-
# èì ýòî áîëüøå âñåãî ïîäõîäèò. Çà óïðàâëåíèå îêíàìè âíóòðè пок и прочего оформления использовать для рисования
# âèðòóàëüíîãî äåñêòîïà îòâå÷àåò Wine. Òàêîé ðåæèì ïîçâîëÿåò
# èçáåæàòü âçàèìîäåéñòâèÿ Windows-ïðèëîæåíèé ñ ñèñòåìíûì внутри эмулируемых приложений. Доступны стили Win31,
# îêîííûì ìåíåäæåðîì, ïîýòîìó îí íàèáîëåå ñîâìåñòèì c ìîäåëüþ Win95 и Win98.
# ðèñîâàíèÿ, èñïîëüçóåìîé íàñòîÿùåé Windows.
;;"Desktop" = "640x480"
[Tweak.Layout]
# Íóæíî ëè, ÷òîáû ïðèëîæåíèÿ, ðàáîòàþùèå ñ DirectDraw, ìîãëè "WineLook" = "Win95"
# âîñïîëüçîâàòüñÿ ïðåèìóùåñòâàìè ðàáîòû ñ ãðàôè÷åñêîé ïîäñèñòåìîé
# â ðåæèìå DGA (XFree86 Direct Graphic Architecture). Îáÿçàòåëüíî Далее в конфигурационном файле идут описания на-
# óáåäèòåñü, ÷òî ó âàñ åñòü äîñòóï ê óñòðîéñòâó /dev/mem
"UseDGA" = "Y" строек звуковой системы, но на них мы тоже не станем
# Åñëè ñ DGA ïîðàáîòàòü íå ïîëó÷èëîñü, òî ìîæíî ïîïðîáîâàòü
останавливаться, потому что они просты и понятны.
# çàñòàâèòü DirectX èñïîëüçîâàòü ðàçäåëÿåìóþ ïàìÿòü äëÿ îáìåíà Итак, закончив с изучением внутреннего строения
# äàííûìè ñ âèäåîïîäñèñòåìîé. Êîíå÷íî, ýòî áóäåò ðàáîòàòü CrossOver Office, перейдем к решению насущных проблем.
# ìåäëåííåå, ÷åì DGA, íî âñå æå áûñòðåå, ÷åì ïðèìåíÿåìûé
# ñòàíäàðòíî îáìåí äàííûìè ñ X11 ÷åðåç ñîêåò. В первой статье мы столкнулись с одним досадным не-
"UseXShm" = "Y" удобством. При пользовании программой /opt/cxoffice/bin/
# Ðàçðåøåíèå èñïîëüçîâàòü äëÿ îòðèñîâêè ðåæèì XVideo officesetup было замечено, что на вкладке «Menus» есть
"UseXVidMode" = "Y" список меню, созданных установленными приложениями
# Óëó÷øåííîå óïðàâëåíèå îêíîì, ïîëó÷èâøèì ôîêóñ ââîäà. и выглядящий вот так.
"UseTakeFocus" = "Y"
# Îïöèÿ äëÿ âêëþ÷åíèÿ ïðîäâèíóòîãî ñïîñîáà êîíòðîëÿ çà ìûøüþ.
# Î÷åíü ïîëåçíà äëÿ ïðèëîæåíèé, èñïîëüçóþùèõ DirectX
"DXGrab" = "N"
# Âêëþ÷àåò äâîéíóþ áóôåðèçàöèþ îêíà, â êîòîðîì îòðèñîâûâàåòñÿ
# äåñêòîï. Ïðèìåíÿåòñÿ òîëüêî âìåñòå ñ îïöèåé Desktop, îïèñàííîé
# âûøå. Î÷åíü ïîìîãàåò ïðè ðàáîòå ñ ïðèëîæåíèÿìè, èíòåíñèâíî
# èñïîëüçóþùèìè OpenGL .
"DesktopDoubleBuffered" = "N"
# Íîìåð ïîðòà äëÿ ðåæèìà XVideo. Íóæíî èñïîëüçîâàòü òîëüêî â
# ñëó÷àå, åñëè ó íàñ íåñêîëüêî ïîðòîâ.
;; "XVideoPort" = "43"

# Îïöèÿ, óêàçûâàþùàÿ, íóæíî ëè ðàáîòàòü â ñèíõðîííîì ðåæèìå.


# Îáû÷íî èñïîëüçóåòñÿ äëÿ îòëàäêè ïðîáëåì ñ X11.
;;"Synchronous" = "Y"
Дальше в этой секции идут настройки шрифтов, ис- Соответственно с помощью нажатия на кнопку
пользуемые для работы Windows-программ. Значения всех «Recreate menu entry» мы могли бы автоматически со-
параметров по умолчанию срабатывают нормально, по- здавать пункты меню для отображения в оконном ме-
этому заострять внимание на них мы не будем. При нали- неджере. Но, к сожалению, с русскими названиями меню
чии интереса все желающие могут ознакомиться с ними CrossOver Office дружить не захотел и при каждой по-
самостоятельно. Далее идет описание привязки виртуаль- пытке создать то или иное меню выводил вот такую
ных портов к физическим устройствам. ошибку.

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

Для исправления данной проблемы, мешающей нам


создавать меню, нужно открыть файл $HOME/.gnome2/
vfolders/applications.vfolder-info, найти в нем все словосо-
четания, содержащие следующий набор букв «яПЕДЯР-
БЮ» и удалить эти странные символы. Такое непонятное
слово получается, если неправильно перевести слово Поэтому нам нужно будет скачать шестую версию вруч-
«средства», содержащееся в названии меню «Средства ную и установить ее самостоятельно. Делается это довольно
Microsoft Office» из кодировки cp1251 в koi8-r. После того просто.
как мы выкорчевали все встречные слова «яПЕДЯРБЮ», Для начала убедимся, что версия Windows, под которую
создание пунктов меню для оконного менеджера должно маскируется CrossOver, называется win98. Для тех, кто за-
заработать так, как и положено. После этого конвертиру- был, как это сделать, напоминаю, что нужно посмотреть в
ем файл-заготовку в нужную кодировку и обновляем сис- файл config и найти в нем секцию [Version]. На отдельной
темное меню. машине или используя VMWare, запускаем операционную
систему Windows 98. Данная машина может быть подклю-
$ iconv -f cp-1251 -t utf-8 $HOME/.menu/cxoffice > ↵ чена к Интернету через прокси-сервер или напрямую. Ска-
$HOME/.menu/cxoffice
$ update-menus –n –u чиваем первую часть инсталлятора, соответствующую язы-
ку используемого у вас браузера: http://www.microsoft.com/
Подробно о смысле этих действий я писал в предыду- windows/ie/downloads/critical/ie6sp1/default.asp. После запус-
щей статье. На следующей картинке в качестве примера вы ка инсталляции используем опцию выборочной установки
можете посмотреть, как выглядит мое меню Windows-при- компонентов.
ложений.

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

Кстати, это всего лишь малый список Windows-приложе-


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

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


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

ADVAUTH.CAB FONTCORE.CAB ie6setup.exe


IELPKAD.CAB IE_S4.CAB iesetup.ini
README.CAB TS95.CAB BRANDING.CAB
FONTSUP.CAB IEDOM.CAB IE_S1.CAB
IE_S5.CAB MOBILE95.CAB SCR56EN.CAB
VGX.CAB CRLUPD.CAB HELPCONT.CAB
IEEXINST.CAB IE_S2.CAB IE_S6.CAB
MPLAYER2.CAB SETUPW95.CAB Ýòó ïàïêó ìîæíî óäàëèòü.txt
filelist.dat HHUPD.CAB IE_EXTRA.CAB
IE_S3.CAB iesetup.dir OAINST.CAB
SWFLASH.CAB

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

IE_S1.CAB IE_S2.CAB IE_S3.CAB


IE_S4.CAB IE_S5.CAB IE_S6.CAB
IEDOM.CAB SCR56EN.CAB

Но все же лучше перестраховаться и на всякий случай


скопировать все имеющиеся файлы во временную дирек- Бояться этого не стоит, просто нажмите кнопку «Да» и
торию Windows, которая у нас находится в $HOME/.cxoffice/ на следующий вопрос ответьте «Заменить все такие ком-
/dotwine/fake_windows/Temp. Распаковываем все файлы с поненты». Инсталляция весело побежит дальше и весьма
расширением .CAB с помощью утилиты cabextract вот та- благополучно доберется до этого момента:
ким образом.

#cabextract IE_S1.CAB IE_S2.CAB IE_S3.CAB

Утилита cabextract существует практически в каж-


дом дистрибутиве Linux. Не стоит пытаться распаковать
за один раз больше 3 файлов, иначе будете получать
ошибки «Segmentation fault».
Закончив с распаковкой, скопируйте файл nashbase.stf
в файл acmsetup.stf и через программу officesetup, как
обычно, начинаем инсталляцию Internet Explorer. Выбира- указывающего на то, что все необходимые файлы скопи-
ем пункт Advanced install и указываем, где у нас находит- рованы и нужно просто перезапустить Windows. Нажимать
ся файл acmsetup.exe. В ответ получаем вот такое весьма на единственную доступную на этом диалоговом окне
приятное для нас изображение. кнопку бесполезно. В ответ будем получать только вот та-
кие ошибки.

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

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


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

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


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

А ТЫ ЧТО ВИДИШЬ?
УДАЛЕННОЕ УПРАВЛЕНИЕ
ПОСРЕДСТВОМ RDESKTOP, RADMIN, VNC
... сейчас мы нажимаем на контакты
и перемещаемся к вам, но если эта машинка
не сработает, тогда уж вы с нами переместитесь,
куда мы вас переместим...
х/ф «Кин-Дза-Дза»

Время
Время идет,
идет, ваша
ваша фирма
фирма развивается.
развивается. Появилась
Появилась ЛВС,
ЛВС, сначала
сначала одноранговая,
одноранговая, затем
затем сс выделенными
выделенными
серверами.
серверами. Хорошо,
Хорошо, когда
когда сеть
сеть однородная,
однородная, все
все работают
работают вв однотипной
однотипной среде.
среде. Но
Но жизнь
жизнь диктует
диктует
свои
свои законы,
законы, вв силу
силу определенных
определенных причин
причин ЛВС
ЛВС получилась
получилась гетерогенной.
гетерогенной. ИИ не
не только
только гетерогенной,
гетерогенной,
но
но ии распределенной.
распределенной. Представьте
Представьте себе
себе машиностроительный
машиностроительный завод завод или
или фирму
фирму сс филиалами
филиалами по по всему
всему
городу.
городу. Что
Что делать,
делать, как
как управлять
управлять всем
всем этим
этим IT-богатством?
IT-богатством?
АНТОН БОРИСОВ
Можно бегать, как горная лань, по этажам и цехам, объяс- bash-2.05b# nmap -v -sS compaq
нять, разъяснять, учить. Можно нанять дополнительный
персонал. Научить бегать его. Однако запомните, что если
вы лично претендуете на звание системного администра-
тора, то главная черта, которая вам должна быть прису-
ща – это лень! В хорошем смысле этого слова (см. статью
Вячеслава Калошина «Каким видится хороший системный
администратор» в июльском номере журнала за 2003 г.).
Рассмотрим, как снизить расходы «на перемещение в про-
странстве и времени» бренного тела администратора.
Объяснять, как получить удаленное управление на
UNIX-машинах я не буду. Считаю, что это известный факт.
Цель этой статьи – показать, с помощью чего управлять с
UNIX-машины парком серверов и рабочих станций с уста-
новленной ОС Windows.
Начнем, пожалуй, с серверов. По всей видимости, у
вас установлены следующие семейства – Windows NT
Terminal Server 4.0, Windows 2000 Server/Advanced Server,
Windows 2003 Server, Datacenter и т. п. Отлично, это даже
нам на руку. Проверим, что установлены терминальные
службы удаленного доступа (terminal services). bash-2.05b# nmap -v -sS fuji

12
администрирование
Чтобы узнать, какой именно порт отвечает за терми- bash-2.05b$ ./configure --prefix=/usr/local/rdesktop
нальные службы, поступим следующим образом: bash-2.05b$ make
bash-2.05b# make install

bash-2.05b$ cat /usr/share/nmap/nmap-services | grep Remote\ Display Теперь пакет rdesktop установлен. Осуществляем со-
единение с удаленным сервером.

А тем, у кого нет nmap, можно посмотреть весь список rdesktop rubin
портов вот тут: http://www.iana.org/assignments/port-numbers.
При установленной службе он будет присутствовать в си- Стоит отметить, что в некоторых случаях соединение
стеме. может не заработать, а в ответ получим вот такую ошибку:
Можете на самом Windows-сервере запустить cmd.exe
и посмотреть порты, которые использует сервер в данный
момент:
Проблема в том, что по умолчанию используется 5-я вер-
netstat -na | more (èëè netstat -na > netstat.txt) сия RDP-протокола, а некоторые сервера, не обращая вни-
мания на все заплатки и обновления, продолжают говорить
Если портов с номером 3389 нет, то стоит добавить на 4-й версии. В таком случае нужно подать команду:
службу следующим образом: Пуск → Настройка → До-
бавление/Удаление Программ (Добавление Windows- rdesktop –4 rubin
компонентов).
В итоге получили работающую терминальную службу. На что выдается окно MSGINA для ввода имени пользо-
Что дальше, спросит любопытный читатель? вателя, пароля, домена (если таковой имеется).
Дальше сходим на сайт http://www.rdesktop.org и забе- Войдя в систему, мы работаем, как за родным Windows-
рем исходники программы rdesktop. Она использует про- терминалом. Есть некоторые специфические моменты,
токол RDP (т.е. протокол терминальной службы). После- когда нельзя использовать удаленный вход (но об этом в
дняя версия 1.3 (на момент написания статьи). Настройка другой раз). В общем, аскетично, т.к. только 256 цветов,
проста. но вы ведь не играть пришли, верно?

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

Теперь приступим непосредственно к запуску rad-


min.exe. В домашей директории есть каталог, относящий-
ся к wine – ~/.wine, где лежит файл конфигурации «config».
Для того чтобы в дальнейшем не было проблем с фокуси-
ровкой мышки и клавиатурного ввода, добавим следую-
Во времена, когда администраторы были еще белыми щие строчки:
и пушистыми, активную популярность приобрел пакет
Remote Administrator. [AppDefaults\\radmin.exe\\x11drv]
"Desktop" = "700x500"
Стоит отметить, что программа на момент своего по- "Managed" = "N"
явления на свет затмила свои аналоги. Одна из причин,
из-за чего программу устанавливают, – это возможность Строка «Desktop» = «700x500» означает, что для при-
показать оператору, работающему за удаленной маши- ложения radmin.exe необходимо использовать окно с гео-
ной, что именно у него нажимается не так, ибо перехва- метрией 700 на 500 точек. Облегчает поиск нашего при-
тывается управление как клавиатурой, так и мышкой. ложения radmin.exe, когда используется разный тип изме-
Среди дополнительных возможностей программы – нали- нения фокуса в оконном менеджере. Из рисунка видно,
чие в некоторой степени аналога ftp-сервиса. Авторизо- что открываемое приложение не будет максимизировано
вавшись на удаленной машине, появляется возможность оконным менеджером, а будет открыто с указанными раз-
перебросить туда файл с нашей локальной машины. мерами «горизонталь на вертикаль».
Еще один немаловажный момент – при нарушении Строка «Managed» = «N» приводит к тому, что изме-
настроек, например, swap-файл не прописался, удален- нить размеры не получится. В любом случае смотрите до-
ный/локальный пользователь не может зайти, т.к. окно кументацию к wine.
приглашения не появляется. Что делать? Выбираем ре- Теперь мы готовы к запуску.
жим работы с удаленной машиной «File transfer» и удаля-
ем неправильный swap-файл. /usr/local/wine/bin/wine ~/RAdmin/radmin.exe
Но! Данный продукт написан под Windows-платформу.
По заявлениям самих разработчиков, версию под UNIX- Подразумевается, что мы установили пакет в каталог
системы они разрабатывают, но как скоро она появится и RAdmin. Далее введем регистрационный ключ и, вуаля,
появится ли вообще – неизвестно. Переустанавливать на далее вопрос техники – заполнить имена хостов. С этого
всех клиентах что-то альтернативное, чтобы администра- момента у нас полноценный доступ к другим машинам с
тор мог со своей машины без затруднений управлять всем установленной radmin-службой.
парком, – лишняя беготня. Нужна ли она? Как увидим чуть Скажу несколько слов об обратной связи. Запустив на
далее – нет. Linux-машине radmin-сервис:
Что нам потребуется для запуска?
Windows-эмулятор, он же wine. Пакет, если у вас его /usr/local/wine/bin/wine ~/RAdmin/r_server.exe
нет, заберем на http://www.winehq.com. Настройка анало-
гична настройке rdesktop. с Windows-машин мы можем видеть рабочий экран Linux-
Никаких дополнительных опций я не задавал. Префикс машины. Правда, управлять нельзя, можно только наблю-
пути, где будет лежать пакет: дать. Это лирическое отступление. Замечены некоторые
проблемы с клавиатурой, а именно при нажатии комби-
--prefix=/usr/local/wine наций клавиш Shift+Key проявляется эффект «залипания»
Shift. С чем это связано, неизвестно. Известно, как от этого
Обращаю ваше внимание, что пакет громоздкий – по- избавиться. Нажать на настройке окна radmin.exe
требуется для сборки порядка 500 Мб. Плюс еще 260 Мб «Options», и залипание пропадет.
для готового к употреблению изделия. И напоследок посмотрим, что такое VNC.
Итак, собрали пакет, научились его запускать на про- VNC – Virtual Network Computing, пакет разрабатывал-
стейших Windows-играх, например, «Сапер», «Паук» и т. д. ся в лаборатории AT&T, сейчас доступен в свободной
Теперь устанавливаем у себя на Linux-машине Remote форме на сайте http://www.realvnc.com. Богатый ассор-
Administrator. тимент настроек, автоматическое определение необхо-

14
администрирование
димой ширины канала для передачи информации и т. п. su - anthony -c "export PATH=$PATH:/usr/X11R6/bin:/usr/ ↵
Например, в любой момент времени можно переключить- local/bin; $BINDIR/$DAEMON :10 -geometry 800x600"
;;
ся из TrueColor-режима в режим 256 цветов. Экономия 'stop')
на трафике. $BINDIR/$DAEMON -kill :10
;;
Работа с использованием VNC-клиента с сервером 'restart')
аналогична двум предыдущим рассмотренным пакетам. $0 stop; $0 start
;;
Нажимая F8, получаем возможность изменить на ходу *)
настройки. Нажатие первый раз обрабатывает наш VNC- echo "usage $0 start|stop|restart" ;;
esac
клиент, которого мы запустили у себя, второй раз уже об-
рабатывает сервер, где запущена VNC-служба. Службу Для запуска нового сервиса сделаем упоминание так-
можно определить по открытым портам 5800, 5900. же в файле /etc/rc.d/rc.local. Добавим строчки:
В качестве эксперимента я поставил VNC у себя в ло-
кальной сети на Linux-сервер под своим аккаунтом. Так echo "***** Starting RealVNC server *****"
/etc/rc.d/rc.vnc start
что при перезагрузке вторая моя машина запускает авто-
матически VNC-сервис. Повторю, что поставил в качестве Появляющийся сервис запускается с правами пользо-
эксперимента, ибо никто не отменял комбинацию со вто- вателя anthony, который присутствует в системе. Экспор-
рым X-сервером и перенаправлением ввода с удаленной тирование пути необходимо, т.к. при запуске «su» авто-
UNIX-машины на этот второй X-сервер. матически переменная PATH заполняется значениями из
Тем не менее опишу, как я провел сию операцию. Обе /etc/login.defs. Мы же чуть-чуть увеличим путь, т.к. для
машины в локальной сети работают под slackware linux, запуска Xvnc необходимо, чтобы vncserver знал, где его
поэтому настройки, которые я добавлял, находятся в ка- найти, а также некоторые дополнительные программы.
талоге /etc/rc.d/. Добавляю туда скрипт rc.vnc. Сервис запускается с виртуальным экраном номер 10,
поэтому для его обслуживания видим сразу 3 открытых
#!/bin/sh для нужд VNC порта – это 5810, 5910 и 6010. Полная кар-
# Start the Virtual Networking Communication (VNC) server
BINDIR=/usr/local/vnc та открытых портов на этой машине приведена ниже.
DAEMON=vncserver
case "$1" in bash-2.05b# nmap -v -sS fuji -p 1-10000
'start')

15
администрирование
туальном экране, с помощью параметра «-geometry 600x400»
указываю, что клиент надо запустить с разрешением 600 на
400 точек. Параметр «-passwd ~/.vnc/passwd» означает, что
пароль можно не вводить, а брать по указанному месту. Кста-
ти, он скопирован с машины, где запущен VNC-сервис.
Вот вроде бы и все. Работа с помощью VNC немного
удобнее по сравнению с остальными. Хотя это мой субъек-
тивный взгляд. В качестве примера рассмотрим, как по-
считать трафик, используемый каждым приложением. Я
опишу, как на стомегабитной сетевой карте добиться ско-
рости 9600 байт в cекунду. Сия скоростная планка взята
из желания посмотреть, насколько устойчиво будут рабо-
тать рассмотренные приложения.
Не секрет, что до сих пор в некоторых местах исполь-
зуются телефонные линии с не очень хорошим качеством
связи. Вы можете указать свою скорость, отличную от ука-
занной, и проанализировать ситуацию. Считаю, что дан-
ный опыт будет полезен в случае, когда организация сто-
ит перед выбором, какой тип соединения использовать для
связи филиалов – ТФОП (телефонные линии общего дос-
тупа), беспроводной доступ или иной вид связи. Проана-
лизировав на локальной сети центрального филиала, что
именно подходит под ваши условия, вы делаете свой вы-
бор. Чтобы «зажать» скорость в указанных пределах, я
Чтобы запустить клиента, пишу следующую строчку: воспользовался traffic shaper – rshaper. Взять можно по
указанному адресу: http://ar.linux.it/software/#rshaper. Сбор-
vncviewer fuji:10 -passwd ~/.vnc/passwd -geometry 600x400 ка происходит через подачу команды make && make install.
Пакет устанавливается в каталог /usr/local/sbin как модуль
где fuji:10 – linux-box, где установлен VNC-сервис на 10 вир- к ядру и программа управления трафиком.

16
администрирование
В целом происходит следующее – данный модуль со- Пролистать показания счетчика:
здает сетевой буфер, где пакеты задерживаются опреде-
ленное время, в результате чего создается эффект «про- iptables -L MyRDP_IN -v
стаивания в очереди», т.е. создается определенная ско-
рость. В нашем случае 9600 б/с на прием. С теорией достаточно. Ближе к практике. Для этих це-
Нам еще потребуется, чтобы у вас в системе также был лей составлен простейший скрипт, в котором задается ско-
простейший брандмауэр, точнее настроены правила для рость для shaper, происходит обнуление/показ прошедше-
iptables. Например, взятый здесь: http://www.faqs.org/docs/ го трафика.
iptables/examplecode.html.
Сначала подгружаем shape-модуль: MyRDPTest.sh

#!/bin/sh
modprobe rshaper.o
IPTL=/usr/sbin/iptables
SHAPER=/usr/local/sbin/rshaperctl
Модуль загружен, далее указываем, с каким хостом MODE=9600
HOST=rubin
мы соединяемся, с какой скоростью и размер простаива- TIME=10
ния в буфере (в секундах):
if [ "$1" = "zero" ]; then
echo "Zeroing IN & OUT counters for $HOST";
rshaperctl HOST SPEED TIME $IPTL -L MyRDP -Z 2>/dev/null 1>/dev/null
$IPTL -L MyRDPOut -Z 2>/dev/null 1>/dev/null
fi
Затем выставляем правила для iptables для подсчета echo "Setting Shaping MODE as $MODE bytes to host $HOST"
$SHAPER $HOST $MODE $TIME
прошедшего трафика. Для входящего от хоста трафика: $SHAPER
echo "Incoming traffic from host"
iptables -N MyRDP_IN IN=`$IPTL -L MyRDP -v -n | grep ACCEPT`
iptables -I INPUT -j MyRDP_IN -s HOST INpkts=`echo $IN | awk '{ print $1 }'`
INbytes=`echo $IN | awk '{ print $2 }'`
iptables -I MyRDP_IN -j INPUT echo "pkts = $INpkts, bytes = $INbytes";

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


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

17
администрирование
Если скрипт вызван с параметром «zero», то счетчики и VNC легче держат канал. Первый даже лучше, нежели
для входящего (MyRDP) и исходящего (MyRDPOut) тра- VNC. Может на других скоростях получатся другие циф-
фика будут обнулены. Вот какие цифры получились у меня ры, но это испытание мы оставим пытливому читателю.
после недолгой работы по разным протоколам с серве- Òàáëèöà 1. Èíôîðìàöèÿ î ïðîøåäøåì òðàôèêå çà 5-ìèíóòíûé
ром по имени RUBIN. Скорость на прием – 9600 байт в ïåðèîä ïî ðàçíûì ïðîòîêîëàì
секунду.

RDP ïðîòîêîë

Incoming traffic from host


pkts = 2604, bytes = 1039K
Outcoming traffic to host
pkts = 3563, bytes = 474K Я специально не стал освещать решения от компании
Citrix, поскольку это отдельный серьезный разговор, т.к.
VNC ïðîòîêîë
заложенных возможностей в данный продукт хватит на-
Incoming traffic from host долго и намного.
pkts = 6277, bytes = 804K
Outcoming traffic to host P.S. Всегда были и будут разговоры об эффективнос-
pkts = 5413, bytes = 321K ти и применимости удаленного доступа и открытых для
RADMIN ïðîòîêîë этих целей дверей в системе. Приходится чем-то жертво-
Incoming traffic from host вать, либо потенциально открыто, либо потенциально зак-
pkts = 2739, bytes = 472K
Outcoming traffic to host рыто. Запомните, самый оптимальный с точки зрения бе-
pkts = 3610, bytes = 267K зопасности стиль работы – держать администрируемую
машину всегда выключенной.
Проводились типизированные действия. В частности, В статье были упомянуты программы со следующих
был запущен MPEG-клип через Media Player. Что следует ресурсов:
отметить – при работе с RDP передавался n-ый кадр с за- 1. http://www.rdesktop.com
метными паузами для перерисовки. Остальные протоко- 2. http://www.radmin.com
лы автоматически пропускали прорисовку кадров, просто- 3. http://www.winehq.com
напросто ничего не рисовали, т.е. старались не занимать 4. http://www.realvnc.com
канал «тяжелым» содержимым. Это касается только ви- 5. http://ar.linux.it/software/#rshaper
део. В остальном субъективно было заметно, что RADMIN 6. http://www.faqs.org/docs/iptables/examplecode.html

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

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

СВОБОДНАЯ ДОС ДЛЯ СВОБОДНЫХ ЛЮДЕЙ,


ИЛИ НЕ LINUX ЕДИНЫМ ЖИВ ЧЕЛОВЕК

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

АНДРЕЙ МАРКЕЛОВ
20
администрирование
Однако до сих пор в эксплуатации остается огромное Установка
число программ, работающих в среде и написанных под Итак, вы решили познакомиться с новой для себя опера-
эту нетребовательную к ресурсам ОС, и не меньшее чис- ционной системой. Прекрасно! Пятидесятимегабайтный
ло морально устаревших компьютеров, прекрасно ра- дистрибутив «FreeDOS Beta9 pre-release 3» (последний на
ботающих под ней. Как же быть? Ведь MS-DOS давно момент написания статьи) скачан в виде ISO-образа с сай-
не поддерживается и не продается. Я бы посоветовал та http://www.freedos.org и записан на «болванку». Встав-
обратить внимание на FreeDOS, изначально написан- ляем полученный загрузочный CD в лоток вашего CD-
ную Джимом Холлом, а сейчас развивающуюся при уча- ROM, и перезагружаем компьютер. Не забудьте попутно
стии целой команды разработчиков из разных концов в качестве устройства для загрузки выбрать привод ком-
света. пакт-дисков.
Свободная ОС 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 на «чистую» ма-
аналогичным функционалом. шину, однако никто не мешает использовать так называе-
Ядром FreeDOS является DOS-C, изначально написан- мую «двойную загрузку». Я успешно ставил на один компь-
ное Pat Villani как DOS-ядро для встраиваемых систем. ютер одновременно MS-DOS, FreeDOS, Linux и Windows 2000.
Первоначальное название – DOS/NT. DOS/NT содержала Причем в качестве загрузчика использовал штатный Boot
32 000 строк кода, была написана на Cи и ассемблере и Loader из Windows 2000. При помощи отличной утилиты
распространялась как shareware. BootPart 2.50 вы можете сохранить образ 512-байтного заг-
FreeDOS работает на устаревшем железе (начиная рузочного сектора с загрузчиком FreeDOS, Lilo или GRUB
от 5МГц IBM PC XT с 640К оперативной памяти), встро- в файл, а далее просто прописать на него ссылку в
енных системах, различных виртуальных машинах, в том C:\BOOT.INI.
числе DOSEmu, VMWare и Bochs. FreeDOS – идеальное, За подробностями отсылаю вас на домашнюю странич-
лицензионно чистое решение для создания «спасатель- ку программы – http://ourworld.compuserve.com/homepages/
ной» загрузочной дискеты. Другое применение – среда gvollant/bootpart.htm. Кроме того, всегда можно попробо-
для исполнения ваших программ или обновлений. Кли- вать запустить FreeDOS в среде виртуальной машины.
енту достаточно загрузиться с полученной от вас диске- Нужно заметить, что для DOSEmu рассматриваемая опе-
ты или компакт-диска, и вот вам (или вашей службе под- рационная система и так является «официальной» и ре-
держки) уже не приходится часами висеть на телефоне, комендуемой к использованию.
объясняя бухгалтеру, находящемуся за несколько сотен Загрузившись с дистрибутивного диска, мы попадаем
километров, как найти диск C:\. в меню инсталлятора. Нажимаем «1» для старта. Далее
FreeDOS обладает отличной совместимостью с DOS- выбираем установку с использованием драйвера CD-ROM
программами, в том числе со старыми добрыми играми: и XMS – «2». На машинах с процессорами 8086 – 80286
DOOM, Quake, Warcraft 2. А небезызвестная фирма Dell нужно выбрать «1».
даже продает свои десктопы, с предустанавливаемой на В следующем меню имеется несколько вариантов:
них одной из версий этой операционной системы. ! «1» – установка;
Из особенностей FreeDOS я хочу отметить: поддерж- ! «2» – переход в командную строку;
ку FAT-32 дисков объемом до 128 Гб, поддержку сети (вы ! «3» – создать загрузочную дискету.
можете поставить на FreeDOS ftp- и HTTP-сервер), но от-
сутствие встроенной поддержки NTFS и USB. Однако Выбираем «1» и еще раз «1», чтобы подтвердить уста-
FreeDOS вполне нормально работает и с USB-клавиату- новки по умолчанию.
рами, USB-мышами, Serial-ATA-дисками, если их поддер- Теперь мы попадаем в меню «FreeDOS Partition Mana-
живает BIOS компьютера. gement». Eсли жесткий диск не был разбит на логические
При помощи дополнительных драйверов возможна диски, то сейчас имеется возможность разбить его ана-
работа с длинными именами. логом MS-DOS-утилиты FDISK. Кроме того, можно запус-

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


администрирование
тить известную всем линуксоидам утилиту для изменения что бинарники ядра распространяются в двух вариантах:
размеров партиций – FIPS, а также отформатировать диск. keXXXX_32.zip – с поддержкой FAT-32 и keXXXX_16.zip –
Замечу, что утилита FORMAT дистрибутива содержит только с поддержкой FAT-16.
ошибки (которые исправлены в более поздней версии, не Затем убедимся, что доступен привод компакт-дисков.
вошедшей в ISO-образ), и при наличии ошибок во время Файл config.sys должен содержать строку:
форматирования лучше выполнить данную операцию из
другой ОС, а FORMAT после инсталляции заменить бо- DEVICE=C:\FDOS\bin\atapicdd.sys /D:FDCD0001
À autoexec.bat êîìàíäó:
лее свежей версией с сайта проекта. Еще один вариант C:\FDOS\bin\Shsucdx /D:FDCD0001
решения этой проблемы – выполнить «быстрое» форма-
тирование FORMAT из FreeDOS. Как видно, синтаксис этих команд не отличается от
Если уже имеется отформатированный диск, то про- синтаксиса команд Microsoft DOS. Отличия только в име-
сто выбираем его клавишами со стрелками и нажимаем нах файлов.
«Enter». После инсталлятор предлагает выбрать вариант Drugim vagnjm voprosom jvljaetsja russifikazcija. В теку-
установки – графический или текстовый. Выбрав, жмем щей версии отсутствует поддержка COUNTRY, но для
«Enter» и в случае с графикой оказываемся в интер- поддержки 866 кодовой страницы можно воспользовать-
фейсе, напоминающем интерфейс установки обычного ся GRAFTABL. С другой стороны, самым простым реше-
Windows-приложения. Принимаем лицензионное соглаше- нием будет использование (до появления полноценной
ние GNU GPL, указываем путь для установки (C:\FDOS\) поддержки русского языка «из коробки») одного из руси-
и набор устанавливаемых пакетов. Теперь остается толь- фикаторов: Keyrus или rc. Они прекрасно служили нам в
ко следить за ходом инсталляции. После завершения ко- MS-DOS, с таким же успехом послужат и во FreeDOS.
пирования файлов будут запущены несколько конфигу- Следующая часто возникающая задача – доступ к то-
рационных скриптов, а затем мы попадаем в командную мам NTFS. В ядре FreeDOS отсутствует поддержка NTFS,
строку, получив напоминание о необходимости записать но по ссылке http://www.sysinternals.com/ntw2k/freeware/ntfs-
загрузочный сектор командой BOOT. Набираем «boot», dos.shtml можно скачать бесплатную версию NTFSDOS –
жмем «Enter». Теперь можно перезагрузить машину, уда- драйверов, работающих под FreeDOS и предоставляющих
лив при этом CD из дисковода. доступ к томам NTFS в режиме «только для чтения». Су-
ществует также платная Professional-версия с возможно-
Настраиваем среду обитания стью записи.
Вначале кратко о структуре каталогов и файлах, входя- Использовать программу крайне просто. Добавьте вы-
щих в дистрибутив. После установки FreeDOS в корне зов файла ntfsdos.exe в файл autuexec.bat и утилита сама
диска C:\ мы имеем: просканирует доступные диски и, если на них будут найде-
! autoexec.bat, config.sys – расширенные по синтаксису ны тома NTFS, подключит их без вашего вмешательства.
аналоги конфигурационных файлов MS-DOS; Теперь перейдем к «длинным», выходящим за рамки
! fdosboot.bin – загрузочный сектор FreeDOS в виде фай- формулы 8+3 именам файлов, которые впервые появи-
ла; лись в ОС Windows 95 SR2. Существует несколько ути-
! command.com – интерфейс командной строки; лит, созданных для поддержки длинных имен. Например,
! kernel.sys – ядро операционной системы (аналог пакет DOSLFN, который можно скачать по адресу http://
msdos.sys). www-user.tu-chemnitz.de/~heha/hs_freeware/freew.html. Про-
писываем в autoexec.bat вызов TSR-модуля doslfn.com,
Сами служебные файлы и утилиты по умолчанию ус- который занимает 16 Кб в оперативной памяти, и на этом
танавливаются в C:\FDOS. Внутри каталога существуют вся установка закончена. Потенциальной проблемой мо-
следующие подкаталоги: жет стать то, что поддерживаются длинные имена не на
! APPINFO – файлы формата lsm с кратким описанием всех приводах CD-ROM. В случае возникновения таких про-
утилит дистрибутива; блем можно попробовать еще один пакет, выполняющий
! BIN – утилиты и драйверы; аналогичные функции, – LFN Tools (http://www.odi.ch/).
! DOC, HELP – документация ;
! INSTBASE – логи инсталляции всех пакетов; Графические оболочки
! NLS – файлы локализации для нескольких языков. Любые задачи в FreeDOS можно выполнить, не выходя за
рамки командной строки. Но, конечно, намного удобнее ис-
Первым делом я бы рекомендовал обновить файлы пользовать одну из многих так называемых «оболочек» –
операционной системы. Главные кандидаты на обновле- shells. Хочу напомнить, что та же MS Windows вплоть до
ние (из тех, что были доработаны по сравнению с версии Windows 3.11 for Workgroups являлась ничем иным,
«FreeDOS Beta9 pre-release 3») – это новая версия ядра как оболочкой для MS-DOS. И лишь Windows 95 присвои-
под номером 2033, FreeCOM shell – интерфейс команд- ла себе гордое имя операционной системы.
ной строки, EMM386, Format, Shsucdx, Undelete, Edit. Ссыл- Говоря об оболочках, в первую очередь упомяну оболоч-
ки на утилиты и файлы для скачивания можно найти на ку – бессмертный файловый менеджер Norton Commander и
сайте проекта. Для обновления, как правило, достаточно его многочисленные клоны, например, миниатюрный
просто заменить старые файлы новыми из скачанного zip- Volkov Commander и менеджер с открытым исходным ко-
архива. Когда будете обновлять файлы ядра, заметьте, дом Dos Navigator (http://www.ritlabs.com/dn/).

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

Вышеперечисленные программы имеют текстовый ин- кет – на жестком диске требуется почти 10 Мб. Есть вер-
терфейс на основе псевдографики. Гораздо интереснее сия, помещающаяся на дискете – GEMini.
познакомиться с по-настоящему графическими оболочка- Кратко по установке. После того как дистрибутив ска-
ми. Часть из тех оболочек, что работают в среде FreeDOS, чан и разархивирован, запускаем install.bat. Программа
перечислена в таблице. установщика задаст несколько вопросов: куда ставить
Очень кратко рассмотрим некоторые из них. пакет и имеется ли на компьютере установленная Windows.
SEAL – тридцатидвухразрядная оболочка, напомина- После отработки «батника» добавляем строки из файла
ющая по интерфейсу MS Windows. В составе пакета име- C:\fgconfig.sys в config.sys. Запускается оболочка коман-
ется некий минимальный набор приложений, включая тек- дой C:\gem.bat. Интерфейс OpenGEM изображен на сле-
стовый редактор, среду разработки, графический редак- дующем рисунке:
тор, файловый менеджер, CD-плейер, программу снятия
образа с дискет, более десятка игр. Для инсталляции до-
статочно разархивировать скачанный с сайта http://
sealsystem.sourceforge.net/ архив и запустить install.exe.
Оболочка запускается командой C:\seal2\seal.exe.

В состав пакета входит более 30 приложений. В том


числе текстовый процессор, электронные таблицы, HTML-
браузер, игры.
На этом все. Остались нераскрытыми многие темы,
относящиеся к FreeDOS, в том числе создание своего ди-
OpenGEM – развитие Digital Research GEM под откры- стрибутива и поддержка сетевых служб. Но это уже мате-
той лицензией GPL. OpenGEM достаточно большой па- риал отдельной статьи.

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


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

С ЮНИКСОМ НА vi

СЕРГЕЙ СУПРУНОВ
24
администрирование
Так уж исторически сложилось, что операционные систе- Надеюсь, мне удалось убедить вас в том, что vi – один
мы UNIX считаются очень сложными и недружественны- из лучших текстовых редакторов для систем UNIX. Ниже
ми по отношению к пользователям. И одним из олицет- мы более подробно рассмотрим его особенности, син-
ворений этого часто называют редактор vi. По мере того, таксис некоторых команд, коротко коснемся режимов ex
как набирает обороты Linux, позиционируемый как сис- и view. Чтобы учесть интересы читателей с разным уров-
тема более дружественная, среди его пользователей все нем подготовки, данная статья будет разбита на следу-
большую популярность приобретают более привычные ющие подразделы:
редакторы, особенно тот, который встроен в Midnight ! основы редактора vi;
Commander (поскольку всегда под рукой), и старый доб- ! команды перемещения и поиска;
рый vi начинает забываться. Тем не менее, этот редак- ! команды редактирования и форматирования;
тор обладает непревзойденной на сегодняшний день ! работа с блоками и буфером;
мощью, функциональностью, универсальностью и удоб- ! команды режима редактирования;
ством работы, а кроме того, разработан в полном соот- ! прочие команды режима visual;
ветствии с идеологией UNIX. Чтобы не быть голословным, ! команды режима ex;
приведу несколько примеров (синтаксис команд редак- ! установки редактора;
тора, которые в них встретятся, будет подробнее рассмот- ! заключение.
рен ниже):
! Задача: в середину некоторой статьи нужно вставить Мне не хочется перегружать статью снимками экра-
вывод команды «ipfw show» (или любой другой). По- нов, поэтому, если вы не очень хорошо знакомы с vi, на-
пробуйте сделать это, используя ваш любимый редак- стоятельно рекомендую вам читать ее перед монитором
тор, а затем посмотрите, как это делается в vi. и сразу пробовать те примеры, которые будут описаны
Конечно же, будучи квалифицированным пользова- ниже, чтобы «почувствовать» этот редактор.
телем, вы не стали вбивать результат вручную, а пе-
ренаправили вывод в файл, который объединили с Основы редактора vi
файлом статьи: Итак, vi – текстовый редактор, входящий в поставку прак-
тически всех операционных систем семейства UNIX. За-
# ipfw show > buffer пуск его осуществляется командой:
# cat article buffer > temp
# mv temp article
# vi [filename]
после чего, воспользовавшись функциями редакти-
рования блоков (ваш же редактор позволяет это?), Помимо основного (visual) режима он может быть за-
перенесли блок в нужное место. Конечно, с помо- пущен в командном режиме, называемом ex (от англ.
щью Midnight Commander можно сделать то же са- execute), ориентированном на работу со строками, и в
мое проще: режиме view (только для чтения). Запуск этих режимов
осуществляется с ключами –e и –R, или командами ex и
# ipfw show > buffer view соответственно:
# mcedit article

Идем в точку, в которую нужно вставить блок, затем # {vi –e | ex} [filename]
# {vi –R | view} [filename]
жмем F9 и выбираем в меню «Файл» пункт «Вставить
файл…», указываем путь к файлу buffer. Если файл с таким именем существует в текущей ди-
Ну а с помощью vi это выполняется одной командой: ректории, то он будет открыт для редактирования. Ну а
если его нет, то будет создан новый файл. Если команда
!lipfw show vi дана без параметров, будет запущено редактирова-
ние нового файла, создаваемого во временном катало-
! Предположим, что у вас есть пронумерованный спи- ге, заданном переменной окружения TMPDIR (обычно это
сок из 12 пунктов. Вам нужно вставить два пункта, папка /tmp) с именем типа vi.L14259 (часть после точки
начиная с третьей позиции, и соответственно попра- создается случайным образом, чтобы обеспечить уни-
вить номера всех нижележащих пунктов. кальность создаваемого файла). В дальнейшем вы смо-
Наверняка решать эту задачу вам придется руками. жете сохранить набранный файл под любым именем.
Vi позволяет сократить число операций до миниму- Если вы последовали моей рекомендации и сразу про-
ма. Для первого пункта списка, номер которого нуж- веряете все на практике, то первое, чему вы должны на-
но поменять, ставим курсор на его номер и даем ко- учиться, это выходить из редактора. Дело в том, что в vi
манду «2#+», после чего на номере каждого последу- вам не помогут ни <escape>, ни <Alt+X>, ни даже <Ctrl+C>.
ющего пункта просто давим символ «.». Нет в нем и так любимой народом верхней строчки, име-
! Двадцать четыре строки в тексте нужно сдвинуть нуемой «Главное меню». Также он не будет отображать
вправо символом табуляции. то, что вы попытаетесь набрать (хотя, если в панике на-
Конечно, не проблема минутку пощелкать «Tab – чать беспорядочно стучать по клавиатуре, то может слу-
Стрелка вниз – Home», но vi предлагает более эле- читься «чудо» и ваш набор станет появляться на экране,
гантный способ: «23>j» над первой строкой. И все. однако выйти из редактора это вам все равно не помо-

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


администрирование
жет). Так что абсолютно черный экран с одинокими тиль- дится курсор, а после него. Кроме того, режим вставки
дами по левому краю, никак не реагирующий на нажа- может быть вызван командами «o» и «O». Первая из них
тия клавиш и не позволяющий вернуться в оболочку ина- добавляет пустую строку после, а вторая – перед теку-
че, как «килянием» процесса из соседнего терминала щей строкой, и дальнейший ввод символов трактуется как
(если вы, конечно, умеете пользоваться командой kill – ввод текста.
иначе только Reset), может надолго отбить охоту запус- Чтобы удалить символ, нужно перейти в режим команд
тить этот редактор еще раз. Поэтому сначала ознакомь- и над удаляемым символом нажать клавишу «x». В режи-
тесь со следующей таблицей, которая поможет вам по- ме вставки удалить только что введенный ошибочно сим-
верить в то, что vi – это действительно редактор: вол можно клавишей <backspace>, однако в vi таким об-
разом может быть удалена только последняя непрерывно
введенная последовательность символов. То есть если вы
откроете для редактирования наш тестовый файл со стро-
кой «Hello, world», и добавите между словами слово «my»:
«Hello, my world», то, используя клавишу <backspace>, вы
сможете удалить только что введенные символы « my», а
вот запятую и последующие символы удалить таким об-
разом уже не удастся. В этом случае придется использо-
вать команду «x».
Удалить целиком строку, на которой находится кур-
сор, можно командой «dd» (просто нажмите два раза
Команды, начинающиеся с символа «:», будут отобра- клавишу <d>). Помните, что в vi строкой считается не
жаться в нижней строке. Остальные выполняются «мол- экранная строка, а последовательность символов до пе-
ча». Редактор vi имеет два режима работы – режим ко- ревода строки (\n). Если строка больше 80 символов (зна-
манд и режим редактирования. чение по умолчанию), то она переносится на новую ли-
Запускается он в командном режиме, так что все на- нию (строку экрана). Используя «dd», вы удалите всю
жатия на клавиши трактуются как команды. Нажатие кла- строку вне зависимости от того, на скольких экранных
виш «i», «a», «o», «O» и ряд других переводят vi в режим линиях она размещается.
вставки, когда набираемые символы трактуются как Чтобы определить, где находится конец строки, нажми-
текст и отображаются на экране. те клавишу «$» (вы, должно быть, уже заметили, что кла-
Возврат к режиму команд выполняется клавишей виши <Home>, <End> и т. п. тут не работают). При навига-
<escape> или в некоторых случаях автоматически, на- ции по экрану ( можно пользоваться стрелками, хотя есть
пример, при попытке передвинуть курсор левее первого и более «правильный» способ) курсор перемещается не
символа в строке (в редакторе vim, являющемся модер- по экранным линиям, а по строкам текста.
низированным вариантом vi и часто заменяющем его в Если вы что-то сделали не так, то отменить после-
Linux, в этом случае редактор остается в режиме встав- днюю операцию можно командой «u». Эта команда от-
ки). Автоматический переход в командный режим обыч- меняет только последнее действие, то есть ее повтор-
но сопровождается звуковым сигналом, как и ошибоч- ное применение отменит только что сделанную отмену.
ная команда. Конечно, отсутствие истории операций – один из серь-
Чтобы почувствовать все это, выполним небольшое езных недостатков vi, однако если работать вдумчиво и
практическое упражнение. Находясь в своем домашнем внимательно, то он почти незаметен. Собственно, идео-
каталоге, запустите редактор командой: логия UNIX-систем такова, что они не особо балуют поль-
зователя подсказками и возможностью отката выполнен-
# vi test.txt ных операций, так что сразу настраивайтесь на ответ-
ственную работу.
Далее нажмите «i», чтобы перейти в режим вставки. Учтите, что по команде «u» отменяется вся команда
Теперь все нажатия на клавиши будут трактоваться как целиком. Например, если вы дали команду «i», набили 3-й
ввод текста, и символы будут отображаться на экране с том «Войны и мира» и вернулись в режим команд, то «u»
позиции курсора. отменит весь этот ввод. Если ошибок получилось слиш-
Наберите «Hello, world!». Постарайтесь не ошибать- ком много, можно выйти из редактора без сохранения
ся, поскольку исправление ошибок, как и все остальное, сделанных изменений (команда «:q!»).
имеет здесь свои особенности, о которых мы поговорим В принципе этих сведений достаточно, чтобы отредак-
ниже. Нажмите <escape> для возврата в командный ре- тировать файл. Однако вряд ли вы поверили, что vi – удоб-
жим. Наберите «:wq» и нажмите <enter>. Убедитесь, что ный редактор. Понимаю, как вам хочется нажать <F4> в
файл test.txt действительно создался. После этого не- своем любимом mc, но все же найдите в себе силы дочи-
большого задания вам будет проще представлять то, о тать статью до конца и попрактиковаться с vi хотя бы пару
чем пойдет речь далее. недель. Думаю, ваше мнение изменится.
Аналогично команде «i», в режим вставки можно пе- В дальнейшей части статьи некоторые команды и их
рейти, нажав клавишу «a». Единственное отличие – текст применение будут рассмотрены более подробно. За опи-
будет вставляться не перед символом, на котором нахо- санием всех остальных команд отсылаю читателя к стра-

26
администрирование
ницам справочного руководства «man vi», в полном соот- на страницах «man vi» или методом «научного тыка». На-
ветствии с идеологией UNIX. пример, команда «5<Ctrl-Y>» прокрутит экран на 5 строк
вниз, не перемещая курсор (очень полезна, если вам нуж-
Команды перемещения и поиска но увидеть несколько строк выше и затем продолжить
Эта часть статьи посвящена командам навигации, кото- редактирование текущей строки).
рые позволят вам быстро и эффективно перемещаться Еще несколько полезных команд навигации:
по редактируемому тексту. Как и все в vi, эти команды ! z. – прокручивает текст так, что текущая строка стано-
также имеют свою специфику, и их удобство и продуман- вится в центре экрана;
ность начинают осознаваться только через несколько ме- ! [№]G – перемещает курсор на №-ю строку от начала
сяцев работы. Хотя и новичок найдет среди них полезные файла, если № не задано – на конец файла;
и интересные. ! [№]H – перемещает курсор на №-ю сверху строку, ви-
В общем случае по тексту можно перемещаться, ис- димую на экране;
пользуя клавиши со стрелками. Но vi разработан таким ! [№]L – перемещает курсор на №-ю снизу строку, ви-
образом, чтобы в процессе работы руки не покидали ос- димую на экране;
новной рабочей зоны клавиатуры. Те, кто владеет мето- ! M – перемещает курсор на строку, расположенную в
дом «слепой» печати, по достоинству оценят эту особен- центре экрана.
ность. Кроме того, это позволяет не заботиться о совмес-
тимости клавиатур и терминалов – vi будет полностью С помощью следующих двух команд вы сможете рас-
функционален даже на самых тупых терминалах. ставлять «маркеры» в тексте, и затем быстро переходить
Команды навигации и поиска представлены ниже. За- на эти метки:
пись «№» означает число, которое набирается перед вво- ! m<симв.> – запоминает текущую позицию курсора как
дом команды (при этом на экране оно не отображается) и символ <симв.>;
задает число повторений команды или в некоторых случа- ! `<симв.> – возвращает курсор на позицию, запомнен-
ях номер строки, к которой команда должна быть примене- ную как <симв.>.
на. Если число не задано, команда выполняется один раз.
Например, запомнив начало второго параграфа как
Команды перемещения курсора «m2», вы в дальнейшем сможете возвращаться к нему ко-
! [№]h – перемещает курсор влево на № символов; мандой «`2».
! [№]k – перемещает курсор на № символов вверх;
! [№]j – перемещает курсор вниз на № символов; Команды поиска
! [№]l, [№]<пробел> – перемещает курсор на № симво- С поиском вроде все понятно, ничего пояснять не буду:
лов вправо; ! /<образец поиска> – поиск в тексте по образцу;
! [№]$ – переход на последний символ строки, №-й пос- ! / – повторный поиск по предыдущему образцу (найти
ле текущей; далее);
! 0 (ноль) – переход на первый символ текущей строки; ! ?<образец поиска> – поиск по образцу в обратном на-
! ^ – перемещает курсор на первый символ текущей правлении;
строки, отличный от пробельного; ! ? – повтор поиска по предыдущему образцу в обрат-
! [№]- – переход на первый непробельный символ №-й ном направлении.
перед текущей строки;
! [№]+ – переход на первый непробельный символ №-й Предыдущие четыре команды должны обязательно
после текущей строки; завершаться нажатием клавиши <Enter>.
! [№]_ – переход на первый непробельный символ (№-1)-й ! [№]<Ctrl-A> – поиск №-го слова, совпадающего с тем,
после текущей строки. на котором стоит курсор, начиная с позиции курсора в
сторону конца документа;
Также существует масса команд для перемещения по ! [№]f<char> – перемещает курсор на №-й после курсо-
словам, группам символов, предложениям, параграфам. ра символ <char> в строке;
При этом под «словом» будет пониматься последователь- ! [№]t<char> – перемещает курсор на символ, стоящий
ность символов, разделенных пробельными символами. перед №-м после курсора символом <char> в строке;
Термином «группа символов» будем именовать после- ! [№]F<char> – перемещает курсор на №-й перед курсо-
довательность символов, не разделенных специальны- ром символ <char> в строке;
ми символами (такими как дефис, точка, запятая и т. д.). ! [№]T<char> – перемещает курсор на символ, стоящий
В терминах vi эти две единицы именуются «большим сло- после №-го перед курсором символа <char> в строке.
вом» (bigword) и «словом» (word) соответственно. Пред-
ложение – последовательность слов, ограниченная точ- Команды редактирования
кой или пустой строкой. Параграф – часть текста, обрам- и форматирования
ленная пустыми строками. Помимо рассмотренных выше команд «i» и «a», полезны
Чтобы вы знали, что искать, просто перечислю эти ко- будут и следующие:
манды: B, W, E, b, w, e, (, ), {, }, <Ctrl-F>, <Ctrl-B>, <Ctrl-D>, ! [№]I – включает режим вставки текста. Текст будет вво-
<Ctrl-U>, <Ctrl-E>, <Ctrl-Y>. Познакомиться с ними можно диться с начала строки;

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


администрирование
! [№]A – включает режим вставки текста. Текст будет ! [№]c<направление> – удаляет символы в указанном
вводиться после последнего символа в текущей направлении, которое задается командами перемеще-
строке; ния курсора (№ отдельных символов для направлений
! [№]o – вставка новой строки после текущей. Текст «влево» и «вправо» и № строк для «вверх» и «вниз»)
будет вводиться с начала новой строки; и переводит редактор в режим вставки текста.
! [№]O – вставка новой строки выше текущей. Текст
будет вводиться с начала новой строки. Все вышеприведенные команды переводят vi в режим
вставки текста, то есть весь последующий ввод будет ото-
Рассматривая две предыдущие команды, необходимо бражаться на экране начиная с указанной позиции. Для
указать на одну особенность. возврата в командный режим используется комбинация
Использование оных со счетчиком № не добавляет № <Ctrl-C> или клавиша <escape>.
пустых строк, как следовало бы ожидать. Добавляется ! [№]x – удаляет № символов после курсора (начиная с
одна, редактор переходит в режим ввода, а затем, после позиции курсора);
возврата в командный режим, введенный блок текста бу- ! [№]X – удаляет № символов перед курсором;
дет повторен № раз. Кстати, и команды вставки ведут себя ! [№]d <направление> – удаляет № символов/строк от-
аналогичным образом – сначала вы получаете возмож- носительно курсора в указанном направлении. На-
ность вставить или добавить текст, начиная с соответству- правление задается командами управления курсором
ющей позиции курсора, после чего, в момент возврата в «h», «j», «k», «l» или стрелками. Если выбрано «вле-
режим команд, введенный вами текст будет продублиро- во» или «вправо», то удаляются № символов соот-
ван № раз. ветственно перед курсором или после него. Направ-
Выполните команду «5i», введите текст «echo », вер- ление, заданное как «вверх» или «вниз», позволяет
нитесь в режим команд (<escape>) и посмотрите, что из удалить № строк соответственно выше или ниже те-
этого получится. Данный комментарий относится и к ряду кущей строки (включая текущую);
команд, перечисленных ниже. ! [№]D – удаляет символы начиная с позиции курсора
! [№]r<char> – заменяет символ в точке нахождения до конца строки;
курсора (и №-1 последующих символов) символом ! [№]J – объединяет текущую строку с № следующими в
<char>; одну;
! [№]~ – заменяет текущий и следующие №-1 симво- ! [№]> <направление> – сдвигает № строк вправо на
лов этими же символами в другом регистре; символ табуляции;
! [№]s – заменяет № символов в строке, начиная с те- ! [№]< <направление> – сдвигает № строк влево на сим-
кущего, вводимым далее текстом. Вводимые симво- вол табуляции.
лы после №-го добавляются после замененных. Гра-
ница области замены отмечается символом «$». В предыдущих двух командах (впрочем, как и в осталь-
ных) направление задается командами управления кур-
Поясним эту команду. Пусть у нас есть строка с тек- сором «h», «j», «k», «l» или стрелками. Так, если выбрано
стом «This is a big string». «вправо» или «влево», то команда сдвига действует только
Мы хотим слово «big» заменить более справедли- на текущую строку, № игнорируется. Если «вверх» или
вым «small». Поставим курсор на букву «b» (естествен- «вниз», то сдвигается данная строка и № предыдущих или
но, используя команду «fb» – мы же уже не маленькие, последующих соответственно.
чтобы стрелочками по тексту скакать). Заменить нам ! [№]#{#|+|-} – инкремент/декремент числа. Если дать
нужно три символа, поэтому: «3s». Теперь просто вво- эту команду, когда курсор стоит под числом, то это
дим наше «small» – первые три символа введутся в ре- число будет увеличено на № (если задан параметр
жиме замены, последующие добавятся, не затирая то, «#» или «+») или уменьшено на № (если задан пара-
что нам нужно. Теперь <escape>, и любуемся на дело метр «-»). Например, чтобы увеличить число 52 на
наших рук, не забывая при этом громко восхищаться 7, ставим курсор на символ «5» или «2» (он может
редактором. быть установлен на любую цифру числа), после чего
! [№]R – включает режим замены (вводимые символы набираем последовательно «7#+». В результате «52»
будут замещать текущие до конца строки, затем сим- изменится на «59». В vim эта функция не поддержи-
волы будут добавляться); вается.
! [№]S – очищает строку и переходит в режим встав- ! [№]!<направление><команда shell> – заменяет в до-
ки текста (аналогичный результат достигается пос- кументе начиная с позиции курсора в заданном направ-
ледовательным выполнением двух команд «[№]dd» лении № строк выводом команды оболочки. Если вам
и «O»). Обратите особое внимание, что № в данном нужно вставить вывод, можно сначала создать две пу-
случае относится к удалению, то есть № строк будут стые строки, а затем выполнить данную команду, на-
удалены, и вместо них можно будет ввести один блок пример: «2o», <escape>, «!kwho».
текста.
! [№]C – удаляет символы от текущей позиции курсора Работа с блоками и буфером
до конца строки и переходит в режим вставки текста. Vi предоставляет пользователю весьма мощные функции
№ также относится к удалению. по работе с блоками.

28
администрирование
! [№]yy – копирует в буфер № строк, начиная с текущей; ! <Ctrl-Z> – временное прерывание сессии редактиро-
! [№]Y – копирует № строк в буфер (аналогична «yy»); вания и выход в командную оболочку. Чтобы вернуть-
! [№]y<направление> – копирует текст в буфер в ука- ся назад в редактор, нужно воспользоваться систем-
занном направлении. № трактуется в зависимости от ной командой «fg», которая переводит фоновый про-
направления (впрочем, как и в остальных подобных ко- цесс в активный. Номер задачи (job), соответствующий
мандах): количество копируемых символов для «впра- отложенному процессу редактирования, который по-
во» и «влево» и число строк (дополнительно к теку- требуется ввести как параметр команды «fg», можно
щей) для «вверх» и «вниз». Например, «2yk» скопиру- уточнить командой «jobs». При попытке выйти из обо-
ет в буфер текущую строку и еще две, расположенные лочки командой «exit» вы получите предупреждение,
выше (итого – три). Если вам нужно скопировать толь- что у вас остались незавершенные задачи:
ко текущую строку, следует использовать команду «yy»
или «Y»; $ exit
You have stopped jobs.
! [№]p – вставляет текст из буфера № раз после курсо- $ jobs
ра; [1] 34336 Suspended vi test
$ fg 34336
! [№]P – вставляет текст из буфера № раз перед курсо-
ром. Здесь test – имя редактируемого файла. Нужно заме-
тить, что если вы вызываете vi из Midnight Commander,
Используя команды расширенного (ex) режима, мож- то в списке приостановленных заданий вместо «vi test»
но работать с несколькими блоками. Где изучить эти воз- будет отображаться «midc» («mc» для Linux). После этих
можности, вы, думаю, уже знаете. Конечно же, в «man vi». действий вы вернетесь назад в vi и сможете завершить
редактирование. Если отложенное задание только одно,
Команды режима редактирования можно вернуться к нему командой fg без параметров.
Находясь в режиме редактирования, редактор все вводи- ! ZZ – выход из редактора с сохранением изменений
мые символы будет отображать на экране как часть тек- (аналог команды «:wq»).
ста. Однако существует несколько последовательностей,
которые трактуются как специальные команды и для кото- Команды режима ex
рых выполняется автоматическая замена введенных сим- Редактор vi имеет помимо рассмотренного еще один ин-
волов последовательности результатом выполнения коман- терфейс, или режим, – ex. Запустить редактор в этом ре-
ды. Наиболее полезные из них следующие: жиме можно одной из следующих команд:
! <escape> – завершает режим ввода текста и перево-
дит редактор в командный режим; # vi –e
# ex
! <Ctrl-C> – также возвращает редактор в режим команд
(при «слепой» печати эта команда более удобна); Кроме того, вы можете перейти в него из режима visual
! <backspace> – удаление только что введенного символа; по команде «Q». Данный интерфейс предоставляет ряд
! <Ctrl-W> – удаление только что введенного слова; расширенных возможностей для обработки текста, таких
! <Ctrl-X>[0-9A-Fa-f] – вставка символа, имеющего код, как работа с несколькими буферами, открытие других
выраженный шестнадцатеричным числом (например, файлов в текущем сеансе, изменение настроек редакто-
«<Ctrl-X>30» отобразится на экране как «^X30» и ав- ра и т. д. В данном разделе будут рассмотрены лишь наи-
томатически заменится символом «0», ASCII-код кото- более полезные из них.
рого – 30h). В отличие от интерфейса vi, ex ориентирован на коман-
дную работу со строками. Редактирование идет как бы всле-
Прочие команды режима visual пую. Редактируемый текст на экране по умолчанию не ото-
Осталось рассмотреть еще несколько команд, которые бражается, вам придется специально вызывать на экран
трудно выделить в ту или иную категорию, но которые требуемые строки. Почти все ex-команды можно исполнить
весьма полезны при работе. из vi-интерфейса, предварив команду двоеточием. Наибо-
! [№]. – повтор последней команды для текущей пози- лее характерный пример: команда – выход из редактора:
ции курсора № раз; «:q». Ниже приведено лишь несколько полезных команд:
! u – отменяет последнее действие; ! :!<команда> – выполняет команду оболочки (резуль-
! U – восстанавливает текущую строку, отменяя все из- тат просто выводится на экран);
менения, сделанные в ней; ! :[<start>] # [№] – выводит на экран № строк начиная со
! Q – переключение в интерфейс ex (см. далее); <start> (в режиме ex);
! <Ctrl-G> – выводит информацию о редактируемом фай- ! :s/<текст1>/<текст2> – замена в текущей строке
ле (состояние – modified/unmodified, отражающее, есть <текст1> на <текст2>;
ли в файле несохраненные изменения; номер текущей ! :s – повтор предыдущей замены для текущей строки;
строки и общее количество строк в файле); ! :%s/<текст1>/<текст2> – замена во всем файле
! <Ctrl-R> – перерисовывает экран (может пригодиться <текст1> на <текст2>;
на плохом канале связи или для восстановления экра- ! :next – переход к редактированию следующего файла
на после вывода на него системных сообщений, если из списка параметров, с которым был вызван редактор.
вы работаете с физической консоли); ! :prev – возврат к редактированию предыдущего файла.

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


администрирование
Например, если вы вызываете редактор командой «vi ! :set [no]list – включает режим отображения служебных
file1 file2», то в процессе редактирования вы сможете пе- символов (таких как конец строки, который будет ото-
реходить между файлами указанными выше командами. бражаться символом «$», и т. д.);
При этом содержимое буферов обмена будет сохранять- ! :set [no]nu – включает отображение номеров строк;
ся, и вы сможете вставлять в файл фрагменты, скопиро- ! :set [no]showmode – включает отображение режима
ванные из другого файла. Заметьте, что редактор не по- (command, insert, append, replace) в нижнем правом углу
зволит вам перейти к другому файлу, пока изменения в экрана, в котором редактор находится в данный момент;
текущем не будут сохранены или отменены (отменить все ! :set [no]verbose – включает режим расширенных сооб-
изменения можно командой «:e!», которая перечитает щений (на каждое ошибочное действие будет выда-
редактируемый файл с диска). ваться соответствующее пояснение).
! :edit <file> – открыть для редактирования файл <file>;
! :w[ <filename>] – уже знакомая вам команда сохранения За остальными настройками, как всегда, – «man vi»,
редактируемого файла. Опциональный параметр соответствующий раздел.
<filename> превращает команду в команду «Сохранить Увековечить сделанные настройки можно в exrc-фай-
как…» для записи изменений в файл с другим именем. лах. Данные файлы применяются в следующей последо-
вательности:
Еще одно пояснение – очень часто бывает, что, отре- ! /etc/vi.exrc – глобальный файл настроек редактора;
дактировав тот или иной файл (например, squid.conf), при ! $HOME/.exrc – пользовательский файл настроек;
попытке сохранить сделанные изменения вы получаете ! .exrc – локальный файл настроек для текущей дирек-
сообщение, что файл недоступен для записи. Причина тории.
понятна – или вы забыли войти как root, или файл имеет
права «r--r--r--». Выходить без сохранения, менять права Действовать будут те настройки, которые применены
и редактировать снова – жалко… А вот сохранить файл последними. В эти файлы следует занести те ex-коман-
под другим именем, а затем, обретя требуемые права, за- ды, которые должны быть исполнены при открытии редак-
менить им оригинал – как раз то решение, которое нас тора. Например, если вы хотите, чтобы редактор всегда
устраивает. Конечно, можно с другого терминала поме- работал с включенным отображением режима и расши-
нять права на сохраняемый файл и снова провести опе- ренными сообщениями, то создайте в своем домашнем
рацию записи. Но при удаленной работе открыть новую каталоге файл .exrc следующего содержания:
ssh-сессию не всегда проще, чем поступить описанным
выше образом. Да и удаленный доступ к нескольким тер- set showmode
set verbose
миналам иногда запрещают из соображений безопаснос-
ти. Кроме того, если вы внесли изменения в системный Теперь каждый раз при вызове редактора эти коман-
файл (скажем, /etc/crontab), будучи зарегистрированным ды будут отрабатываться автоматически.
как простой пользователь, то вряд ли безопасно менять к
нему права доступа, пусть и кратковременно. Кроме того, Заключение
статья рассматривает редактор vi, а потому примеры при- Итак, вы в общих чертах познакомились с редактором vi.
званы прежде всего показать его пригодность для реше- Приведу еще несколько преимуществ редактора vi, поми-
ния тех или иных задач, пусть и не всегда оптимальным мо его функциональности:
образом. ! способность работать практически на любых терминалах;
! :g /<шаблон>/ <команда> – указанная команда, кото- ! обязательное наличие в любой UNIX-системе;
рой может быть одна из ex-команд, применяется к стро- ! надежная работа даже на самых плохих линиях;
кам, которые соответствуют шаблону. Например, ко- ! используется в некоторых системных командах (напри-
манда «:g /qwerty/ delete» удалит все строки, в которых мер, vipw), следовательно, умение в нем работать потре-
присутствует последовательность символов «qwerty»; буется в любом случае;
! :v /<шаблон>/ <команда> – работает аналогично пре- ! а сможете ли вы просмотреть файл, являющийся ката-
дыдущей, но команда применяется к тем строкам, ко- логом (в UNIX каталог – это специальный файл), с помо-
торые не соответствуют шаблону; щью «ee» или «mcedi»? Хотя редактировать такой файл
! :vi – переход в интерфейс visual. вам и vi не позволит, но посмотреть для интереса – мож-
но (например, «view /etc»).
Опции и параметры редактора
Было бы странно, если бы оказалось, что столь мощ- Попытайтесь с ним подружиться!
ный редактор не позволяет настраивать себя под тре- P.S. Если вы все же отважились сделать vi вашим основ-
бования и предпочтения конкретного пользователя. ным редактором, для этого установите значение перемен-
Однако не следует думать, что настройкой можно пре- ной $EDITOR=vi (например, для оболочки sh нужно попра-
вратить vi в редактор ee или что-то подобное. Следую- вить файл .profile в вашем домашнем каталоге, для csh – это
щие опции позволяют лишь добавить «удобства», не файл .cshrc). Также в настройках Midnight Commander отме-
меняя общих принципов работы. Все они устанавлива- ните использование встроенного редактора (пункт меню
ются с помощью ex-команды «:set». «no» перед именем «Настройки» – «Конфигурация…»), и по <F4> будет вызы-
опции отключает ее. ваться тот редактор, который задан в переменной $EDITOR.

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

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

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

32
безопасность
Наибольшей популярностью среди антивирусов пользу- Установка
ется DrWeb от ЗАО «ДиалогНаука»: http://www.drweb.ru, Из библиотек требуются zlib и bzip2, которые имеются в
обладающий действительно хорошими характеристика- большинстве систем. Если привычнее пользоваться уже
ми и эвристическим анализатором, позволяющим иног- скомпилированными пакетами, то зайдите на страницу http:/
да обнаружить неизвестный вирус. Все, в общем, хоро- /clamav.sourceforge.net/binary.html и выберите нужную
шо, но, собрав полностью сервер из бесплатных компо- ссылку: на момент написания статьи это Debian, RedHat –
нентов, выбить финансы для того, чтобы платить за ли- Fedora, PLD (Polish(ed) Linux Distribution), Mandrake, AIX,
ценцию, под конец года не получилось. А ограничения FreeBSD, OpenBSD и MS Windows, на установке в этом
ознакомительной версии, в частности невозможность случае останавливаться не буду. В остальных случаях нуж-
проверки архивов, мне не совсем подходят. Плюс зацик- но компилировать самому, хотя ничего особо сложного
ливание на одном продукте обычно мешает увидеть его разработчики не придумали.
слабые и сильные стороны, все, как говорится, познает-
ся в сравнении. Тем более что в Интернете я постоянно #tar xzvf clamav-0.65.tar.gz
# cd clamav-0.65
натыкался на другие антивирусы, и мне захотелось по-
искать замену (или убедиться в отсутствии таковой, что Единcтвенная задержка возникает при конфигуриро-
тоже хорошо). В результате я вышел на несколько до- вании и выглядит это так:
вольно интересных проектов, о которых речь пойдет в
этой и следующей статьях. #./configure
...
Clam AntiVirus (http://clamav.sourceforge.net/ или http:// /dev/(u)random detected.
www.clamav.net/) представляет собой антивирусный ком- Checking /etc/passwd...
ERROR: User "clamav" (and/or group "clamav") doesn't exist.
плект для UNIX-систем. Главная цель продукта – интег- Please create it. You can omit this check with the --disable-
рация с почтовыми серверами для проверки вложений clamav option.
на предмет наличия вирусов. В настоящий момент под-
держивается широкий спектр операционных систем: Дело в том, что разработчики в целях безопасности
Linux, Solaris, FreeBSD, OpenBSD, NetBSD, AIX, Mac OS X, рекомендуют запускать утилиту от лица пользователя
BeOS, HPUX, SCO UNIX и Windows/Cygwin на несколь- clamav, а не root, и не устанавливать ни в коем случае
ких архитектурах: Intel, Alpha, Sparc, Cobalt MIPS boxes, SUID или SGID.
PowerPC, RISC 6000, что уже вызывает уважение. Рас- Избежать этого сообщения можно двумя способами:
пространяется по лицензии GPL, POSIX-интерфейс и об- добавить параметр --disable-clamav при конфигурирова-
щедоступные библиотеки позволяют быстро адаптиро- нии или просто создать этого пользователя.
вать его с другими приложениями. Работает с архивами
и сжатыми файлами, в настоящее время встроена под- # groupadd clamav
# useradd -g clamav -s /bin/false -c "Clam AntiVirus" clamav
держка RAR, Zip, Gzip, Bzip2. Также встроена поддерж-
ка защиты от mail-бомб, которые периодически любят По умолчанию ClamAV устанавливается в /usr/local, и,
закидывать в пользовательские ящики, и поддержива- соответственно, конфигурационный файл будет лежать в
ется milter-интерфейс к программе Sendmail. Обнаружи- /usr/local/etc, его месторасположение на /etc можно изме-
вает, по данным разработчиков, более 20 000 вирусов, нить, добавив опцию --sysconfdir=/etc.
червей и троянов (хотя программа при запуске выдает Если конфигурирование завершилось без ошибок, ком-
сообщение о чуть больше 10 000, остальное в дополни- пилируем и устанавливаем.
тельных базах). Конечно, по сравнению с другими подоб-
ными продуктами число получилось небольшое, но ведь # make
# su -c "make install"
мы знаем, что количество можно считать по-разному,
хотя сама программа при запуске выдает сообщение о После окончания установки в нашем распоряжении
10 000 вирусов. При необходимости можно воспользо- будет несколько исполняемых файлов:
ваться он-лайн-сканером, позволяющим протестировать ! clamscan – утилита командной строки, предназначен-
файлы на жестком диске. Для этого заходим по адресу: ная для проверки файлов и каталогов на предмет на-
http://www.gietl.com/test-clamav и указываем на файл. личия вирусов.
Если же вы имеете вирус, который не обнаруживается ! clamd – антивирусный демон, прослушивающий под-
ClamAV с обновленными базами, то по адресу: http:// ключения к UNIX или TCP-сокетам и сканирующий ка-
www.nervous.it/~nervous/cgi-bin/sendvirus.cgi или http:// талоги по требованию. Обеспечена возможность on-
www.clamav.net/cgi-bin/sendvirus.cgi можно заполнить access просмотра (только Linux) при применении ути-
форму, где нужно обязательно указать свой e-mail, имя литы clamuko.
и место расположения зараженного файла, опциональ- ! clamdscan – простой интерфейс к демону clamd, по-
но можно также проставить антивирус, обнаруживший зволяет также сканировать файлы и каталоги, при этом
заразу. Другой вариант: послать zip-архив с паролем virus используются те же параметры, что и в clamscan, и мо-
по адресу virus@clamav.net. После чего вирус будет про- жет полностью заменить clamscan.
анализирован и добавлен в базу данных. Об остальных ! clamav-milter (при конфигурировании с опцией --enable-
возможностях поговорим, когда посмотрим на его рабо- milter) – представляет собой антивирусный интерфейс
ту в действии. к sendmail, использует для просмотра почты clamd.

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


безопасность
! freshclam – утилита автоматического обновления ви- паковки, и дополнительных указаний ей не надо, но если
русной базы данных через Интернет, позволяющая появляются сообщения вроде:
держать ее в самом современном состоянии.
! sigtool – генерирует вирусную сигнатуру, используя вне-
шний антивирусный сканер, который способен обна- то указываем на необходимость проверки архивов, и если
ружить вирус. Может создавать шестнадцатиричный не видно нужного архиватора в переменной $PATH, то
дамп и формировать и распаковывать CVD-базу дан- указываем также местонахождение такой программы. На-
ных (ClamAV Virus Database). пример, для rar: -unrar[=FULLPATH]. Так, для zip-архива
строка запуска может выглядеть так:
Теперь по порядку и поподробней. Проверить текущий
каталог на наличие вирусов можно, просто набрав # clamscan –unzip /mnt/test/test.zip
clamscan без каких-либо параметров. В результате полу-
чим список проверенных файлов и отчет. Список проска- После чего программа должна вывести список всех
нированных файлов позволяет проверить работу утили- файлов архива с результатами проверки. И еще одна про-
ты с различными типами файлов на начальном этапе, но блема может подстерегать при проверке архивов. Выгля-
в большинстве случаев лучше добавить параметр -i для дит она так.
вывода только зараженных файлов. Указать на файлы,
находящиеся в другом каталоге, можно, перечислив их в
строке запуска, или, если проверяется каталог, то указать Каталог /tmp забивается таким образом очень быст-
путь к нему, не забыв опцию -r для рекурсивного обхода ро, т.е., закинув большой архив, можно провести DOS-
(для проверки работы антивируса с пакетом поставляет- атаку. Чтобы избежать этого, можно указать при помощи
ся несколько тестовых файлов). -tempdir= на другой каталог, в котором побольше свобод-
ного места, или установив максимальное количество из-
# /usr/local/bin/clamscan -r -i /home/sergej/work/clamav-0.65/ влекаемых за один раз файлов (-max-files=#n), или извлечь
сначала #n Кб архива (использовав nM или nm, можно
указать на количество Мб) при помощи –max-space=#n.
Можно просто указать на максимальный уровень рекур-
сии обхода архива: -max-recursion=#n.
В следующем примере используем новую антивирусную
базу и ограничиваем размер временных файлов в 50 Мб,
плюс проверяем архивы.

#clamscan -d /tmp/newclamdb –tgz –deb –unrar ↵


--max-space=50m -r /home

Я надеюсь, по clamscan все понятно. Переходим к де-


Опция --database= позволяет указать место располо- мону clamd. Главное отличие демона от сканера заключа-
жения дополнительной антивирусной базы. Также по умол- ется в том, что он один раз при старте загружает все не-
чанию пограмма не ведет никаких логов, при работе с cron обходимые базы и настройки и находится в оперативной
это не совсем удобно, т.к. теряется контроль над работой памяти постоянно готовым выполнить работу. В своей ра-
программы, при помощи --log= можно указать, в какой боте он использует конфигурационный файл clamav.conf.
файл их заносить. При необходимости проверки отдель- Если запустить программу без дополнительного редакти-
ных файлов каталога можно воспользоваться опциями - рования (в том случае, если установка происходила из
exclude=PATT и -include=PATT. Первая позволяет указать исходных текстов), то демон откажется работать.
шаблоны файлов, которые не надо проверять, а вторая,
наоборот, только те, которые надо просканировать в по- # /usr/local/sbin/clamd
иске вирусов. Опция -mbox включает сканирование почто-
вых каталогов и файлов.

#clamscan -r --mbox /var/spool/mail Файл хорошо комментирован, и опции описаны в man,


чтобы заставить работать демон в конфигурации по умол-
Или можно проверять выход другой программы на на- чанию, достаточно убрать или закомментировать строку
личие вирусов. Example в самом начале файла. Пример (ненужные пара-
метры достаточно закомментировать):
#cat testfile | clamscan -
#Example
# Ïóòü ê ëîã-ôàéëó
Кроме вывода информации об обнаружении вируса мож- LogFile /var/log/clamav/clamd.log
но удалить (--remove) или переместить (--move=DIRECTORY) # Áëîêèðîâêà çàïèñè â ëîã-ôàéë (íåîáõîäèìà ïðè çàïóñêå
# íåñêîëüêèõ äåìîíîâ îäíîâðåìåííî)â òîì ÷èñëå è âî èçáåæàíèå
такие файлы в другой каталог. Обычно при работе с ар- # ðàáîòû ñ îäèíàêîâîé êîíôèãóðàöèåé
хивами программа сама находит нужную утилиту для рас- #LogFileUnlock

34
безопасность
# ìàêñèìàëüíûé ðàçìåð ëîã-ôàéëà (0 – áåç îãðàíè÷åíèé) ! STREAM – просмотр потока, при этом демон выдаст
LogFileMaxSize 0 номер порта, в который необходимо посылать сигнал.
# Èñïîëüçîâàíèå syslog
LogSyslog
# Ïîäðîáíûé îò÷åò С сигналами понятно, только вот как их посылать, в
#LogVerbose
# Ôàéë äëÿ ñîõðàíåíèÿ èäåíòèôèêàòîðà ïðîöåññà документации сказано довольно невнятно. Оказалось, все
PidFile /var/run/clamav/clamd.pid замешано на межпроцессорном взаимодействии или под-
# Ïóòü ê àíòèâèðóñíûì áàçàì (ïî óìîë÷àíèþ /usr/local/share/clamav)
DataDirectory /var/lib/clamav ключении к сетевому порту. Например, команду «проска-
# Äåìîí ìîæåò ðàáîòàòü â ñåòåâîì èëè ëîêàëüíîì ðåæèìå, нировать каталог» можно дать таким образом (при сете-
# â öåëÿõ áåçîïàñíîñòè ðåêîìåíäóåòñÿ ïîêà ïîñëåäíèé, íî âîò
# ïîñûëàòü ñèãíàëû ìíå ïîêàçàëîñü áîëåå óäîáíûì èìåííî вом режиме работы демона):
# â ñåòåâîì. Íåñêîëüêî ñëåäóþùèõ ñòðîê íåîáõîäèìû äëÿ
# íàñòðîéêè ñåòåâîãî ðåæèìà.
#LocalSocket /var/run/clamav/clamd.sock # telnet localhost 3310
#FixStaleSocket
#TCPSocket 3310
#TCPAddr 127.0.0.1
#MaxConnectionQueueLength 30
# Ïðåäâàðèòåëüíàÿ çàïèñü ïîòîêà
StreamSaveToDisk
# Ïðåäåë äëÿ ïîòîêà, ïîñëå êîòîðîãî ñîåäèíåíèå çàêðûâàåòñÿ
#StreamMaxLength 10M
# Ìàêñèìàëüíîå êîëè÷åñòâî îäíîâðåìåííî âûïîëíÿåìûõ çàäà÷
MaxThreads 10
# Ìàêñèìàëüíàÿ ðåêóðñèÿ êàòàëîãà
MaxDirectoryRecursion 15
# Ñëåäîâàíèå ñèìâîëè÷åñêèì ññûëêàì äëÿ êàòàëîãîâ è ôàéëîâ Поэтому все-таки более удобным способом является
#FollowDirectorySymlinks
#FollowFileSymlinks использование утилиты clamdscan, просто введя в каче-
# Ïðîâåðêà öåëîñòíîñòè áàç (ïî óìîë÷àíèþ 1 ÷àñ) стве аргумента проверяемый каталог или файл.
#SelfCheck 600
# Êîìàíäà, êîòîðàÿ äîëæíà âûïîëíèòüñÿ ïðè îáíàðóæåíèè âèðóñà.
# Ïðè ýòîì èñïîëüçóþòñÿ ïîäñòàíîâêè %f – èìÿ èíôèöèðîâàííîãî #clamdscan /home
# ôàéëà, %v – íàçâàíèå âèðóñà. Äîëæåí èñïîëüçîâàòüñÿ ïîëíûé
# ïóòü ê êîìàíäå
#VirusEvent /usr/local/bin/send_sms 123456789 "VIRUS ALERT: %f: %v" Для автоматического запуска clamd вместе с системой
# Èìÿ ïîëüçîâàòåëÿ, îò êîòîðîãî çàïóñêàåòñÿ äåìîí, îí äîëæåí
# èìåòü ïðàâà íà èçìåíåíèå âñåõ ïåðå÷èñëåííûõ ôàéëîâ è êàòàëîãîâ. необходимо положить файл clamd.sh в каталог /etc/init.d/
User clamav и прописать путь для запуска в /etc/rc.d/rc.local или создать
# Ðàáîòà ñ ïî÷òîé è àðõèâàìè, äëÿ RAR íóæíà îòäåëüíàÿ ñòðîêà
ScanMail символическую ссылку в каталоге соответствующему
ScanArchive уровню запуска системы.
ScanRAR
# Óñòàíîâêà ìàêñèìàëüíûõ çíà÷åíèé äëÿ àðõèâîâ äëÿ çàùèòû
# îò mail-áîìá (0 – áåç îãðàíè÷åíèé). #ln -s /etc/init.d/clamd.sh /etc/rc.d/rc5.d/S50clamd
ArchiveMaxFileSize 10M
ArchiveMaxRecursion 5
ArchiveMaxFiles 1000 Хотя все в этом вопросе зависит от используемой опе-
ArchiveLimitMemoryUsage
рационной системы или дистрибутива Linux.
И далее в файле вы найдете несколько строк для ра- С clamav-milter все просто. Если антивирус устанавли-
боты с Clamuko. Это интерфейс к модулю Dazuko (http:// вался при помощи rpm-пакетов, то необходимо доустано-
dazuko.org), обеспечивает (только для Linux) работу clamd вить пакет clamav-milter-0.65-4.i386.rpm, в котором прак-
в режиме on-access через устройство /dev/dazuko. Это тически все уже настроено, и в каталоге /usr/share/doc/
пока еще экспериментальная разработка, пока я не убе- clamav-milter-0.65/ лежат документы RPM-clamav-milter.txt
дился в необходимости пользоваться ею, поэтому, если и HOWTO-logwathch.txt, в которых все расписано по ша-
кто-то заинтересовался, за подробностями обращайтесь гам. При установке из исходников также ничего сложно-
в документацию, в ней все понятно расписано. го. Добавляем в файл /etc/mail/sendmail.mc строку:
Запущенный демон ничего не делает. Для указания
того, чем именно сейчас ему заниматься, необходимо по- INPUT_MAIL_FILTER(`clmilter',`S=local:/var/run/clmilter.sock,
F=, T=S:4m;R:4m')dnl
слать сигнал: define(`confINPUT_MAIL_FILTERS', `clmilter')
! PING – проверка связи, в ответ демон посылает PONG, À â clamav.conf ïðîâåðÿåì íàëè÷èå òàêèõ ñòðîê.
LocalSocket /var/run/clamd.sock
и закрывает соединение. ScanMail
! VERSION – вывод версии. StreamSaveToDisk
! RELOAD – перезагрузка антивирусных баз.
! QUIT – остановка демона. И запускаем утилиту:
! SCAN file/directory – рекурсивный обход указанных ка-
талогов в поисках вирусов с поддержкой архивов (если #/usr/local/sbin/clamav-milter -blo /var/run/clmilter.sock
не запрещено в конфигурационном файле).
! RAWSCAN file/directory – то же, только без поддержки При необходимости ограничить число процессов до-
работы с архивами. бавляем опцию -max-children=, если сlamd работает в
! CONTSCAN file/directory – то же, что и SCAN, но при сетевом режиме, то дополнительно используется опция
обнаружении вируса программа не прерывает свою ра- -server= с указанием IP-адреса, последним аргументом в
боту, а продолжает обход каталога дальше. этом случае проставляется номер порта.

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


безопасность
Утилита автоматического обновления антивирусных морфного варианта. В документе «Creating signatures for
баз может запускаться в двух режимах: интерактивном – ClamAV», который поставляется вместе с архивом, рас-
из командной строки, и как демон. Утилита использует писано, как получить сигнатуру из тестовых «вирусов»,
базу http://database.clamav.net для автоматического вы- поставляемых вместе в ClamAV. Мне повезло чуть боль-
бора зеркала. В комплекте имеется также список таких ше. Погоняв чуть дольше недели антивирус в боевом ре-
баз, занесенный в файл mirror.txt, утилита пробует по жиме, удалось найти вирус который ClamAV не обнару-
порядку соединиться с первым в списке и в случае не- жил, а Dr.Web по его поводу сказал следующее:
удачи далее следует по списку. Можно подобрать для
себя оптимальный вариант и поставить его первым. Для #drweb /mnt/dos.ext.1/virus_test/
начала следует запустить утилиту без параметров, если
все нормально, то следующим создать лог-файлы, не-
обходимые для работы.

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

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

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

Параметр -с указывает на промежуток времени об-


новления базы в днях (число от 1 до 50). Для указания
отличной от установленной по умолчанию директории, в
которую должны помещаться обновления, используйте
опцию -datadir=. Прокси можно указать двумя способа- Другой антивирус F-prot, о котором речь пойдет в сле-
ми: либо задать в командной строке параметры -http- дующий раз, выдал сообщение:
proxy=hostname[:port] и при необходимости указания па-
роля для доступа -proxy-user=user:password; второй вари-
ант – установить нужное значение переменной http_proxy: Очевидно, разработчики ориентируются в первую оче-
редь на новые, недавно появившееся вирусы, и антиви-
#export http_proxy="proxy.server:8080" рус пока плохо знаком со старой гвардией. Сначала про-
буем создать такую сигнатуру при помощи clamscan:
Для контроля за обновлениями можно воспользо-
ваться параметрами: -on-error-execute=COMMAND и -on- # sigtool -c "clamscan --stdout" ↵
-f /home/sergej/virus_test/test.exe -s
update-execute=COMMAND. Первая позволяет задать ко-
манду, которая будет выполнена при неудачном обновле-
нии баз, вторая – наоборот, при успешном проведении об-
новления. Для одноразового запуска утилиты в случае не-
обходимости немедленного обновления она запускается Опция -с говорит, какую команду запускать, здесь дол-
без опции -d (да и -с смысла не имеет). Остальные пара- жен быть один из установленных в системе антивирусов,
метры при этом остаются теми же. В rpm-пакете лежит -f задает инфицированный файл, а -s – уникальная стро-
файл-шаблон /etc/sysconfig/freshclam, в котором можно за- ка, которую вывел антивирус, обнаруживший вирус, в
полнить соответствующие поля для установки всех выше- большинстве случаев сюда пишем имя обнаруженного ви-
перечисленных параметров, а запускать утилиту при по- руса. Как видите, при помощи clamscan обнаружить его
мощи скрипта /etc/init.d/freshclam. Можно для запуска ис- не получилось, поэтому пробуем Dr.Web.
пользовать и cron, занеся в /etc/сrontab для еженедельно-
го обновления примерно такую строку: # sigtool -c "drweb" -f -f /home/sergej/virus_test/test.exe ↵
-s "Win32.HLLP.Underscore.36864"
0 00 * * 07 /usr/local/bin/freshclam --quiet ↵
-l /var/log/clam-update.log

И последняя, довольно интересная утилита sigtool, по-


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

36
безопасность
се. Этот вирус, например, переименовывает файлы и со- компании не очень любят делиться своими наработками,
здает в системном каталоге файл mc42.exe. Поэтому при поэтому как-то приделать внешние базы пока не получа-
помощи Midnight Commander, или дав такую команду: ется, но некоторые сигнатуры в удобочитаемом виде мож-
но взять, например, на Sophos http://www.us.sophos.com/
# strings test.exe | less downloads/ide/, по крайней мере Bagle появился там быс-
тро, а простота операции позволила также оперативно за-
или двоичный дамп для анализа: нести информацию о нем в свою базу. В документации
показано, как можно затем обратно упаковать базу, вос-
#cat test.exe | sigtool --hex-dump > virus.sig пользовавшись опцией --build, но для этого необходимо
иметь доступ к специальному серверу, для подписи, по-
а лучше, воспользовавшись двоичным редактором, нахо- этому дальше я не пошел, оставил все как есть.
дим специфические для данного вируса строки (рис. 1) и
заносим их в отдельный файл. Но этот метод хоть интере-
сен и работает на ура, мне созданная таким образом сиг-
натура позволила найти все файлы на зараженном ком-
пакте, в том числе и упрятанные в архив (куда не смог
заглянуть Dr.Web), но все-таки этот процесс может занять
значительный промежуток времени, особенно при боль-
шом исходном файле. Можно попробовать разбить исход-
ный файл на меньшие по размеру, в котором(ых) внешний
антивирус будет еще находить вирус, и затем повторить
операцию. Разбить файл на части можно, воспользовав-
шись, например, split. Мне удалось, немного повозившись,
создать такой файл в 10 Кб и в результате: Ðèñóíîê 1
Предвидя некоторую критику, сразу отвечу: да, не дело
# sigtool -c "drweb" -f -f /home/sergej/work/xaf ↵ сисадмина собирать по всему свету сигнатуры. Но, с дру-
-s "Win32.HLLP.Underscore.36864"
гой стороны, так можно среагировать все-таки побыстрее,
чем антивирусные компании (ну, по крайней мере, такая
возможность греет душу), плюс новые сигнатуры добав-
ляются в базу данных ClamAV ежедневно, поэтому, я ду-
В результате в файле xaf.sig будет примерно такая маю, эта проблема будет решена в скором времени. Мне
строка. этот антивирус в общем-то понравился и не в последнюю
очередь разнообразием инструментов и удобством рабо-
ты. Также одним из положительных моментов знакомства
с ним отмечаю именно открытость продукта, позволившую
Добавляем в ее начало: наконец разобраться с технологией и понять реальный
механизм работы антивирусов. Для сомневающихся в сле-
Win32.HLLP.Underscore.36864 (Clam)= дующих статьях продолжим поиск. Успехов!

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


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

#sigtool --unpack-current daily.cvd

после чего в текущем каталоге появится файл viruses.db2,


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

#cat xaf.sig >> viruses.db2


#md5sum viruses.db2 > viruses.md5

Теперь можно пользоваться обновленной базой, ука-


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

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


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

DEVICELOCK

АНДРЕЙ БЕШКОВ
В последнее время все больше людей, работающих в ляющих повысить степень безопасности наших систем.
сфере ИТ, задумываются о безопасности. Все же недав- У каждого из них свои проценты полезности и соотно-
ние вирусные эпидемии и постоянные взломы тех или шение между ценой и качеством.
иных сайтов поневоле привлекают к себе внимание. В За всем этим валом правдивой, иногда не очень, а
связи с этим очень четко прослеживается тенденция ро- бывает, и откровенно рекламной информации скрывает-
ста рынка услуг, тем или иным образом связанных с бе- ся один интересный факт – большинство описываемых
зопасностью. Больше всего бросается в глаза разнооб- средств предназначены для защиты от внешних злоумыш-
разие видов брандмауэров и антивирусных систем. Прак- ленников. На первый взгляд это естественно, но если по-
тически каждое печатное и электронное издание, при- дойти к вопросу без излишней спешки и проанализиро-
частное к ИТ-тематике, посчитало необходимым расска- вать доступные факты, то получится, что, в соответствии
зать либо о первом, либо о втором виде продуктов. Бла- с последней статистикой, восемьдесят процентов инци-
годаря такому мощному потоку информации методы дентов происходят по вине людей, находящихся внутри
борьбы с внешними злоумышленниками всеми нами за- охраняемой сети, и только двадцать процентов приходит-
учены практически наизусть. Любой мало-мальски све- ся на внешние угрозы.
дущий в этом вопросе человек расскажет, что для защи- К сожалению, с внутренними угрозами безопасности
ты внутренней сети лучше всего вынести сервера, пре- все не так просто. Достаточно часто складывается такое
доставляющие публичные сервисы, в демилитаризован- положение дел, что сотрудники организации по умолча-
ные сети. А на всех шлюзах в корпоративную сеть и Ин- нию получают слишком большие полномочия, которые
тернет в зависимости от денежных средств, выделенных совершенно излишни для выполнения их ежедневных обя-
нам для этих целей, нужно обязательно поставить бран- занностей. Таким образом, получается, что внутри объек-
дмауэр аппаратной или программной реализации. Ну а та, тщательно защищаемого снаружи, образуется никем
с вирусами мы будем бороться, проверяя, где возможно, не контролируемый источник проблем. Можно защитить
потоки данных с помощью антивирусного программного сервера, находящиеся внутри корпоративной сети, с по-
обеспечения. Кроме описанных выше, существует еще мощью внутренних брандмауэров, но их использование
некоторое количество добавочных мероприятий, позво- приводит к дополнительным накладным расходам. Но все

38
безопасность
равно у обычного пользователя остается довольно боль- отличается, кроме временного ограничения и изредка
шой простор для злонамеренных действий, направленных появляющегося на экране напоминания с предложением
на локальную систему и системы, находящиеся рядом. Не- зарегистрироваться. Итак, дистрибутив размером в 1.6 Мб
которые особо продвинутые реализации брандмауэров мо- был довольно быстро скачан. После чтения документации,
гут менять свою схему действий в зависимости от даты и которую можно взять на том же сайте, было выяснено, что
времени. Такой подход, к примеру, помогает реализовать программа предназначена для работы в системах Windows
политики, при которых определенным IP-адресам разре- NT/2000/XP/2003. Для машин, функционирующих под уп-
шено работать с теми или иными сервисами только по равлением версий Windows 9x и Windows Millenium, тре-
будним дням с 9 часов утра до 17 часов вечера. Основная буется DeviceLock Millennium Edition. Для проведения тес-
проблема подобного решения заключается в том, что на тов были выбраны две машины: одна с Windows 2000
одном и том же компьютере могут работать одновремен- Professional, а вторая с Windows Server 2003. Пришло вре-
но или поочередно несколько пользователей, и большин- мя пробовать, какова на вкус эта новинка. Инсталляция
ство брандмауэров не обучены принимать в расчет этот прошла легко и без каких-либо проблем. Комплект
факт. Так что не стоит считать такой подход панацеей, DeviceLock состоит из двух частей:
спасающей от внутренних злоумышленников. ! DeviceLock Service – сервис, предоставляющий интер-
Сегодня я хотел бы рассказать о программе DeviceLock, фейс локального или удаленного управления
созданной компанией SmartLine. Эта программа помога- DeviceLock.
ет решить часть проблем с безопасностью рабочих мест ! DeviceLock Manager – программа, позволяющая сис-
и, таким образом, повысить общую защищенность сети темному администратору управлять всем комплексом.
изнутри. К сожалению, многие пользователи имеют при-
вычку приносить на свое рабочее место программы и дан- Поэтому стоит обратить внимание на один интересный
ные из посторонних источников. В этом случае никто не момент: если во время установки выбрать вариант
может поручиться за отсутствие в них троянских программ «custom», то появится возможность поставить на машину
и вирусов. Самым простым способом, конечно, было бы только DeviceLock Service без DeviceLock Manager. Таким
изъять все потенциально опасные устройства. Но я думаю, образом, на пользовательских машинах можно расставить
что руководство не одобрит тотального демонтирования только сервис, отвечающий за разграничение полномо-
CD-ROM, DVD, дисководов и прочих устройств, способ- чий, а управлять всем этим хозяйством через сеть с по-
ных переносить данные между компьютерами в обход мощью менеджера. Также доступен режим с автоматичес-
локальной сети. Да и большинство пользователей не оце- кой локальной инсталляцией. Чтобы воспользоваться этой
нит таких нововведений и запишет вас в черный список возможностью, нужно положить в директорию с дистри-
заклятых друзей. К тому же есть желание работать спо- бутивом файл devicelock.ini и запустить программу уста-
койно, а не тратить все силы на войну с пользователями, новки с ключом –s. Такой подход позволит поручить про-
поэтому нужно искать какой-то другой путь. Мне, как и цедуру обхода пользовательских машин и установку про-
многим другим администраторам, хотелось бы иметь воз- граммы младшему администратору без риска, что он мо-
можность более аккуратно и гибко управлять доступом жет случайно сделать что-то не так. Более подробно по-
пользователей к устройствам, установленным в компью- читать о том, каков формат файла devicelock.ini и что нуж-
тере, чем это позволяет делать административный интер- но в него записать, можно в прилагаемой к программе и
фейс, встроенный в Windows-системы. Также очень хо- доступной на сайте документации. Ну а для тех, кто умеет
чется, чтобы система безопасности автоматически меня- работать с Microsoft Systems Management Server (SMS),
ла свои настройки в зависимости от даты и времени. В есть вариант автоматической установки программного
решении именно таких проблем нам должен помочь обеспечения на целевые машины через сеть.
DeviceLock. Судя по документации, поставляемой вместе Кстати, стоит отметить очень хорошее качество доку-
с программой, она может контролировать и разграничи- ментации, взятой с сайта, а вот то, что поставляется в
вать доступ пользователей к следующим устройствам: пакете с программой в качестве встроенной системы по-
! Дисководы гибких дисков. мощи, выглядит весьма скудно. Надеюсь, в ближайшей
! Магнито-оптические дисководы. версии разработчики исправят этот досадный недостаток.
! CD-ROM. По окончании инсталляции программа выводит на экран
! DVD. вот такой диалог.
! ZIP.
! Все виды устройств, подключаемых через USB.
! Инфракрасный порт.
! Устройства, подключаемые через FireWire.
! Серийные или параллельные порты.
! BlueTooth и WiFi-адаптеры .
! Накопители на магнитных лентах.

Заинтересовавшись этой программой, я отправился на


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

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


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

Первый запуск утилиты особых сюрпризов не приносит,


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

Также обратите внимание на опцию «Allow eject» – с


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

Как видите, в этом временном интервале наш запрет


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

40
безопасность
очень полезное свойство программы, позволяющее лег- Стоит отметить, что список машин можно создать с по-
ко и надежно разграничить полномочия пользователей при мощью графического интерфейса или загрузить из пред-
работе с FireWire и USB-портами. К сожалению, стандар- варительно созданного файла. Следующим шагом созда-
тными средствами администрирования Windows решить ем список пользователей, на которых будут распростра-
эту проблему невозможно, потому что для добавления в няться наши правила. Затем помечаем галочками нуж-
систему вышеуказанных устройств не требуется иметь ные устройства, настраиваем временные интервалы, раз-
каких либо особых привилегий, а это значит, что любой решения и прочие опции. Нажав кнопку «Set permissions»,
мало-мальски грамотный пользователь может подключить наслаждаемся процессом. Обратите внимание на опцию
свои собственные устройства и спокойно уносить домой «Install/Update Service», она очень полезна для нас, если
корпоративные документы. В отсутствии DeviceLock един- во время копирования правил на целевой машине будет
ственным надежным решением было бы полное отключе- найдена устаревшая версия DeviceLock Service, то про-
ние таких портов, но как я уже говорил выше, нам такой грамма выполнит всю черную работу за нас, и нужный
вариант не подходит. компонент будет обновлен до текущей версии.
Наигравшись вдоволь с разными комбинациями правил, В течение нескольких дней, когда я самыми разными
я решил проверить, насколько удобным будет применение способами тестировал работу Batch permisions, была за-
DeviceLock в масштабе предприятия. Часто случается так, мечена всего одна ошибка. Видимо, во время копирова-
что в организации есть некоторое количество машин, ко- ния правил через сеть, что-то пошло не так, и я получил
торыми пользуется определенный круг работников, и все вот такую ошибку.
они должны быть настроены примерно одинаково. Для ма-
лой сети из нескольких машин описать все правила для
всех пользователей на каждом компьютере – процедура
не особенно приятная, хотя ради обеспечения собственно-
го дальнейшего спокойствия можно и потерпеть. В край- Судя по надписи, сработала защита от ошибок RPC, и
нем случае это неблагодарное занятие можно поручить никаких критичных действий выполнено не было. Повтор-
тому же младшему администратору. А вот в средних или ный запуск процедуры завершился удачно. Кроме выше-
больших сетях такое мероприятие может превратиться в описанной ошибки никаких других проблем обнаружено
продолжительную пытку. И самое главное неудобство кро- не было. Отдельным словом благодарности стоит отме-
ется в повседневном обслуживании такой системы. С те- тить удобство управления сервисами DeviceLock работа-
чением времени одни люди увольняются, а других нанима- ющими на удаленных машинах. Два раза щелкнув на име-
ют на освободившиеся должности. Неужели из-за этого при- ни компьютера, который нужно настроить, и введя пароль,
дется удалять или модифицировать вручную на всех ком- можно управлять им так же просто, как и локальным. Ка-
пьютерах правила, касающиеся конкретного пользовате- жется, что иногда можно даже запутаться и забыть, какой
ля? Вот тут-то на сцену выходит одна из самых мощных именно машиной мы сейчас управляем, но, как ни стран-
способностей DeviceLock, называемая batch permissions. С но, этого не происходит.
ее помощью мы за несколько минут решим эту проблему.
Для того чтобы воспользоваться этой возможностью, жмем
кнопку с изображением двух ключей или проходим через
меню File → Batch Permission. В появившемся диалоге до-
бавляем в список компьютеры, на которые нужно скопиро-
вать создаваемые правила.

В целом можно считать, что программа показалась мне


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

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


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

ТРИ ПОРОСЁНКА Snort:


«НИФ-НИФ», «НУФ-НУФ» И «НАФ-НАФ».
НАСТРОЙКА НЕСКОЛЬКИХ СЕНСОРОВ Snort
С ПОМОЩЬЮ SnortCenter

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

ПАВЕЛ ЗАКЛЯКОВ
42
безопасность
Прежде чем перейти к практическим вопросам использо- их в систему. Благо правила всё время находятся в одном
вания нескольких сенсоров на базе IDS Snort, рассмотрим и том же месте на сайте, а имя файла с последними прави-
теоретические аспекты этой задачи. Для этого оценим труд- лами остаётся неизменным. Либо http://www.snort.org/dl/
ности, возникающие при различных способах реализации, rules/snortrules-stable.tar.gz (* см.ниже) – стабильная ветка,
и создадим модель, по большей части лишённую замечен- либо http://www.snort.org/dl/rules/snortrules-current.tar.gz (* см.
ных недостатков. ниже) – активно развивающаяся. Во время процесса уста-
«Одна голова хорошо, а две лучше», – подумал змей новки в систему правила разархивируются, распаковыва-
Горыныч, убегая от Ильи Муромца. Так и в вопросах обна- ются, возможно, как-то проверяются, помещаются на мес-
ружения атак: информация лишней не бывает, больше сен- то старых правил, в конфигурационный файл, возможно,
соров – меньше вероятность пропуска атаки. Конечно, эф- вносятся изменения и происходит перезапуск демона snort,
фективность подключения новых сенсоров, начиная с не- чтобы внесённые изменения вступили в силу.
которого числа, не даст такого прироста эффективности, Таким образом, система работает с завидной стабиль-
как вначале, но это уже другой вопрос. ностью, присущей Linux/*BSD, некоторое, возможно, и про-
При использовании нескольких сенсоров наиболее должительное время. Позже планомерно появляются но-
удобным способом ведения логов будет использование вые хосты с сенсорами, меняются правила и происходят
одной или нескольких БД. Подробнее об этом можно про- другие мелкие события. В общем, всё работает.
читать в [4]. Задача заставить два сенсора вносить свои Но вот наступает тот самый момент, когда в алгоритме
записи в одну БД не представляет из себя никакой слож- работы системы наступает сбой либо вероятность его воз-
ности. Об этом не было рассказано ранее, но можно дога- никновения велика. Нет, это не правила неверно скачались.
даться, что необходимо в третьей секции конфигурацион- И не изменилось их местоположение, хотя и такое частень-
ного файла snort.conf, отвечающей за вывод данных, про- ко бывает. По этой причине вверху у ссылок стоят звёздоч-
писать всего лишь в одной строчке другое имя хоста с ки, ссылки уже не действительны. Так, недавно обновились
БД, номер порта, логин и пароль. Далее, если доступ к БД адреса и форматы правил для Snort после выхода версии
не закрыт каким-нибудь пакетным фильтром или МЭ по 2.1.1-RC1 из серии 2.1.x. Сейчас для разных серий надо
пути, то никаких проблем быть не должно. Даже ACID бу- скачивать разные правила, в результате имеем следующие
дет исправно показывать статистику от двух и более сен- реальные ссылки для скачивания:
соров. Работа такой системы только на первый взгляд ка- ! http://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
можно найти однозначный ответ. нашли очередную ошибку, например, для временного реше-
Давайте остановимся и частично рассмотрим пробле- ния которой необходимо отключение того или иного препро-
мы и пути решения первого вопроса. цессора в системе обработки трафика. То есть просто-на-
При отсутствии каких-либо целенаправленных решений просто надо внести изменения в конфигурационные файлы,
поставленный вопрос решается неудобно, но просто. Ад- например, закомментировать одну строчку. И вот ситуация
министратор подключается к компьютеру стандартными повторяется, администратор залезает и вручную правит пра-
средствами администрирования, например, с помощью ssh вила на каждом из сенсоров. А тут ситуация усугубляется
или telnet. Руками вносит изменения в конфигурационный тем, что раньше он работал один, а к моменту сбоя штаты
файл и перезапускает snort. Потом подключается к друго- разрослись, и администраторов стало много. Так что для ус-
му хосту, где установлен другой сенсор и повторяет опера- тановки всего лишь одного знака комментария необходимо
цию. Согласитесь, что при большом количестве узлов си- всем знать пароль суперпользователя и прочие неудобства.
туация не очень удобная. Поэтому администратор, чтобы Какой же может быть выход? Наиболее оптимальным
избавить себя от подобной рутинной работы, один раз ав- решением для данного случая было бы использование не-
томатизирует процесс – пишет скрипт на bash, который пе- кой единой конфигурационной БД с правилами для всех сен-
риодически запускается через cron, скачивает c помощью соров. Удобно, когда все правила в одном месте, соответ-
wget новые правила с сайта www.snort.org и устанавливает ственно, для внесения изменений уже требуются права толь-

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


безопасность
ко на доступ к конфигурационной БД с правилами, то есть Из чего состоит SnortCenter?
нет того случая, когда выдаются излишние права и пользо- 1. Из управляющей консоли SnortCenter Management Con-
ватель может сильно повредить работоспособность систе- sole – программы, написанной на PHP и осуществляю-
мы. Всё, казалось бы, хорошо, но только за любое удобство щей взаимодействие:
приходится чем-то расплачиваться. В данном случае нам при- ! с сенсорами посредством агентов;
дётся решать проблемы связи сенсоров с центральной кон- ! с правилами посредством БД;
фигурационной БД. Проблем здесь не меньше, а именно: ! с пользователем посредством веб-интерфейса.
! выбор того, кто с кем будет связываться: база данных 2. Из агентов SnortCenter Sensor Agents, запускаемых на
с сенсорами или сенсоры с БД; компьютерах-сенсорах с установленным Snort. Агенты –
! защита от пассивных атак (прослушивание трафика); это автономные (не требуют наличия веб-сервера) CGI-
! защита от активных атак, подмена правил и пр. программы на Perl, которые позволяют пользователю
или SnortCenter Management Console через веб-интер-
На наше счастье, нет необходимости придумывать дан- фейс взаимодействовать со Snort и его файлами кон-
ную систему с нуля, так как уже имеется пакет SnortCenter фигурации. Для защиты соединений от прослушивания
[1], изучением и настройкой которого мы займёмся далее. используется SSL-библиотека для perl SSLeay [5].

Коротко Если попытаться наглядно представить работу данной


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

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

44
безопасность
подходит или данная реализация всё же лучше, чем её от- В то время как на другом компьютере конфигурация про-
сутствие, то давайте приступим к её установке и настройке. шла без проблем. Первая мысль, что пришла в голову –
поискать на нём файл pcre.h, запустив:
Установка Snort
Выберем три узла, которые будут сенсорами, назовём их, # find / -name pcre.h
например, «Ниф-Ниф», «Нуф-Нуф» и «Наф-Наф» и попро-
буем создать схему, аналогичную приведённой выше, для В результате поиска были получены две строки:
этого, как и ранее, нам потребуется скачать и установить
Snort с поддержкой ведения логов в БД (подробнее см. [4]) /usr/include/pcre/pcre.h
/progi/snort/snort-2.1.1/src/win32/WIN32-Includes/pcre.h
на каждый из узлов-сенсоров. Те, у кого Snort уже уста-
новлен, могут пропустить несколько шагов, со всеми ос- после чего возникла мысль узнать, какой rpm-пакет со-
тальными скачиваем последнюю версию Snort: держит нужный файл, после чего была выполнена следу-
ющая команда:
# 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 # rpm -qf /usr/include/pcre/pcre.h
Сравниваем значение хеша выданного командами:
которая и сообщила, что нужный нам пакет – это pcre-
# cat snort-2.1.1.tar.gz.md5 devel-3.9-2, который успешно нашёлся на втором диске
# md5sum snort-2.1.1-RC1.tar.gz
RedHat 7.3 и был установлен командой:

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

Распаковываем содержимое архива snort-2.1.1.tar.gz после чего конфигурирование, запущенное повторно, про-
куда-нибудь, например, в уже имеющуюся директорию /progi: шло без проблем.
После конфигурирования необходимо скомпилировать
# tar -zxvf snort-2.1.1.tar.gz -C /progi Snort командой:

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

# cd /progi/snort-2.1.1 И установить командой:

и запускаем конфигурирование с опцией --with-mysql, не # make install


забыв о том, что для осуществления этого шага нам необ-
ходимо, чтобы в системе уже стояла библиотека libpcap, В процессе установки, если вы не задавали дополни-
например, licpcap-0.6.2-12, и часть файлов от MySQL, в час- тельных ключей, у вас будет установлено всего лишь 2
тности пакеты mysql-3.23.58-1.73 и mysql-devel-3.23.58-1.73. файла: /usr/local/bin/snort – сама программа и man-стра-
Подробнее см. [4]. ница к ней /usr/local/man/man8/snort.8. Далее следует со-
здать директорию /etc/snort, если вы ставите Snort на дан-
# ./configure --with-mysql ный компьютер в первый раз, или удалить все файлы и
поддиректории оттуда, если они у вас остались от преды-
Замечание. В процессе обновления Snort на одном из дущих версий. То же самое следует сделать с директори-
сенсоров с версии 2.0.4 до версии 2.1.1 во время запуска ей /var/log/snort. В целом нам эта директория не понадо-
команды конфигурации новой версии выдалась следующая бится, но если вдруг не получится вести логи в БД, то она
ошибка об отсутствии библиотеки pcre (Perl Compatible может нам пригодиться в процессе отладки.
Regular Expressions [9]). Аналогичным образом следует установить Snort на все
будущие сенсоры.
Следующим шагом мы осуществим установку агентов
(SnortSensor Agent) на наши сенсоры. После того как мы
убедимся, что они работают, мы установим и настроим
консоль управления SnortSensor (SnortCenter Management
Console), через которую загрузим на все сенсоры их фай-
лы конфигурации и осуществим дополнительную отладку
агентов, если это понадобится.

Установка SnortSensor Agent


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

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


безопасность
# wget http://symlabs.com/Net_SSLeay/Net_SSLeay.pm-1.21.tar.gz диться, что модуль SSL установился правильно, запустите:

Распаковываем содержимое архива Net_SSLeay.pm- # perl -e 'use Net::SSLeay'


1.21.tar.gz куда-нибудь, например, в уже имеющуюся ди-
ректорию /progi: Если не будет никаких сообщений об ошибках, то это
значит, что SSL-модуль установился правильно.
# tar -zxvf Net_SSLeay.pm-1.21.tar.gz -C /progi После того как модули установлены, можно приступить
к непосредственной установке SnortSensor Agent. Для это-
После заходим в появившуюся директорию по имени го скачиваем последнюю версию из [2].
и номеру версии модуля:
# wget http://users.pandora.be/larc/download/ ↵
# cd /progi/Net_SSLeay.pm-1.21 snortcenter-agent-v1.0-RC1.tar.gz

Скорее всего версия у вас будет та же самая, так как


и запускаем уже более года не обновляются новости и не выпускают-
ся новые версии. В процессе отладки продукта мы встре-
# perl Makefile.PL тимся с некоторыми проблемами, часть которых попро-
буем решить своими силами. К сожалению, попытки
либо связаться с автором («Stefan Dens» <larc@pandora.be>),
чтобы скоординировать усилия и, возможно, способ-
# ./Makefile.PL ствовать выходу новой версии без замеченных недо-
статков, не привели к успеху. На форуме от Snort воп-
Запущенный perl-скрипт проверяет наличие в системе росами SnortCenter не интересуются. В российской час-
OpenSSL и его версию, создаёт необходимые для дальней- ти, например на sysadmins.ru, поиск чего-нибудь по клю-
шей установки Makefile файлы. OpenSSL необходим для чевому слову snortcenter абсолютно бесполезен. Можно
нормальный работы Net_SSLeay. В случае необходимости констатировать, что проект «не отполирован до конца».
выдаются рекомендации по обновлению версии. Несмотря на подобное равнодушие к нему, в нём можно
Замечание 1. Следует отметить, что не всегда лучше найти некоторые полезные свойства, о которых можно
иметь самый последний номер того или иного пакета, в каж- прочитать ниже.
дом конкретном случае следует разбираться отдельно. Так, После скачивания архив необходимо куда-нибудь рас-
например, тот же Red Hat очень любит выпускать исправле- паковать, например в /progi:
ния к старым версиям. В результате получается, что номер
версии пакета остаётся старый, а ошибок в пакете уже нет. # tar -zxvf snortcenter-agent-v1.0-RC1.tar.gz -C /progi
Замечание 2. Для компиляции модуля Net_SSLeay не-
обходимо, чтобы также был установлен пакет openssl-devel, После запуска команды следует зайти в появившуюся
хотя его наличие не проверяется. Сделать это можно, на- директорию /progi/sensor:
пример, командой:
# cd /progi/sensor
# rpm -ihv openssl-devel-0.9.6b-35.7.i386.rpm
Далее следует запустить скрипт setup.sh для конфигу-
Если пакет openssl-devel у вас не будет установлен, то рации сенсора посредством ответов на вопросы:
в процессе компиляции вы получите следующую ошибку:
# ./setup.sh

Появится следующая картинка (см. рис. 2, 3).


На запрос «Config file directory» вместо /progi/sensor/
conf следует указать /etc/snort / – то место, где будут рас-
полагаться и куда будут записываться конфигурационные
файлы, необходимые для запуска Snort.
На запрос «Log file directory» вместо /progi/sensor/log
следует указать /var/log/snort – это место, куда будут вес-
Для компиляции запускаем: тись логи.
На запрос расположения интерпретатора Perl «Full path
# make to perl» нажмите просто {ENTER}, если вы не меняли его
месторасположение и имя на отличные от приведённых
После успешной компиляции запускаем: по умолчанию /usr/bin/perl.
То же самое и по поводу Snort – нажмите просто {ENTER}.
# make install На запрос о пути к правилам Snort «Snort Rule config
file directory» введите /etc/snort вместо предлагаемых /progi/
для установки модулей и man к ним. Для того чтобы убе- sensor/rules/.

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

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

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


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

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


Замечание. Несмотря на то что в предыдущих настрой- Замечание. Реальные пользователи в системе не за-
ках мы располагали правила в /etc/snort/rules, сейчас, ис- водятся. Заведённые пользователи с хэшами от паролей
ходя из соображений удобства, мы этого делать не будем. находятся в /etc/snort/sensor.users. В силу особенностей
Далее задаются вопросы, необходимые для настрой- реализации не используйте символы «:» и «@» в логине и
ки собственного веб-сервера. пароле во избежание ошибок.
Уточняется порт, на котором будет веб-сервер агента На запросы «Login password:» и «Password again:» при-
«Sensor port», лучше всего его оставить без изменений, думайте и введите два раза пароль: ваш_пароль№7 для
если у вас нет других соображений на этот счёт, нажав доступа вышеобозначенного пользователя к веб-серверу.
{ENTER}. (По умолчанию 2525). Будьте внимательны, во время ввода пароля в соответ-
Далее спрашивается, какой IP-адрес следует прослу- ствии с одним из требований безопасности System V звёз-
шивать. Это нужно на тот случай, если у вас несколько IP- дочки вместо вводимых символов не отображаются. В слу-
адресов на одном интерфейсе или более сложная схема. чае несовпадения паролей программа выдаст ошибку:
По умолчанию следует оставить «any», и тогда будут про-
слушиваться только те адреса, которые связаны с конк-
ретным интерфейсом. Это первое неудобство агентов, что и необходимо будет запустить конфигурацию ещё раз:
их следует привязывать к интерфейсам. Это не самое
страшное неудобство, и об этом мы поговорим чуть ниже. # ./setup.sh
Пока же на запрос «If this host has multiple IP addresses,
the server can be configured to listen on only one address и ответить на вышеописанные вопросы заново. После
(default any):» нажмём просто {ENTER}. удачного ввода пароля появится вопрос, как называется
Далее программа настройки запрашивает логин хост, на котором установлен сенсор. «Sensor host name
пользователя, которому будет разрешено в дальнейшем (default %имя_вашего_хоста%):» Можно оставить то имя,
подключаться к веб-серверу. Для начала на запрос «Login что указано по умолчанию, нажав {ENTER}, а можно на-
name (default admin)» можно нажать просто {ENTER}, од- писать что-то новое, вроде Nif-Nif или Nuf-Nuf, чтобы как-
нако если вы хотите несколько повысить защищённость, то различать сенсоры в дальнейшем.
то придумайте своё имя, которое вам придётся соответ- На вопрос об использовании SSL отвечаем «y» и жмём
ственно заменить и в других местах самостоятельно, где {ENTER}.
это понадобится. Далее нас спрашивают о диапазоне IP-адресов, с ко-

48
безопасность
торых можно будет осуществлять доступ к агенту. Это до- # 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
лее гибко можно сделать с помощью какого-нибудь па-
кетного фильтра, вроде iptables, однако одно другому не Переменные $REMOTE_IP и $SENSOR_IP следует заме-
мешает и на запрос «Allowed IP addresses» лучше ввести нить нужными значениями. Данные правила не учитывают
IP-адрес или имя центра управления сенсорами. При не- направления установления соединения, но при необходимо-
обходимости ввести несколько адресов разделяйте их сти их можно подправить, ещё больше «закрутив гайки».
пробелами, следуя выведенной подсказке. После захода на веб-страничку агента будет запрошен
Следующим будет вопрос о том, следует ли запускать логин и пароль. И выдастся следующая картинка:
агента автоматически при загрузке системы «Start Sensor
at boot time (y/n):», то есть необходимо ли создать соответ-
ствующие файлы в /etc/rc.d/... Отвечаем на этот вопрос «y»
и жмём {ENTER}, в противном случае нам придётся каж-
дый раз после перезагрузки системы по тем или иным при-
чинам запускать агентов руками, что может быть не очень
удобно. После ответа на все вопросы осуществляется за-
пуск агента, и фактически он уже готов работать.
В директории /etc/snort у вас появится 11 файлов и 2
директории с необходимыми файлами для работы агента
(см. рис. 4). В частности, будут созданы файлы для запус-
ка, остановки и деинсталляции, так что совсем не обяза- Нам этого вполне достаточно, пытаться что-то запус-
тельно запускать и останавливать работу агента через /etc/ тить на данный момент есть бессмысленное занятие, так
rc.d/init.d/sensor. как у нас ещё нет конфигурационного файла, с которым
бы следовало запускать Snort. Аналогичным образом ус-
танавливаются и проверяются SnortSensor Agent на дру-
гих узлах.
Для того чтобы создать необходимые конфигурацион-
ные файлы и запустить Snort, нам необходимо теперь за-
няться центром управления, для этого установить на него
непосредственно консоль управления, так называемую
SnortSensor Management Console, и настроить её на со-
вместную работу с БД правил и сенсорами, далее необ-
ходимо создать правила для сенсоров, передать их на
узлы. После этого на узлах-сенсорах будут созданы соот-
Ðèñóíîê 4. Âèä äèðåêòîðèè /etc/snort ïîñëå óñòàíîâêè ветствующие им файлы конфигурации, и можно будет по-
SnortSensor Agent пытаться запустить Snort.
Запустив:
Установка и настройка консоли управления
# /etc/rc.d/init.d/sensor status SnortSensor Management Console
По идее, центр управления лучше установить на отдель-
можно убедиться, что агент запущен и работает. Если на ком- ном компьютере, но так как на сам центр могут также со-
пьютере будущего центра имеется веб-браузер или вы захо- вершаться атаки, то лучше и на нём установить сенсор
дите с другого компьютера, указанного в списке разрешён- для их обнаружения. В результате получится конфигура-
ных для доступа к веб-серверу, и правила пакетного фильтра ция, когда центральная консоль управления устанавлива-
позволяют проходить пакетам, то вы можете запустить брау- ется на одном из сенсоров.
зер и подключиться к агенту через защищённый веб-интерфейс, Для начала установки скачиваем из [2] последнюю вер-
набрав просто адрес «https://адрес_агента:2525». Проверить сию SnortSensor Management Console, способную работать
работу агента таким образом желательно, чтобы не искать пос- со Snort v.2.x.
ле ошибку, потратив большее количество времени.
Если вы не позаботились ранее о возможности подклю- # wget http://users.pandora.be/larc/download/ ↵
snortcenter-v1.0-RC1.tar.gz
чения к агенту с других хостов, хотя бы на время настройки
системы, то, возможно, вам потребуется дописать разреше- Далее распаковываем содержимое архива туда, где на-
ние на нужный вам хост в файле /etc/snort/miniserv.conf че- ходятся файлы веб-сервера, например, в директорию /var/
рез пробел после того, что написано у параметра «allow=». www/html:
Удалить лишние разрешённые хосты можно там же.
Для разрешения прохождения пакетов через пакетный # tar -zxvf snortcenter-v1.0-RC1.tar.gz -C /var/www/html
фильтр iptables, настроенный на политику запрета по умол-
чанию, следует указать два следующих правила: Далее, чтобы не запутаться, распаковавшуюся только

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


безопасность
что директорию /var/www/html/www переименуем в /var/www/ ! $DB_dbname – переменная, определяющая имя БД, в
html/snortcenter: которой находятся все правила наших сенсоров, при
желании имя для БД можно сменить, но тогда и далее,
# mv /var/www/html/www /var/www/html/snortcenter когда мы будем создавать эту БД, придётся ей указать
другое имя. Поэтому оставляем это значение без из-
Затем нам необходимо отредактировать файл config.php, менения $DB_dbname = «snortcenter»;
для этого либо запускаем: ! $DB_host – переменная, определяющая имя (адрес) хос-
та, на котором стоит БД с правилами. При желании БД
# mcedit /var/www/html/snortcenter/config.php может располагаться не обязательно на том же хосте,
где находится SnortSensor Management Console. В слу-
либо жмём F4 на нужном файле в mc (midnight commander). чае если хосты будут разными, то помимо удобств это
Если у вас не установлен mc, то редактируем файл с по- добавит проблем, а именно необходимо будет дополни-
мощью vi: тельно осуществлять защиту соединений от прослуши-
вания и навязывания информации между БД и управля-
# vi /var/www/html/snortcenter/config.php ющей консолью. В нашем случае хосты совпадают, по-
этому оставляем без изменений: $DB_host = «localhost»;
Предполагается, что на центральном компьютере уже ! $DB_user – переменная, определяющая, от имени како-
установлен ACID и все необходимые для его работы ком- го пользователя следует подключаться к базе данных с
поненты, в частности php, php-mysql и ADODB – абстракт- именем $DB_dbname. По умолчанию в программе пред-
ный класс доступа к базам данных, написанный на PHP [7]. полагается использование имени root – суперпользова-
Подробнее об установке ACID см. [4]. теля БД MySQL. Если оставить эту переменную без из-
В процессе редактирования конфигурационного файла менений, то в качестве пароля в следующей перемен-
необходимо правильно определить следующие переменные: ной придётся задать ваш_пароль№2 см. [4]. В принци-
! $DBlib_path – переменная отвечает за путь к ADODB, пе это не очень хорошо, так как SnortCenter Management
если следовать установке, описанной в [4], то вместо Console получит излишние права над всеми БД, хотя ей
$DBlib_path = «./adodb/»; следует написать $DBlib_path = всего лишь достаточно прав на одну лишь БД snortcenter
«../adodb/»; ($DB_dbname). Для того чтобы лишний раз не риско-
! $DBtype – переменная, отвечающая за тип БД, так как вать, в качестве $DB_user мы напишем пользователя
мы работаем пока только с БД MySQL, то и оставим её snortcenteruser $DB_user = «snortcenteruser»; а потом со-
без изменения: $DBtype = «mysql»; здадим такого пользователя в БД MySQL.

50
безопасность
! $DB_password – переменная, определяющая пароль # mysql -u root -p
пользователя БД $DB_user. Если ранее вы оставили
пользователя root, запишите ваш_пароль№2, в про- На запрос пароля вводим ваш_пароль№2 (см. [4]). Да-
тивном случае необходимо придумать ваш_пароль№6 лее даём команды:
и записать: $DB_password = «ваш_пароль№6»;
! $DB_port – переменная определяет порт, на котором mysql> CREATE DATABASE snortcenter;
mysql> grant CREATE,INSERT,SELECT,DELETE,UPDATE ↵
работает БД и к которому следует подключаться. По on snortcenter.* to snortcenteruser@localhost;
умолчанию в БД MySQL используется порт 3306, если mysql> grant CREATE,INSERT,SELECT,DELETE,UPDATE ↵
on snortcenter.* to snortcenteruser;
вы его не меняли, то оставьте значение этой перемен- mysql> set password for ↵
ной пустым, будет использоваться именно этот порт. 'snortcenteruser'@'localhost'=password('âàø_ïàðîëü¹6');
mysql> set password for ↵
! $hidden_key_num – в эту переменную необходимо запи- 'snortcenteruser'@'%'=password('âàø_ïàðîëü¹6');
сать придуманное вами случайное число. Данное случай- mysql> exit
ное число используется в дальнейшем в системе аутен-
тификации для шифрования значений, хранящихся в Третью и пятую команды можно не давать, если у вас
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». Если вас не устраивает обновление через центра, где установлена управляющая консоль SnortCenter
Интернет, например, по соображениям безопасности, то (http://адрес_SnortCenter/snortcenter/, а лучше, если ваш веб-
некоторые рекомендации вы встретите ниже. сервер поддерживает защищённое соединение https://
! $max_lines – данная переменная отвечает за число пра- адрес_SnortCenter/snortcenter/).
вил, помещающихся на одной странице, естественно, при Программа быстро определяет, что была запущена в
маленьком значении переменной большое число правил первый раз, и создаёт необходимые для её работы табли-
ведёт к большому числу страниц, что неудобно. Лучше цы. Также среди строчек мы можем увидеть строчку о со-
увеличить это значение, но если канал связи медленный, здании пользователя:
то делать число правил на странице большим не следу-
ет. Однако удобнее вначале сделать его большим, акти-
вировать все правила, а после придать параметру какое- из которой мы можем узнать логин и пароль для доступа
нибудь разумное значение, например, $max_lines = 50 к SnortSensor Management Console в дальнейшем.
вместо установленных по умолчанию $max_lines = 12. Если подождать некоторое время либо набрать вышеука-
занный URL повторно, то мы попадём на страничку, где будут
В конфигурационном файле встречаются и другие пе- спрашиваться вышеуказанные login и password. В дальней-
ременные, но для нас они менее существенны, поэтому шем мы сменим пароль на другой, а пока вводим «change».
мы их не рассматриваем. Подробнее обо всех перемен-
ных см. [8].
После того как управляющая консоль SnortCenter на-
строена, нам необходимо:
! создать БД snortcenter;
! создать пользователя snortcenteruser;
! задать пароль ваш_пароль№6 этому пользователю;
! задать необходимые права данному пользователю для
доступа к его БД. После входа нам необходимо записать в БД новые
Для этого подключаемся к БД MySQL от имени супер- правила, обычно для этого рекомендуется зайти в меню
пользователя этой БД. Admin → Import/Update rules → Update from Internet.

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


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

После чего программа скачивает все правила из Ин- ям выше, как будто вы загружаете правила из Интернета.
тернета с адреса $snortrules_url, указанного в файле Второй – так же вручную скачать правила, распаковать,
config.php. Иногда по соображениям безопасности серве- проверить, создать из них единый текстовый файл. После
ра не имеют доступа к веб-сайтам, поэтому такое обнов- использовать этот текстовый файл для записи правил в БД
ление может потерпеть неуспех. Если у вас подобный слу- либо путём копирования всего его содержимого в соответ-
чай, то вместо обновления правил вас ждёт через некото- ствующую загрузочную область веб-формы (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-ю строку:
вить $snortrules_url в config.php и, возможно, дописать пару
разрешающих правил для iptables и проследовать указани- //echo "$sql<BR>";

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

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

52
безопасность
которая находится перед: строчку, и что теперь они могут переноситься с помощью
указания обратного слеша «\» в конце строки.
$result = $db->acidExecute($sql); После того как стала ясна причина ошибки, можно по-
$result_a = $db->acidExecute("SELECT max(id) FROM preprocessor");
$myrow = $result_a->acidFetchRow(); пытаться её исправить, для этого пишем небольшой
$update_rule_count[1] = 'add-spp'; скрипт на perl, который будет перенесённые строки соби-
$update_rule_count[2] = $myrow[0];
рать в одну строку.
В результате была получена следующая картинка пос- Создадим файл /var/www/html/snortcenter/convert_ru-
ле запуска (см. рис. 6). les.pl следующего содержания:
После этого, глядя на «global \», возникла мысль, что
проблема, скорее всего, связана с переносом длинных #!/usr/bin/perl
while ($temp=<STDIN>){
строк в файлах конфигурации. В разборщике правил для if ($temp=~/^[^#].*\\\n$/) { chomp $temp;
SnortCenter, видимо, забыли учесть, что, начиная со Snort chop $temp; }
print $temp;
v.1.8, правила не обязательно должны писаться в одну }

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

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


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

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

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


Не забудем придать атрибут запускаемости этому файлу. ного слеша, что приводит к тому, что последующая строка
как бы приклеивается к текущей в общем потоке символов.
# chmod +x convert_rules.pl Далее необходимо внести изменения в скрипт разбо-
ра файлов в нужном месте, чтобы наш файл оттуда вы-
При желании скрипт можно сократить, но тогда он бу- зывался перед тем, как правила попадут к разборщику.
дет менее наглядным. Скрипт делает следующее: читает Для этого вносим изменения в строки 74 и 78 файла
построчно стандартный поток ввода и помещает прочи- db_pars.php, отвечающие за загрузку правил с веб-сервера.
танное в переменную $temp. Вносить изменения в файлы, загружаемые вручную так-
Далее эта переменная проверяется на наличие в конце же желательно, но не обязательно, так как в этом случае
строки обратного слеша и что эта строка не есть коммента- вы всегда имеете возможность их подправить, придав им
рий. Если обратный слеш есть и строка не начинается со нужный вид. Поэтому исправления будут только в двух ме-
знака «#» (какой смысл переносить комментарии), то осу- стах, а не в большем количестве мест.
ществляется отрезание от строки символа её конца и обрат- Вместо:

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

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

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


$fp=popen($curl_path."curl -s $proxyline $snortrules_url | ↵ После этого правила успешно загружаются, уже не вы-
gunzip -dcf - | tar -xOf - rules/*.rules ↵
rules/*.conf rules/*.config", "r"); давая сообщения об ошибке. В окошке браузера у вас по-
явится примерно следующая картинка (см. рис. 7).
и Как видно, во время разгрузки правил выдаются пре-
дупреждения о неизвестности некоторых полей с коммен-
$fp=popen($curl_path."curl -s $proxyline $snortrules_url ↵ тариями: Unknown Rule option: msg:«....», однако на рабо-
2>/dev/null | tar xzOf - rules/*.rules rules/*.conf ↵
rules/*.config", "r"); тоспособность snort это не влияет. После загрузки пра-
вил можно убедиться, что они оказались в БД snortcenter,
пишем для этого выбираем Resources → Rules → View Rules и
наблюдаем правила (см. рис. 8).
$fp=popen($curl_path."curl -s $proxyline $snortrules_url | ↵ Аналогичным образом можно просмотреть переменные
gunzip -dcf - | tar -xOf - rules/*.rules rules/*.conf ↵
rules/*.config | ↵ (Resources → Variables → View Variables), препроцессоры
/var/www/html/snortcenter/convert_rules.pl", "r"); (Resources → Preprocessors → View Preprocessors) и дру-
гую информацию. Для просмотра не обязательно исполь-
и зовать средства SnortCenter, можно воспользоваться
phpMyAdmin или напрямую использовать клиент mysql [4].
$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"); здать конфигурации сенсоров, активировать нужные для

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


безопасность
каждого сенсора правила и закачать конфигурации на Можно проверить, все ли правила вы активировали или
свои места, чтобы конфигурационные файлы сенсоров со- нет, для этого необходимо щёлкнуть на Rule Category
ответствовали записям в БД для каждого сенсора. Overview.
Для того чтобы добавить сенсор в БД, выбираем Sensor
Console → Add Sensor (см. рис. 9).
И далее заполняем поля таблички. В имени сенсора
не имеет смысла вводить знак «-», так как он автомати-
чески после будет оттуда удалён. Среди параметров ко-
мандной строки желательно указать ключ -D, чтобы snort
запустился и стал демоном. В качестве пароля вводим
ранее придуманный ваш_пароль№7. После того как все
поля заполнены, нажимаем save (см. рис. 10).
Далее необходимо для созданного сенсора активиро-
вать правила, для этого выбираем в меню Sensor Config →
Rule Selection (см. рис. 11).
В появившемся окне после списка внизу нажимаем на После чего появится табличка, в которой правила бу-
Select, после чего все правила выделяются галочками: дут разбиты по категориям, около каждой категории бу-
дет два числа через дробь – числа активированных пра-
вил к общему числу правил в категории. Если в категории
не все правила активированы, то она для удобства подсве-
чивается жёлтым. Те категории, в которых все правила ак-
тивированы, подсвечены зелёно-салатовым (cм. рис. 12).
Аналогично, даже чуть более просто активируем пе-
ременные, для этого выбираем в меню Sensor Config →
Variable selection и т. д.

далее в падающем меню выбираем пункт Activate и знач-


ки около правил изменяются.

Аналогично поступаем с препроцессорами и другими пун-


ктами меню RuleType Selection, Classificaton Selection и т. д.
Единственный недостаток программы, что All означа-
ет не все правила, как может показаться, а всего лишь
все правила на текущей странице, поэтому не следует
забывать активировать правила на 2-й, 3-й... и т. д. стра-
ницах. Разработчики не позаботились об удобстве, поэто-
му нелишним будет вспомнить про наличие переменной
$max_lines в файле conig.php. Однако не стоит увлекать-
ся, уже на значении $max_lines=1000 в процессе работы с
правилами может появиться следующая ошибка.

Перед тем как активировать Output Plugin Selection,


необходимо создать конфигурации для каждого из сенсо-

56
безопасность
ров, для этого необходимо выбрать Resources → Output вый конфигурационный файл на выбранный сенсор. Для
Plugins → Create Output Plugin (см. рис. 13). этого следует выбрать Sensor Console → View Sensors и у
В появившемся падающем меню следует выбрать Databa- нужного сенсора (пока он один) нажать push (см. рис. 16).
se (Log to a variety of databases) и нажать select (см. рис. 14). После чего снизу на жёлтом фоне появится надпись,
Далее появится таблица, которую необходимо запол- сообщающая об успешном сбросе файла конфигурации
нить (см. рис. 15). на его место.
В DB Host следует указать имя или адрес сервера, на
котором запущена БД, в которую следует вести логи. Ана-
логично заполняются и другие параметры. После заполне-
ния необходимо нажать на save. После того как будет со-
здан хотя бы один output plugin, его можно будет выбрать и
активировать в Sensor Config → Output Plugin Selection.
После того как все необходимые составляющие правил для
нужного сенсора выбраны, можно создать и скинуть итого- Казалось бы, что на этом настройка должна быть за-

Ðèñóíîê 12. Ïðîñìîòð àêòèâèðîâàííîñòè ïðàâèë ïî êàòåãîðèÿì

Ðèñóíîê 13. Âûáîð ïóíêòà ìåíþ «Create Output Plugin»

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


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

Ðèñóíîê 14. Âûáîð ïóíêòà ìåíþ «Database (Log to a variety of databases)»

Ðèñóíîê 15. Íàñòðîéêà ïàðàìåòðîâ âåäåíèÿ ëîãîâ â ÁÄ


кончена и достаточно нажать на start, чтобы всё зарабо-
тало, но, к сожалению, это не так. Сейчас мы осуществим
некоторые действия, догадка о выполнении которых была
получена опытным путём. Если попытаться нажать start,
то мы получим сообщение об ошибке, не дающее запус- Из чего можно сделать предположение о том, что системе
тить snort на сенсоре: не хватает файла unicode.map (находится в файле с правила-

58
безопасность
ми). По идее этот файл не должен меняться так же часто, как пока в этом нет необходимости. Также при визуальном
правила, поэтому нет смысла править SnortCenter, чтобы он просмотре было замечено несколько опечаток: в строч-
умел его скидывать вместе с файлом конфигурации. Проще ках 166, 232, 250, 251 файла db_pars.php и строчке 307
его скинуть один раз руками в директорию /etc/snort. Чтобы в файла rules.php, скорее всего, вместо Unknown-Catagory
дальнейшем не возникало подобных ошибок, лучше всего следует написать Unknown-Category.
вместе с unicode.map скинуть и другие *.map-файлы, а имен- После этого при нажатии на start snort успешно запус-
но для текущей версии это sid-msg.map и gen-msg.map. тился, имя сенсора стало подсвеченным салатово-зелёным
Далее следует подправить строчки 140-142 в файле цветом.
parser.php. Вместо Аналогичным образом следует усновить Snort и Snort-
Center Agent на другие машины-сенсоры и настроить их на
elseif ($what == "byte_test") { совместную работу со SnortCenter Management Console. (Об-
if ($rule['byte_test']) $rule['byte_test'] ↵
[$content_nr] .= "; byte_test: $val"; ратите внимание, у разных сенсоров переменная HOME_NET
else $rule['byte_test'][$content_nr] = $val; будет разная).
В результате после запуска Snort на всех сенсорах у
следует написать: вас получится примерно следующая картинка консоли
управления, где все запущенные сенсоры окажутся на
elseif ($what == "byte_test") { зелёно-салатовом фоне (см. рис. 17).
$rule['byte_test'][$content_nr] = $val;
Если Snort остановлен, то подсветка будет жёлто-оран-
До того, как это было сделано, разборщик правил не- жевая, и справа вместо «stop» будет «start», а вот если
верно разбирал правила, в результате чего дописывалось сенсор недоступен, то подсветка будет красной, и также
лишнее значение byte_test: и snort не хотел запускаться. будет соответствующее сообщение (см. рис. 18).
Возможно, подобную операцию по корректированию в Теперь, когда всё работает, самое время поговорить
дальнейшем придётся сделать со строками 136-138, но об удобствах и недостатках.

Ðèñóíîê 16. Ñêèäûâàíèå êîíôèãóðàöèîííîãî ôàéëà íà ñåíñîð

Ðèñóíîê 17. Óñïåøíî ðàáîòàþùèå ñåíñîðû

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


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

Ðèñóíîê 18. Íåêîòîðûå ñåíñîðû íåäîñòóïíû, îñòàíîâëåíû


Удобства. либо с выводом имени каждого копируемого файла:
SnortCenter + ACID
Обычно SnortCenter и ACID [10] запускаются на одном сер- # cp -Rv /progi/acid-0.9.6b23_plugin/* /var/www/html/acid
вере, поэтому возникает логичный вопрос, почему бы не
интегрировать интерфейс одного средства с другим. Ко- Далее необходимо подредактировать файл plugin.conf.php,
нечно, этого можно и не делать, но почему бы не иметь изменив в нём переменную $snortcenter_home таким об-
возможность с помощью мышки из одной страницы с за- разом, чтобы она указывала путь к файлам snortcenter.
писями об атаках попасть путём одного щелчка на стра- В нашем случае вместо $snortcenter_home = «http://
ничку состояния сенсоров. В данном случае не надо ниче- localhost/»; пишем $snortcenter_home = «../snortcenter/»;
го придумывать, так как уже имеется готовое решение в Следует заметить, что помимо обычного интерфейса
виде SnortCenter ACID Plugin. Нам необходимо просто ска- к ACID с полными правами мы также создавали интер-
чать Plugin и установить в соответствии с прилагаемыми фейс только для просмотра (см. [4]), соответственно, если
к нему инструкциями. (Предполагается, что у пользовате- это необходимо, все вышеописанные действия следует
ля уже стоит ACID и работает, если нет, то его необходи- повторить и по отношению к нему.
мо установить, см. [4].) Для этого скачиваем файл acid- После установки в результате запуска ACID обычным
0.9.6b23-plugin-v1.tar.gz: образом мы получим следующую картинку (см. рис. 19).
Следует заметить, что так как изменения не коснулись
# wget http://users.pandora.be/larc/download/ ↵ файлов snortcenter, то специальной кнопки по прямому
acid-0.9.6b23-plugin-v1.tar.gz
переходу в ACID из него нет. На этом статью можно было
Распаковываем содержимое архива в какую-нибудь бы и закончить, если бы не ряд недостатков, которые не
директорию, например в /progi: хочется оставлять без внимания.

# tar -zxvf acid-0.9.6b23-plugin-v1.tar.gz -C /progi Недостатки


Первый из них это то, что если произойдёт перезапуск ком-
Переименовываем как-нибудь файлы ACID пьютера-сенсора, на котором запущен snort, то после пе-
acid_main.php, acid_output_html.inc, acid_style.css, чтобы резапуска работу snort, как это мы делали ранее, никто не
они не потерялись, так как на их место будут записаны восстановит. Как вариант необходимо вносить изменения
новые. Например, допишем к ним расширения .bak: в консоль управления SnortCenter, чтобы она умела запус-
кать Snort автоматически и при этом отличала аварийно
# 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 га, описанных выше. Решение этой проблемы довольно
просто: необходимо, как и ранее, создать файл snortd, по-
Далее копируем все файлы с учётом поддиректорий местить его в директорию /etc/rc.d/init.d и сделать на него
из директории /progi/acid-0.9.6b23_plugin в директорию, где ссылки из директорий, соответствующих необходимым
установлен ACID: /var/www/html/acid: уровням запуска. Однако в связи с тем, что имена конфи-
гурационных файлов теперь другие, изменится и содержа-
# cp -R /progi/acid-0.9.6b23_plugin/* /var/www/html/acid ние файла snortd.

60
безопасность
Например, вместо ранее snort.conf теперь может быть # July 08, 2000 Dave Wreski <dave@guardiandigital.com>
snort.eth0.conf. В принципе эту проблему можно бы было # - added snort user/group
# - support for 1.6.2
решить путём создания соответствующих мягких ссылок,
но сделать это невозможно, так как в некоторых случаях # Source function library.
. /etc/rc.d/init.d/functions
на одном узле может быть запущено несколько демонов
snort, прослушивающих разные интерфейсы. Этот слу- # Specify your network interface here
INTERFACE=eth0
чай наиболее неудобный, но не безысходный.
Первый способ решения – это правка файла ниже и дуб- # See how we were called.
case "$1" in
лирование строк запуска с разными конфигурациями. Од- start)
нако этот путь имеет недостатки, а именно все демоны ра- echo -n "Starting snort: "
# ifconfig eth0 up
ботают или не работают одновременно, как остановить или daemon /usr/local/bin/snort -o -i $INTERFACE -d -D ↵
запустить лишь один из демонов? Написав более сложный -c /etc/snort/snort.$INTERFACE.conf
touch /var/lock/subsys/snort
скрипт, можно решить и эту проблему. Возможно, в следую- sleep 3
щих статьях я напишу этот файл и приведу его с коммента- if [ -f /var/log/snort/alert ]
then
риями, однако он явно понадобится не всем, да и существу- rm /var/log/snort/alert
ет более простое решение, как создание нескольких фай- fi
echo
лов запуска/останова, каждый из которых будет отвечать ;;
только за свою конфигурацию snort. В этом случае просто stop)
echo -n "Stopping snort: "
создаём файлы snortd2, snortd3 и т. д., аналогичные файлу killproc snort
snortd, вносим в них изменения и также делаем необходи- rm -f /var/lock/subsys/snort
echo
мые ссылки. Листинг файла snortd.(snortd2, snortd3...): ;;
restart)
$0 stop
#!/bin/bash $0 start
# ;;
# snortd Start/Stop the snort IDS daemon. status)
# status snort
# chkconfig: 2345 79 11 ;;
# description: snort is a lightweight network intrusion *)
# detection tool that currently detects more than 1100 host echo "Usage: $0 {start|stop|restart|status}"
# and network vulnerabilities, portscans, backdoors, and more. exit 1
# esac
# June 10, 2000 -- Dave Wreski <dave@linuxsecurity.com>
# - initial version exit 0
#

Ðèñóíîê 19. Âèä ACID ïîñëå óñòàíîâêè SnortCenter ACID Plugin

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


безопасность
Далее следует дать команду: ! Данные между сенсорами и консолью управления пе-
редаются будучи закрытыми средствами слабой и не-
# chkconfig snortd on проверенной криптографии, что является защитой
(# chkconfig snortd2 on)
только от дилетантов и создаёт заведомо ложную за-
и т. д., чтобы в директориях соответствующих уровней щищённость канала.
появились символические ссылки на этот файл. ! Все передаваемые в системе данные никак не защи-
Далее следует дать команду: щаются от подмены.
! Отсутствие ведения логов в системе – кто, когда и что
# chkconfig snortd on исправлял, например, на случай, если в системе име-
ется несколько администраторов.
чтобы в директориях соответствующих уровней появились ! Отсутствие продуманного взаимодействия с другими
символические ссылки на этот файл. После этого выше- средствами защиты, например, с пакетными фильтра-
описанная проблема запуска snort будет решена. ми. По большей части написание тех или иных разре-
Вторым недостатком в работе SnortCenter можно на- шающих/запрещающих правил на компьютере центра
звать слабые возможности по редактированию правил. и сенсорах лежит на администраторе и не защищено
Через веб-интерфейс нельзя внести существенные изме- от его ошибки.
нения в правила, а также я не заметил возможности уда- ! Отсутствие продуманных механизмов резервной свя-
ления правил через веб-интерфейс. Конечно, это не кри- зи на случай атак на саму систему или её части.
тические недостатки, их можно обойти путём создания
своих собственных правил (кстати, свои правила уже уда- В целом это не единственные недостатки данной си-
ляются), их активации и деактивации ненужных, но в це- стемы, а лишь основные, которые бросаются сразу в гла-
лом в этом направлении я бы доработал эту программу в за. Многие из них выходят за рамки описанного выше
будущем. средства, решающего только одну узкую проблему еди-
ного хранения файлов конфигурации и диагностики, и
Положительные моменты затрагивают более широкий спектр средств, обеспечи-
Помимо отрицательных моментов в работе программы вающих безопасность. Описанные выше проблемы ско-
есть и положительные моменты, а именно хорошая «за- рее повод для их будущего более глубокого осмысления,
щита от дурака» при создании нерабочеспособных кон- решения и последующего описания полученных резуль-
фигурационных файлов. Система себя ведёт очень хит- татов на страницах журнала.
рым образом, а именно на сенсорах всегда после перво-
го запуска хранятся две конфигурации – основная и ре- Литература, ссылки:
зервная. Когда вы загружаете новый файл конфигура- 1. SnortCenter – Snort management console http://
ции, то перед его запуском система осуществляет тес- users.pandora.be/larc/
тирование файла конфигурации и параметров запуска с 2. SnortCenter: раздел download http://users.pandora.be/
опцией «-T». В случае успешного тестирования происхо- larc/download/
дит запуск Snort с новым файлом конфигурации, а ре- 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 с.
пускает Snort «в предыдущей» конфигурации. Таким об- 5. Net::SSLeay.pm Home Page http://symlabs.com/
разом, даже неумелому администратору будет сложно Net_SSLeay/
заставить Snort не работать ошибочными правилами, 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/.
ет попытаться решить, если есть потребность в создании
надёжной, отказоустойчивой и безопасной системы об-
наружения атак. Среди недостатков можно отметить сле-
дующие:
! Передача данных с сенсоров в центральную БД в от-
крытом виде.

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

ОШИБКИ ПЕРЕПОЛНЕНИЯ БУФЕРА ИЗВНЕ


И ИЗНУТРИ КАК ОБОБЩЕННЫЙ ОПЫТ
РЕАЛЬНЫХ АТАК

Мы живем в суровом мире. Программное обеспечение, окружающее нас, содержит дыры, многие
из которых размерами со слона. В дыры лезут хакеры, вирусы и черви, совершающие набеги изо
всех концов Сети. Червям противостоят антивирусы, заплатки, брандмауэры и другие умные слова,
существующие лишь на бумаге и бессильные сдержать размножение червей в реальной жизни.
Сеть небезопасна – это факт. Можно до потери пульса закидывать Била Гейтса тухлыми яйцами
и кремовыми тортами, но ситуация от этого вряд ли изменится.
Анализ показывает, что подавляющее большинство червей и хакерских атак основано на ошибках
переполнения буфера, которые носят фундаментальный характер и которых не избежало
практически ни одно полновесное приложение. Попытка разобраться в этой, на первый взгляд
довольно скучной и незатейливой проблеме безопасности погружает вас в удивительный мир,
полный приключений и интриг. Захват управления системой путем переполнения буфера –
сложная инженерная задача, требующая нетривиального мышления и превосходной экипировки.
Диверсионный код, заброшенный на выполнение, находится в весьма жестких и агрессивных
условиях, не обеспечивающих и минимального уровня жизнедеятельности.
Если вам нужен путеводитель по стране переполняющихся буферов, снабженный исчерпывающим
руководством по выживанию, – эта статья для вас!

КРИС КАСПЕРСКИ
64
безопасность
Чудовищная сложность современных компьютерных сис- Переполнение при записи приводит к затиранию, а
тем неизбежно приводит к ошибкам проектирования и следовательно, искажению одной или нескольких пере-
реализации, многие из которых позволяют злоумышлен- менных (включая служебные переменные, внедряемые
нику захватывать контроль над удаленным узлом или де- компилятором, такие, например, как адреса возврата или
лать с ним что-то нехорошее. Такие ошибки называются указатели this), нарушая тем самым нормальный ход вы-
дырами или уязвимостями (holes и vulnerability соответ- полнения программы и вызывая одно из следующих по-
ственно). следствий:
Мир дыр чрезвычайно многолик и разнообразен: это и ! нет никаких последствий;
отладочные люки, и слабые механизмы аутентификации, ! программа выдает неверные данные или, попросту го-
и функционально-избыточная интерпретация пользо- воря, делает из чисел винегрет;
вательского ввода, и некорректная проверка аргумен- ! программа «вылетает», зависает или аварийно завер-
тов и т. д. Классификация дыр чрезвычайно размыта, вза- шается с сообщением об ошибке;
имно противоречива и затруднена (во всяком случае, сво- ! программа изменяет логику своего поведения, выпол-
его Карла Линнея дыры еще ждут), а методики их поиска няя незапланированные действия.
и «эксплуатации» не поддаются обобщению и требуют
творческого подхода к каждому отдельному случаю. Было Переполнение при чтении менее опасно, т.к. «всего
бы наивно надеяться, что одна-единственная публикация лишь» приводит к потенциальной возможности доступа к
сможет описать весь этот зоопарк! Давайте лучше сосре- конфиденциальным данным (например, паролям или иден-
доточимся на ошибках переполнения буферов как на наи- тификаторам TCP/IP-соединения).
более важном, популярном, перспективном и приоритет-
ном направлении. Ëèñòèíã 1. Ïðèìåð ïîñëåäîâàòåëüíîãî ïåðåïîëíåíèÿ áóôåðà ïðè
çàïèñè
Большую часть статьи мы будем витать в бумажных
абстракциях теоретических построений и лишь к концу seq_write(char *p)
{
спустимся на ассемблерную землю, обсуждая наиболее char buff[8];
актуальные проблемы практических реализаций. Нет, не …
strcpy(buff, p);
подумайте! Никто не собирается в сотый раз объяснять, }
что такое стек, адреса памяти и откуда они растут! Эта
Ëèñòèíã 2. Ïðèìåð èíäåêñíîãî ïåðåïîëíåíèÿ áóôåðà ïðè ÷òåíèè
публикация рассчитана на хорошо подготовленную чи-
тательскую аудиторию, знающую ассемблер и бегло idx_write(int i)
{
изъясняющуюся на Си/Си++ без словаря. Как происхо- char buff[]="0123456789";
дит переполнение буфера, вы уже представляете и те- …
return buff[i];
перь хотели бы ознакомиться с полным списком возмож- }
ностей, предоставляемых переполняющимися буферами.
Какие цели может преследовать атакующий? По какому За концом буфера могут находиться данные следую-
принципу происходит отбор наиболее предпочтительных щих типов: другие буфера, скалярные переменные и ука-
объектов атаки? затели или же вовсе может не находиться ничего (на-
Другими словами, сначала мы будем долго говорить о пример, невыделенная страница памяти). Теоретически
том, что можно сделать с помощью переполнения, и лишь за концом буфера может располагаться исполняемый
потом перейдем к вопросу «как именно это сделать». В код, но на практике такая ситуация почти никогда не
любом случае эта тема заслуживает отдельной статьи. встречается.
Описанные здесь приемы работоспособны на большин- Наибольшую угрозу для безопасности системы пред-
стве процессорных архитектур и операционных систем ставляют именно указатели, поскольку они позволяют ата-
(например, UNIX/SPARC). Пусть вас не смущает, что при- кующему осуществлять запись в произвольные ячейки
водимые примеры в основном относятся к Windows NT и памяти или передавать управление по произвольным ад-
производным от нее системам. Просто в момент написа- ресам, например, на начало самого переполняющегося
ния статьи другой операционной системы не оказалось буфера, в котором расположен машинный код, специаль-
под рукой. но подготовленный злоумышленником и обычно называ-
емый shell-кодом.
Мясной рулет ошибок переполнения, Буфера, располагающиеся за концом переполняюще-
или попытка классификации гося буфера, могут хранить некоторую конфиденциаль-
Согласно «Новому словарю хакера» Эрика Раймонда ную информацию (например, пароли). Раскрытие чужих
ошибки переполнения буфера – это «то, что с неизбежно- паролей, равно как и навязывание атакуемой програм-
стью происходит при попытке засунуть в буфер больше, ме своего пароля – вполне типичное поведение для ата-
чем тот может переварить». На самом деле, это всего лишь кующего.
частный случай последовательного переполнения при Скалярные переменные могут хранить индексы (и тог-
записи. Помимо него существует индексное переполне- да они фактически приравниваются к указателям), фла-
ние, заключающееся в доступе к произвольной ячейке ги, определяющие логику поведения программы (в том
памяти за концом буфера, где под «доступом» понимают- числе и отладочные люки, оставленные разработчиком),
ся как операции чтения, так и операции записи. и прочую информацию.

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


безопасность
В зависимости от своего местоположения буфера де- ред выходом из функции приходится выполнять специ-
лятся на три независимые категории: альный код, освобождающий все, что программист ус-
! локальные буфера, расположенные в стеке и часто на- пел к этому времени понавыделять. Без критикуемого
зываемые автоматическими переменными; goto эта задача решается только глубоко вложенными if,
! статичные буфера, расположенные в секции (сегмен- обработчиками структурных исключений, макросами или
те) данных; внешними функциями, что захламляет листинг и служит
! динамические буфера, расположенные в куче. Все они источником многочисленных и трудноуловимых ошибок.
имеют свои специфичные особенности переполнения, Многие библиотечные функции (например, gets,
которые мы обязательно рассмотрим во всех подроб- sprintf) не имеют никаких средств ограничения длины воз-
ностях, но сначала немного пофилософствуем. вращаемых данных и легко вызывают ошибки перепол-
нения. Руководства по безопасности буквально кишат ка-
Неизбежность ошибок переполнения тегорическими запретами на использование последних,
в исторической перспективе рекомендуя их «безопасные» аналоги – fgets и snprintf,
Ошибки переполнения – это фундаментальные програм- явно специфицирующие предельно допустимую длину
мистские ошибки, которые чрезвычайно трудно отслежи- буфера, передаваемую в специальном аргументе. Поми-
вать и фундаментальность которых обеспечивается самой мо неоправданного загромождения листинга посторон-
природой языка Си – наиболее популярного языка про- ними аргументами и естественных проблем с их синхро-
граммирования всех времен и народов, – а точнее его низацией (при работе со сложными структурами данных,
низкоуровневым характером взаимодействия с памятью. когда один-единственный буфер хранит много всякой
Поддержка массивов реализована лишь частично, и ра- всячины, вычисление длины оставшегося «хвоста» ста-
бота с ними требует чрезвычайной аккуратности и вни- новится не такой уж очевидной арифметической зада-
мания со стороны программиста. Средства автоматичес- чей, и здесь очень легко допустить грубые ошибки)
кого контроля выхода за границы отсутствуют, возмож- программист сталкивается с необходимостью контроля
ность определения количества элементов массива по ука- целостности обрабатываемых данных. Как минимум не-
зателю и не ночевала, строки, завершающиеся нулем, – обходимо убедиться, что данные не были варварски об-
вообще песня… резаны и/или усечены, а как максимум – корректно об-
Дело даже не в том, что малейшая небрежность и за- работать ситуацию с обрезанием. А что мы, собствен-
бытая или некорректно реализованная проверка коррек- но, здесь можем сделать? Увеличить буфер и повторно
тности аргументов приводит к потенциальной уязвимос- вызывать функцию, чтобы скопировать туда остаток?
ти программы. Корректную проверку аргументов невоз- Не слишком-то элегантное решение, к тому же всегда
можно осуществить в принципе! Рассмотрим функцию, существует вероятность потерять завершающий нуль
определяющую длину переданной ей строки и посимволь- на конце.
но читающую эту строку до встречи с завершающим ее В Си++ ситуация с переполнением обстоит намного
нулем. А если завершающего нуля на конце не окажет- лучше, хотя проблем все равно хватает. Поддержка ди-
ся? Тогда функция вылетит за пределы утвержденного намических массивов и «прозрачных» текстовых строк
блока памяти и пойдет чесать непаханую целину посто- наконец-то появилась (и это очень хорошо), но подавля-
ронней оперативной памяти! В лучшем случае это закон- ющее большинство реализаций динамических массивов
чится выбросом исключения. В худшем – доступом к кон- работает крайне медленно, а строки тормозят еще силь-
фиденциальным данным. Можно, конечно, передать мак- нее, поэтому в критических участках кода от них лучше
симальную длину строкового буфера с отдельным аргу- сразу же отказаться. Иначе и быть не может, поскольку
ментом, но кто поручится, что она верна? Ведь этот ар- существует только один способ построения динамичес-
гумент приходится формировать вручную, и, следова- ких массивов переменной длины – представление их со-
тельно, он не застрахован от ошибок. Короче говоря, держимого в виде ссылочной структуры (например, дву-
вызываемой функции ничего не остается, как заклады- направленного списка). Для быстрого доступа к произ-
ваться на корректность переданных ей аргументов, а раз вольному элементу список нужно индексировать, а саму
так – о каких проверках мы вообще говорим?! таблицу индексов где-то хранить. Таким образом, чте-
С другой стороны – выделение буфера возможно ние/запись одного-единственненного символа выливает-
лишь после вычисления длины принимаемой структуры ся в десятки машинных команд и множество обращений
данных, т.е. должно осуществляться динамически. Это к памяти (а память была, есть и продолжает оставаться
препятствует размещению буферов в стеке, поскольку самым узким местом, существенно снижающим общую
стековые буфера имеют фиксированный размер, зада- производительность системы).
ваемый еще на стадии компиляции. Зато стековые бу- Даже если компилятор вдруг решит заняться контро-
фера автоматически освобождаются при выходе из фун- лем границ массива (одно дополнительное обращение к
кции, снимая это бремя с плеч программиста и предотв- памяти и три-четыре машинных команды), это не решит
ращая потенциальные проблемы с утечками памяти. Ди- проблемы, поскольку при обнаружении переполнения от-
намические буфера, выделяемые из кучи, намного ме- компилированная программа не сможет сделать ничего
нее популярны, поскольку их использование уродует умнее, чем аварийно завершить свое выполнение. Вы-
структуру программы. Если раньше обработка текущих зов исключения не предлагается, поскольку если про-
ошибок сводилась к немедленному return, то теперь пе- граммист забудет его обработать (а он наверняка забу-

66
безопасность
дет это сделать), мы получим атаку типа отказ в обслу- А теперь для контраста перечислим мифы противопо-
живании. Конечно, это не захват системы, но все равно ложной стороны – стороны защитников информации, с
нехорошо. какой-то детской наивностью свято верящих, что от хаке-
Так что ошибки переполнения были, есть и будут! От ров можно защититься хотя бы в принципе:
этого никуда не уйти, и коль скоро мы обречены на дли- ! не существуют никаких надежных методик автомати-
тельное сосуществование с последними, будет нелишним ческого (или хотя бы полуавтоматического) поиска пе-
познакомиться с ними поближе… реполняющихся буферов, дающих удовлетворитель-
ный результат, и по-настоящему крупные дыры не об-
Окутанные желтым туманом наруживаются целенаправленным поиском. Их откры-
мифов и легенд тие – игра слепого случая;
Журналисты, пишущие о компьютерной безопасности, и ! все разработанные методики борьбы с переполняющи-
эксперты по безопасности, зарабатывающие на жизнь мися буферами снижают производительность (под час
установкой этих самых систем безопасности, склонны пре- очень значительно), но не исключают возможности пе-
увеличивать значимость и могущество атак, основанных реполнения полностью, хотя и портят атакующему
на переполнении буфера. Дескать, хакеры буфера гребут жизнь;
лопатой, и если не принять адекватных (и весьма дорого- ! межсетевые экраны отсекают лишь самых примитив-
стоящих!) защитных мер, ваша информация превратится нейших из червей, загружающих свой хвост через от-
в пепел. дельное TCP/IP-соединение, отследить же передачу
Все это так (ведь и на улицу лишний раз лучше не вы- данных в контексте уже установленных TCP/IP-соеди-
ходить – случается, что и балконы падают), но за всю ис- нение никакой межсетевой экран не в силах.
торию существования компьютерной индустрии не насчи-
тывается и десятка случаев широкомасштабного исполь- Существуют сотни тысяч публикаций, посвященных
зования переполняющихся буферов для распространения проблеме переполнения, краткий список которых был при-
вирусов или атак. Отчасти потому, что атаки настоящих веден в предыдущей статье этого цикла. Среди них есть
профессионалов происходят бесшумно. Отчасти – пото- как уникальные работы, так и откровенный «поросячий
му, что настоящих профессионалов среди современных визг», подогреваемый собственной крутизной (мол, смот-
хакеров практически совсем не осталось… рите, я тоже стек сорвал! Ну и что, что в лабораторных
Наличие одного или нескольких переполняющихся бу- условиях?!). Статьи теоретиков от программирования эле-
феров еще ни о чем не говорит, и большинство ошибок ментарно распознаются замалчиванием проблем, с кото-
переполнения не позволяет атакующему продвинуться рыми сразу же сталкиваешься при анализе полновесных
дальше банального DoS. Вот неполный перечень ограни- приложений и проектировании shell-кодов (по сути своей
чений, с которыми приходится сталкиваться червям и ха- являющихся высокоавтономными роботами).
керам: Большинство авторов ограничиваются исключительно
! строковые переполняющиеся буфера (а таковых сре- вопросами последовательного переполнения автомати-
ди них большинство) не позволяют внедрять символ ческих буферов, оттесняя остальные виды переполнений
нуля в середину буфера и препятствуют вводу некото- на задний план, в результате чего у многих читателей со-
рых символов, которые программа интерпретирует осо- здается выхолощенное представление о проблеме. На
бым образом; самом деле, мир переполняющихся буферов значитель-
! размер переполняющихся буферов обычно оказыва- но шире, многограннее и интереснее, в чем мы сейчас и
ется катастрофически мал для вмещения в них даже убедимся.
простейшего загрузчика или затирания сколь-нибудь
значимых структур данных; Похороненный под грудой распечаток
! абсолютный адрес переполняющегося буфера атаку- исходного и дизассемблерного кода
ющему чаще всего неизвестен, поэтому приходится Как происходит поиск переполняющихся буферов и как
оперировать относительными адресами, что очень не- осуществляется проектирование shell-кода? Первым де-
просто с технической точки зрения; лом выбирается объект нападения, роль которого игра-
! адреса системных и библиотечных функций меняют- ет уязвимое приложение. Если вы хотите убедиться в соб-
ся от одной операционной системы к другой – это раз. ственной безопасности или атаковать строго определен-
Ни на какие адреса уязвимой программы также ный узел, вы должны исследовать конкретную версию
нельзя закладываться, поскольку они непостоянны конкретного программного пакета, установленного на
(особенно это актуально для UNIX-приложений, ком- конкретной машине. Если же вы стремитесь прославить-
пилируемых каждым пользователем самостоятель- ся на весь мир или пытаетесь сконструировать мощное
но) – а это два; оружие, дающее вам контроль над десятками тысяч, а
! наконец, от атакующего требуется глубокое знание то и миллионами машин, ваш выбор становится уже не
команд процессора, архитектуры операционной систе- так однозначен.
мы, особенностей различных компиляторов языка, сво- С одной стороны, это должна быть широко распрост-
бодное от академических предрассудков мышление, раненная и по возможности малоисследованная програм-
плюс уйма свободного времени для анализа, проекти- ма, исполняющаяся с наивысшими привилегиями и си-
рования и отладки shell-кода. дящая на портах, которые не так-то просто закрыть. Ра-

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


безопасность
зумеется, с точки зрения межсетевого экрана все порты но нашпигованные ошибками переполнения. Тщатель-
равноценны и ему абсолютно все равно, что закрывать. ность сама по себе еще ни от чего не спасает. Для пре-
Однако пользователи сетевых служб и администраторы дотвращения ошибок нужен богатый программистский
придерживаются другого мнения. Если от 135-порта, ис- опыт, и опыт, оставленный граблями в том числе. Но
пользуемого червем Love San, в подавляющем большин- вместе с опытом зачастую появляется и вальяжная не-
стве случаев можно безболезненно отказаться (лично брежность – своеобразный «отходняк» от юношеского
автор статьи именно так и поступил), то без услуг того увлечения эффективностью и оптимизацией.
же веб-сервера обойдешься едва ли. Признаком откровенного непрофессионализма явля-
Чем сложнее исследуемое приложение, тем больше ется пренебрежение #define или безграмотное использо-
вероятность обнаружить в нем критическую ошибку. Сле- вание последних. В частности, если размер буфера buff
дует также обращать внимание и на формат представ- определяется через MAX_BUF_SIZE, то и размер копиру-
ления обрабатываемых данных. Чаще всего переполня- емой в него строки должен ограничиваться им же, а не
ющиеся буфера обнаруживаются в синтаксических ана- MAX_STR_SIZE, заданным в отдельном define. Обращай-
лизаторах, выполняющих парсинг текстовых строк, од- те внимание и на характер аргументов функций, работа-
нако большинство этих ошибок уже давно обнаружено и ющих с блоками данных.
устранено. Лучше искать переполняющиеся буфера там, Передача функции указателя без сообщения разме-
где до вас их никто не искал. Народная мудрость утвер- ра блока – частая ошибка начинающих, равно как и зло-
ждает: хочешь что-то хорошо спрятать – положи это на употребление функциями strcpy/strncpy. Первая небезо-
самое видное место. На фоне нашумевших эпидемий пасна (отсутствует возможность ограничить предельно
Love San и Slapper с этим трудно не согласиться. Кажет- допустимую длину копируемой строки), вторая ненадеж-
ся невероятным, что такие очевидные переполнения до на (отсутствует возможность оповещения о факте «об-
последнего времени оставались необнаруженными! резания» хвоста строки, не уместившегося в буфер, что
Наличие исходных текстов одновременно желатель- само по себе может служить весьма нехилым источни-
но и нежелательно. Желательно – потому что они суще- ком ошибок).
ственно упрощают и ускоряют поиск переполняющихся Хорошо, ошибка переполнения найдена. Что дальше?
буферов, а нежелательно… по той же самой причине! А дальше только дизассемблер. Не пытайтесь выжать из
Как говорится: больше народу – меньше кислороду. Дей- исходных текстов хоть какую-то дополнительную инфор-
ствительно, трудно рассчитывать найти что-то новое в мацию. Порядок размещения переменных в памяти не
исходнике, зачитанном всеми до дыр. Отсутствие исход- определен и практически никогда не совпадает с поряд-
ных текстов существенно ограничивает круг исследова- ком их объявления в программе. Может оказаться так, что
телей, отсекая многочисленную армию прикладных про- большинства из этих переменных в памяти попросту нет
граммистов и еще большую толпу откровенных непро- и они размещены компилятором в регистрах либо же вовсе
фессионалов. Здесь, в прокуренной атмосфере ассемб- отброшены оптимизатором как ненужные. (Попутно заме-
лерных команд, выживает лишь тот, кто программирует тим, что все демонстрационные листинги, приведенные в
быстрее, чем думает, а думает быстрее, чем говорит. Тот, этой статье, рассчитывают, что переменные располага-
кто может удержать в голове сотни структур данных, бук- ются в памяти в порядке их объявления.)
вально на физическом уровне ощущая их взаимосвязь и Впрочем, не будем забегать вперед – дизассемблиро-
каким-то шестым чувством угадывая, в каком направле- вание – тема отдельной статьи, которую планируется опуб-
нии нужно копать. Собственный программистский опыт ликовать в следующих номерах журнала.
может только приветствоваться. Во-первых, так легче
вжиться в привычки, характер и образ мышления разра- Цели и возможности атаки
ботчика исследуемого приложения. Задумайтесь: а как Конечная цель любой атаки – заставить систему сделать
бы вы решили данную задачу, окажись на его месте? что-то «нехорошее», чего нельзя добиться легальным пу-
Какие бы могли допустить ошибки? Где бы проявили тем. Существует по меньшей мере четыре различных спо-
непростительную небрежность, соблазнившись компак- соба реализации атаки:
тностью кода и элегантностью листинга? ! чтение секретных переменных;
Кстати об элегантности. Бытует мнение, что неряш- ! модификация секретных переменных;
ливый стиль программного кода неизбежно провоциру- ! передача управления на секретную функцию програм-
ет программиста на грубые ошибки (и ошибки перепол- мы;
нения в том числе). Напротив, педантично причесанная ! передача управления на код, переданный жертве са-
программа ошибок скорее всего не содержит, и анали- мим злоумышленником.
зировать ее означает напрасно тратить свое время. Как
знать… Автору приходилось сталкиваться с вопиюще Чтение секретных переменных. На роль секретных
небрежными листингами, которые работали как часы, переменных в первую очередь претендуют пароли на
потому что были сконструированы настоящими профес- вход в систему, а также пароли доступа к конфиденци-
сионалами, наперед знающими, где подстелить солом- альной информации. Все они так или иначе содержатся
ку, чтобы не упасть. Встречались и по-академически ак- в адресном пространстве уязвимого процесса, зачастую
куратные программы, дотошно и не по одному разу про- располагаясь по фиксированным адресам (под «входом
веряющие все, что только можно проверить, но букваль- в систему» здесь подразумеваются имя пользователя и

68
безопасность
пароль, обеспечивающие удаленное управление уязви- ячейку памяти на свой выбор (за исключением ячеек,
мым приложением). явно защищенных от модификации, например кодовой
Еще в адресном пространстве процесса содержатся секции или секции .rodata, разумеется).
дескрипторы секретных файлов, сокеты, идентификато- Передача управления на секретную функцию про-
ры TCP/IP-соединений и многое другое. Разумеется, вне граммы. Модификация указателей на исполняемый код
текущего контекста они не имеют никакого смысла, но приводит к возможности передачи управления на любую
могут быть использованы кодом, переданном жертве зло- функцию уязвимой программы (правда, с передачей ар-
умышленником, и осуществляющим, например, установ- гументов имеются определенные проблемы). Практичес-
ку «невидимого» TCP/IP-соединения, прячась под «кры- ки каждая программа содержит функции, доступные
шей» уже существующего. только root, и предоставляющие те или иные управлен-
Ячейки памяти, хранящие указатели на другие ячей- ческие возможности (например, создание новой учетной
ки, «секретными» строго говоря не являются, однако, зна- записи, открытие сессии удаленного управления, запуск
ние их содержимого значительно облегчает атаку. В про- файлов и т. д.). В более изощренных случаях управле-
тивном случае атакующему придется определять опор- ние передается на середину функции (или даже на се-
ные адреса вслепую. Допустим, в уязвимой программе редину машинной инструкции) с таким расчетом, что-
содержится следующий код: бы процессор выполнил замысел злоумышленника,
даже если разработчик программы не предусматривал
char *p = malloc(MAX_BUF_SIZE); ничего подобного.
Передача управления обеспечивается либо за счет
где p – указатель на буфер, содержащий секретный па- изменения логики выполнения программы, либо за счет
роль. Допустим так же, что в программе имеется ошиб- подмены указателей на код. И то, и другое опирается
ка переполнения, позволяющая злоумышленнику читать на модификацию ячеек программы, кратко рассмотрен-
содержимое любой ячейки адресного пространства. Весь ную выше.
вопрос в том: как этот буфер найти? Сканировать всю Передача управления на код, переданный жертве
кучу целиком не только долго, но и небезопасно, т.к. самим злоумышленником, является разновидностью
можно легко натолкнуться на невыделенную страницу механизма передачи управления на секретную функцию
памяти и тогда выполнение процесса аварийно завер- программы, только сейчас роль этой функции выполня-
шится. Автоматические и статические переменные в этом ет код, подготовленный злоумышленником и тем или
отношении более предсказуемы. Поэтому атакующий иным способом переданный на удаленный компьютер.
должен сначала прочитать содержимое указателя p, а Для этой цели может использоваться как сам перепол-
уже затем – секретный пароль, на который он указыва- няющийся буфер, так и любой другой буфер, доступный
ет. Разумеется, это всего лишь пример, которым возмож- злоумышленнику для непосредственной модификации и
ности переполняющего чтения не ограничиваются. в момент передачи управления на shell-код присутству-
Само же переполняющее чтение реализуется по мень- ющий в адресном пространстве уязвимого приложения
шей мере четырьмя следующими механизмами: «поте- (при этом он должен располагаться по более или менее
рей» завершающего нуля в строковых буферах, моди- предсказуемым адресам, иначе передавать управление
фикаций указателей (см. «Указатели и индексы»), индек- будет некому и некуда).
сным переполнением (см. там же) и навязыванием фун-
кции printf (и другим функциям форматированного вы- Жертвы переполнения или объекты атаки
вода) лишних спецификаторов. Переполнение может затирать ячейки памяти следую-
Модификация секретных переменных. Возможность щих типов: указатели, скалярные переменные и буфе-
модификации переменных дает значительно больше воз- ра. Объекты языка Си++ включают в себя как указате-
можностей для атаки, позволяя: ли (указывающие на таблицу виртуальных функций,
! навязывать уязвимой программе «свои» пароли, дес- если таковые в объекте есть), так и скалярные данные-
крипторы файлов, TCP/IP-идентификаторы и т. д.; члены (если они есть). Самостоятельной сущности они
! модифицировать переменные, управляющие ветвле- не образуют и вполне укладываются в приведенную
нием программы; выше классификацию.
! манипулировать индексами и указателями, передавая
управление по произвольному адресу (и адресу, содер- Указатели и индексы
жащему код, специально подготовленный злоумыш- В классическом Паскале и других «правильных» языках
ленником в том числе). указатели отсутствуют, но в Си/Си++ они вездесущи.
Чаще всего приходится иметь дело с указателями на дан-
Чаще всего модификация секретных переменных ре- ные, несколько реже встречаются указатели на испол-
ализуется посредством последовательного переполне- няемый код (указатели на виртуальные функции, указа-
ния буфера, по обыкновению своему поражающего це- тели на функции, загружаемые динамической компонов-
лый каскад побочных эффектов. Например, если за кон- кой и т. д.). Современный Паскаль (раньше ассоциируе-
цом переполняющегося буфера расположен указатель на мый с компилятором Turbo Pascal, а теперь еще и
некоторую переменную, в которую после переполнения DELPHI) также немыслим без указателей. Даже если в
что-то пишется, злоумышленник сможет затереть любую явном виде указатели и не поддерживаются, на них дер-

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


безопасность
жатся динамические структуры данных (куча, разряжен- рые расположены непосредственно за концом перепол-
ные массивы), используемые внутри языка. няющегося буфера). Таблица виртуальных функций (да-
Указатели удобны. Они делают программирование лее просто виртуальная таблица) принадлежит не экзем-
простым, наглядным, эффективным и естественным. В то пляру объекта, а самому объекту, т.е. упрощенно говоря,
же время указатели во всех отношениях категорически мы имеем одну виртуальную таблицу на каждый объект.
небезопасны. Попав в руки хакера или пищеварительный «Упрощенно» потому, что в действительности виртуаль-
тракт червя, они превращаются в оружие опустошитель- ная таблица помещается в каждый obj-файл, в котором
ной мощности – своеобразный аналог BFG-900 или, по встречается обращение к членам данного объекта (раз-
крайней мере, плазмогана. Забегая вперед, отметим, что дельная компиляция дает о себе знать). И хотя линкеры в
указатели обоих типов потенциально способны к переда- подавляющем большинстве случаев успешно отсеивают
че управления на несанкционированный машинный код. лишние виртуальные таблицы, иногда они все-таки дуб-
Вот с указателей на исполняемый код мы и начнем. лируются (но это уже слишком высокие материи для на-
Рассмотрим ситуацию, когда следом за переполняющим- чинающих). В зависимости от «характера» выбранной
ся буфером buff, расположен указатель на функцию, ко- среды разработки и профессионализма программиста
торая инициализируется до и вызывается после перепол- виртуальные таблицы размещаются либо в секции .data
нения буфера (возможно, вызывается не сразу, а спустя (не защищенной от записи), либо в секции .rodata (дос-
некоторое время). Тогда мы заполучим аналог функции тупной лишь на чтение), причем последний случай встре-
call или, говоря другими словами, инструмент для пере- чается значительно чаще.
дачи управления по любому (ну или почти любому) ма- Давайте для простоты рассмотрим приложения с вир-
шинному адресу, в том числе и на сам переполняющийся туальными таблицами в секции .data. Если злоумышлен-
буфер (тогда управление получит код, переданный зло- нику удастся модифицировать один из элементов вирту-
умышленником). альной таблицы, то при вызове соответствующей вирту-
альной функции управление получит не она, а совсем дру-
Ëèñòèíã 3. Ôðàãìåíò ïðîãðàììû, ïîäâåðæåííîé ïåðåïîëíåíèþ гой код! Однако добиться этого будет непросто! Виртуаль-
ñ çàòèðàíèåì óêàçàòåëÿ íà èñïîëíÿåìûé êîä
ные таблицы обычно размещаются в самом начале сек-
code_ptr() ции данных, т.е. перед статическими буферами и доста-
{
char buff[8]; void (*some_func) (); точно далеко от автоматических буферов (более конкрет-
… ное расположение указать невозможно, т.к. в зависимос-
printf("passws:"); gets(buff);
… ти от операционной системы стек может находиться как
some_func(); ниже, так и выше секции данных). Так что последователь-
}
ное переполнение здесь непригодно и приходится уповать
Подробнее о выборе целевых адресов мы поговорим на индексное, все еще остающееся теоретической экзо-
в другой раз, сейчас же сосредоточимся на поиске зати- тикой, робко познающей окружающий мир.
раемых указателей. Первым в голову приходит адрес воз- Модифицировать указатель на объект и/или указатель
врата из функции, находящийся внизу кадра стека (прав- на виртуальную таблицу намного проще, поскольку они
да, чтобы до него дотянуться, требуется пересечь весь не только находятся в области памяти, доступной для мо-
кадр целиком и не факт, что нам это удастся, к тому же дификации, но и зачастую располагаются в непосред-
его целостность контролируют многие защитные систе- ственной близости от переполняющихся буферов.
мы, подробнее о которых планируется рассказать в сле- Модификация указателя this приводит к подмене вир-
дующей статье). туальных функций объекта. Достаточно лишь найти в па-
Другая популярная мишень – указатели на объекты. В мяти указатель на интересующую нас функцию (или вруч-
Си++ программах обычно присутствует большое количе- ную сформировать его в переполняющемся буфере) и
ство объектов, многие из которых создаются вызовом установить на него this с таким расчетом, чтобы адрес
оператора new, возвращающим указатель на свежесоз- следующей вызываемой виртуальной функции попал на
данный экземпляр объекта. Невиртуальные функции-чле- подложный указатель. С инженерной точки зрения это
ны класса вызываются точно так же, как и обычные Си- достаточно сложная операция, поскольку кроме вирту-
функции (т.е. по их фактическому смещению), поэтому они альных функций объекты еще содержат и переменные,
неподвластны атаке. Виртуальные функции-члены вызы- которые более или менее активно используют. Переус-
ваются намного более сложным образом через цепочку тановка указателя this искажает их «содержимое» и
следующих операций: указатель на экземпляр объекта → очень может быть, что уязвимая программа рухнет рань-
указатель на таблицу виртуальных функций → указатель ше, чем успеет вызвать подложную виртуальную функ-
на конкретную виртуальную функцию. Указатели на таб- цию. Можно, конечно, сымитировать весь объект цели-
лицу виртуальных функций не принадлежат объекту и ком, но не факт, что это удастся. Сказанное относится и
внедряются в каждый его экземпляр, который чаще всего к указателю на объект, поскольку с точки зрения компи-
сохраняется в оперативной памяти, реже – в регистровых лятора они скорее похожи, чем различны. Однако нали-
переменных. Указатели на объекты так же размещаются чие двух различных сущностей дает атакующему свобо-
либо в оперативной памяти, либо в регистрах, при этом ду выбора – в некоторых случаях предпочтительнее за-
на один и тот же объект может указывать множество ука- тирать указатель this, в некоторых случаях – указатель
зателей (среди которых могут встретиться и такие, кото- на объект.

70
безопасность
Ëèñòèíã 4. Ôðàãìåíò ïðîãðàììû, ïîäâåðæåííîé ïîñëåäîâàòåëüíîìó .text:00401051 mov ecx, [ebp+var_4]
ïåðåïîëíåíèþ ïðè çàïèñè, ñ çàòèðàíèåì óêàçàòåëÿ íà òàáëèöó .text:00401051 ; ïåðåäàåì ôóíêöèè óêàçàòåëü this
âèðòóàëüíûõ ôóíêöèé .text:00401051 ;
.text:00401054 call dword ptr [eax]
class A{ ; âûçûâàåì âèðòóàëüíóþ ôóíêöèþ – ïåðâóþ ôóíêöèþ âèðòóàëüíîé
public: ; òàáëèöû
virtual void f() { printf("legal\n");}; .text:00401054
}; .text:00401054 ;
.text:00401056 mov esp, ebp
main() .text:00401058 pop ebp
{ .text:00401059 retn
char buff[8]; A *a = new A; .text:00401059 main endp
printf("passwd:");gets(buff); a->f();
} Рассмотрим ситуацию, когда следом за переполняю-
Ëèñòèíã 5. Äèçàññåìáëåðíûé ëèñòèíã ïåðåïîëíÿþùèéñÿ ïðîãðàì- щимся буфером идет указатель на скалярную перемен-
ìû ñ êðàòêèìè êîììåíòàðèÿìè ную p и сама переменная x, которая в некоторый момент
; 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 ющих оригинальное содержимое переменных x и p, мы
; îòêðûâàåì êàäð ñòåêà è ðåçåðâèðóåì 14h ñòåêîâîé ïàìÿòè
.text:00401003 сможем записать любое значение x по произвольному
.text:00401003 ; адресу p, осуществляя это «руками» уязвимой програм-
.text:00401006 push 4
.text:00401008 call operator new(uint) мы. Другими словами, мы получаем аналог функций POKE
.text:0040100D add esp, 4 и PatchByte/PatchWord языков Бейсик и IDA-Си соответ-
; âûäåëÿåì ïàìÿòü äëÿ íîâîãî ýêçåìïëÿðà îáúåêòà A è ïîëó÷àåì
; óêàçàòåëü ственно. Вообще-то, на выбор аргументов могут быть на-
.text:0040100D ложены некоторые ограничения (например, функция gets
.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 ; Ëèñòèíã 6. Ôðàãìåíò ïðîãðàììû, ïîäâåðæåííîé ïîñëåäîâàòåëüíîìó
.text:00401019 mov ecx, [ebp+var_10] ïåðåïîëíåíèþ ïðè çàïèñè è çàòèðàíèåì ñêàëÿðíîé ïåðåìåííîé
.text:0040101C call A::A è óêàçàòåëÿ íà äàííûå, ïîãëîùàþùèìè çàòåðòóþ ïåðåìåííóþ
.text:0040101C ; âûçûâàåì êîíñòðóêòîð îáúåêòà A
.text:0040101C ; data_ptr()
.text:00401021 mov [ebp+var_14], eax {
; çàíîñèì âîçâðàùåííûé óêàçàòåëü this â ïåðåìåííóþ var_14 char buff[8]; int x; int *p;
.text:00401021 printf("passws:"); gets(buff);
.text:00401021 ; …
… *p = x;
.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 ; ресуемые относительно некоторой базы. Смотрите, p[i]
; "passwd:"
.text:00401033 push offset aPasswd можно представить и как *(p+i), практически полностью
.text:00401038 call _printf уравнивая p и i в правах.
.text:0040103D add esp, 4
.text:0040103D ; âûâîäèì ïðèãëàøåíèå ê ââîäó íà ýêðàí Модификация индексов имеет свои слабые и сильные
.text:0040103D ; стороны. Сильные – указатели требуют задания абсолют-
.text:00401040 lea ecx, [ebp+var_C]
; ïåðåïîëíÿþùèéñÿ áóôåð ðàñïîëîæåí íèæå óêàçàòåëÿ íà îáúåêò ного адреса целевой ячейки, который обычно неизвестен,
; è ïåðâè÷íîãî óêàçàòåëÿ this, íî âûøå ïîðîæäåííîãî óêàçàòåëÿ в то время как относительный вычисляется на ура. Ин-
; this, ÷òî äåëàåò ïîñëåäíèé óÿçâèìûì
.text:00401040 дексы, хранящиеся в переменных типа char, лишены про-
.text:00401040 блемы нулевых символов. Индексы, хранящиеся в пере-
.text:00401040
.text:00401040 ; менных типа int, могут беспрепятственно затирать ячей-
.text:00401043 push ecx ки, расположенные «выше» стартового адреса (т.е. лежа-
.text:00401044 call _gets
.text:00401049 add esp, 4 щие в младших адресах), при этом старшие байты индек-
.text:00401049 ; ÷òåíèå ñòðîêè â áóôåð са содержат символы FFh, которые значительно более ми-
.text:00401049 ;
.text:0040104C mov edx, [ebp+var_4] ролюбивы, чем символы нуля.
; çàãðóæàåì óÿçâèìûé óêàçàòåëü this â ðåãèñòð EDX Однако, если обнаружить факт искажения указателей
.text:0040104C
.text:0040104C ; практически невозможно (дублировать их значение в ре-
.text:0040104F mov eax, [edx] зервных переменных не предлагать), то оценить коррект-
.text:0040104F ; èçâëåêàåì àäðåñ âèðòóàëüíîé òàáëèöû
.text:0040104F ; ность индексов перед их использованием не составляет

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


безопасность
никакого труда, и многие программисты именно так и по- дификация переменных b и c приведет к переполнению
ступают (правда, «многие» еще не означает «все»). Дру- буфера p со всеми отсюда вытекающими последствиями.
гой слабой стороной индексов является их ограниченная В-третьих… да мало ли что можно придумать – всего и не
«дальнобойность», составляющая ±128/256 байт (для ин- перечислишь! Затирание скалярных переменных при пе-
дексов типа signed/unsigned char) и -2147483648 байт для реполнении обычно не приводит к немедленному обруше-
индексов типа signed int. нию программы, поэтому такие ошибки могут долго оста-
ваться не обнаруженными. Будьте внимательными!
Ëèñòèíã 7. Ôðàãìåíò ïðîãðàììû, ïîäâåðæåííîé ïîñëåäîâàòåëüíîìó
ïåðåïîëíåíèþ ïðè çàïèñè, ñ çàòèðàíèåì èíäåêñà
Массивы и буфера
index_ptr() Что интересного можно обнаружить в буферах? Прежде
{
всего это строки, хранящиеся в PASCAL-формате, т.е. с
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]; ный пример:
}
Ëèñòèíã 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
менные сами по себе). // ïðàâèëüíûé ïàðîëü
Рассмотрим случай, когда вслед за переполняющим- }
ся буфером расположена переменная buks, инициализи-
руемая до переполнения, а после переполнения исполь- Еще интересны буфера, содержащие имена открыва-
зуемая для расчетов количества денег, снимаемых со сче- емых файлов (можно заставить приложение записать кон-
та (не обязательно счета злоумышленника). Допустим, фиденциальные данные в общедоступный файл или, на-
программа тщательно проверяет входные данные и не против, навязать общедоступный файл взамен конфиден-
допускает использования ввода отрицательных значений, циального), тем более что несколько подряд идущих бу-
однако, не контролирует целостность самой переменной феров, вообще говоря, не редкость.
buks. Тогда, варьируя ее содержимым по своему усмот-
рению, злоумышленник без труда обойдет все проверки Заключение
и ограничения. Изначально статья задумывалась как исчерпывающее ру-
ководство, снабженное большим количеством листингов
Ëèñòèíã 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); материала осталась за кадром. Ох, и не следовало мне
}
пытаться объять необъятное…
При всей своей искусственности приведенный пример Надеюсь, что следующие статьи этого цикла исправят
чрезвычайно нагляден. Модификация скалярных перемен- положение. В первую очередь планируется рассказать о пе-
ных только в исключительных случаях приводит к захвату редовых методиках переполнения кучи, приводящих к зах-
управления системой, но легко позволяет делать из чи- вату управления удаленной машиной, обсудить технические
сел винегрет, а на этом уже можно сыграть! Но что же это аспекты разработки shell-кода (приемы создания позицион-
за исключительные случаи? Во-первых, многие програм- но-независимого кода, проблема вызова системных функ-
мы содержат отладочные переменные, оставленные раз- ций, оптимизация размера и т. д.), затем можно будет пе-
работчиками, и позволяющие, например, отключить сис- рейти к разговору о способах поиска переполняющихся бу-
тему аутентификации. Во-вторых, существует множество феров и о возможных мерах по заблаговременному предот-
переменных, хранящих начальные или предельно допус- вращению оных. Отдельную статью хотелось бы посвятить
тимые значения других переменных, например, счетчиков целиком червям Love Sun и Slapper, поскольку их дизассем-
цикла – for (a =b; a < c; a++) *p++ = *x++; очевидно, что мо- блерные листинги содержат очень много интересного.

72
hardware

РЕАЛИЗАЦИЯ НИЗКОУРОВНЕВОЙ ПОДДЕРЖКИ ШИНЫ PCI


В ЯДРЕ ОПЕРАЦИОННОЙ СИСТЕМЫ LINUX

В данной статье на примере решения простой задачи – определения MAC-адреса сетевой карты –
рассмотрена реализация низкоуровневой поддержки (low-level support) шины PCI в ядре
операционной системы Linux.
ВЛАДИМИР МЕШКОВ
74
hardware
Постановка задачи и исходные данные I/O, выделенного адаптеру. При выходе из цикла в буфе-
Исходные данные – имеется компьютер, функционирую- ре mac[] будет находиться искомый MAC-адрес.
щий под управлением ОС Linux, версия ядра 2.4.24. В PCI- Теперь вся задача сводится к определению значения
слот установлен сетевой адаптер на чипсете RTL8139C базового адреса порта I/O адаптера RTL8139C. Как найти
(далее – адаптер RTL8139C). этот адрес? Чтобы ответить на этот вопрос, давайте по-
Задача – определить MAC-адрес этого адаптера. знакомимся поближе с шиной PCI.
Путей решения этой задачи несколько. Можно восполь-
зоваться командами dmesg или ifconfig: Общая характеристика шины PCI
Разработка шины PCI началась весной 1991 года как внут-
root@bob~/# dmesg | grep eth0 ренний проект корпорации Intel (Release 0.1). Специалис-
eth0: RealTek RTL8139 at 0xc000, 00:02:44:72:5e:4e, IRQ 11
eth0: Identified 8139 chip type 'RTL-8100B/8139D' ты компании поставили перед собой цель разработать не-
дорогое решение, которое бы позволило полностью реа-
root@bob~/# ifconfig | grep eth0
eth0 Link encap:Ethernet HWaddr 00:02:44:72:5E:4E лизовать возможности нового поколения процессоров 486/
Pentium/P6. Особенно подчеркивалось, что разработка
Можно написать небольшое приложение следующего проводилась «с нуля», а не была попыткой установки но-
вида: вых «заплат» на существующие решения. В результате
шина PCI появилась в июне 1992 года (R1.0). Разработчи-
/* get_mac.c */ ки Intel отказались от использования шины процессора и
#include <stdio.h>
#include <sys/socket.h> ввели еще одну «антресольную» (mez-zanine) шину.
#include <sys/ioctl.h> Благодаря такому решению шина получилась, во-пер-
#include <linux/if.h>
вых, процессорно-независимой, а во-вторых, могла рабо-
int main() { тать параллельно с шиной процессора, не обращаясь к
int fd; ней за запросами и тем самым снижая её загрузку. Стан-
struct ifreq ifr; дарт шины был объявлен открытым и передан PCI Special
unsigned char mac[6];
Interest Group (www.pcisig.com), которая продолжила ра-
fd=socket(AF_INET,SOCK_DGRAM,0); боту по совершенствованию шины. В настоящее время
memset(&ifr,0,sizeof(struct ifreq));
memcpy(ifr.ifr_name,"eth0",4); действует спецификация PCI версии 2.3.
ioctl(fd,SIOCGIFHWADDR,&ifr); Основные возможности шины следующие:
memcpy(mac,(char *)&(ifr.ifr_hwaddr.sa_data), ↵
sizeof(struct sockaddr)); ! Синхронный 32- или 64-разрядный обмен данными. При
этом для уменьшения числа контактов (и стоимости)
printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); используется мультиплексирование, то есть адрес и
данные передаются по одним и тем же линиям.
return 0;
} ! Поддержка 5V и 3.3V логики. Частота 66 МГц поддер-
живается только 3.3V логикой.
Можно извлечь MAC-адрес из самого адаптера ! Частота работы шины 33 МГц или 66 МГц позволяет
RTL8139C. Рассмотрим, как это делается. обеспечить широкий диапазон пропускных способно-
Согласно спецификации на сетевой адаптер RTL8139C, стей (с использованием пакетного режима):
MAC-адрес занимает первые 6 байт в пространстве пор- ! 132 Мб/сек при 32-бит/33 МГц;
тов ввода/вывода (I/O), отведенного адаптеру. Задавая ! 264 Mб/сек при 32-бит/66 МГц;
смещение относительно базового порта I/O, можно про- ! 264 Mб/сек при 64-бит/33 МГц;
читать все 6 байт MAC-адреса. ! 528 Мб/сек при 64-бит/66 МГц.
Пример функции, выполняющей процедуру чтения
MAC-адреса, приведен ниже: При этом для работы шины на частоте 66 МГц необхо-
димо, чтобы все периферийные устройства работали
void get_mac_addr(u32 base_addr) на этой частоте.
{
u8 mac[6]; ! Полная поддержка multiply bus master (например, не-
сколько контроллеров жестких дисков могут одновре-
/*
* Ïîñëåäîâàòåëüíî ÷èòàåì áàéòû èç ïîðòà base_addr менно работать на шине).
* è ñîõðàíÿåì èõ â ìàññèâå mac[]
*/
! Автоматическое конфигурирование карт расширения
for(int i = 0; i < 6; i++) при включении питания.
mac[i] = inb(base_addr + i); ! Спецификация шины позволяет комбинировать до вось-
/* ми функций на одной карте (например, видео + звук).
* Îòîáðàæàåì ðåçóëüòàò
*/
! Шина позволяет устанавливать до 4 слотов расшире-
printf("%02X:%02X:%02X:%02X:%02X:%02X\n", ния, однако возможно использование моста PCI-PCI
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); для увеличения количества карт расширения.
}
! PCI-устройства оборудованы таймером, который ис-
Функция get_mac_addr() принимает в качестве пара- пользуется для определения максимального промежут-
метра адрес порта I/O адаптера RTL8139C и в цикле про- ка времени, в течение которого устройство может за-
изводит считывание данных MAC-адреса из пространства нимать шину.

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


hardware
Шина поддерживает метод передачи данных, называ-
емый «linear burst» (метод линейных пакетов). Этот метод
предполагает, что пакет информации считывается (или
записывается) «одним куском», то есть адрес автомати-
чески увеличивается для следующего байта, при этом
увеличивается скорость передачи данных за счет умень-
шения числа передаваемых адресов.
На одной шине PCI может присутствовать несколько
устройств, каждое из которых имеет свой номер (device
number). В системе может присутствовать несколько шин
PCI, каждая из которых имеет свой номер (PCI bus number).
Шины нумеруются последовательно; шина, подключённая
к главному мосту, имеет нулевой номер.
В каждой транзакции (обмене по шине) участвуют два
устройства – инициатор (initiator) обмена, он же мастер
(master) или ведущее устройство, и целевое (target) уст-
ройство, оно же ведомое (slave). Шина PCI все транзак-
ции трактует как пакетные: каждая транзакция начинает-
ся фазой адреса, за которой может следовать одна или
несколько фаз данных.

Конфигурационное пространство
устройства PCI
Согласно спецификации, каждое устройство PCI имеет
конфигурационное пространство (configuration space) раз-
мером 256 байт, в котором содержится информация о са-
мом устройстве и о ресурсах, занимаемых устройством.
Это пространство не приписано ни к пространству памя-
ти, ни к пространству ввода-вывода. Доступ к нему осу- Ðèñóíîê 1. Ôîðìàò êîíôèãóðàöèîííîãî ïðîñòðàíñòâà PCI
ществляется по специальным циклам шины Configuration
Read и Configuration Write. После аппаратного сброса (или Vendor_ID, Device_ID, Class_Code
по включении питания) устройства PCI доступны только Поля Vendor_ID, Device_ID и Class_Code содержат код
для операций конфигурационного чтения и записи. В этих фирмы-изготовителя устройства, код устройства и код
операциях устройства выбираются по индивидуальным класса устройства. Классификация устройств и указание
сигналам IDSEL и сообщают о потребностях в ресурсах и кода класса в его конфигурационном пространстве явля-
возможных вариантах конфигурирования. После распре- ется важной частью спецификации PCI.
деления ресурсов, выполняемого программой конфигури- Код изготовителя, код устройства и код класса приме-
рования (во время теста POST), в конфигурационные ре- няются в процессе поиска заданного устройства. Если
гистры устройства записываются параметры конфигури- необходимо найти конкретное устройство, то поиск вы-
рования. Только после этого к устройству становится воз- полняется по кодам устройства и его изготовителя; если
можным доступ по командам обращения к памяти и пор- необходимо найти все устройства определенного типа, то
там ввода-вывода. Для того чтобы всегда можно было поиск выполняется по коду класса устройства. После того
найти работоспособную конфигурацию, все ресурсы, за- как устройство найдено, при помощи регистров базовых
нимаемые картой, должны быть перемещаемыми в своих адресов можно определить выделенные ему области в
пространствах. Для многофункциональных устройств каж- адресном пространстве памяти и пространстве ввода-
дая функция должна иметь свое конфигурационное про- вывода (I/O).
странство.
Конфигурационное пространство, формат которого Header_Type
представлен на рис. 1, состоит из трех областей: Поле Header_Type определяет формат header-type облас-
! область, не зависимая от устройства (device-independent ти, а также является ли устройство многофункциональ-
header region); ным. Идентификатором многофункционального устрой-
! область, определяемая типом устройства (header-type ства является бит 7 поля: если бит установлен в 1 – уст-
region); ройство поддерживает несколько функций, если сброшен
! область, определяемая пользователем (user-defined в 0 – устройство выполняет только функцию.
region). Биты 0 – 6 определяют собственно формат header-type
области: если эти биты обнулены (содержат код 0x00), то
Подробное описание полей конфигурационного про- формат области header-type соответствует формату, пред-
странства приведено в спецификации [4]. Рассмотрим ставленому на рис. 1; значение 0x01 идентифицирует уст-
кратко основные поля. ройство как мост PCI-to-PCI, и формат header-type области

76
hardware
описан в спецификации PCI-to-PCI Bridge Architecture Порядок работы Configuration Mechanism #1 следую-
Specification; значение 0x02 идентифицирует устройство как щий – в порт CONFIG_ADDRESS (0xCF8) заносится ад-
мост CardBus. Остальные значения зарезервированы. рес, соответствующий формату, приведенному на рис. 2;
обращением к порту CONFIG_DATA (0xCFC) производит-
Command ся чтение или запись данных в требуемый регистр конфи-
Командный регистр (поле Command) содержит средства гурационного пространства.
управления устройством. Назначение отдельных бит это-
го регистра: PCI BIOS
! бит 0 – определяет реакцию устройства на обращение Для взаимодействия с устройствами PCI имеются допол-
к нему через пространство портов I/O. Если бит сбро- нительные функции BIOS, доступные как из реального,
шен в 0, устройство игнорирует попытки доступа к нему так и защищенного режима работы процессора. Эти фун-
через порты I/O; кции предназначены для работы с конфигурационным
! бит 1 – определяет реакцию устройства на обращение пространством и генерации специальных циклов PCI.
к нему через адресное пространство. Если бит установ- Функции PCI BIOS для 16-битного реального режима
лен в 1, устройство отвечает на обращения к нему че- вызываются через прерывание int 0x1A. Номер функции
рез адресное пространство; если бит сброшен в 0, то задается в регистре AX. Признаком нормального выпол-
устройство на попытки доступа к нему не реагирует; нения являются значения флага CF = 0 и ноль в регистре
! бит 2 – установленный в 1 бит разрешает устройству AH (AH = 0x00, SUCCESFUL). Если CF = 1, то регистр AH
работать в режиме Bus Master. содержит код ошибки:
! 0x81 – неподдерживаемая функция (FUNC_NOT_SUP-
Base Address Registers PORTED);
Регистры базовых адресов (Base Address Registers) содер- ! 0x83 – неправильный идентификатор производителя
жат выделенные устройству области в адресном простран- (BAD_VENDOR_ID);
стве и пространстве портов I/O. Бит 0 во всех регистрах ! 0x86 – устройство не найдено (DEVICE_NOT_FOUND);
базовых адресов определяет, куда будет отображен ре- ! 0x87 – неправильный номер регистра PCI (BAD_REGIS-
сурс – на пространство портов I/O или на адресное про- TER_NUMBER), т.е. неправильно задано смещение в
странство. Регистр базового адреса, отображаемый на конфигурационном пространстве.
пространство портов, всегда 32-разрядный, бит 0 установ-
лен в 1. Регистр базового адреса, отображаемый на ад- Перечислим некоторые функции PCI BIOS (полный
ресное пространство, может быть 32- и 64-разрядным, бит перечень содержится в [6]):
0 сброшен в 0. ! 0xB101 – проверка присутствия PCI BIOS;
! 0xB102 – поиск устройства по коду фирмы-изготови-
Программный доступ теля;
к конфигурационному пространству PCI ! 0xB103 – поиск устройства по коду класса;
! 0xB108 – чтение байта конфигурационного простран-
Configuration Mechanism #1 ства устройства PCI;
Поскольку конфигурационное пространство не имеет при- ! 0xB109 – чтение слова конфигурационного простран-
вязки к какой-либо определенной области адресного про- ства устройства PCI;
странства, для доступа к нему применяется специальный ! 0xB10A – чтение двойного слова конфигурационного
механизм, названый в спецификации Configuration пространства устройства PCI.
Mechanism #1. Для работы этого механизма в простран-
стве портов I/O зарезервированы два 32-разрядных пор- При чтении информации из конфигурационного простран-
та, входящих в главный мост: CONFIG_ADDRESS с адре- ства в регистры процессора заносятся следующие значения:
сом 0xCF8 и CONFIG_DATA с адресом 0xCFC. Формат ! AX – номер функции;
CONFIG_ADDRESS представлен на рис. 2. ! BH – номер шины, к которой подключено устройство
(от 0 до 255);
! BL – номер устройства в старших 5 битах и номер фун-
кции в трех младших;
! DI – смещение в конфигурационном пространстве.
Ðèñóíîê 2. Ôîðìàò ðåãèñòðà CONFIG_ADDRESS После этого следует вызов прерывания int 0x1A, в ре-
Установленный в 1 бит 31 разрешает обращение к кон- зультате которого в регистрах процессора будут размеще-
фигурационному пространству через порт CONFIG_DATA, ны следующие значения:
биты 30 – 24 зарезервированы (read-only), при чтении дол- ! ECX – считанная информация (байт/слово/двойное
жны возвращать 0, биты 23 – 26 содержат номер шины, слово);
биты 15 – 11 – номер устройства, биты 10 – 8 – номер ! AH – код возврата (SUCCESFUL/BAD_REGISTER_NUM-
функции и биты 7 – 2 – номер регистра, к которому вы- BER);
полняется обращение (смещение в конфигурационном ! CF – статус возврата (0 – функция успешно выполне-
пространстве). на, 1 – ошибка).

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


hardware
BIOS32 был необходим базовый адрес в пространстве I/O, и это
При работе в 32-разрядном защищенном режиме для дос- значение, как мы уже установили, находится в конфигу-
тупа к функциям PCI BIOS используются средства BIOS32. рационном пространстве устройства. Чтобы извлечь его
Процедура проверки наличия BIOS32 предполагает обра- оттуда, можно воспользоваться сервисом BIOS32 либо ра-
щение к физическим адресам памяти, поэтому обычно ботать с устройством напрямую, при помощи Configuration
производится из реального режима, до переключения в Mechanism #1.
защищенный. Если BIOS32 поддерживается, то в облас- Алгоритм решения задачи при использовании серви-
ти памяти BIOS, расположенной в диапазоне 0xE0000 – са BIOS32 следующий:
0xFFFFF, должна присутствовать специальная 16-байтная ! определяем адрес точки входа в BIOS32. Для этого вы-
структура данных – служебный каталог (BIOS32 Service полняем поиск служебного каталога BIOS32 в диапа-
Directory). Структура каталога приведена в таблице 1. зоне 0xE0000 – 0xFFFFF;
Òàáëèöà 1 ! определяем адрес точки в сервис BIOS32 – PCI BIOS.
Для этого выполняем дальний вызов через точку вхо-
да в BIOS32, задав в регистре EAX идентификатор зап-
рашиваемого сервиса ($PCI);
! используя PCI BIOS, выполняем поиск сетевого адап-
тера и определяем его координаты – номер шины, но-
мер устройства и номер функции. Поиск производим
Процесс поиска служебного каталога BIOS32 заключа- по коду класса. Код класса сетевого контроллера ра-
ется в сканировании памяти ПЗУ BIOS: производится по- вен 0x00020000 (см. [4]);
иск сигнатуры «_32_» в диапазоне 0xE0000 – 0xFFFFF по ! из конфигурационного пространства сетевого адапте-
16-байтным параграфам (начало служебного каталога вы- ра считываем значение базового адреса порта I/O и,
ровнено на границу 16 байт). После обнаружения сигнату- задавая смещение относительно этого адреса, считы-
ры производится вычисление и проверка контрольной сум- ваем MAC-адрес адаптера RTL8139C.
мы: если сумма совпадает, то служебный каталог найден.
Для доступа к PCI BIOS в 32-разрядном режиме требу- При использовании Configuration Mechanism #1 всё го-
ется выполнить дальний вызов через точку входа BIOS32. раздо проще и сводится к последовательной записи ин-
Перед выполнением вызова в регистры записывается сле- формации в порт CONFIG_ADDRESS и чтении её из пор-
дующая информация: та CONFIG_DATA. Рассмотрим программную реализацию
! в EAX – идентификатор запрашиваемого сервиса, ко- этих алгоритмов.
торый для PCI BIOS имеет значение «$PCI»
(0x49435024); Программная реализация алгоритма
! в EBX – селектор функции (значение должно быть рав- чтения MAC-адреса
но нулю). Разработаем модуль ядра, который при загрузке будет
выполнять поиск сетевого адаптера RTL8139C и считы-
После выполнения вызова в регистре AL будет возвра- вать его MAC-адрес. Все исходные тексты, рассмотрен-
щен код результата: ные в статье, доступны на сайте журнала.
! 0 – операция успешно завершена; Начнём с описания заголовочных файлов, переменных
! 0x80 – некорректный идентификатор сервиса; и информационных структур.
! 0x81 – недопустимое значение селектора функции. Заголовочных файлов у нас два:

Если вызов завершен успешно, в регистрах процессо- #include <linux/module.h>


#include <linux/pci.h>
ра будет размещена следующая информация:
! в EBX – физический адрес базы сервиса BIOS; Определим код фирмы-изготовителя адаптера
! в ECX – размер сегмента сервиса BIOS; RTL8139C, код типа устройства и код класса устройства.
! в EDX – точка входа в сервис BIOS (смещение относи-
тельно базы, возвращенной в EBX). // êîä ôèðìû-èçãîòîâèòåëÿ – RealTek
#define VENDOR_ID 0x10EC
// êîä óñòðîéñòâà – ñåòåâàÿ êàðòà RTL8139C
Адрес точки входа в сервис определяется путем сло- #define DEVICE_ID 0x8139
// êîä êëàññà ñåòåâîãî êîíòðîëëåðà ([4])
жения физического адреса базы сервиса и смещения от- #define CLASS_CODE 0x00020000
носительно базы. Дальнейший порядок обращения к фун-
кциям сервиса PCI BIOS не отличается от реального ре- Функции PCI BIOS, которые мы будем использовать
жима, за исключением того, что вместо вызова прерыва- (полный перечень приведен в [6]):
ния int 0x1A необходимо выполнить дальний вызов через
точку входа в сервис. // ïðîâåðêà ïðèñóòñòâèÿ PCI BIOS â ñèñòåìå
#define PCIBIOS_PCI_BIOS_PRESENT 0xb101
// ïîèñê óñòðîéñòâà PCI çàäàííîãî òèïà
Алгоритм чтения MAC-адреса #define PCIBIOS_FIND_PCI_DEVICE 0xb102
// ïîèñê óñòðîéñòâà PCI çàäàííîãî êëàññà
Итак, вернемся к решению нашей задачи – определению #define PCIBIOS_FIND_PCI_CLASS_CODE 0xb103
MAC-адреса сетевого адаптера RTL8139C. Для этого нам // ïðî÷èòàòü áàéò èç êîíôèãóðàöèîííîãî ïðîñòðàíñòâà

78
hardware
// óñòðîéñòâà PCI // 32-õ áèòíûé ôèçè÷åñêèé àäðåñ òî÷êè âõîäà â BIOS32
#define PCIBIOS_READ_CONFIG_BYTE 0xb108 u32 entry;
// ïðî÷èòàòü ñëîâî èç êîíôèãóðàöèîííîãî ïðîñòðàíñòâà // íîìåð âåðñèè, Revision level, 0
// óñòðîéñòâà PCI u8 revision;
#define PCIBIOS_READ_CONFIG_WORD 0xb109 // ðàçìåð ñëóæåáíîãî êàòàëîãà â 16-áàéòíûõ ïàðàãðàôàõ
// ïðî÷èòàòü äâîéíîå ñëîâî èç êîíôèãóðàöèîííîãî ïðîñòðàíñòâà u8 length;
// óñòðîéñòâà PCI // êîíòðîëüíàÿ ñóììà, äîïîëíÿåò âñå áàéòû äî 0
#define PCIBIOS_READ_CONFIG_DWORD 0xb10a u8 checksum;
// çàðåçåðâèðîâàíî, çàïîëíÿåòñÿ íóëÿìè
Сигнатура, по которой производится поиск служебно- u8 reserved[5];
} fields;
го каталога BIOS32 (_32_): char chars[16];
};
#define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ↵
('2' << 16) + ('_' << 24))
Рассмотрим функцию, которая производит поиск слу-
Сигнатура для проверки присутствия PCI BIOS в систе- жебного заголовка BIOS32.
ме (используется функцией PCIBIOS_PCI_BIOS_PRESENT):
int pci_find_bios(void)
#define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ↵ {
('I' << 16) + (' ' << 24)) union bios32 *check; // ñëóæåáíûé êàòàëîã BIOS32
u8 sum;
int i, length;
Сигнатура, по которой осуществляется поиск сервиса
BIOS32: Сканируем область памяти BIOS в диапазоне адресов
0xe0000 и 0xfffff в поисках сигнатуры «_32_» и служебно-
#define PCI_SERVICE (('$' << 0) + ('P' << 8) + ↵ го каталога BIOS32:
('C' << 16) + ('I' << 24))

Определим структуру для хранения информации об for (check = (union bios32 *) __va(0xe0000);
check <= (union bios32 *) __va(0xffff0); ++check) {
устройстве PCI: if (check->fields.signature != BIOS32_SIGNATURE) continue;

struct pci_dev_struct { Поиск выполняется относительно нижней границы ад-


// êîä ôèðìû-èçãîòîâèòåëÿ è êîä òèïà óñòðîéñòâà
u16 vendor_id, device_id; ресного пространства ядра 0xC0000000, на что указыва-
// êîä êëàññà óñòðîéñòâà ет макрос __va(0xe0000) и __va(0xffff0).
u32 class_code;
// àäðåñ ïîðòà I/O Этот макрос определен в файле include/page.h следу-
u32 base_addr; ющим образом:
// êîîðäèíàòû óñòðîéñòâà – íîìåð øèíû, íîìåð óñòðîéñòâà
// íà øèíå è íîìåð ôóíêöèè óñòðîéñòâà
u8 bus, dev, fn; // íèæíÿÿ ãðàíèöà àäðåñíîãî ïðîñòðàíñòâà ÿäðà
}; #define __PAGE_OFFSET 0xC0000000
#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
Следующие две структуры описывают физические #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET))
адреса точек входа в BIOS32 и в сервис BIOS32 (PCI BIOS).
Физический адрес точки входа в BIOS32 (в формате Если сигнатура найдена – определяем размер служеб-
селектор:смещение): ного каталога BIOS32 в байтах:

static struct { length = check->fields.length * 16;


u32 address; if (!length) continue;
u16 segment;
} bios32_indirect = { 0, __KERNEL_CS }; Считываем контрольную сумму и определяем номер
версии реализации:
Физический адрес точки входа в сервис BIOS32 (PCI
BIOS): sum = 0;
for (i = 0; i < length ; ++i)
sum += check->chars[i];
static struct { if (sum != 0)
u32 address; continue;
u16 segment; if (check->fields.revision != 0) {
} pci_indirect = { 0, __KERNEL_CS }; printk("PCI: unsupported BIOS32 revision %d ↵
at 0x%p\n", check->fields.revision, check);
continue;
__KERNEL_CS – селектор сегмента кода, определен в }
файле include/asm-i386/segment.h:
Если вышли за пределы диапазона сканирования, то
#define __KERNEL_CS 0x10 использовать BIOS32 мы не сможем:

Стандартный служебный каталог BIOS32 имеет сле- if (check->fields.entry >= 0x100000) {


printk("PCI: BIOS32 entry (0x%p) in high memory, ↵
дующий вид: cannot use.\n", check);
return 0;
union bios32 { } else {
struct {
// ñèãíàòóðà _32_ Если всё в порядке – вычисляем адрес точки входа в
u32 signature; BIOS32 и заполняем структуру bios32_indirect:

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


hardware
unsigned long bios32_entry = check->fields.entry; Проанализируем код возврата:
bios32_indirect.address = bios32_entry + ↵
PAGE_OFFSET; // àäðåñ òî÷êè âõîäà â BIOS32
printk(KERN_INFO "PCI: BIOS32 entry point at ↵ switch (return_code) {
0x%08x\n", bios32_indirect.address);
}
break; Если код возврата равен 0, то сервиc PCI BIOS присут-
/* Hopefully more than one BIOS32 cannot happen... */ ствует, и адрес точки входа в него можно определить, сло-
}
return 0; жив значение адреса базы (address) и смещения относи-
} тельно базы (entry):
Следующая функция, которую мы рассмотрим, опре-
деляет адрес точки входа в сервис BIOS32. case 0:
// èñêîìûé àäðåñ òî÷êè âõîäà â ñåðâèñ BIOS32 (PCI BIOS)
return address + entry;
static u32 bios32_service(u32 service)
{
u8 return_code; /* %al, êîä âîçâðàòà */ Если код возврата равен 0x80, запрашиваемый сер-
u32 address; /* %ebx, àäðåñ áàçû ñåðâèñà*/ вис отсутствует:
u32 length; /* %ecx, ðàçìåð ñåãìåíòà ñåðâèñà */
u32 entry; /* %edx, òî÷êà âõîäà â ñåðâèñ */
u32 flags; 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 ↵
Адрес точки входа в сервис BIOS32 определяется пу- 0x%x -- BIOS bug!\n", service, return_code);
return 0;
тем дальнего вызова через точку входа в BIOS32. Перед }
выполнением вызова в регистры процессора заносится }
следующая информация:
! EAX – идентификатор сервиса (в нашем случае это $PCI); А теперь рассмотрим порядок обращения к сервису PCI
! EBX – селектор функции (должен быть равен 0); BIOS в защищенном режиме, выполнив проверку присут-
! EDI – адрес точки входа в BIOS32. ствия PCI BIOS в системе:

После вызова регистры процессора будут содержать int check_pcibios(void)


{
следующую информацию: u32 signature, eax, ebx, ecx;
! AL – код возврата: 0 – запрашиваемый сервис найден, u8 status, major_ver, minor_ver, hw_mech;
u32 flags,
0x80 – сервис отсутствует (не поддерживается); u32 pcibios_entry;
! EBX – физический адрес базы сервиса;
! ECX – размер сегмента сервиса; pcibios_entry – это точка входа в сервис, назначение осталь-
! EDX – точка входа в сервис BIOS32 (смещение отно- ных переменных рассмотрим ниже. Ищем точку входа в сер-
сительно базы, возвращённой в регистре EBX). вис PCI путём вызова функции bios32_service(). Параметр
функции – идентификатор сервиса, сигнатура $PCI. Все ад-
Вот как выполняется данный вызов: реса отсчитываются относительно нижней границы адрес-
ного пространства ядра (PAGE_OFFSET = 0xC0000000).
__save_flags(flags); __cli();
__asm__("lcall (%%edi); cld" if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
: "=a" (return_code), pci_indirect.address = pcibios_entry + PAGE_OFFSET;
// ôèçè÷åñêèé àäðåñ áàçû ñåðâèñà
"=b" (address),
// ðàçìåð ñåãìåíòà ñåðâèñà Выполняем обращение к функции проверки присутствия
"=c" (length), PCI BIOS в системе – 0xB101. Для этого выполняем дальний
// òî÷êà âõîäà â ñåðâèñ BIOS32 (ñìåùåíèå îòíîñèòåëüíî
// áàçû, âîçâðàùåííîé â EBX) вызов через точку входа pcibios_entry, предварительно за-
"=d" (entry) полнив регистры процессора следующей информацией:
// èäåíòèôèêàòîð çàïðàøèâàåìîãî ñåðâèñà ($PCI)
: "0" (service), ! EAX – запрашиваемая функция сервиса, в данном слу-
// ñåëåêòîð ôóíêöèè, äîëæåí áûòü ðàâåí íóëþ чае 0xB101;
"1" (0),
// àäðåñ òî÷êè âõîäà â BIOS32 ! EDI – адрес точки входа в сервис.
"D" (&bios32_indirect));
__restore_flags(flags);
В результате выполнения вызова в регистрах процес-
Конструкция типа сора будет находиться следующая информация:
! EDX – сигнатура запрашиваемого сервиса (PCI в на-
__save_flags(flags); шем случае);
__cli();
! AH – признак присутствия сервиса (0 – PCI BIOS при-
/* This code runs with interrupts disabled */ сутствует, если в EDX правильная сигнатура, любое
__restore_flags(flags); другое значение – PCI BIOS отсутствует);
! AL – поддерживаемый аппаратный механизм конфи-
используется для защиты критичных участков кода от воз- гурирования (см. «Configuration Mechanism #1»);
действия прерываний. ! BH – номер версии интерфейса;

80
hardware
! BL – подномер версии интерфейса; шине и номер функции), передаются по ссылке и будут
! CL – номер последней шины PCI в системе. изменены на реальные значения.
Для поиска устройства выполняем дальний вызов че-
Итак, выполняем вызов: рез точку входа в сервис BIOS32, задав в регистрах про-
цессора соответствующие параметры:
__save_flags(flags); __cli();
__asm__(
! EAX – запрашиваемая функция сервиса, в данном слу-
"lcall (%%edi); cld\n\t" чае 0xB102.
"jc 1f\n\t"
"xor %%ah, %%ah\n"
! ECX – код типа устройства.
"1:" ! EDX – код фирмы-изготовителя устройства.
// â EDX âîçâðàùàåòñÿ ñèãíàòóðà "PCI"
: "=d" (signature),
! ESI – индекс (порядковый номер) устройства заданно-
// â AH – ïðèçíàê ïðèñóòñòâèÿ, â AL – àïïàðàòíûé ìåõàíèçì го типа.
"=a" (eax),
// â BH - íîìåð âåðñèè èíòåðôåéñà PCI, BL – ïîäíîìåð
! В регистр EDI занесем адрес точки входа в сервис.
// âåðñèè èíòåðôåéñà
"=b" (ebx), В результате выполнения вызова в регистрах процес-
// ECX – íîìåð ïîñëåäíåé øèíû PCI â ñèñòåìå
"=c" (ecx) сора будет находиться следующая информация:
// 0xB101 – ôóíêöèÿ ïðîâåðêè ïðèñóòñòâèÿ PCI BIOS
// â ñèñòåìå
! BH – номер шины, к которой подключено устройство;
: "1" (PCIBIOS_PCI_BIOS_PRESENT), ! BL – номер устройства в старших пяти битах и номер
// òî÷êà âõîäà â ñåðâèñ BIOS32 функции в трёх младших;
"D" (&pci_indirect)
: "memory"); ! AH – код возврата (может принимать значения BAD_VEN-
__restore_flags(flags); DOR_ID, DEVICE_NOT_FOUND и SUCCESFUL).

и обрабатываем полученные результаты: Выполняем дальний вызов:

// ïðèçíàê ïðèñóòñòâèÿ ñåðâèñà ñ ñèñòåìå __asm__("lcall (%%edi); cld\n\t"


status = (eax >> 8) & 0xff; "jc 1f\n\t"
// ïîääåðæèâàåìûé àïïàðàòíûé ìåõàíèçì "xor %%ah, %%ah\n"
hw_mech = eax & 0xff; "1:"
// íîìåð âåðñèè : "=b" (bx),
major_ver = (ebx >> 8) & 0xff; "=a" (ret)
// íîìåð ïîäâåðñèè : "1" (PCIBIOS_FIND_PCI_DEVICE),
minor_ver = ebx & 0xff; "c" (device_id),
"d" (vendor),
Если сервис присутствует, переменная status будет рав- "S" ((int) index),
// àäðåñ òî÷êè âõîäà â ñåðâèñ
на 0. Проверяем это, а заодно и полученную сигнатуру: "D" (&pci_indirect));

if (status || signature != PCI_SIGNATURE) { Обрабатываем полученный результат:


printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] ↵
found\n", status, signature);
return 0; *bus = (bx >> 8) & 0xff; // íîìåð øèíû
} *dev = (bx & 0xff) >> 3; // íîìåð óñòðîéñòâà íà øèíå
printk(KERN_INFO "PCI: PCI BIOS revision %x.%02x entry ↵ *fn = bx & 0x3; // íîìåð ôóíêöèè
at 0x%08x\n", major_ver, minor_ver, pcibios_entry); return (int) (ret & 0xff00) >> 8;
}
return 1;
} Функция поиска устройства заданного класса
return 0;
} pci_bios_find_class() практически не отличается от функ-
ции поиска устройства по типу:
Функция pci_bios_find_device() выполняет поиск устрой-
ства заданного типа при помощи PCI BIOS и возвращает static int pci_bios_find_class(u32 class_code, u16 index, ↵
struct pci_dev_struct *pd)
его координаты – номер шины, к которой подключено ус- {
тройство, номер устройства на шине и номер функции ус- u16 bx;
u16 ret;
тройства:
В параметрах функции передается указатель на инфор-
static int pci_bios_find_device(u16 vendor, u16 device_id, ↵ мационную структуру struct pci_dev_struct *pd.
u16 index, u8 *bus, u8 *dev, u8 *fn)
{ Перед выполнением дальнего вызова в регистры за-
u16 bx; носятся следующие данные:
u16 ret;
! EAX – запрашиваемая функция сервиса – 0xB103.
Функция принимает следующие параметры: ! ECX – код класса устройства.
! vendor – код фирмы-изготовителя устройства PCI; ! ESI – индекс (порядковый номер) устройства заданно-
! device_id – код типа устройства; го типа.
! index – порядковый номер устройства заданного типа. ! В регистр EDI занесем адрес точки входа в сервис.
Если устройство одно, то его порядковый номер равен 0.
Результаты выполнения вызова аналогичны предыду-
Параметры bus, dev и fn, соответствующие координа- щим:
там устройства PCI (номер шины, номер устройства на ! в регистре BH – номер шины;

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


hardware
! в BL – номер устройства в старших пяти битах и номер После выполнения функции в регистре ECX будут нахо-
функции в трёх младших; диться считанные данные, а регистр AH будет содержать код
! в AH – код возврата (DEVICE_NOT_FOUND или возврата. Подготовим значение для загрузки в регистр BX и
SUCCESFUL): прочитаем информацию из конфигурационного простран-
ства устройства, учитывая размер запрашиваемых данных:
__asm__("lcall (%%edi); cld\n\t"
"jc 1f\n\t" bx = ((bus << 8) | (dev << 3) | fn);
"xor %%ah, %%ah\n"
"1:"
: "=b" (bx), switch (len) {
case 1: // ñ÷èòûâàåì áàéò
"=a" (ret) __asm__("lcall (%%esi); cld\n\t"
: "1" (PCIBIOS_FIND_PCI_CLASS_CODE),
"c" (class_code), "jc 1f\n\t"
"xor %%ah, %%ah\n"
"S" ((int) index), "1:"
// àäðåñ òî÷êè âõîäà â ñåðâèñ
"D" (&pci_indirect)); : "=c" (*value),
"=a" (result)
: "1" (PCIBIOS_READ_CONFIG_BYTE),
Заносим в структру struct pci_dev_struct *pd координа- "b" (bx),
ты устройства: "D" ((long)reg),
// òî÷êà âõîäà â ñåðâèñ
"S" (&pci_indirect));
// íîìåð øèíû break;
pd->bus = (bx >> 8) & 0xff;
// íîìåð óñòðîéñòâà íà øèíå case 2: // ñ÷èòûâàåì ñëîâî
pd->dev = (bx & 0xff) >> 3; __asm__("lcall (%%esi); cld\n\t"
// íîìåð ôóíêöèè "jc 1f\n\t"
pd->fn = bx & 0x03; "xor %%ah, %%ah\n"
return (int) (ret & 0xff00) >> 8; "1:"
} : "=c" (*value),
"=a" (result)
После того как устройство заданного типа найдено, : "1" (PCIBIOS_READ_CONFIG_WORD),
"b" (bx),
необходимо получить данные, находящиеся в его конфи- "D" ((long)reg),
гурационном пространстве (см. «Конфигурационное про- // òî÷êà âõîäà â ñåðâèñ
"S" (&pci_indirect));
странство устройства PCI»). Сделаем это при помощи break;
функции pci_bios_read():
case 4: // ñ÷èòûâàåì äâîéíîå ñëîâî
__asm__("lcall (%%esi); cld\n\t"
static int pci_bios_read(int bus, int dev, int fn, int reg, ↵ "jc 1f\n\t"
int len, u32 *value) "xor %%ah, %%ah\n"
{ "1:"
u32 result = 0; : "=c" (*value),
u32 bx; "=a" (result)
: "1" (PCIBIOS_READ_CONFIG_DWORD),
Параметрами функции являются координаты устрой- "b" (bx),
"D" ((long)reg),
ства (bus – номер шины, dev – номер устройства, fn – но- // òî÷êà âõîäà â ñåðâèñ
мер функции), смещение в конфигурационном простран- "S" (&pci_indirect));
break;
стве (reg) и размер данных для считывания (len, байт/сло- }
во/двойное слово). В последний параметр мы поместим return (int)((result & 0xff00) >> 8);
}
считанное из конфигурационного пространства значение,
поэтому этот параметр передается по ссылке. Помимо средств BIOS32 для работы с конфигурацион-
Проверяем правильность переданных параметров: ным пространством устройства PCI в защищенном режиме
также используется Configuration Mechanism #1. Его поря-
if (bus > 255 || dev > 31 || fn > 7 || reg > 255) док работы был рассмотрен в «Configuration Mechanism #1»:
return -EINVAL;
в порт CONFIG_ADDRESS (0xCF8) заносится адрес, соот-
Для чтения информации из конфигурационного про- ветствующий формату, приведенному на рис. 2; обраще-
странства устройства PCI BIOS предоставляет следующие нием к порту CONFIG_DATA (0xCFC) производится чте-
функции [6]: ние или запись данных в требуемый регистр конфигура-
! 0xB108 – чтение байта; ционного пространства.
! 0xB109 – чтение слова; Формировать адрес установленного формата будет
! 0xB10A – чтение двойного слова. макрос PCI_CONF1_ADDRESS():

Эти функции отличаются только размером считывае- #define PCI_CONF1_ADDRESS(bus, dev, fn, reg) | ↵
(0x80000000 | (bus << 16) | (dev << 11) | ↵
мых данных – байт, слово или двойное слово. Перед вы- (fn << 8) | (reg & ~3))
зовом функции в регистры процессора помещается сле-
дующая информация: Самый старший бит установлен в 1 – это позволит нам
! EAX – код функции; получить данные из порта CONFIG_DATA.
! BH – номер шины, к которой подключено устройство; После того как адрес сформирован, записываем его в
! BL – номер устройства в старших пяти битах и номер порт CONFIG_ADDRESS.
функции в трёх младших битах; Функция pci_direct_read() выполняет обращение к уст-
! DI – смещение в конфигурационном пространстве. ройству PCI при помощи Configuration Mechanism #1:

82
hardware
static int pci_direct_read(int bus, int dev, int fn, ↵ for(dev = 0; dev < 32; dev++) {
int reg, int len, u32 *value) // ñêàíèðóåì âñå ôóíêöèè
{ for(fn = 0; fn < 8; fn++) {

Параметры функции – номер шины bus, номер устрой- Считываем двойное слово, находящееся по смещению
ства на шине dev, номер функции fn, смещение в конфи- idx, и получаем код класса:
гурационном пространстве reg, длина запрашиваемых
данных (байт/слово/двойное слово). Результат помещает- pci_direct_read(bus, dev, fn, idx, 4, &config_dword);
code = config_dword >> 8;
ся в параметр value, который передается по ссылке.
Проверяем правильность переданных параметров: Сравниваем полученный код класса с искомым. При
совпадении сохраняем координаты устройства
if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
return -EINVAL if(code == class_code) {
Формируем адрес при помощи макроса PCI_CONF1_ printk(KERN_INFO "OK. Device found.\n");
ADDRESS() и записываем его в порт CONFIG_ADDRESS: printk(KERN_INFO "bus - %d, dev - %d, ↵
fn - %d\n", bus, dev, fn);
outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); pd->bus = bus;
pd->dev = dev;
pd->fn = fn;
Считываем значение из порта CONFIG_DATA:
return 0;
}
switch (len) { }
case 1: // ñ÷èòûâàåì áàéò }
*value = inb(0xCFC + (reg & 3)); }
break; return 0x80;
case 2: // ñ÷èòûâàåì ñëîâî }
*value = inw(0xCFC + (reg & 2));
break; Все функции, которые мы рассмотрели, будут вызва-
case 4: // ñ÷èòûâàåì äâîéíîå ñëîâî
*value = inl(0xCFC); ны во время процедуры инициализации модуля:
break;
} static int __init pcidev_on(void)
return 0; {
}
// ñòðóêòóðà ñ ïàðàìåòðàìè PCI-óñòðîéñòâà
struct pci_dev_struct pdev;
// ñìåùåíèå ê äàííûì â êîíôèãóðàöèîííîì ïðîñòðàíñòâå
Функция pci_direct_find_class() выполняет поиск устрой- // óñòðîéñòâà PCI
ства заданного класса, используя Configuration Mechanism int idx = 0;
// êîîðäèíàòû óñòðîéñòâà
#1, и возвращает его координаты – номер шины, номер u8 bus = 0, dev = 0, fn = 0;
устройства на шине и номер функции: // êîìàíäíûé ðåãèñòð
u16 command_reg = 0;
u32 config_dword = 0;
int pci_direct_find_class(u32 class_code, ↵
struct pci_dev_struct *pd)
{ Напомню, что наша задача – прочитать MAC-адрес се-
тевого адаптера RTL8139C, и для этого нам необходимо
Параметры функции – код класса устройства и струк- получить его базовый адрес в пространстве I/O. Ищем слу-
тура struct pci_dev_struct *pd, в которую необходимо запи- жебный заголовок BIOS32, вычисляем адрес точки входа в
сать координаты устройства. BIOS32 и производим проверку присутствия PCI BIOS:

int bus, dev, fn = 0, idx = 0x08; pci_find_bios();


u32 config_dword, code; check_pcibios();

Переменная idx – это смещение в конфигурационном Выполняем поиск устройства (сетевого адаптера
пространстве устройства, и указывает оно на поле Revision RTL8139C) по коду типа устройства. В результате мы по-
ID, за которым следуют три байта поля Class Code. Для лучим его координаты – номер шины, номер устройства
считывания Class Code достаточно считать двойное сло- на шине и номер функции:
во, находящееся по смещению idx, и сдвинуть результат
на 8 бит в сторону младших разрядов. 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);
все функции устройства – до тех пор, пока не найдем уст-
ройство соответствующего класса (или пока не закончат- Повторим процедуру, но в этот раз будем искать уст-
ся шины). С этой целью организуем цикл: ройство по коду класса:

printk(KERN_INFO "Looking for device with class code ↵ memset((void *)&pdev, 0, sizeof(struct pci_dev_struct));
0x%X\n", class_code); if(pci_bios_find_class(CLASS_CODE, idx, ↵
memset(pd, 0, sizeof(struct pci_dev_struct)); &pdev) == PCIBIOS_SUCCESSFUL)
// ñêàíèðóåì âñå øèíû printk(KERN_INFO "Device found by class, bus - %d, ↵
for(bus = 0; bus < 256; bus++) { dev - %d, fn - %d\n", pdev.bus, pdev.dev, pdev.fn);
// ñêàíèðóåì âñå óñòðîéñòâà íà êàæäîé øèíå else {

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


hardware
printk(KERN_INFO "Device not founf by class\n");
return 0; return;
} }

Итак, устройство найдено. Считываем из конфигура- void get_mac_addr(u32 base_addr)


{
ционного пространства код фирмы-производителя и за- int i = 0;
носим это значение в структуру struct pci_dev_struct pdev: u8 mac[6];
memset(mac, 0, 6);
/* Read VENDOR ID */
idx = 0x00; /* Get and display MAC address */
if(pci_bios_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵ for(; i < 6; i++)
2, &config_dword) == PCIBIOS_SUCCESSFUL) mac[i] = inb(base_addr + i);
pdev.vendor_id = (u16)config_dword;
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;
}
/* Read DEVICE ID */
idx = 0x02;
if(pci_bios_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵ Теперь давайте выполним процедуру чтения MAC-ад-
2, &config_dword) == PCIBIOS_SUCCESSFUL) реса сетевого адаптера RTL8139C, используя Configuration
pdev.device_id = (u16)config_dword;
Mechanism #1 для доступа к конфигурационному простран-
/* 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; /* 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");
/* Read Command Register */ return 0;
idx = 0x04; }
if(pci_bios_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵
1, &config_dword) == PCIBIOS_SUCCESSFUL) Считываем код фирмы-производителя, код типа уст-
command_reg = config_dword;
ройства и код класса устройства:
Считываем значение базового адреса в пространстве
I/O. Предварительно проверяем, чтобы бит 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 Base Address Registers */ /* Read DEVICE_ID */
idx = 0x10; idx = 0x02;
if(command_reg & 0x01) { if(pci_direct_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵
// ñêàíèðóåì Base Address Registers â ïîèñêàõ àäðåñà 2, &config_dword) == 0)
// ïîðòà I/O printk(KERN_INFO "DEVICE_ID - 0x%X\n", config_dword);
for(; idx < 0x28 ;) {
if(pci_bios_read(pdev.bus, pdev.dev, pdev.fn, ↵ /* Read Class Code */
idx, 4, &config_dword) == PCIBIOS_SUCCESSFUL) { idx = 0x08;
// åñëè íóëåâîé áèò ðàâåí 1, òî àäðåñ ïîðòà if(pci_direct_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵
// I/O íàéäåí 4, &config_dword) == 0)
if(config_dword & 0x01) { printk(KERN_INFO "CLASS_CODE - 0x%X\n", ↵
config_dword &= ~0x1; config_dword >> 8);
pdev.base_addr = config_dword;
break;
} Считываем содержимое командного регистра и зна-
idx += 4; чение адреса порта I/O:
}
}
} else return 0; /* Read Command Register */
command_reg = 0;
idx = 0x04;
Базовый адрес найден. Отобразим информацию об if(pci_direct_read(pdev.bus, pdev.dev, pdev.fn, idx, ↵
2, &config_dword) == 0)
устройстве и прочитаем MAC-адрес адаптера RTL8139C: command_reg = config_dword;

display_pcidev_info(&pdev); /* Read Base Address Registers */


get_mac_addr(pdev.base_addr); idx = 0x10;
if(command_reg & 0x01) {
for(; idx < 0x28 ;) {
Функции display_pcidev_info() и get_mac_addr() выгля- if(pci_direct_read(pdev.bus, pdev.dev, pdev.fn, ↵
дят следующим образом: idx, 4, &config_dword) == PCIBIOS_SUCCESSFUL) {
if(config_dword & 0x01) {
config_dword &= ~0x1;
void display_pcidev_info(struct pci_dev_struct *pdev) pdev.base_addr = config_dword;
{ break;
printk(KERN_INFO "VENDOR ID - 0x%X\n", pdev->vendor_id); }
printk(KERN_INFO "DEVICE ID - 0x%X\n", pdev->device_id); idx += 4;
printk(KERN_INFO "CLASS CODE - 0x%X\n", pdev->class_code); }
printk(KERN_INFO "BASE ADDRESS - 0x%X\n", pdev->base_addr); }

84
hardware
} else return 0; Пример записи из этого файла сравните с результата-
ми, полученными при помощи команд dmesg и ifconfig (см.
Считываем значение MAC-адреса сетевого адаптера. «Постановка задачи и исходные данные»).

get_mac_addr(config_dword);
return 0;
Заключение
} Рассмотренные нами функции являются базовыми в под-
системе низкоуровневой поддержки (low-level support)
Выгружает модуль из памяти функция pcidev_off: шины PCI ядра ОС Linux. Все эти функции можно найти в
файле arch/i386/kernel/pci-pc.c.
static void __exit pcidev_off(void) В повседневной практике нет особой необходимости
{
return; работать напрямую с шиной, для этих целей целесообраз-
} но применять функции более высокого уровня, перечень
которых приведён в файле Documentation/pci.txt.
Инициализация модуля и выгрузка его из памяти вы- Насчет спецификаций и где их брать – спецификация
полняется при помощи двух макросов: на RTL8139C находится на сайте компании RealTek,
www.realtek.com.tw, спецификация PCI 3.0 и перевод на
module_init(pcidev_on); русский язык спецификации PCI 2.0 были найдены на сай-
module_exit(pcidev_off);
те http://dsp.neora.ru. На сайте Intel (www.intel.com) можно
Исходные тексты модуля доступны на сайте журнала взять спецификацию на сетевые карты Intel 8255x – для это-
и находятся в файле pcidev.c. При помощи команды make го в строке поиска задайте 8255X_OpenSDM (OpenSDM –
получаем объектный модуль pcidev.o и загружаем его ко- Open Source Software Developer Manual). Также посетите
мандой insmod: сайт фирмы Phoenix (www.phoenix.com) – материалы по
BIOS.
insmod pcidev.o Список кодов классов и подклассов устройств PCI на-
ходится в [4], приложение D.
Вся информация, полученная от устройства, будет со-
брана в файле /var/log/messages. Литература:
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, 1993
6. PCI BIOS specification. Revision 2.0. 1993.

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


образование

ПРОГРАММНОЕ УПРАВЛЕНИЕ
ADSI: LDAP

В предыдущих статьях [1, 2] были рассмотрены теоретические аспекты построения Active Directory
и проведен обзор доступных провайдеров, с помощью которых можно программно управлять
Active Directory, а также описаны основы программирования одного из провайдеров – WinNT.
Данный материал содержит основы программирования провайдера LDAP, объектная модель
которого рассмотрена на примере стандартных утилит, созданных компанией Microsoft.

ИВАН КОРОБКО

88
образование

Объектная модель OU=OU_Name_Level1/OU=OU_Name_Level2…/OU=OU_Na-


me_Levelµ представляют собой вложенные друг в друга
провайдера LDAP элементы. В развернутой форме доступа объект CN яв-
Для программного управления Active Directory с помощью ляется «дном колодца» в иерархии.
провайдера LDAP необходимо использовать его объектную Пример: запрос к объекту CN=User3 с помощью раз-
модель. Объектная модель представляет собой совокуп- вернутой формы доступа выглядит следующим образом
ность объектов, которые взаимосвязаны друг с другом и (см. рис. 1):
образуют между собой иерархическую структуру. Каждый
из этих объектов имеет набор свойств, характерных исклю- Set obj = GetObject ("LDAP://DC=RU/DC=Domain1/OU=Group1/ ↵
OU=Group4/CN=User3")
чительно для объектов данного типа. Существует несколь-
ко типов (идентификаторов) объектов: CN, DС, OU. Рас-
шифровка и назначение каждого объекта см. в таблице 1. Сокращенная форма
Òàáëèöà 1 Форма характеризуется тем, что строка запроса строится
в соответствии с обратной иерархией структуры органи-
зации. Шаблон выглядит следующим образом:

Set obj=GetObject("LDAP://CN=CN_Name,OU=OU_Name_Levelµ…, ↵
OU=OU_Name_Level2,OU=OU_Name_Level1/DC=…")

Имена LDAP URL


Имена LDAP URL (см. RFC 1779, RFC 2247) построены на Соответственно запрос к объекту CN=User3 с помощью
основе протокола X.500 и используются для связывания с сокращенной формы доступа выглядит следующим образом:
объектами. Идентификаторы объектов DC, OU, CN обра-
зуют полное составное имя (Distinguished Name, DN), а имя Set obj=GetObject("LDAP://CN=User3,OU=Group4, ↵
OU=Group3,DC=Domain1,dc=RU")
самого объекта – относительное составное имя (Relative
Distinguished Name, RDN). Полное составное имя объекта
включает в себя имя объекта и всех его родителей, начи- Инструменты, обеспечивающие доступ
ная с корня домена (см. рис. 1). к объектной модели каталога
Существует несколько программ, предназначенных для
просмотра объектной модели каталога. Остановимся лишь
на двух из них: Active Directory Viewer (Microsoft) и LDAP
Browser 2.5.3 (Softerra).

Active Directory Viewer (Microsoft)


Active Directory Viewer (ADV) является графической ути-
литой, позволяющей выполнять операции чтения, моди-
фицирования, осуществлять поиск в любых совместимых
каталогах, таких как Active Directory, Exchange Server,
Netscape Directory, Netware Directory.
Active Directory Viewer входит в состав SDK для Active
Directory Services Interface, который можно бесплатно заг-
Ðèñóíîê 1 рузить с сайта Microsoft: http://www.microsoft.com/ntserver/
Существуют две формы доступа к ADSI: развернутая и nts/downloads/other/adsi25.
сокращенная. Рассмотрим принципы построения путей к После установки SDK for ADSI утилита Active Directory
ресурсу двумя способами на примере домена domain.com Viewer (AdsVw.exe) будет находиться в c:\Program Files\
(см. рис. 1). Microsoft\ADSI Resource Kit, Samples and Utilities\ADsVw\.
Программа работает в двух режимах: ObjectViewer и
Развернутая форма Query (см. рис. 2). Для просмотра объектной модели ка-
При использовании этого вида формы строка связывания кого-либо провайдера необходимо использовать режим
начинается с описания верхнего элемента структуры. За- ObjectViewer. Режим Query используется для осуществ-
тем происходит переход вниз по иерархии. Важно помнить, ления поиска объектов в выбранной объектной модели. В
что при написании пути к объекту необходимо исключать данной статье режим Query рассматриваться не будет.
пробелы.
В качестве шаблона может служить выражение вида:

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")

где DC=Domain_name1/DC=Domain_name2/DC=Domain_na-
me3 образуют полное имя контроллера домена, элементы Ðèñóíîê 2

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


образование
Просмотр и редактирование объектной модели Обратите внимание на две особенности в этом шаб-
программой ADV в режиме ObjectViewer лоне: в шаблоне не должно быть пробелов, «слэши» дол-
После выбора режима работы ObjectViewer появится диа- жны быть прямыми – «/». Невыполнение хотя бы одного
логовое окно (см. рис. 3). Для получения доступа к ката- из перечисленных условий приведет к ошибке в соедине-
логу необходимо указать путь к каталогу и параметры нии с каталогом. Для доступа к серверу server домена
учетной записи, обладающей правами администратора domain.ru с помощью протокола LDAP используется сле-
(имя и пароль). Путь к каталогу должен быть построен в дующий запрос:
соответствии со следующим шаблоном:
LDAP://server/DC=domain,DC=ru;
<Provider_Name:>//<Server_Name>/<Full_Domain_Name>
После соединения с каталогом на экране будет ото-
бражена его иерархическая структура (см. рис. 4). В ле-
вой части экрана отображается иерархическая структура
каталога. В правой части отображаются характеристики
объекта, на котором установлен курсор. Список свойств
объекта и соответствующих им значений приведен в
«Properties» и «Property Value».
С помощью кнопок «Change», «Clear», «Append»,
«Delete» можно изменять объектную модель каталога: из-
менять, удалять, добавлять поля в свойствах объектов.

LDAP Browser 2.5.3 (Softerra)


LDAP Browser 2.5.3 является бесплатной программой (http://
www.ldapadministrator.com).
По своим возможностям программа превосходит Active
Directory Viewer, в использовании LDAP Browser гораздо
удобнее. В процессе создания соединения с каталогом
Ðèñóíîê 3 могут быть заданы фильтры, параметры административ-

Ðèñóíîê 4

90
образование
ной учетной записи, порт TCP, по которому имеет место чение по размеру, сортировка и т. д. Форма запроса
соединение, и другие параметры. Общий вид программы (Distributed Query) заимствована из Microsoft SQL Server.
приведен на рис. 5. Запрос строится по шаблону:

SELECT ïîëå11,ïîëå21,ïîëån1 FROM ïóòü ↵


Различия в функционале WHERE objectClass="òèï_îáúåêòà"

провайдеров LDAP и WinNT где путь – путь к интересующему объекту AD в формате


Об одном из отличий речь велась в предыдущей статье LDAP URL.
[2] – провайдер LDAP (Lightweight Directory Access Protocol) На практике поиск объектов осуществляется следую-
рассматривает принтер как сетевое устройство, в то вре- щим образом:
мя как провайдер WinNT рассматривает принтер исклю-
чительно как локальное устройство. Использование обо- Ïðèìåð 1:
их провайдеров при работе с принтерами позволяет пол- Set objNameSpace = GetObject("WinNT:")
ностью управлять принтерами. Наглядный пример управ- For Each Domain in objNameSpace
DomainName=Domain.Name
ления принтерами домена рассмотрен в статье «Управ- Next
ление сетевыми принтерами домена» [3].
Set objConnection = CreateObject("ADODB.Connection")
Вторым принципиальным отличием провайдеров явля- Set objCommand = CreateObject("ADODB.Command")
ются расширенные возможности поиска провайдера objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
LDAP. Используя провайдер WinNT, можно было осуще- Set objCommand.ActiveConnection = objConnection
ствлять поиск, пользуясь фильтром, который позволял осу- objCommand.CommandText = "SELECT printerName, serverName ↵
FROM " _ & " 'LDAP://"& DomainName & "' ↵
ществлять поиск всех объектов, принадлежащих к одно- WHERE objectClass='printQueue'"
му из классов – computer, user, service и др. Провайдер objCommand.Properties("Cache Results") = False
Set objRecordSet = objCommand.Execute
позволяет искать объект, при этом не обязательно указы- objRecordSet.MoveFirst
вать класс, к которому относится объект. Найдя объект,
Do Until objRecordSet.EOF
осуществляем чтение его свойств, включая местоположе- temp=temp & "Printer Name: " ↵
ние объекта в AD, класс, к которому относится объект, и & objRecordSet.Fields("printerName").Value ↵
& " Server Name: " ↵
другие параметры. & objRecordSet.Fields("serverName").Value & chr(13)
Поиск объектов осуществляется с помощью OLE objRecordSet.MoveNext
Loop
Distributed Query (DB) интерфейса, который вызывается пря-
мо из интерфейса службы активного каталога (Active Directory wscript.echo temp
Service Interface – ADSI). Поиск осуществляется на основа-
нии запроса и его параметров. В качестве параметров зап- В приведенном примере осуществляется поиск всех
роса могут быть: уровень поиска, диапазон поиска, ограни- зарегистрированных в AD-принтеров. У найденных прин-

Ðèñóíîê 5

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


образование
теров происходит чтение двух полей: название принтера В том случае если доступ анонимным пользователям
и название сервера печати. к записям блокирован, то необходимо читать свойства
Поиск объектов с помощью провайдера LDAP осуще- объектов от имени учетной записи, которая имеет права
ствляется по следующему шаблону: на чтение свойств. Пусть пользователь User1 имеет пра-
! устанавливается соединение с Active Directory Provider во на чтение всех полей объектов. Пароль пользователя
через ADODB; User1 – 1234567. Осуществим чтение идентификационного
! составляется запрос, на основе которого будет осуще- номера учетной записи User3 от имени User1. Чтение па-
ствляться поиск; раметров от имени другого пользователя осуществляет-
! осуществляется поиск по заданным критериям. ся с помощью функции OpenDSObject():

В том случае если искомые объекты найдены, то осу- Ïðèìåð 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
торое необходимо прочитать, можно указать порядковый
номер поля, под которым оно обозначено в запросе. Поля
отсчитываются с нуля.
Таким образом, основываясь на приведенном приме-
Изменение атрибутов
ре, вместо objRecordSet.Fields(«serverName»).Value мож- учетной записи
но записать objRecordSet.Fields(1).Value. Модификация атрибутов учетной записи осуществля-
Третье отличие – это управление коммерческими про- ется с помощью функции Put() и метода SetInfo, служа-
дуктами, поддерживающими LDAP. Множество коммер- щего для сохранения внесенных изменений в Active
ческих продуктов использует каталог LDAP для хранения Directory. В приведенном ниже примере атрибут учет-
информации. Используя ADSI, можно управлять коммер- ной записи User3 – Canonical Name (CN) будет изменен
ческими продуктами, в число которых входят: Microsoft с User3 на User4.
Windows 2000, 2003; Microsoft Exchange 5.5, 2000, 2003;
Microsoft Site Server 3.0 + SP2; Netscape Directory Server и Ïðèìåð 4:
др. Кроме того, компании Cisco и Microsoft предложили Set PreObj= GetObject("LDAP:")
стандарт сети на основе каталога, в котором описывает- Set obj= PreObj.OpenDSObject("LDAP://CN=User3, OU=Group1, ↵
OU=Users, o=domain.ru", "CN=User1","1234567",0)
ся интеграция сетевых устройств в каталоге LDAP. Set U_obj=obj.GetObject("InetOrgPerson","CN=User3")
В настоящей статье будет рассмотрен вопрос, касаю- U_obj.Put "CN","User4"
U_obj.SetInfo
щийся управления Microsoft Windows 200х, а именно Active MsgBox "Ïàðàìåòð CN èçìåíåí."
Directory. Рассмотрим следующие вопросы, касающиеся
управления AD через провайдер LDAP: просмотр атрибу- InetOrgPerson – тип учетной записи.
тов записи от анонимной и конкретной учетной записи;
изменение атрибутов учетной записи; создание и удале-
ние учетной записи.
Создание и удаление
учетной записи
Для создания учетной записи в Active Directory необхо-
Просмотр атрибутов записи димо задать несколько обязательных параметров, от-
от анонимной и конкретной носящихся к учетной записи и ее родительскому кон-
тейнеру:
учетной записи ! создание учетной записи должно выполняться пользо-
Просмотр атрибутов объектов осуществляется с помощью вателем, имеющим административные привилегии;
функции Get(), вызову которой предшествует вызов функ- ! путь к родительскому контейнеру, в котором необходи-
ции GetObject(). Для получения анонимного доступа к объек- мо создать учетную запись;
там необходимо указать путь к объекту, начиная с контрол- ! класс создаваемого объекта;
лера домена. В приведенном примере читается идентифи- ! соответствующие свойства создаваемого класса объек-
кационный номер учетной записи User3 (см. рис. 2) – UserID, та записи.
которому соответствует поле uid. Объектная модель провай-
дера LDAP будет рассмотрена позже. Необходимо отметить, Ïðèìåð 5:
что свойства имеют все типы объектов – OU, CN и другие. Set PreObj= GetObject("LDAP:")
Set obj= PreObj.OpenDSObject("LDAP:// OU=Group1, OU=Users, ↵
Ïðèìåð 2: o=domain.ru", "CN=User1","1234567",0)
Set U_obj=obj.Create("InetOrgPerson","CN=User3")
ClassArray=Array("InetOrgPerson","person","top","organizationPerson")
Set obj=GetObject("LDAP://CN=User3, OU=Group1, ↵ U_obj.Put "objectClass", ClassArray
OU=Users, o=domain.ru")
For Each U_obj In obj U_obj.Put "cn", "User_Name_3"
U_obj.Put "sn", "Second_Name_3"
wscript.echo "UserUID: " & U_obj.Get("uid") U_obj.SetInfo
Next
MsgBox "Ó÷åòíàÿ çàïèñü ñîçäàíà."

92
образование
Для удаления учетных записей используется метод objRecordSet.MoveFirst
Delete («InetOrgPerson», object_name). Do Until objRecordSet.EOF
If objRecordSet.Fields("sAMAccoutName").Value=UserLogonName
msgbox "FullName: "+ objRecordSet.Fields("name").Value
end if
Заключение Loop

На практике управление Active Directory преимуществен- Как видно, листинг примера 6 б) в несколько раз больше,
но осуществляется с помощью провайдера WinNT или в чем листинг примера 6 а). За счет того, что в примере 6 б)
совокупности WinNT с LDAP. В «чистом» виде програм- «просматривается» весь массив пользователей, сценарий
мирование LDAP используется очень редко. Основная будет отрабатываться в несколько раз медленнее, чем сце-
причина заключается в том, что для доступа к любому нарий 6 а). Скорость выполнения сценария напрямую зави-
объекту с помощью провайдера LDAP необходимо знать сит от количества объектов в просматриваемом массиве.
полный путь к этому объекту. Эта проблема легко реша- Очевидно, что чем больше размер массива, тем медленнее
ется: происходит осуществление поиска объекта, затем будет работать скрипт.
чтение его свойств. Приведем пример чтения поля Многократное использование данного механизма в од-
FullName для пользователя USER1 с помощью провайде- ном скрипте дополнительно уменьшит скорость выполнения
ров LDAP и WinNT. скрипта и увеличивает его размер по сравнению с анало-
гичным скриптом, в котором доступ к объектам осуществля-
Ïðèìåð 6 a) - WinNT: ется с помощью провайдера WinNT. Однако отказаться от
Set obj=GetObject("WinNT:") доступа к AD с помощью провайдера LDAP невозможно, по-
For Each str In obj скольку существует много функций, которые реализованы
DomainName=str.Name
Next только в провайдере LDAP. Оптимальным вариантом явля-
Set UserName="Value" ется совместное использование провайдеров LDAP и WinNT.
Set element=GetObject("WinNT://" & DomainName & "/ USER1")
Msgbox "FullName: "+ cstr(element.FullName) Ярким примером является чтение свойств сетевого принте-
ра: с точки зрения провайдера WinNT принтер – локальное
Ïðèìåð 6 á) - LDAP:
устройство, с точки зрения LDAP – сетевое.
set rootDSE_ = GetObject("LDAP://RootDSE")
DomainName = rootDSE_.Get("defaultNamingContext")
Литература:
UserLogonName="USER1" 1. Коробко И. Active Directory – теория построения. –
Const ADS_SCOPE_SUBTREE = 2
Set objConnection = CreateObject("ADODB.Connection") // Журнал «Системный администратор», №1(14), ян-
Set objCommand = CreateObject("ADODB.Command") варь 2004 г. – 90-94с.
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider" 2. Коробко И. Программное управление ADSI: WinNT. –
Set objCommand.ActiveConnection = objConnection // Журнал «Системный администратор», №2(15), фев-
objCommand.CommandText = "SELECT name, sAMAccoutName ↵
FROM " _ & " 'LDAP://"& DomainName & "' ↵ раль 2004 г. – 66-74с.
WHERE objectClass='users'" 3. Коробко И. Управление сетевыми принтерами доме-
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.Properties("Cache Results") = False на. – // Журнал «Системный администратор», №10(11),
Set objRecordSet = objCommand.Execute октябрь 2003 г. – 38-46с.

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


подписка

Открыта подписка на II полугодие 2004 г.


Более подробная информация на сайте www.samag.ru
в разделе «Подписка»

Подписной
индекс:

81655
по каталогу
агентства
«Роспечать»

Рады видеть
Вас нашими
читателями!

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


СИСТЕМНЫЙ АДМИНИСТРАТОР
№3(16), Март, 2004 год

РЕДАКЦИЯ
ЧИТАЙТЕ
Исполнительный директор
Владимир Положевец
В СЛЕДУЮЩЕМ
Ответственный секретарь
Наталья Хвостова
sekretar@samag.ru
НОМЕРЕ:
Технический редактор
Владимир Лукин
Редактор Transparent proxy. Работа по расписанию
Андрей Бешков Быть или не быть? в FreeBSD
Научно-технические консультанты Данная статья посвящена проблемам Способность операционной системы
Дмитрий Горяинов прозрачного проксирования на приме- выполнять задачи в заданное время
Валерий Цуканов ре популярного сервера Squid. В каче- (по расписанию) может сделать ад-
стве ОС использовалась стабильная министрирование существенно про-
РЕКЛАМНАЯ СЛУЖБА версия FreeBSD 4.7. При работе прокси- ще и эффективнее, а в ряде случа-
тел./факс: (095) 928-8253 сервера в прозрачном режиме (Trans- ев такая способность просто необ-
Константин Меделян parent mode) для веб-доступа пользо- ходима.
reсlama@samag.ru вателей в Интернет не требуется на- В данной статье рассмотрены
страивать браузер для взаимодействия средства отложенной работы и рабо-
Верстка и оформление с прокси на каждом рабочем месте, а ты по расписанию, имеющиеся во
imposer@samag.ru сами пользователи могут вообще не FreeBSD (на примере FreeBSD 5.1),
maker_up@samag.ru знать о существовании прокси-серве- однако большинство описанных здесь
Дизайн обложки ра. В таком режиме администраторы и функций будут доступны вам и в дру-
Николай Петрочук техники получают меньше вопросов и гих ОС семейства UNIX, включая
жалоб от пользователей по настройке Linux. Особое внимание уделено ме-
103045, г. Москва, пользовательского ПО. Технически этот ханизмам работы, знание которых не-
Ананьевский переулок, дом 4/2 стр. 1 режим реализуется следующим обра- обходимо для эффективного поиска
тел./факс: (095) 928-8253 зом. С помощью брандмауэра все со- возможных проблем.
Е-mail: info@samag.ru единения на определённый порт (в слу-
Internet: www.samag.ru чае HTTP – порт 80) внешних серверов NTP – атомные часы
перенаправляются на локальный порт на каждом столе
РУКОВОДИТЕЛЬ ПРОЕКТА прокси сервера (обычно – 3128). Каждый из нас, работая за компью-
Петр Положевец По стандарту протокола HTTP 1.1 тером, иногда смотрит на часы. При
УЧРЕДИТЕЛИ (RFC2616) каждый запрос клиента этом кто-то поглядывает на стену, кто-
Владимир Положевец должен содержать заголовок «Host», то на руку, а кто-то бросает беглый
Александр Михалев в котором указывается адрес сервера- взгляд в угол экрана монитора. Конеч-
получателя запроса. Именно с помо- но, часы могут быть разными, глав-
ИЗДАТЕЛЬ щью этого заголовка прокси-сервер ное – чтобы они шли точно. И если для
ЗАО «Издательский дом определяет адресата и соединяется с обычных часов их точность во многом
«Учительская газета» ним. Что же касается других популяр- определятся фирмой-производите-
ных протоколов (FTP, HTTPS, и т. д.), лем, то для практически любых «ком-
Отпечатано типографией то такой возможности в них просто не пьютерных» высокая точность может
ГП «Московская Типография №13» предусмотрено. На этой «весёлой ноте» быть достигнута благодаря синхро-
Тираж 6600 экз. можно начать описание проблем. низации времени, например, с помо-
Журнал зарегистрирован щью протокола NTP (Network Time
в Министерстве РФ по делам печати, Автоматизация веб-проектов Protocol), об использовании которо-
телерадиовещания и средств мас- через электронную почту го и пойдет речь в данной статье.
совых коммуникаций (свидетельство Кто и как управляет сайтами? Инфор-
ПИ № 77-12542 от 24 апреля 2002г.) мации об этом крайне мало, хотя, ду- Создание кластера
маю, существует достаточное количе- на Windows 2000/2003.
За содержание статьи ответственность ство интересных решений. Наша за- Шаг за шагом
несет автор. За содержание рекламно- дача – сделать как можно более удоб- В этой статье я попытаюсь собрать
го обьявления ответственность несет ный и доступный интерфейс для на- свой опыт по созданию кластерных
рекламодатель. Все права на опубли- полнения сайта контентом, то есть пе- систем на базе Windows и дать не-
кованные материалы защищены. Ре- реложить кучу рутины на скрипты и большое пошаговое руководство по
дакция оставляет за собой право изме- сотрудников. Значит, нам предстоит созданию двухузлового кластера сер-
нять содержание следующих номеров. заняться автоматизацией этого про- веров с разделяемым хранилищем
цесса. данных.

96