98
журнал для cистемных администраторов, вебмастеров и программистов №12(13) декабрь 2003 подписной индекс 81655 Практические советы по восстановлению системы Крепость для пингвина: Bastille Linux Вторая жизнь модемов Осваиваем Nagios LTSP Инвентаризация в сети Конвертирование из Excel в HTML Профсоюз IT-специалистов Практические советы по восстановлению системы Крепость для пингвина: Bastille Linux Вторая жизнь модемов Осваиваем Nagios LTSP Инвентаризация в сети Конвертирование из Excel в HTML Профсоюз IT-специалистов №12(13) декабрь 2003

013 Системный Администратор 12 2003

Embed Size (px)

DESCRIPTION

№12(13) декабрь 2003 журнал для cистемных администраторов, вебмастеров и программистов подписной индекс 81655 №12(13) декабрь 2003 Возможные причины нестабильной работы и сбоев си- стемы и рекомендации по их устранению. Крис Касперски [email protected] Осваиваем Nagios Практические советы по восстановлению системы в боевых условиях Общие принципы решения задачи. Сергей Супрунов [email protected] ПРОГРАММИРОВАНИЕ 3 2 6 1 календарь событий 20 декабря 2003 года, г. Москва 2

Citation preview

Page 1: 013 Системный Администратор 12 2003

журнал для cистемных администраторов,вебмастеров и программистов

№12(13) декабрь 2003подписной индекс 81655

Практические советыпо восстановлению системы

Крепость для пингвина:Bastille Linux

Вторая жизнь модемов

Осваиваем Nagios

LTSP

Инвентаризация в сети

Конвертированиеиз Excel в HTML

Профсоюз IT-специалистов

Практические советыпо восстановлению системы

Крепость для пингвина:Bastille Linux

Вторая жизнь модемов

Осваиваем Nagios

LTSP

Инвентаризация в сети

Конвертированиеиз Excel в HTML

Профсоюз IT-специалистов

№12

(13)

дек

абрь

200

3

Page 2: 013 Системный Администратор 12 2003
Page 3: 013 Системный Администратор 12 2003

1№12(13), декабрь 2003

оглавление

ПРОГРАММИРОВАНИЕ

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

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

3

КАЛЕНДАРЬ СОБЫТИЙ

SYSM.02Запланируйте участие: второй Семинар системныхадминистраторов и инженеров.

2

Практические советы по восстановлениюсистемы в боевых условиях

Возможные причины нестабильной работы и сбоев си-стемы и рекомендации по их устранению.Крис Касперски[email protected] 6

Решение задач инвентаризации в сетиИнвентаризация аппаратного обеспечения рабочих стан-ций в сети, построенной на основе Windows 2000/XP.Иван Коробко[email protected] 26

Крепость для пингвинаОбзор и установка Bastille Linux – утилиты, позволяю-щей улучшить и укрепить безопасность Linux-системы.Сергей Яремчук[email protected] 40

Учет работы Dialup-пользователейв системе FreeBSD

Общие принципы решения задачи.Сергей Супрунов[email protected] 44

Осваиваем NagiosРусификация веб-интерфейса, описание процедурыинсталляции дополнительного программного обеспе-чения, необходимого для работы с плоской и трехмер-ной картами сети, создание иконок хостов и сервисов,настройка иерархии хостов и многое другое.Андрей Бешков[email protected] 48

HARDWARE

Вторая жизнь модемовСпособы использования модемов, внутреннее устрой-ство постоянной памяти, программирование микро-схем flash-памяти с помощью модема Acorp, заменаверсий в модемах ZyXEL 1496, подключение 3-х моде-мов, развод используемых прерываний и настройка вОС Linux.Павел Закляков[email protected] 62

Конвертирование из Excel в HTML:корректно, качественно, просто

Идеи для корректного конвертирования документов изформата xls в формат HTML с учетом форматирова-ния исходных документов.Алексей Мичурин[email protected] 76

WEB

ОБРАЗОВАНИЕ

LTSP – вторая жизнь старых компьютеровИспользование инструмента LTSP (Linux Terminal ServerProekt) для решения вопроса загрузки бездисковыхтерминалов.Сергей Яремчук[email protected] 84

Содержание журнала за 2003 год 92

Page 4: 013 Системный Администратор 12 2003

2

календарь событий

Портал SysAdmins.RU объявляет о проведении второгоСеминара системных администраторов и инженеров иприглашает специалистов принять участие в меропри-ятии, которое обещает быть плодотворным и информа-тивным.

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

Далее состоится учредительное собрание «Профсою-за специалистов в области информационных технологий»,будут проведены выборы Правления профсоюза и выра-ботана программа действий профсоюза на 2004 год.

Опыт проведения первого Семинара показал, чтоданное мероприятие вызывает живейший интерес спе-циалистов IT-индустрии – системных и сетевых адми-нистраторов, инженеров, IT-аналитиков, IT-директорови менеджеров. Можно утверждать, что активные и пло-

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

С материалами выступлений можно будет ознакомить-ся в ближайших номерах журнала и на официальном сайтеСеминара: http://SYSM.ru

С материалами профсоюза, Уставом, Положениями,протоколами собраний и программой действий можноознакомиться на официальном сайте профсоюза IT-спе-циалистов: http://ITCU.ru

Семинар состоится в субботу, 20 декабря 2003 года вочень уютном и удобном месте – Доме ветеранов кино(ДВК) по адресу: г. Москва, ул. Нежинская, 5. (От м. Киев-ская на маршрутном такси №7 до остановки «Дом Вете-ранов Кино»).

Регистрация участников второго Семинара на сайте:http://SYSM.ru

Стоимость участия 600 рублей.

SYSM.0220 декабря 2003 года, г. Москва

Page 5: 013 Системный Администратор 12 2003

3№12(13), декабрь 2003

календарь событий

Впервые в России появится общественная организация,которая объединит под своим началом всех IT-специали-стов, – Межрегиональный Профессиональный союз спе-циалистов в области информационных технологий. Этаидея уже давно обсуждалась в различных интернет-из-даниях и на профессиональных конференциях. Теперь оначётко сформировалась и стала реальностью. Странно, нов нашей стране до сих пор не было такого сообщества!Ведь профсоюзы есть у всех – от врачей до журналистов.Профсоюз представляет собой сообщество специалистов,объединённых общими профессиональными интересамии ставит перед собой цель создать организацию, котораябудет решать проблемы различного характера, такие какзащита прав IT-специалистов, помощь в трудоустройстве,совершенствование профессиональных навыков, повы-

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

Учредительное собрание Межрегионального Профес-сионального союза специалистов в области информаци-онных технологий пройдёт 20 декабря 2003 на СеминареSYSM.02 (http://SYSM.ru).

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

Самое главное – участники Семинара первыми полу-чат возможность стать членами профсоюза.

Общие положенияÏðîôåññèîíàëüíûé ñîþç ñïåöèàëèñòîâ â îáëàñòè èíôîðìàöèîííûõ òåõ-íîëîãèé, èìåíóåìûé â äàëüíåéøåì «Ïðîôñîþç», ÿâëÿåòñÿ äîáðîâîëü-íûì ñàìîóïðàâëÿåìûì íåêîììåð÷åñêèì ôîðìèðîâàíèåì, îñíîâàííûì íà÷ëåíñòâå è ñîçäàííûì ïî èíèöèàòèâå ãðàæäàí, ñâÿçàííûõ îáùèìèïðîèçâîäñòâåííûìè, ïðîôåññèîíàëüíûìè èíòåðåñàìè ïî ðîäó èõ äåÿ-òåëüíîñòè.

Ïðîôñîþç îáúåäèíÿåò ëèö, ðàáîòàþùèõ â îáëàñòè èíôîðìàöèîííûõòåõíîëîãèé, à òàêæå ó÷àùèõñÿ è ñòóäåíòîâ ó÷åáíûõ çàâåäåíèé, îáó-÷àþùèõñÿ ïî ñîîòâåòñòâóþùèì ñïåöèàëüíîñòÿì.

Цели и задачи профсоюза� Çàùèùàòü ïðàâà è èíòåðåñû ÷ëåíîâ ïðîôñîþçà ïî âîïðîñàì èíäè-

âèäóàëüíûõ òðóäîâûõ è ñâÿçàííûõ ñ òðóäîì îòíîøåíèé.� Âûñòóïàòü ñ ïðåäëîæåíèÿìè î ïðèíÿòèè ñîîòâåòñòâóþùèìè îðãàíà-

ìè ãîñóäàðñòâåííîé âëàñòè çàêîíîâ è íîðìàòèâíûõ ïðàâîâûõ àê-òîâ, êàñàþùèõñÿ ñîöèàëüíî-òðóäîâîé ñôåðû, à òàêæå èíôîðìàöè-îííûõ òåõíîëîãèé.

� Çàùèùàòü ïðàâà ñâîèõ ÷ëåíîâ ñâîáîäíî ðàñïîðÿæàòüñÿ ñâîèìè ñïî-ñîáíîñòÿìè ê òðóäó, à òàêæå ïðàâî íà âîçíàãðàæäåíèå çà òðóäáåç êàêîé áû òî íè áûëî äèñêðèìèíàöèè, â òîì ÷èñëå ïî ïîëîâîìóïðèçíàêó.

� Ñîãëàñîâûâàòü ñèñòåìû îïëàòû òðóäà, ôîðìû ìàòåðèàëüíîãî ïîîù-ðåíèÿ, ðàçìåðû òàðèôíûõ ñòàâîê, à òàêæå íîðìû òðóäà ñ ðàáîòî-äàòåëÿìè è óïîëíîìî÷åííûìè ãîñóäàðñòâåííûìè îðãàíàìè è çàê-ðåïëÿòü ñîîòâåòñòâóþùèå ïîëîæåíèÿ â êîëëåêòèâíûõ äîãîâîðàõ èèíûõ äîêóìåíòàõ.

� Ó÷àñòâîâàòü â ðàññìîòðåíèè îðãàíàìè ãîñóäàðñòâåííîé âëàñòè,îðãàíàìè ìåñòíîãî ñàìîóïðàâëåíèÿ, ðàáîòîäàòåëÿìè, èõ îáúåäè-íåíèÿìè ñâîèõ ïðåäëîæåíèé.

� Ó÷àñòâîâàòü â óðåãóëèðîâàíèè êîëëåêòèâíûõ òðóäîâûõ ñïîðîâ,îðãàíèçîâûâàòü è ïðîâîäèòü â ñîîòâåòñòâèè ñ ôåäåðàëüíûì çàêî-íîì çàáàñòîâêè, ìèòèíãè, äåìîíñòðàöèè è äðóãèå êîëëåêòèâíûåäåéñòâèÿ, èñïîëüçóÿ èõ êàê ñðåäñòâî çàùèòû ñîöèàëüíî-òðóäîâûõïðàâ è èíòåðåñîâ ðàáîòíèêîâ.

� Îñóùåñòâëÿòü ïðîôñîþçíûé êîíòðîëü çà ñîáëþäåíèåì ðàáîòîäàòå-ëÿìè, äîëæíîñòíûìè ëèöàìè çàêîíîäàòåëüñòâà î òðóäå è òðåáî-âàòü óñòðàíåíèÿ âûÿâëåííûõ íàðóøåíèé.

� Îñóùåñòâëÿòü îáó÷åíèå, ïîäãîòîâêó, ïåðåïîäãîòîâêó è ïîâûøåíèåêâàëèôèêàöèè ÷ëåíîâ ïðîôñîþçà.

� Îñóùåñòâëÿòü þðèäè÷åñêóþ è èíóþ ïîääåðæêó.

Членство в профсоюзе×ëåíîì ïðîôñîþçà ìîæåò áûòü ëþáîé ãðàæäàíèí ÐÔ, äîñòèãøèé 14-ëåòíåãî âîçðàñòà, ïðèçíàþùèé è âûïîëíÿþùèé Óñòàâ ïðîôñîþçà,ðåãóëÿðíî óïëà÷èâàþùèé ÷ëåíñêèå âçíîñû ïðîôñîþçó è ñâÿçàííûéîáùèìè ïðîèçâîäñòâåííûìè è(èëè) ïðîôåññèîíàëüíûìè èíòåðåñàìè ñèíôîðìàöèîííûìè òåõíîëîãèÿìè, ðàáîòàþùèé â îáëàñòè èíôîðìàöè-îííûõ òåõíîëîãèé, ïåíñèîíåð, à òàêæå ó÷àùèéñÿ èëè ñòóäåíò ó÷åá-íîãî çàâåäåíèÿ, îáó÷àþùèéñÿ ïî ñîîòâåòñòâóþùåé ñïåöèàëüíîñòè.

×ëåíû ïðîôñîþçà èìåþò ïðàâî:� Ó÷àñòâîâàòü â óïðàâëåíèè ïðîôñîþçîì â ñîîòâåòñòâèè ñ íàñòîÿ-

ùèì Óñòàâîì.� Èçáèðàòü è áûòü èçáðàííûìè â ðóêîâîäÿùèå è êîíòðîëüíî-ðåâèçè-

îííûå îðãàíû.� Êîíòðîëèðîâàòü äåÿòåëüíîñòü ðóêîâîäÿùèõ îðãàíîâ ïðîôñîþçà.� Ó÷àñòâîâàòü â ìåðîïðèÿòèÿõ è ïðîãðàììàõ ïðîôñîþçà.� Âíîñèòü íà ðàññìîòðåíèå ðóêîâîäÿùèõ îðãàíîâ ïðåäëîæåíèÿ ïî

âîïðîñàì äåÿòåëüíîñòè ïðîôñîþçà.� Ïîëó÷àòü íåîáõîäèìóþ èíôîðìàöèþ î äåÿòåëüíîñòè ïðîôñîþçà.� Èñïîëüçîâàòü ìàòåðèàëüíî-òåõíè÷åñêóþ áàçó ïðîôñîþçà.� Ñîñòîÿòü ÷ëåíîì êàññû âçàèìîïîìîùè (êðåäèòíî-ïîòðåáèòåëüñêîãî

ñîþçà).� Ïîëó÷àòü áåñïëàòíóþ þðèäè÷åñêóþ ïîìîùü, îêàçûâàåìóþ ïðîôñîþçîì.

×ëåíû ïðîôñîþçà îáÿçàíû:� Ñîáëþäàòü íàñòîÿùèé Óñòàâ.� Âûïîëíÿòü ðåøåíèÿ ñîáðàíèÿ, Ïðàâëåíèÿ è ïðåäñåäàòåëÿ Ïðàâëåíèÿ.� Ïëàòèòü ÷ëåíñêèå âçíîñû.� Àêòèâíî ñîäåéñòâîâàòü ðåøåíèþ ñòîÿùèõ ïåðåä ïðîôñîþçîì çàäà÷

ñâîèìè òåõíè÷åñêèìè, èíòåëëåêòóàëüíûìè è äðóãèìè ðåñóðñàìè.� Âîçäåðæèâàòüñÿ îò äåéñòâèé, êîòîðûå ìîãóò íàíåñòè óùåðá çà-

êîííûì èíòåðåñàì ïðîôñîþçà è åãî ÷ëåíîâ.

Структура и управление организациейÐóêîâîäñòâî ïðîôñîþçîì îñóùåñòâëÿþò: ñîáðàíèå, Ïðàâëåíèå è ïðåä-ñåäàòåëü Ïðàâëåíèÿ.

Ñîáðàíèå ïðîôñîþçà – âûñøèé îðãàí óïðàâëåíèÿ, ïðàâîìî÷íûé ïðè-íèìàòü ðåøåíèÿ ïî âñåì âîïðîñàì äåÿòåëüíîñòè ïðîôñîþçà. Ñîáðàíèåïðîôñîþçà ñîçûâàåòñÿ ïî ìåðå íåîáõîäèìîñòè, íî íå ðåæå îäíîãîðàçà â 2 ãîäà.

Ïðàâëåíèå – îðãàí, ðóêîâîäÿùèé äåÿòåëüíîñòüþ ïðîôñîþçà â ïåðèîäìåæäó ñîáðàíèÿìè. Ïðàâëåíèå èçáèðàåòñÿ ñîáðàíèåì ïðîôñîþçà èç ÷èñëà÷ëåíîâ ïðîôñîþçà. Ïðàâëåíèå äåéñòâóåò íà îñíîâàíèè Ïîëîæåíèÿ î Ïðàâ-ëåíèè, ïðèíÿòûì íà Îáùåì ñîáðàíèè ïðîôñîþçà. Çàñåäàíèÿ Ïðàâëåíèÿïðîâîäÿòñÿ ïî ìåðå íåîáõîäèìîñòè, íî íå ðåæå îäíîãî ðàçà â êâàðòàë.

Ïðåäñåäàòåëü Ïðàâëåíèÿ èçáèðàåòñÿ Ïðàâëåíèåì èç ÷èñëà ÷ëåíîâÏðàâëåíèÿ.

Ïðåäñåäàòåëü Ïðàâëåíèÿ ïîäîò÷åòåí ñîáðàíèþ è Ïðàâëåíèþ, îðãà-íèçóåò âûïîëíåíèå ðåøåíèé ñîáðàíèÿ è Ïðàâëåíèÿ.

Ïåðâè÷íàÿ ïðîôñîþçíàÿ îðãàíèçàöèÿ – îñíîâà ñòðóêòóðû Ïðîôñîþ-çà – äîáðîâîëüíîå îáúåäèíåíèå íå ìåíåå 3-õ ÷ëåíîâ ïðîôñîþçà,äåéñòâóþùåå íà îñíîâàíèè Ïîëîæåíèÿ, ïðèíÿòîãî èì â ñîîòâåòñòâèèñ íàñòîÿùèì Óñòàâîì, èëè íà îñíîâàíèè îáùåãî Ïîëîæåíèÿ î ïåðâè÷-íîé îðãàíèçàöèè ïðîôñîþçà, óòâåðæäåííîãî Ïðàâëåíèåì ïðîôñîþçà.Âûñøèì îðãàíîì ïåðâè÷íîé ïðîôñîþçíîé îðãàíèçàöèè ÿâëÿåòñÿ ñîáðà-íèå åå ÷ëåíîâ. Ðàáîòíèêè îäíîãî ïðåäïðèÿòèÿ, ó÷ðåæäåíèÿ, îðãà-íèçàöèè, ó÷àùèåñÿ è ïðåïîäàâàòåëè ó÷åáíûõ çàâåäåíèé îáúåäèíÿþò-ñÿ, êàê ïðàâèëî, â îäíó ïåðâè÷íóþ ïðîôñîþçíóþ îðãàíèçàöèþ.

Резюме Устава Профсоюза

ПРОФСОЮЗ IT-СПЕЦИАЛИСТОВОфициальный сайт : http://ITCU.ru

Page 6: 013 Системный Администратор 12 2003
Page 7: 013 Системный Администратор 12 2003
Page 8: 013 Системный Администратор 12 2003

6

программирование

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

КРИС КАСПЕРСКИ

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

2. Запросы операционной системы к ошибкамошибками могут игнорироваться.

3. Запросы ошибок к операционной системеигнорироваться не могут.

4. При работе с файлами ошибки могут пользоватьсяфайловой системой базовой ОС и ее ошибками.

5. На ЭВМ с параллельной архитектурой можетвыполняться несколько ошибок одновременно.

В. Тихонов «Теория ошибок»

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

Page 9: 013 Системный Администратор 12 2003

7№12(13), декабрь 2003

программирование

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

Вообще-то хорошо отлаженная система, базирующа-яся на ОС типа FreeBSD (или подобной ей), способна безсбоев работать годами, не требуя к себе совершенно ни-какого внимания. Системы, построенные на базеWindows NT, этим, увы, похвастаться не могут, и для дос-тижения сколь-нибудь стабильной работы за ними прихо-дится постоянно ухаживать.

Аппаратное обеспечение, собираемое на коленках вближайшем подвале, также не отличается высокой надеж-ностью, а отличить качественную подделку от оригиналапо внешним признакам достаточно трудно. На просторахРоссии свободно продаются отбракованные чипы, левымпутем добытые у производителей и выдаваемые за насто-ящие. Кстати, многие из именитых производителей грешатпередачей своих торговых марок третьим фирмам, выпус-кающим довольно посредственное оборудование, но про-дающих его по «брэндовским» ценам. Яркий тому пример –пишущий привод TEAC 552E, к которому фирма TEAC во-обще не имеет никакого отношения. Про материнские пла-ты и модули памяти вообще говорить не стоит. Их клепаютвсе кому не лень, и многие модели вообще не работают,кое-как запускаясь на пониженных таймингах и частотах.

Словом, если сбой старушки БЭСМ-6 был настоящимЧП, то зависание современного сервера – вполне обычноедело, воспринимаемое администраторами как неизбежноезло. Эта статья не убережет вас ни от критических ошибокприложений, ни от отказа оборудования, но, по крайнеймере, научит быстро и безошибочно находить их источник.Речь пойдет преимущественно о Windows NT и производ-ных от нее системах (Windows 2000, Windows XP), хотя по-клонники UNIX также найдут здесь немало интересного.

Аппаратная частьВот два основных аппаратных виновника нестабильнойработы системы – оперативная память и блок питания.Рассмотрим их поподробнее, отмечая особенности взаи-модействия с памятью в современных чипсетах, таких какIntel 875P и подобных ему.

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

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

Оперативная памятьОперативная память относится к одному из наименее на-дежных компонентов вычислительной системы, и потомульвиная доля всех сбоев приходится именно на нее. Прояв-ления их могут быть самыми разнообразными: от критичес-ких ошибок приложений до периодических или непериоди-ческих ошибок чтения (записи) на жесткий диск или дажекаскадных ошибок приема/передачи TCP/IP-пакетов (что непокажется удивительным, если вспомнить о кэширующемприводе всех драйверов, обслуживающих устройства вво-да/вывода). Любой аппаратный ресурс, требующий для сво-ей работы некоторого количества оперативной памяти, такили иначе зависим от работоспособности последней.

Существует мнение, что память «с четностью» полнос-тью решает проблему своей надежности и сводит риск раз-рушения данных к разумному минимуму. На самом деле этоне так. Память с четностью распознает лишь одиночныеошибки и не гарантирует обнаружение групповых. Памятьтипа ECC (Error Check & Correction/Error Correction Code –Контроль и Исправление Ошибок), способна автоматичес-ки исправлять любые одиночные ошибки и обнаруживатьлюбые двойные. До тех пор, пока оперативная память фун-кционирует более или менее нормально, противостояниеэнтропии и помехозащитных кодов решается в пользу пос-ледних. Однако при полном или частичном выходе одногоили нескольких модулей памяти из строя корректирующихспособностей контролирующих кодов перестает хватать, исистема начинает работать крайне нестабильно.

Концепция виртуальной памяти, реализованная в опе-рационных системах семейства Windows и UNIX, рассмат-ривает основную оперативную память как своеобразныйкэш. А это значит, что одни и те же логические страницыадресного пространства в разное время могут отображать-ся на различные физические адреса. Разрушение одной-единственной физической ячейки памяти затрагивает мно-жество виртуальных ячеек, и потому сбои памяти практи-чески всегда проявляются «коллективными» критически-ми ошибками приложений, рассредоточенными в широкомдиапазоне адресов. Если же критические ошибки возни-кают лишь в некоторых процессах и располагаются по бо-лее или менее постоянным адресам – с высокой степеньювероятности можно предположить, что это программная, ане аппаратная ошибка. Исключение составляет неоткачи-ваемая область памяти (non-paged pool), занятая ядромсистемы и всегда размещающаяся по одним и тем же фи-зическим адресам. Наличие дефективных ячеек в даннойобласти обычно приводит к синему экрану смерти и/илиполному зависанию системы, хотя в некоторых случаяхошибки драйверов передаются на прикладной уровень ироняют один или несколько процессов.

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

Page 10: 013 Системный Администратор 12 2003

8

программирование

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

Худший случай – это разрушение буферов ввода/вы-вода, зачастую приводящее к полному краху файловойсистемы без какой-либо надежды на ее восстановление.По непонятной причине разработчики дисковых драйверовотказались от подсчета контрольной суммы пересылаемыхчерез них блоков данных, что сделало файловую системучрезвычайно уязвимой. Причем NTFS оказывается даже вхудшей ситуации, чем FAT32, поскольку требует значитель-но меньшего объема буферной памяти для своей поддер-жки и к тому же значительно легче поддается «ручному»восстановлению. Автор настоящей статьи использует от-казоустойчивые буфера, построенные на основе демонст-рационных драйверов, входящих в состав DDK, и допол-ненные специальными средствами контроля. Главное ноу-хау данной технологии состоит в том, что обмен с дискомведется на «сыром» (RAW MODE) уровне, т.е. помимо об-ласти пользовательских данных в сектор входит конт-рольная сумма, по которой драйвер с одной и привод сдругой стороны контролируют целостность данных. В жиз-ни автора эта технология срабатывала дважды (т.е. выяв-ляла дефективный модуль памяти, пытавшийся разрушитьжесткий диск), так что усилия, затраченные на разработкудрайверов, многократно окупили себя сполна!

Кстати, тестирование оперативной памяти путем про-гона специальных программ (Check It, PC Diagnostic и имподобных) – не самый лучший путь для выявления ее ра-ботоспособности. В силу физической неоднородности под-системы памяти дефективность бракованных модулей за-частую проявляется не на любой, а на строго определен-ной последовательности запросов и при определенномсочетании содержимого разрушенной и окрестных яче-ек. Тестирующие программы перебирают ограниченноеколичество наиболее типичных шаблонов и потому обна-руживают лишь некоторые, наиболее дефективные де-фекты. Ряд серверных чипсетов содержит в себе болееили менее продвинутые средства тестирования памяти,работающие в фоновом режиме и работающие достаточ-но эффективно.

Ряд тестовых пакетов, таких, например, как TestMemот SERJ_M, перебирают большое количество разнотип-ных шаблонов и довольно лихо выявляют скрытые дефек-ты модулей памяти, в обычной жизни проявляющиесялишь при стечении множества маловероятных обстоя-тельств. К сожалению, эволюция чипсетов в конце кон-цов привела к тому, что и эти шаблоны перестали рабо-тать. При слишком интенсивном обмене с памятью чипсетIntel 875P и другие подобные ему чипсеты начинают встав-лять холостые циклы, давая памяти время «остыть», пре-дотвращая тем самым ее перегрев. С одной стороны, та-кое конструкторское решение можно только приветство-вать, поскольку оно значительно повышает надежностьсистемы, но с другой – чрезвычайно затрудняет ее тес-тирования. Для получения сколь-нибудь достоверных ре-зультатов тестирующая программа должна подобрать та-кую интенсивность прогона памяти, при которой холостыециклы еще не вставляются, но система работает уже напределе. Насколько известно автору, подобных программеще нет и когда они появятся на рынке – неизвестно. Такчто спасение утопающих – забота самих утопающих.

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

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

Практически все уважающие себя производители ма-теринских плат оснащают свои детища развитой элект-ронной системой контроля основных (опорных) напряже-ний, показания которых отображаются специальными ути-литами. Убедитесь, что питающий потенциал соответству-ет норме, отклонясь от нее не более чем на 5-10%, и ос-тается более или менее постоянным в процессе работыкомпьютера. Причем «недобор» напряжения намного бо-лее опасен, чем «перебор». Увеличение потенциала на15-20% практически никогда не приводит к моментально-му выходу электроники из строя, правда, вызывает ее пе-регрев, но при наличии качественной системы охлажде-ния с этим можно и смириться. Но даже незначительноеуменьшение потенциала заметно снижает реакционностьпереходных процессов полупроводниковых элементов, исистема не успевает поспевать за тактовой частотой, чтоприводит к зависаниям, критическим ошибкам, перезаг-рузкам и т. д.

Page 11: 013 Системный Администратор 12 2003

9№12(13), декабрь 2003

программирование

На рисунке 1 приведен плохой блок питания, обнару-живающий значительную просадку на линии 12 вольт ичудовищные пульсации напряжения. Линия 3.3 вольт, об-служивающая святую святых – оперативную память, так-же слегка пульсирует, хотя стабилизируется отнюдь неблоком питания, но самой материнской платой, пределстабилизации которой, впрочем, тоже небезграничен, идаже качественная материнская плата бессильна выпра-вить кривой от рождения блок питания.

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

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

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

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

Программная частьКатастрофическая небрежность тестирования фирменно-го и кустарного ПО приводит к появлению многочислен-ных критических ошибок при его исполнении: «Програм-ма выполнила недопустимую операцию и будет закрыта.

Если ошибка будет повторяться, обратитесь к разработ-чику». К несчастью, критические ошибки приложения (втерминологии Windows 2000 просто «ошибки приложе-ния») имеют устойчивую тенденцию появляться в самыеответственные моменты времени, например, наканунесдачи финансового отчета. А разработчики… они в боль-шинстве своем такие сообщения просто игнорируют.Иногда потому, что просто не знают, как эту информа-цию интерпретировать, иногда потому, что вообще не за-ботятся о проблемах своих пользователей.

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

Иногда сообщения о критических ошибках удается пре-дотвратить установкой нового сервис-пака, а иногда, на-оборот, – путем удаления нового. Еще можно попробоватьпереустановить операционную систему или только само не-стабильно работающее приложение. Однако никаких га-рантий, что после всех этих манипуляций сбой действитель-но у вас исчезнет, нет. Достаточно вспомнить нашумев-шую историю с червем MSBLASTER, вызывающим крити-ческую ошибку в системном сервисе svchost. Но сколькобы вы ни переустанавливали свою Windows 2000, сколькобы ни меняли железо, ситуация не улучшалась. Антивиру-сы, правда, сообщали о наличии вируса на компьютере (даи то не всегда), однако не объясняли, какие меры безопас-ности следует принять. К тому же обрушение сервисаsvchost происходило отнюдь не вследствие инфицирова-ния компьютера вирусом, а лишь при неудачной попыткеоного. Именно неумение хакеров сорвать стек, не уронивпри этом всю систему, и демаскировало вирус, попутноорганизовав разрушительную DoS-атаку, до сих пор при-носящую весьма ощутимые убытки.

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

Приложения,недопустимые операциии все-все-всеРазличные операционные системы по-разному реагиру-ют на критические ошибки. Так, например, Windows NTрезервирует два региона своего адресного пространствадля выявления некорректных указателей. Один находит-

Ðèñóíîê 1. Ïðèìåð ïëîõîãî áëîêà ïèòàíèÿ

Page 12: 013 Системный Администратор 12 2003

10

программирование

ся на самом «дне» карты памяти и предназначен для от-лавливания нулевых указателей. Другой расположен меж-ду «кучей» и областью памяти, закрепленной за опера-ционной системой. Он контролирует выход за пределыпользовательской области памяти и, вопреки расхожемумнению, никак не связан в функцией WriteProcessMemory(см. техническую заметку ID: Q92764 в MSDN). Оба ре-гиона занимают по 64 Кб, и всякая попытка доступа кним расценивается системой как критическая ошибка.В Windows 9x имеется всего лишь один 4 Кб регион, сле-дящий за нулевыми указателями, поэтому по своим конт-ролирующим способностям она значительно уступает NT.

В Windows NT экран критической ошибки (см. рис. 2)содержит следующую информацию:� адрес машинной инструкции, возбудившей исключение;� словесное описание категории исключения (или его

код, если категория исключения неизвестна);� параметры исключения (адрес недействительной ячей-

ки памяти, род операции и т. д.).

Операционные системы семейства Windows 9x в этомотношении намного более информативны (см. рис. 3) ипомимо категории исключения выводят содержимое ре-гистров ЦП на момент сбоя, состояние стека и байты па-мяти по адресу CS:EIP (т.е. текущему адресу исполне-ния). Впрочем, наличие «Доктора Ватсона» (о нем – да-лее) стирает различие между двумя системами, и пото-му можно говорить лишь об удобстве и эргономике 9x,сразу предоставляющей весь минимум необходимых све-дений, в то время как в NT отчет об ошибке создаетсяотдельной утилитой.

Если никакой из отладчиков в системе не установ-лен, то окно о критической ошибке имеет всего лишьодну кнопку – кнопку «ОК», нажатие которой приводитк аварийному закрытию политнекорректного приложе-ния. При желании окно критической ошибки можно ос-настить кнопкой «Отмена» («Cancel»), запускающей от-ладчик или иную утилиту анализа ситуации. Важно по-нять, что «Отмена» отнюдь не отменяет автоматическоезакрытие приложения, но при некоторой сноровке выможете устранить «пробоину» вручную, продолжив нор-мальную работу1.

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

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

Для установки «Доктора Ватсона» отладчиком поумолчанию добавьте в реестр следующую запись или за-пустите файл Drwtsn32.exe c ключом «–i» (для выполне-ния обоих действий вы должны иметь права админист-ратора):

Ðèñóíîê 2. Ñîîáùåíèå î êðèòè÷åñêîé îøèáêå, âûäàâàåìîå îïå-ðàöèîííîé ñèñòåìîé Windows 2000

Ðèñóíîê 3. Ñîîáùåíèå î êðèòè÷åñêîé îøèáêå, âûäàâàåìîå îïå-ðàöèîííîé ñèñòåìîé Windows 98

1 Запустите «Редактор Реестра» и перейдите в раздел «HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug».Если такого раздела нет – создайте его самостоятельно. Строковой параметр «Debugger» задает путь к файлу отладчи-ка со всеми необходимыми ключами; строковой параметр «Auto» указывает, должен ли отладчик запускаться автомати-чески (значение «1») или предлагать пользователю свободу выбора («0»). Наконец двойное слово параметра«UserDebuggerHotKey» специфицирует скэн-код горячей клавиши для принудительного вызова отладчика.

Ëèñòèíã 1. Óñòàíîâêà «Äîêòîðà Âàòñîíà» îòëàä÷èêîì ïî óìîë÷àíèþ

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ ↵

CurrentVersion\AeDebug]"Auto"="1""Debugger"="drwtsn32 -p %ld -e %ld -g""UserDebuggerHotKey"=dword:00000000

Page 13: 013 Системный Администратор 12 2003

11№12(13), декабрь 2003

программирование

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

Образец дампа, созданный «Доктором Ватсоном», при-веден ниже. Комментарии, добавленные автором, выде-лены красным цветом:

Ðèñóíîê 4. Ðåàêöèÿ «Äîêòîðà Âàòñîíà» íà êðèòè÷åñêóþ îøèáêó

Ëèñòèíã 2. Îáðàçåö îò÷åòà «Äîêòîðà Âàòñîíà»

Èñêëþ÷åíèå â ïðèëîæåíèè:Ïðèë.: (pid=612); pid ïðîöåññà, â êîòîðîì ïðîèçîøëî èñêëþ÷åíèå.

Âðåìÿ: 14.11.2003 @ 22:51:40.674; Âðåìÿ, êîãäà ïðîèçîøëî èñêëþ÷åíèå.

Íîìåð: c0000005 (íàðóøåíèå ïðàâ äîñòóïà); Êîä êàòåãîðèè èñêëþ÷åíèÿ.; Ðàñøèôðîâêó êîäîâ èñêëþ÷åíèé ìîæíî íàéòè â WINNT.H; âõîäÿùèì â ñîñòàâ SDK, ïðèëàãàåìîì ê ëþáîìó; Windows-êîìïèëÿòîðó. Ïîäðîáíîå îïèñàíèå âñåõ èñêëþ÷åíèé; ñîäåðæèòñÿ â äîêóìåíòàöèè ïî ïðîöåññîðàì Intel è AMD,; áåñïëàòíî ðàñïðîñòðàíÿåìîé èõ ïðîèçâîäèòåëÿìè (âíèìàíèå:; äëÿ ïåðåâîäà êîäà èñêëþ÷åíèÿ îïåðàöèîííîé ñèñòåìû â; âåêòîð ïðåðûâàíèÿ ÖÏ, âû äîëæíû îáíóëèòü ñòàðøåå ñëîâî),; â äàííîì ñëó÷àå ýòî 0x5 – ïîïûòêà äîñòóïà ê ïàìÿòè; ïî çàïðåùåííîìó àäðåñó.

*----> Ñâåäåíèÿ î ñèñòåìå <----*Èìÿ êîìïüþòåðà: KPNCÈìÿ ïîëüçîâàòåëÿ: Kris Kaspersky×èñëî ïðîöåññîðîâ: 1Òèï ïðîöåññîðà: x86 Family 6 Model 8 Stepping 6Âåðñèÿ Windows 2000: 5.0Òåêóùàÿ ñáîðêà: 2195Ïàêåò îáíîâëåíèÿ: NoneÒåêóùèé òèï: Uniprocessor FreeÇàðåãèñòðèðîâàííàÿ îðãàíèçàöèÿ:Çàðåãèñòðèðîâàííûé ïîëüçîâàòåëü: Kris Kaspersky; Êðàòêèå ñâåäåíèÿ î ñèñòåìå.

*----> Ñïèñîê çàäà÷ <----* 0 Idle.exe 8 System.exe 232 smss.exe…1244 os2srv.exe1164 os2ss.exe1284 windbg.exe1180 MSDEV.exe1312 cmd.exe 612 test.exe1404 drwtsn32.exe 0 _Total.exe

(00400000 - 00406000)(77F80000 - 77FFA000)(77E80000 - 77F37000); Ïåðå÷åíü çàãðóæåííûõ DLL.; Ñîãëàñíî äîêóìåíòàöèè, ñïðàâà îò àäðåñîâ äîëæíû áûòü; ïåðå÷èñëåíû èìåíà ñîîòâåòñòâóþùèõ ìîäóëåé, îäíàêî; ïðàêòè÷åñêè âñå îíè òàê õîðîøî «çàìàñêèðîâàëèñü», ÷òî ñòàëè; ñîâåðøåííî íå âèäíû. Âûòàùèòü èõ èìåíà èç ôàéëà ïðîòîêîëà; âñå-òàêè ìîæíî, íî ïðèäåòñÿ íåìíîãî «ïîøàìàíèòü» (ñì. íèæå; «òàáëèöó ñèìâîëîâ»).

Êîïèÿ ïàìÿòè äëÿ ïîòîêà 0x188; Íèæå èäåò êîïèÿ ïàìÿòè ïîòîêà, âûçûâàâøåãî èñêëþ÷åíèå.

eax=00000064 ebx=7ffdf000 ecx=00000000 edx=00000064 ↵

esi=00000000 edi=00000000eip=00401014 esp=0012ff70 ebp=0012ffc0 iopl=0 ↵

nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 ↵

efl=00000202; Ñîäåðæèìîå ðåãèñòðîâ è ôëàãîâ.

ôóíêöèÿ: <nosymbols>; Ðàñïå÷àòêà îêðåñòíîé òî÷êè cáîÿ.

00400ffc 0000 add [eax],al ds:00000064=??; Çàïèñûâàåì â ÿ÷åéêó, íà êîòîðóþ ññûëàåò EAX, çíà÷åíèå AL.; Çíà÷åíèå àäðåñà ÿ÷åéêè, âû÷èñëåííîé Äîêòîðîì Âàòñîíîì,; ðàâíî 64h, ÷òî, î÷åâèäíî, íå ñîîòâåòñòâóåò; äåéñòâèòåëüíîñòè. «Äîêòîð Âàòñîí» ïîäñòàâëÿåò â âûðàæåíèå; çíà÷åíèå ðåãèñòðà EAX íà ìîìåíò âîçíèêíîâåíèÿ ñáîÿ,; è ýòî ñîâñåì íå òî çíà÷åíèå, êîòîðîå áûëî â ìîìåíò; èñïîëíåíèÿ! Ê ñîæàëåíèþ, ÷åìó áûë ðàâåí EAX â ìîìåíò; èñïîëíåíèÿ íè íàì, íè «Äîêòîðó Âàòñîíó» íå èçâåñòåí.

00400ffe 0000 add [eax],al ds:00000064=??; Çàïèñûâàåì â ÿ÷åéêó, íà êîòîðóþ ññûëàåò EAX, çíà÷åíèå AL.; Êàê? Îïÿòü? Âîîáùå-òî òàê êîäèðóåòñÿ ïîñëåäîâàòåëüíîñòü; 00 00 00 00, ïî âñåé âèäèìîñòè ÿâëÿþùàÿñÿ îñêîëêîì; íåêîòîðîé ìàøèííîé êîìàíäû, íåïðàâèëüíî; èíòåðïðåòèðîâàííîé äèçàññåìáëåðíûì äâèæêîì; «Äîêòîðà Âàòñîíà».

00401000 8b542408 mov edx,[esp+0x8] ss:00f8d547=????????; Çàãðóæàåì â EDX àðãóìåíò ôóíêöèè.; Êàêîé èìåííî àðãóìåíò – ñêàçàòü íåâîçìîæíî, ò.ê. ìû íå; çíàåì àäðåñ ñòåêîâîãî ôðåéìà.

00401004 33c9 xor ecx,ecx; Îáíóëÿåì ECX

00401006 85d2 test edx,edx00401008 7e18 jle 00409b22; Åñëè EDX == 0, ïðûãàåì íà àäðåñ 409B22h.

0040100a 8b442408 mov eax,[esp+0x8] ss:00f8d547=????????; Çàãðóæàåì óæå óïîìÿíóòûé àðãóìåíò â ðåãèñòð EAX.

0040100e 56 push esi; Ñîõðàíÿåì ESI â ñòåêå, ïåðåìåùàÿ òåì ñàìûì óêàçàòåëü; âåðøèíû ñòåêà íà 4 áàéòà ââåðõ (â îáëàñòü ìëàäøèõ; àäðåñîâ).

0040100f 8b742408 mov esi, [esp+0x8] ss:00f8d547=????????; Çàãðóæàåì â ESI î÷åðåäíîé àðãóìåíò.; Ïîñêîëüêó ESP áûë òîëüêî ÷òî èçìåíåí, ýòî ñîâñåì íå òîò; àðãóìåíò, ñ êîòîðûì ìû èìåëè äåëî ðàíåå.

00401013 57 push edi; Ñîõðàíÿåì ðåãèñòð EDI â ñòåêå.

ÑÁÎÉ -> 00401014 0fbe3c31 movsx edi,byte ptr [ecx+esi] ↵

ds:00000000=??; Âîò ìû è äîáðàëèñü äî èíñòðóêöèè, âîçáóäèâøåé èñêëþ÷åíèå; äîñòóïà. Îíà îáðàùàåòñÿ ê ÿ÷åéêå ïàìÿòè, íà êîòîðóþ; óêàçûâàåò ñóììà ðåãèñòðîâ ECX è ESI, à ÷åìó ðàâíî èõ; çíà÷åíèå? Ïðîêðó÷èâàåì ýêðàí íåìíîãî ââåðõ è íàõîäèì, ÷òî; ECX è ESI ðàâíû 0, î ÷åì «Äîêòîð Âàòñîí» íàì è ñîîáùàåò:; «ds:000000» îòìåòèì, ÷òî ýòîé èíôîðìàöèè ìîæíî âåðèòü,; ïîñêîëüêó ïîäñòàíîâêà ýôôåêòèâíîãî àäðåñà îñóùåñòâëÿëàñü; íåïîñðåäñòâåííî â ìîìåíò èñïîëíåíèÿ, òåïåðü âñïîìíèì,; ÷òî ESI ñîäåðæèò êîïèþ ïåðåäàííîãî ôóíêöèè àðãóìåíòà; è ÷òî ECX áûë îáíóëåí ÿâíî, ñëåäîâàòåëüíî, â âûðàæåíèè; [ECX+ESI] ðåãèñòð ESI – óêàçàòåëü, à ECX – èíäåêñ. Ðàç ESI; ðàâåí íóëþ, òî íàøåé ôóíêöèè ïåðåäàëè óêàçàòåëü; íà íåâûäåëåííóþ îáëàñòü ïàìÿòè. Îáû÷íî ýòî ïðîèñõîäèò; ëèáî âñëåäñòâèå àëãîðèòìè÷åñêîé îøèáêè â ïðîãðàììå,; ëèáî âñëåäñòâèå èñ÷åðïàíèÿ âèðòóàëüíîé ïàìÿòè,; ê ñîæàëåíèþ, «Äîêòîð Âàòñîí» íå îñóùåñòâëÿåò; äèçàññåìáëèðîâàíèå ìàòåðèíñêîé ôóíêöèè, è êàêîé èç äâóõ; ïðåäïîëàãàåìûõ âàðèàíòîâ ïðàâèëüíûé – íàì îñòàåòñÿ ëèøü; ãàäàòü… Ïðàâäà, ìîæíî äèçàññåìáëèðîâàòü äàìï ïàìÿòè; ïðîöåññà (åñëè, êîíå÷íî, îí áûë ñîõðàíåí), íî ýòî óæå; íå òî…

00401018 03c7 add eax, edi; Ñëîæèòü ñîäåðæèìîå ðåãèñòðà EAX ñ ðåãèñòðîì EDI; è çàïèñàòü ðåçóëüòàò â EAX.

0040101a 41 inc ecx; Óâåëè÷èòü ECX íà åäèíèöó.

Page 14: 013 Системный Администратор 12 2003

12

программирование

Microsoft Visual Studio DebuggerПри установке среды разработки Microsoft Visual Studioона регистрирует свой отладчик основным отладчикомкритических ошибок по умолчанию. Это простой в исполь-зовании, но функционально ущербный отладчик, не под-держивающий даже такой банальной операции, как по-иск hex-последовательности в оперативной памяти. Един-ственная «вкусность», отличающая его от продвинутогово всех отношениях Microsoft Kernel Debugger – это воз-можность трассировки «упавших» процессов, выбросив-ших критическое исключение.

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

Для ручной установки Microsoft Visual Studio Debuggerосновным отладчиком критических ошибок добавьте вреестр следующие данные:

0040101b 3bca cmp ecx,edx0040101d 7cf5 jl 00407014; Äî òåõ ïîð ïîêà ECX < EDX, ïåðåõîäèòü íà àäðåñ 407014; (î÷åâèäíî, ìû èìååì äåëî ñ öèêëîì, óïðàâëÿåìûì ñ÷åò÷èêîì; ECX). Ïðè èíòåðàêòèâíîé îòëàäêå ìû ìîãëè áû ïðèíóäèòåëüíî; âûéòè èç ôóíêöèè, âîçâðàòèâ ôëàã îøèáêè, ÷òîáû ìàòåðèíñêàÿ; ôóíêöèÿ (à ñ íåé è âñÿ ïðîãðàììà öåëèêîì) ìîãëà ïðîäîëæèòü; ñâîå âûïîëíåíèå, è â ýòîì ñëó÷àå ïîòåðÿííîé îêàæåòñÿ ëèøü; ïîñëåäíÿÿ îïåðàöèÿ, íî âñå îñòàëüíûå äàííûå îêàæóòñÿ; íåèñêàæåííûìè.

0040101f 5f pop edi00401020 5e pop esi00401021 c3 ret; Âûõîäèì èç ôóíêöèè.

*----> Îáðàòíàÿ òðàññèðîâêà ñòåêà <----*; Ñîäåðæèìîå ñòåêà íà ìîìåíò âîçíèêíîâåíèÿ ñáîÿ.; Ðàñïå÷àòûâàåò àäðåñà è ïàðàìåòðû ïðåäûäóùèõ âûïîëíÿåìûõ ôóíêöèé,; ïðè èíòåðàêòèâíîé îòëàäêå ìû ìîãëè áû ïðîñòî ïåðåäàòü óïðàâëåíèå; íà îäíó èç âûøåëåæàùèõ ôóíêöèé, ÷òî ýêâèâàëåíòíî âîçâðàùåíèþ; â ïðîøëîå, ýòî òîëüêî â ðåàëüíîé æèçíè ðàçáèòóþ ÷àøêó; âîññòàíîâèòü íåëüçÿ, â êîìïüþòåðíîé âñåëåííîé âîçìîæíî âñå!FramePtr ReturnAd Param#1 Param#2 Param#3 Param#4 ↵

Function Name; FramePtr: Óêàçûâàåò íà çíà÷åíèå ôðåéìà ñòåêà,; âûøå (ò.å. â áîëåå ìëàäøèõ àäðåñàõ); ñîäåðæàòñÿ àðãóìåíòû ôóíêöèè, íèæå – åå; ëîêàëüíûå ïåðåìåííûå.;; ReturnAd: Áåðåæíî õðàíèò àäðåñ âîçâðàòà â ìàòåðèíñêóþ; ôóíêöèþ. Åñëè çäåñü ñîäåðæèòñÿ ìóñîð è; îáðàòíàÿ òðàññèðîâêà ñòåêà íà÷èíàåò; õàðàêòåðíî øóìåòü, ñ âûñîêîé ñòåïåíüþ; âåðîÿòíîñòè ìîæíî ïðåäïîëîæèòü, ÷òî ìû; èìååì äåëî ñ îøèáêîé «ñðûâà ñòåêà», à; âîçìîæíî, è ñ ïîïûòêîé àòàêè âàøåãî; êîìïüþòåðà.;; Param#: ×åòûðå ïåðâûõ ïàðàìåòðà ôóíêöèè – èìåííî; ñòîëüêî ïàðàìåòðîâ «Äîêòîð Âàòñîí» îòîáðàæàåò; íà ýêðàíå. Ýòî äîñòàòî÷íî æåñòêîå îãðàíè÷åíèå –; ìíîãèå ôóíêöèè èìåþò äåñÿòêè ïàðàìåòðîâ è; ÷åòûðå ïàðàìåòðà åùå íè î ÷åì íå ãîâîðÿò;; îäíàêî íåäîñòàþùèå ïàðàìåòðû ëåãêî âûòàùèòü; èç êîïèè íåîáðàáîòàííîãî ñòåêà âðó÷íóþ –; äîñòàòî÷íî ëèøü ïåðåéòè ïî óêàçàííîìó â ïîëå; FramePtr àäðåñó.;; Func Name: Èìÿ ôóíêöèè (åñëè òîëüêî åãî âîçìîæíî; ëåãêî âûòàùèòü è îïðåäåëèòü);; ðåàëüíî îòîáðàæàåò ëèøü èìåíà ôóíêöèé,; èìïîðòèðóåìûå èç äðóãèõ DLL, ïîñêîëüêó; âñòðåòèòü êîììåð÷åñêóþ ïðîãðàììó,; îòêîìïèëèðîâàííóþ âìåñòå ñ îòëàäî÷íîé; èíôîðìàöèåé ïðàêòè÷åñêè íåðåàëüíî.;0012FFC0 77E87903 00000000 00000000 7FFDF000 C0000005 !<nosymbols>0012FFF0 00000000 00401040 00000000 000000C8 00000100 ↵

kernel32!SetUnhandledExceptionFilter; Ôóíêöèè ïåðå÷èñëÿþòñÿ â ïîðÿäêå èõ èñïîëíåíèÿ; ñàìîé ïîñëåäíåé; èñïîëíÿëàñü kernel32!SetUnhandledExceptionFilter ôóíêöèÿ,; îáðàáàòûâàþùàÿ äàííîå èñêëþ÷åíèå.

*----> Êîïèÿ íåîáðàáîòàííîãî ñòåêà <----*; Êîïèÿ íåîáðàáîòàííîãî ñòåêà ñîäåðæèò ñòåê òàêèì, êàêîé îí åñòü.; Î÷åíü ïîìîãàåò ïðè îáíàðóæåíèè buffer overfull àòàê –; âåñü shell-êîä, ïåðåäàííûé çëîóìûøëåííèêîì, áóäåò ðàñïå÷àòàí; «Äîêòîðîì Âàòñîíîì», è âàì îñòàíåòñÿ âñåãî ëèøü îïîçíàòü åãî; (ïîäðîáíåå îá ýòîì ðàññêàçûâàåòñÿ â ìîåé êíèãå "Òåõíèêà; ñåòåâûõ àòàê")0012ff70 00 00 00 00 00 00 00 00 - 39 10 40 00 00 00 00 00 [email protected] 64 00 00 00 f4 10 40 00 - 01 00 00 00 d0 0e 30 00 [email protected].…00130090 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................001300a0 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................

*----> Òàáëèöà ñèìâîëîâ <----*; Òàáëèöà ñèìâîëîâ ñîäåðæèò èìåíà âñåõ çàãðóæåííûõ DLL âìåñòå; ñ èìåíàìè èìïîðòèðóåìûõ ôóíêöèé. Èñïîëüçóÿ ýòè àäðåñà â; êà÷åñòâå îòïðàâíîé òî÷êè, ìû áåç òðóäà ñìîæåì âîññòàíîâèòü; «ïåðå÷åíü çàãðóæåííûõ DLL».

ntdll.dll77F81106 00000000 ZwAccessCheckByType…77FCEFB0 00000000 fltused

kernel32.dll77E81765 0000003d IsDebuggerPresent…77EDBF7A 00000000 VerSetConditionMask;; Èòàê, âîçâðàùàåìñÿ ê òàáëèöå çàãðóæåííûõ DLL.; (00400000 - 00406000) - ýòî, î÷åâèäíî, îáëàñòü ïàìÿòè,; çàíÿòàÿ ñàìîé ïðîãðàììîé; (77F80000 - 77FFA000) – ýòî KERNEL32.DLL; (77E80000 - 77F37000) - ýòî NTDDL.DLL

Ëèñòèíã 3. Óñòàíîâêà Microsoft Visual Studio Debugger îñ-íîâíûì îòëàä÷èêîì êðèòè÷åñêèõ îøèáîê

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ ↵

CurrentVersion\AeDebug]"Auto"="1""Debugger"="\"C:\\Prg Files\\MS VS\\Common\\MSDev98\\Bin\\ ↵

msdev.exe\" -p %ld -e %ld""UserDebuggerHotKey"=dword:00000000

Ëèñòèíã 4. Äåìîíñòðàöèîííàÿ ïðîãðàììà, âûçûâàþùàÿ ñîîáùå-íèå î êðèòè÷åñêîé îøèáêå

// Ôóíêöèÿ âîçâðàùàåò ñóììó n ñèìâîëîâ òèïà char. Åñëè åé// ïåðåäàòü null-pointer, îíà «óïàäåò», õîòÿ èñòî÷íèê îøèáêè// íå â íåé, à â àðãóìåíòàõ, ïåðåäàííûõ ìàòåðèíñêîé ôóíêöèåé.test(char *buf, int n){

int a, sum;// Çäåñü âîçáóæäàåòñÿ èñêëþ÷åíèå.for (a = 0; a < n; a++) sum += buf[a];return sum;

}

main(){

#define N 100// Èíèöèàëèçèðóåì óêàçàòåëü íà áóôåð.char *buf = 0;

Page 15: 013 Системный Администратор 12 2003

13№12(13), декабрь 2003

программирование

Обитатели сумеречной зоны,или из морга в реанимациюХотите узнать, как заставить приложение продолжитьнормальную работу после появления сообщения о крити-ческой ошибке? Это действительно очень актуально.Представьте, что рухнуло приложение, содержащее уни-кальные и еще не сохраненные данные. По минимуму ихпридется набивать заново, по максимуму – они потеряныдля вас навсегда. На рынке имеется некоторое количе-ство утилит, нацеленных на эту задачу (взять те же NortonUtilities), но их интеллектуальность оставляет желать луч-шего и в среднем они срабатывают один раз из десяти. Вто же самое время ручная реанимация программы вос-крешает ее в 75-90% случаев.

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

Существует по меньшей мере три различных способареанимации:� принудительный выход из функции, возбудившей ис-

ключение;� «раскрутка» стека с передачей управления назад;� передача управления на функцию обработки сообщений.

Рассмотрим каждый из этих способов на примере при-ложения test.exe, копию которого вы можете скачать поадресу: www.samag.ru/sourse/test.zip.

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

Принудительный выход из функцииЗапускаем тестовую программу, набиваем в одном илинескольких окнах какой-нибудь текст, затем в меню «Help»выбираем пункт «About TestCEdit» и в появившемся диа-логовом окне щелкаем по кнопке «make error». Програм-ма выбрасывает критическую ошибку и, если мы нажмемна «ОК», все несохраненные данные необратимо погиб-нут, что никак не входит в наши планы. Однако при нали-чии предварительно установленного отладчика мы ещеможем кое-что предпринять. Пусть для определенностиэто будет Microsoft Visual Studio Debugger.

Нажимаем «Отмену», и отладчик немедленно дизассем-блирует функцию, возбудившую исключение (см. листинг 5).

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

Переместив курсор в окно дампа, набьем в строке ад-реса название регистра указателя вершины стека – «ESP»и нажмем на <Enter>. Содержимое стека тут же предста-нет перед нашими глазами:

Первые два двойных слова соответствуют машиннымкомандам POP EDI/POP ESI и не представляют для нассовершенно никакого интереса. А вот следующее двой-ное слово содержит адрес выхода в материнскую проце-дуру (в приведенном выше листинге оно выделено крас-ным шрифтом). Как раз оно-то нам и нужно!

Нажимаем <Ctrl-D> и затем 0x4012FF, отладчик по-слушно отображает следующий дизассемблерный текст:

// «Çàáûâàåì» âûäåëèòü ïàìÿòü, çäåñü îøèáêà./* buf = malloc(100); */// Ïåðåäàåì null-pointer íåêîòîðîé ôóíêöèè.test(buf, N);

}

Ëèñòèíã 5. Îòëàä÷èê Microsoft Visual Studio Debugger äèçàñ-ñåìáëèðîâàë ôóíêöèþ, âîçáóäèâøóþ èñêëþ÷åíèå

0040135C push esi0040135D mov esi,dword ptr [esp+8]00401361 push edi00401362 movsx edi,byte ptr [ecx+esi]00401366 add eax,edi00401368 inc ecx00401369 cmp ecx,edx0040136B jl 004013620040136D pop edi0040136E pop esi0040136F ret 8

Ëèñòèíã 6. Ïîèñê àäðåñà âîçâðàòà èç òåêóùåé ôóíêöèè (âûäå-ëåí êðàñíûì øðèôòîì)

0012F488 0012FA64 0012FA64 004012FF0012F494 00000000 00000064 004034580012F4A0 FFFFFFFF 0012F4C4 6C291CEA0012F4AC 00000019 00000000 6C32FAF00012F4B8 0012F4C0 0012FA64 011000590012F4C4 006403C2 002F5788 000000000012F4D0 00640301 77E16383 004C1E20

Ëèñòèíã 7. Äèçàññåìáëåðíûé ëèñòèíã ìàòåðèíñêîé ôóíêöèè

004012FA call 00401350004012FF cmp eax,0FFh00401302 je 0040132D00401304 push eax00401305 lea eax, [esp+8]00401309 push 405054h0040130E push eax0040130F call dword ptr ds:[4033B4h]00401315 add esp, 0Ch00401318 lea ecx, [esp+4]0040131C push 00040131E push 000401320 push ecx00401321 mov ecx, esi00401323 call 00401BC400401328 pop esi00401329 add esp,64h0040132C ret0040132C

Page 16: 013 Системный Администратор 12 2003

14

программирование

Смотрите: если регистр EAX равен FFh, то материнс-кая функция передает управление на ветку 40132Dh и, спу-стя несколько машинных команд, завершает свою работу,передавая бразды правления функции более высокогоуровня. Напротив, если EAX != FFh, то его значение пере-дается функции 4033B4h. Следовательно, мы можем пред-положить, что FFh – это флаг ошибки и есть. Возвращаем-ся в подопытную функцию, нажав <Ctrl-G> и «EIP», пере-ходим в окно «Registers» и меняем значение EAX на FFh.

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

В общем случае число PUSH-команд должно в точно-сти соответствовать количеству POP (также учитывайте,что PUSH DWORD X эквивалентен SUB ESP, 4, а POPDWORD X – ADD ESP, 4). Проанализировав дизассемб-лерный листинг функции, мы приходим к выводу, что длядостижения гармонии добра и зла мы должны стащить свершины стека два двойных слова, соответствующие ма-шинным командам 40135С:PUSH ESI и 401361:PUSH EDI.Это достигается передачей управления по адресу40136Dh, где живут два добродушных POP, приводящиестек в равновесное состояние. Подводим сюда курсор иуверенным щелчком правой клавиши мыши вызываемконтекстное меню, среди пунктов которого выбираем «SetNext Statement». Как вариант можно перейти в окно реги-стров и изменить значение EIP с 401362h на 40136Dh.

Нажатием <F5> мы заставляем процессор продолжитьвыполнение программы и… о чудо! Она действительнопродолжает свою работу (незлобное ругательство наошибку последней операции – не в счет!). Несохранен-ные данные спасены!

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

ны, чрезмерно глубокий откат ведет к потере всех несох-раненных данных…

Процедура отката состоит из трех шагов:� построения дерева вызовов;� определения координат стекового фрейма для каждо-

го из них;� восстановления регистрового контекста материнской

функции.

Хороший отладчик все это сделает за нас, и нам оста-нется лишь записать в регистры EIP и ESP соответствую-щие значения. К сожалению, отладчик Microsoft VisualStudio Debugger к хорошим отладчикам не относится. Ондовольно посредственно трассирует стек, пропуская FPO-функции (Frame Point Omission – функции с оптимизиро-ванным фреймом) и не сообщает координат стековогофрейма, «благодаря» чему самую трудоемкую часть ра-боты нам приходится выполнять самостоятельно.

Впрочем, даже такой стек вызовов все же лучше, чемсовсем ничего. Раскручивая его вручную, мы будем от-талкиваться от того, что координаты фрейма естествен-ным образом определяются по адресу возврата. Допус-тим, содержимое окна «Call Stack» выглядит так:

Попробуем найти в стеке адреса 6C2922AEh и6C298FC5h, соответствующие двум последним ступенямисполнения. Нажимаем <ATL-6> для перехода в окно дам-па и, воспользовавшись горячей комбинацией клавиш<Ctrl-G> в качестве базового адреса отображения, выби-раем «ESP». Прокручивая окно дампа вниз, мы обнару-живаем оба адреса возврата (в приведенном ниже лис-тинге они выделены рамкой):

0040132D push 00040132D ; ýòà âåòêà ïîëó÷àåò óïðàâëåíèå, åñëè Ôóíêöèÿ

; 401350h âåðíåò FFh0040132F push 000401331 push 405048h00401336 mov ecx,esi00401338 call 00401BC40040133D pop esi0040133E add esp,64h00401341 ret

Ëèñòèíã 8. Ñîäåðæèìîå îêíà Call Stacks îòëàä÷èêà MicrosoftVisual Studio Debugger

TESTCEDIT! 00401362()MFC42! 6c2922ae()MFC42! 6c298fc5()MFC42! 6c292976()MFC42! 6c291dcc()MFC42! 6c291cea()MFC42! 6c291c73()MFC42! 6c291bfb()MFC42! 6c291bba()

Ëèñòèíã 9. Ñîäåðæèìîå ñòåêà ïîñëå ðàñêðóòêè

0012F488 0012FA64 0012FA64 004012FF ↵

<-- 0040136F:ret 8 ïåðâûé àäðåñ âîçâðàòà0012F494 00000000 00000064 00403458 ↵

<-- 00401328:pop esi0012F4A0 FFFFFFFF 0012F4C4 6C291CEA0012F4AC 00000019 00000000 6C32FAF00012F4B8 0012F4C0 0012FA64 011000590012F4C4 00320774 002F5788 000000000012F4D0 00320701 77E16383 004C1E200012F4DC 00320774 002F5788 000000000012F4E8 000003E8 0012FA64 004F8CD80012F4F4 0012F4DC 002F5788 0012F5600012F500 77E61D49 6C2923D8 00403458 ↵

<-- 0040132C:ret;0012F50C 00000111 0012F540 6C2922AE ↵

<--6C29237E:pop ebx/pop ebp/ret 1Ch0012F518 0012FA64 000003E8 000000000012F518 0012FA64 000003E8 000000000012F524 004012F0 00000000 0000000C0012F530 00000000 00000000 0012FA640012F53C 000003E8 0012F564 6C298FC50012F548 000003E8 00000000 000000000012F554 00000000 000003E8 0012FA64

Page 17: 013 Системный Администратор 12 2003

15№12(13), декабрь 2003

программирование

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

Возвращаясь к листингу 5, отметим, что два двойныхслова, лежащие на верхушке стека, соответствуют ма-шинным командам POP EDI и POP ESI, а следующий заними адрес – 4012FFh – это тот самый адрес, управлениекоторому передается командой 40136Fh:RET 8. Для про-должения раскрутки стека мы должны дизассемблироватькод по этому адресу:

Прокручивая экран вниз, мы замечаем инструкциюADD ESP, 64, закрывающую текущий кадр стека. Ещевосемь байт снимает инструкция 40136Fh:RET 8 и четы-ре байта оттягивает на себя 401328:POP ESI. Таким об-разом, позиция адреса возврата в стеке равна:current_ESP + 64h + 8 + 4 == 70h. Спускаемся на 70h байтниже и видим:

Первое двойное слово – это значение регистра ESI,который нам предстоит вручную восстановить; второе –адрес возврата из функции. Нажатием <Ctrl-G>,«0x6C2923D8» мы продолжаем раскручивать стек:

Вот мы и добрались до восстановления регистров!Сместившись на одно двойное слово вправо (оно толькочто было вытолкнуто из стека командой RET), переходимв окно «Registers» и восстанавливаем регистры ESI, EBX,EBP, извлекая сохраненные значения из стека:

Как вариант можно переместить регистр EIP на адрес6C29237Dh, а регистр ESP на адрес 12F508h, после чегонажать на <F5> для продолжения выполнения програм-мы. И этот прием действительно срабатывает! Причемреанимированная программа уже не ругается на ошибкупоследней операции (как это было при восстановлениипутем принудительного выхода из функции), а просто еене выполняет. Красота!

Передача управления на функциюобработки сообщенийДвум предыдущим способам «реанимации» приложенийприсущи серьезные ограничения и недостатки. При тя-желых разрушениях стека, вызванных атаками типаbuffer overfull или же просто алгоритмическими ошибка-ми, содержимое важнейших регистров процессора ока-жется искажено, и мы уже не сможем ни совершить откат(стек утерян), ни выйти из текущей функции (EIP смотритв космос). В консольных приложениях в такой ситуациидействительно очень мало что можно сделать… Вот GUI –другое дело! Концепция событийно ориентированной ар-хитектуры наделяет всякое оконное приложение опреде-ленными серверными функциями. Даже если текущийконтекст выполнения необратимо утерян, мы можем пе-редать управление на цикл извлечения и диспетчериза-ции сообщений, заставляя программу продолжить обра-ботку действий пользователя.

Классический цикл обработки сообщений выглядит так:

Все, что нам нужно, – это передать управление на циклwhile, даже не заботясь о настройке кадра стека, посколькуоптимизированные программы (а таковых большинство)адресуют свои локальные переменные не через EBP, анепосредственно через сам ESP. Конечно, при обраще-нии к переменной msg, функция угробит содержимое сте-ка, лежащее ниже его вершины, но это уже не важно.

Правда, при выходе из приложения оно упадет окон-чательно (ведь вместо адреса возврата из функции об-работки сообщений машинная команда RET обнаружитна вершине стека неизвестно что), но это произойдет пос-ле сохранения всех данных, и потому никакой угрозы ненесет. Исключение составляют приложения, «забываю-щие» закрыть все открытые файлы и перекладывающиеэту работу на плечи функции ExitProcess. Что ж! Можнотак подправить адрес возврата, чтобы он указывал наExitProcess!

Давайте создадим простейшее Windows-приложениеи поэкспериментируем с ним. Запустив Microsoft Visual

Ëèñòèíã 10. Äèçàññåìáëåðíûé ëèñòèíã ïðàìàòåðèíñêîé ôóíêöèè(«áàáóøêè»)

004012FA call 00401350004012FF cmp eax,0FFh00401302 je 0040132D00401304 push eax00401305 lea eax,[esp+8]00401309 push 405054h0040130E push eax0040130F call dword ptr ds:[4033B4h]00401315 add esp,0Ch00401318 lea ecx,[esp+4]0040131C push 00040131E push 000401320 push ecx00401321 mov ecx,esi00401323 call 00401BC400401328 pop esi00401329 add esp,64h0040132C ret ; SS:[ESP] = 6C2923D8

Ëèñòèíã 11. Àäðåñ âîçâðàòà èç ïðàìàòåðèíñêîé ôóíêöèè

0012F500 77E61D49 6C2923D8 00403458 <-- 00401328:POP ESI/ret;

Ëèñòèíã 12. Äèçàññåìáëåðíûé ëèñòèíã ïðàïðàìàòåðèíñêîé ôóíêöèè

6C2923D8 jmp 6C29237B…6C29237B mov eax,ebx6C29237D pop esi6C29237E pop ebx6C29237F pop ebp6C292380 ret 1Ch

Ëèñòèíã 13. Ñîäåðæèìîå ðåãèñòðîâ, ðàíåå ñîõðàíåííûõ â ñòåêåâìåñòå ñ àäðåñîì âîçâðàòà

0012F500 77E61D49 6C2923D8 00403458 <-- 6C29237D:pop esi0012F50C 00000111 0012F540 6C2922AE <-- 6C29237E:pop ebx ↵

/pop ebp/ret 1Ch

Ëèñòèíã 14. Êëàññè÷åñêèé öèêë îáðàáîòêè ñîîáùåíèé

while (GetMessage(&msg, NULL, 0, 0)){

TranslateMessage(&msg);DispatchMessage(&msg);

}

Page 18: 013 Системный Администратор 12 2003

16

программирование

Studio выберем «New → Project → Win32 Application» итам – «Typical Hello, World application». Добавим новыйпункт меню, а в нем: char *p; *p = 0; и откомпилируем этотпроект с отладочной информацией.

Роняем приложение на пол и, запустив отладчик, под-гоняем мышь к первой строке цикла обработки сообще-ний и в появившемся контекстном меню находим пункт«Set Next Statement». Нажимаем <F5> для возобновленияработы программы и… она действительно возобновляетсвою работу!

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

Целью нашего поиска будут функции TranslateMessage/DispatchMessage и перекрестные ссылки, ведущие к цик-лу выборки сообщений.

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

Мы видим, что цикл обработки сообщений начинаетсяс адреса 401050h и именно на этот адрес следует пере-дать управление, чтобы возобновить работу упавшей про-граммы. Пробуем сделать это и… программа работает!

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

Рассмотрим, как устроен цикл обработки сообщений вMFC. Большую часть своего времени исполнения MFC-при-ложения проводят внутри функции CWinThread::Run(void),которая периодически опрашивает очередь на предметпоступления свежих сообщений и рассылает их соответ-ствующим обработчикам. Если один из обработчиковспоткнулся и довел систему до критической ошибки, вы-полнение программы может быть продолжено в функцииRun. В этом-то и заключается ее главная прелесть!

Функция не имеет явных аргументов, но принимаетскрытый аргумент this, указывающей на экземпляр клас-

Ëèñòèíã 15. Ïîèñê ôóíêöèé TranslateMessage/DispatchMessageâ òàáëèöå èìïîðòà

.idata:004040E0 ; BOOL __stdcall ↵

TranslateMessage(const MSG *lpMsg).idata:004040E0 extrn TranslateMessage:dword ; DATA ↵

XREF: _WinMain@16+71?r.idata:004040E0 ; _WinMain@16+8D?r.idata:004040E4 ; LONG __stdcall ↵

DispatchMessageA(const MSG *lpMsg).idata:004040E4 extrn DispatchMessageA:dword ; DATA ↵

XREF: _WinMain@16+94?r.idata:004040E8

Ëèñòèíã 16. Äèçàññåìáëåðíûé ëèñòèíã ôóíêöèè îáðàáîòêè ñîîáùåíèé

.text:00401050 mov edi, ds:GetMessageA

.text:00401050 ; ïåðâûé âûçîâ GetMessageA (ýòî åùå; íå öèêë, ýòî òîëüêî åãî ïðåääâåðüå)

.text:00401050

.text:00401056 push 0 ; wMsgFilterMax

.text:00401058 push 0 ; wMsgFilterMin

.text:0040105A lea ecx, [esp+2Ch+Msg]

.text:0040105A ; ECX óêàçûâàåò íà îáëàñòü ïàìÿòè, ÷åðåç

.text:0040105A ; êîòîðóþ GetMessageA ñòàíåò âîçâðàùàòü

.text:0040105A ; ñîîáùåíèå. Òåêóùåå çíà÷åíèå ESP ìîæåò áûòü

.text:0040105A ; ëþáûì, ãëàâíîå, ÷òîáû îíî óêàçûâàëî íà

.text:0040105A ; äåéñòâèòåëüíóþ îáëàñòü ïàìÿòè (ñì. êàðòó; ïàìÿòè, åñëè çíà÷åíèå ESP îêàçàëîñü èñêàæåíî; íàñòîëüêî, ÷òî âûâåëî åãî â «êîñìîñ»)

.text:0040105A

.text:0040105E push 0 ; hWnd

.text:00401060 push ecx ; lpMsg

.text:00401061 mov esi, eax

.text:00401063 call edi ; GetMessageA

.text:0040106 ; âûçûâàåì GetMessageA

.text:00401063

.text:00401065 test eax, eax

.text:00401067 jz short loc_4010AD

.text:00401067 ; ïðîâåðêà íà íàëè÷èå íåîáðàáîòàííûõ; ñîîáùåíèé â î÷åðåäè

.text:00401067….text:00401077 loc_401077: ;CODE XREF: _WinMain@16+A9?j

.text:00401077 ; íà÷àëî öèêëà îáðàáîòêè ñîîáùåíèé

.text:00401077

.text:00401077 mov eax, [esp+2Ch+Msg.hwnd]

.text:0040107B lea edx, [esp+2Ch+Msg]

.text:0040107B ; EDX óêàçûâàåò íà îáëàñòü ïàìÿòè,; èñïîëüçóåìóþ äëÿ ïåðåäà÷è ñîîáùåíèé

.text:0040107B

.text:0040107F push edx ; lpMsg

.text:00401080 push esi ; hAccTable

.text:00401081 push eax ; hWnd

.text:00401082 call ebx ; TranslateAcceleratorA

.text:00401082 ; âûçûâàåì ôóíêöèþ TranslateAcceleratorA

.text:00401082

.text:00401084 test eax, eax

.text:00401086 jnz short loc_40109A

.text:00401086 ; ïðîâåðêà íà íàëè÷èå â î÷åðåäè; íåîáðàáîòàííûõ ñîîáùåíèé

.text:00401086

.text:00401088 lea ecx, [esp+2Ch+Msg]

.text:0040108C push ecx ; lpMsg

.text:0040108D call ebp ; TranslateMessage

.text:0040108D ; âûçûâàåì ôóíêöèþ TranslateMessage, åñëè; åñòü ÷òî òðàíñëèðîâàòü

.text:0040108D

.text:0040108F lea edx, [esp+2Ch+Msg]

.text:00401093 push edx ; lpMsg

.text:00401094 call ds:DispatchMessageA

.text:00401094 ; äèñïåò÷åðèçóåì ñîîáùåíèå

.text:0040109A

.text:0040109A loc_40109A: ; CODE XREF: _WinMain@16+86?j

.text:0040109A push 0 ; wMsgFilterMax

.text:0040109C push 0 ; wMsgFilterMin

.text:0040109E lea eax, [esp+34h+Msg]

.text:004010A2 push 0 ; hWnd

.text:004010A4 push eax ; lpMsg

.text:004010A5 call edi ; GetMessageA

.text:004010A5 ; ÷èòàåì î÷åðåäíîå ñîîáùåíèå èç î÷åðåäè

.text:004010A5

.text:004010A7 test eax, eax

.text:004010A9 jnz short loc_401077

.text:004010A9 ; âðàùàåì öèêë îáðàáîòêè ñîîáùåíèé

.text:004010A9

.text:004010AB pop ebp

.text:004010AC pop ebx

.text:004010AD

.text:004010AD loc_4010AD: ; CODE XREF: _WinMain@16+67?j

.text:004010AD mov eax, [esp+24h+Msg.wParam]

.text:004010B1 pop edi

.text:004010B2 pop esi

.text:004010B3 add esp, 1Ch

.text:004010B6 retn 10h

.text:004010B6 _WinMain@16 endp

Page 19: 013 Системный Администратор 12 2003

17№12(13), декабрь 2003

программирование

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

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

Таким образом, функция Run ожидает получить ука-затель на двойное слово, указывающее на таблицу вир-туальных методов, 0x19 и 0x1B элементы которой пред-ставляют собой функции PumpMessage и IsIdleMessageсоответственно (или переходники к ним). Адреса импор-тируемых функций, если только динамическая библиоте-ка не была перемещена, можно узнать в том же дизас-семблере; в противном случае, следует отталкиваться отбазового адреса модуля, отображаемого отладчиком покоманде «Modules». При условии, что эти две функции небыли перекрыты программистом, поиск нужной нам вир-туальной таблицы не составит никакого труда.

По непонятным причинам библиотека MFC42.DLL неэкспортирует символьных имен функций, и эту информа-цию нам приходится добывать самостоятельно. Обрабо-тав библиотеку MFC42.LIB утилитой dumpbin, запущен-ной с ключом «/ARCH», мы определим ординалы обеихфункций (ординал PumpMessage – 5307, а IsIdleMessage –4079). Остается найти эти значения в экспорте библиоте-ки MFC42.DLL (dumpbin /EXPORTS mfc42.dll > mfc42.txt),из чего мы узнаем что адрес функции PumpMessage:6C291194h, а IsIdleMessage – 6С292583h.

Теперь мы должны найти указатели на функцииPumpMessage/IsIdleMessage в памяти, а точнее – в сек-ции данных, базовый адрес которой содержится в заго-ловке PE-файла, только помните, что в x86-процессорах

наименее значимый байт располагается по меньшемуадресу, т.е. все числа записываются задом наперед (ксожалению, отладчик Microsoft Visual Studio Debugger неподдерживает операцию поиска в памяти, и нам прихо-дится действовать обходным путем – копировать содер-жимое дампа в буфер обмена, вставлять его в текстовойфайл и, нажав <F7>, искать адреса уже там).

Долго ли, коротко ли, но интересующие нас указателиобнаруживаются по адресам 403044h/40304Сh (естествен-но, у вас эти адреса могут быть и другими). Причем обра-тите внимание: расстояние между указателями в точнос-ти равно расстоянию между указателями на [EAX + 64h]и [EAX + 6Ch], а очередность их размещения в памятиобратна порядку объявления виртуальных методов. Этохороший признак, и мы, скорее всего, находимся на пра-вильном пути:

Указатели, указывающие на адреса 403048h/40304Ch,очевидно, и будут кандидатами в члены искомой табли-цы виртуальных методов класса CWinThread. Расширивсферу поиска всем адресным пространством отлаживае-мого процесса, мы обнаруживаем два следующих пере-ходника:

Ага, уже теплее! Мы нашли не сами виртуальные фун-кции, но переходники к ним. Раскручивая этот запутан-ный клубок, попробуем отыскать ссылки на 401A26h/401A2Ch, которые передают управление на приведенныйвыше код:

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

Ëèñòèíã 17. Äèçàññåìáëåðíûé ëèñòèíã ôóíêöèè Run (ôðàãìåíò)

.text:6C29919D n2k_Trasnlate_main:; CODE XREF: MFC42_5715+1F?j

.text:6C29919D ; MFC42_5715+67?j ...

.text:6C29919D mov eax, [esi]

.text:6C29919F mov ecx, esi

.text:6C2991A1 call dword ptr [eax+64h]; CWinThread::PumpMessage(void)

.text:6C2991A4 test eax, eax

.text:6C2991A6 jz short loc_6C2991DA

.text:6C2991A8 mov eax, [esi]

.text:6C2991AA lea ebp, [esi+34h]

.text:6C2991AD push ebp

.text:6C2991AE mov ecx, esi

.text:6C2991B0 call dword ptr [eax+6Ch]; CWinThread::IsIdleMessage(MSG*)

.text:6C2991B3 test eax, eax

.text:6C2991B5 jz short loc_6C2991BE

.text:6C2991B7 push 1

.text:6C2991B9 mov [esp+14h], ebx

.text:6C2991BD pop edi

.text:6C2991BE

.text:6C2991BE loc_6C2991BE:; CODE XREF: MFC42_5715+51?j

.text:6C2991BE push ebx ; wRemoveMsg

.text:6C2991BF push ebx ; wMsgFilterMax

.text:6C2991C0 push ebx ; wMsgFilterMin

.text:6C2991C1 push ebx ; hWnd

.text:6C2991C2 push ebp ; lpMsg

.text:6C2991C3 call ds:PeekMessageA

.text:6C2991C9 test eax, eax

.text:6C2991CB jnz short n2k_Trasnlate_main

.text:6C2991CD

Ëèñòèíã 18. Àäðåñà ôóíêöèé IsIdleMessage/PumpMessage, íàé-äåííûå â ñåêöèè äàííûõ

; IsIdleMessage/PumpMessage00403044 6C2911D4 6C292583 6C29119400403050 6C2913D0 6C299144 6C2971290040305C 6C297129 6C297129 6C291A47

Ëèñòèíã 19. Ïåðåõîäíèêè ê ôóíêöèÿì IsIdleMessage/PumpMessage,íàéäåííûå òàì æå

00401A20 jmp dword ptr ds:[403044h] ; IsIdleMessage00401A26 jmp dword ptr ds:[403048h] ;00401A2C jmp dword ptr ds:[40304Ch] ; PumpMessage

Ëèñòèíã 20. Âèðòóàëüíàÿ òàáëèöà êëàññà CWinThread

00403490 00401A9E 00401040 004015F0<-- 0x0, 0x1, 0x2 ýëåìåíòû

0040349C 00401390 004015F0 00401A98<-- 0x3, 0x4, 0x5 ýëåìåíòû

004034A8 00401A92 00401A8C 00401A86<-- 0x6, 0x7, 0x8 ýëåìåíòû

004034B4 00401A80 00401A7A 00401A74<-- 0x9, 0xA, 0xB ýëåìåíòû

004034C0 00401010 00401A6E 00401A68<-- 0xC, 0xD, 0xE ýëåìåíòû

004034CC 00401A62 00401A5C 00401A56<-- 0xF, 0x10, 0x11 ýëåìåíòû

004034D8 00401A50 00401A4A 00401A44<-- 0x12, 0x13, 0x14 ýëåìåíòû

004034E4 00401A3E 004010B0 00401A38<-- 0x15, 0x16, 0x17 ýëåìåíòû

004034F0 00401A32 00401A2C 00401A26<-- 0x18, 0x19, 0x1A ýëåìåíòû (PumpMessage)

004034FC 00401A20 00401A1A 00401A14<-- 0x1B, 0x1C, 0x1D ýëåìåíòû (IsIdleMessage)

Page 20: 013 Системный Администратор 12 2003

18

программирование

Указатели на переходники к PumpMessage/IsIdleMessageразделяются ровно одним элементом, как того и требуютусловия задачи. Предположим, что это виртуальная таб-лица, которая нам и нужна. Для проверки этого предпо-ложения отсчитаем 0x19 элементов верх от 4034F4h ипопытаемся найти указатель, ссылающийся на ее нача-ло. Если повезет и он окажется экземпляром классаCwinThread, тогда программа сможет корректно продол-жить свою работу:

Действительно, в памяти обнаруживается нечто похо-жее. Записываем в регистр ECX значение 4050B8h, нахо-дим в памяти функцию Run (как уже говорилось, еслитолько она не была перекрыта, ее адрес – 6C299164h –известен). Нажимаем <Ctrl-G>, затем «0x6C299164», и вконтекстном меню, вызванном правой клавишей мыши,выбираем «Set Next Statement». Программа, отделавшисьлегким испугом, продолжает свое исполнение, ну а мы нарадостях идем пить пиво (кофе, квас, чай – по вкусу).

Аналогичным путем можно вернуть к жизни и завис-шие приложения, потерявшие нить управления и не реа-гирующие ни на мышь, ни на клавиатуру.

Как подключить дамп памяти…в отделе программ весь пол был усеян дырочками от перфокарт

и какие-то мужики ползали по раскатанной по полу 20-метровойраспечатке аварийного дампа памяти с целью обнаружения ошибкив распределителе памяти ОС-360. К президенту подошел начальник

отдела и сообщил, что есть надежда сделать это еще к обеду.Ю.Антонов «Юность Гейтса»

Дамп памяти (memory dump, также называемый корой [отанглийского core – сердцевина], crash- или аварийнымдампом), сброшенный системой при возникновении кри-тической ошибки – не самое убедительное средство длявыявления причин катастрофы, но ничего другого в ру-ках администратора зачастую просто не бывает. После-дний вздох операционной системы, похожий на дурно пах-нущую навозную кучу, из которой высовывается чей-тонаполовину разложившийся труп, мгновенным снимкомзапечатленный в момент неустранимого сбоя, – вот чтотакое дамп памяти! Копание в нем вряд ли доставит вамудовольствие. Не исключено, что истинного виновникакраха системы вообще не удастся найти. Допустим, не-кий некорректно работающий драйвер вторгся в областьпамяти, принадлежащую другому драйверу, и наглым об-разом затер критические структуры данных, сделав изчисел винегрет. К тому моменту, когда драйвер-жертвапойдет вразнос, драйвер-хищник может быть вообщевыгружен из системы, и определить его причастность ккрушению системы по одному лишь дампу практическинереально.

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

Ëèñòèíã 21. Ýêçåìïëÿð êëàññà CWinThread, âðó÷íóþ íàéäåííûéíàìè â ïàìÿòè

004050B8 00403490 00000001 00000000004050C4 00000000 00000000 00000001

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

Первым делом необходимо войти в конфигурациюсистемы («Панель управления» → «Система»/«ControlPanel» → «System») и убедиться, что настройки дампасоответствуют предъявляемым к ним требованиям(«Дополнительно» → «Загрузка и восстановление» →

«Отказ системы»/«Startup/Shutdown» → «Recovery» вWindows 2000 RUS и Windows NT 4.0 ENG соответствен-но). Операционная система Windows 2000 поддержива-ет три разновидности дампов памяти: малый дамп па-мяти (small memory dump), дамп памяти ядра (kernelmemory dump) и полный дамп памяти (complete dumpmemory). Для изменения настроек дампа вы должныиметь права администратора.

Малый дамп памяти занимает всего лишь 64 Кб (аотнюдь не 2 Мб, как утверждает контекстная помощь) ивключает в себя:� копию голубого экрана смерти;� перечень загруженных драйверов;� контекст обрушившегося процесса со всеми его пото-

ками;� первые 16 Кб содержимого ядерного стека обрушив-

шегося потока.

Разочаровывающие малоинформативные сведения!Непосредственный анализ дампа дает нам лишь адресвозникновения ошибки и имя драйвера, к которому этотадрес принадлежит. При условии, что конфигурация сис-темы не была изменена после возникновения сбоя, мыможем загрузить отладчик и дизассемблировать подозре-ваемый драйвер, но это мало что даст. Ведь содержимоесегмента данных на момент возникновения сбоя нам не-известно, более того, мы не можем утверждать, что ви-дим те же самые машинные команды, что вызвали сбой.Поэтому малый дамп памяти полезен лишь тем админис-траторам, которым достаточно одного лишь имени неста-бильного драйвера. Как показывает практика, в подавля-ющем большинстве случаев этой информации оказыва-ется вполне достаточно. Разработчикам драйвера отсы-лается гневный бан-рапорт (вместе с дампом!), а сам драй-вер тем временем заменяется другим – более новым инадежным. По умолчанию малый дамп памяти записыва-ется в директорию %SystemRoot%\Minidump, где ему при-сваивается имя «Mini», дата записи дампа и порядковыйномер сбоя на данный день. Например «Mini110701-69.dmp» – 69 дамп системы от 07 ноября 2001 года (непугайтесь! это просто я отлаживал драйвера).

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

Page 21: 013 Системный Администратор 12 2003

19№12(13), декабрь 2003

программирование

лее вероятным (техническая документация на систему со-общает, что ориентировочный размер дампа ядра состав-ляет треть объема физической оперативной памяти, ус-тановленной на системе). Это наилучший компромиссмежду накладными расходами на дисковое пространство,скоростью сброса дампа и информативностью последне-го. Весь джентльменский минимум информации в вашемраспоряжении. Практически все типовые ошибки драйве-ров и прочих ядерных компонентов могут быть локализо-ваны с точностью до байта, включая и те, что вызваны фи-зическим сбоем аппаратуры (правда, для этого вы должныиметь некоторый патологоанатомический опыт исследова-ния трупных дампов системы). По умолчанию дамп памятиядра записывается в файл %SystemRoot%\Memory.dmp, за-тирая или не затирая (в зависимости от текущих настро-ек «Системы») предыдущий дамп.

Полный дамп памяти включает в себя все содержи-мое физической памяти компьютера, занятое как приклад-ными, так и ядерными компонентами. Полный дамп памя-ти оказывается особенно полезным при отладке ASPI/SPTIприложений, которые в силу своей специфики могут уро-нить ядро даже с прикладного уровня. Несмотря на доволь-но большой размер, равный размеру оперативной памяти,полный дамп остается наиболее любимым дампом всехсистемных программистов (системные же администрато-ры в своей массе предпочитают малый дамп). Это не пока-жется удивительным, если вспомнить, что объемы жест-ких дисков давно перевалили за отметку 100 Гб, а оплататруда системных программистов за последние нескольколет даже несколько возросла. Лучше иметь невостребо-ванный полный дамп под рукой, чем кусать локти при егоотсутствии. По умолчанию полный дамп памяти записыва-ется в файл %SystemRoot%\Memory.dmp, затирая или незатирая (в зависимости от текущих настроек «Системы»)предыдущий дамп.

Выбрав предпочтительный тип дампа, давайте совер-шим учебный урон системы, отрабатывая методику егоанализа в полевых условиях. Для этого нам понадобится:� Комплект разработчика драйверов (Driver Development

Kit или сокращенно DDK), бесплатно распространяе-мый фирмой Microsoft и содержащий в себе подроб-ную техническую документацию по ядру системы; не-сколько компиляторов Си/Си++ и ассемблера, а так-же достаточно продвинутые средства анализа дампапамяти.

� Драйвер W2K_KILL.SYS или любой другой драйвер-убийца операционной системы, например BDOS.EXE отМарка Русиновича, позволяющий получить дамп в лю-бое удобное для нас время, не дожидаясь возникнове-ния критической ошибки (бесплатную копию програм-мы можно скачать с адреса http://www.sysinternals.com).

� Файлы символьных идентификаторов (symbol files), не-обходимые отладчикам ядра для его нормального функ-ционирования и делающие дизассемблерный код болеенаглядным. Файлы символьных идентификаторов входятв состав «зеленого» набора MSDN, но, в принципе, безних можно и обойтись, однако переменная окружения_NT_SYMBOL_PATH по любому должна быть определе-на, иначе отладчик i386kd.exe работать не будет.

� Одна или несколько книжек, описывающих архитекту-ру ядра системы. Очень хороша в этом смысле «Внут-реннее устройство Windows 2000» Марка Руссинови-ча и Дэвида Соломона, интересная как системным про-граммистам, так и администраторам.

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

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

Мы начнем с левого верхнего угла экрана и, зигзага-ми спускаясь вниз, трассируем все надписи по порядку.� «*** STOP:» буквально означает «останов [системы]» и

не несет в себе никакой дополнительной информации;� «0x0000001E» представляет собой Bug Check-код, со-

держащий категорию сбоя. Расшифровку Bug Check-кодов можно найти в DDK. В данном случае это 0x1E –KMODE_EXEPTION_NOT_HALTED, о чем и свидетель-ствует символьное имя, расположенное строкой ниже.Краткое объяснение некоторых, наиболее популярныхBug Check-кодов приведено в таблице 1. Полноту фир-менной документации она, разумеется, не заменяет,но некоторое представление о целесообразности ска-чивания 70 Мб DDK все-таки дает;

� арабская вязь в круглых скобках – это четыре BugCheck-параметра, физический смысл которых зави-сит от конкретного Bug Check-кода и вне его кон-текста теряет всякий смысл; применительно кKMODE_EXEPTION_NOT_HALTED – первый Bug Check-параметр содержит номер возбужденного исключения.Судя по таблице 1, это – STATUS_ACCESS_VIOLATION –доступ к запрещенному адресу памяти – и четвертыйBug Check-параметр указывает, какой именно. В дан-ном случае он равен нулю, следовательно, некотораямашинная инструкция попыталась совершить обраще-ние по null-pointer соответствующему инициализиро-ванному указателю, ссылающемуся на невыделенныйрегион памяти. Ее адрес содержится во втором BugCheck-параметре. Третий Bug Check-параметр в дан-ном конкретном случае не определен;

� «*** Address 0xBE80B00» – это и есть тот адрес, по ко-торому произошел сбой. В данном случае он иденти-чен второму Bug Check-параметру, однако так бываетдалеко не всегда (Bug Check-коды собственно и не под-ряжались хранить чьи-либо адреса);

Ðèñóíîê 5. Ãîëóáîé ýêðàí ñìåðòè (BSOD – Blue Screen Of Death),ñâèäåòåëüñòâóþùèé î âîçíèêíîâåíèè íåóñòðàíèìîãî ñáîÿ ñèñòåìûñ êðàòêîé èíôîðìàöèåé î íåì

Page 22: 013 Системный Администратор 12 2003

20

программирование

� «base at 0xBE80A00» – содержит базовый адрес заг-рузки модуля нарушителя системного порядка, по ко-торому легко установить паспортные данные самого это-го модуля (внимание: далеко не во всех случаях пра-вильное определение базового адреса вообще возмож-но). Воспользовавшись любым подходящим отладчиком(например, soft-ice от Нумега или i386kd от Microsoft),введем команду, распечатывающую перечень загружен-ных драйверов с их краткими характеристиками (вi386kd это осуществляется командой «!drivers»). Какодним из вариантов можно воспользоваться утилитойdrivers.exe, входящей в NTDDK. Но какой бы вы путь ниизбрали, результат будет приблизительно следующим:

Обратите внимание на выделенную жирным цветомстроку с именем «w2k_kill.sys», найденную по ее базо-вому адресу 0xBE80A00. Это и есть тот самый драй-вер, который нам нужен! А впрочем, этого можно и неделать, поскольку имя «неправильного» драйвера ибез того присутствует на голубом экране;

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

Восстановление системыпосле критического сбоя

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

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

Неестественное, почти половое влечение к кнопке F8 появилосьв Кролике совершенно не внезапно.

Щербаков Андрей«14400 бод и 19200 юзеров, и те же самые все-все-все...»

Òàáëèöà 1.

Page 23: 013 Системный Администратор 12 2003

21№12(13), декабрь 2003

программирование

димость в подобной двухтактной схеме сброса дампаобъясняется тем, что в момент возникновения критичес-кой ошибки работоспособность драйверов файловой си-стемы уже не гарантируется, и операционная система неможет позволить себе их использовать, ограничиваясьвременным размещением дампа в виртуальной памяти.Кстати, если имеющегося объема виртуальной памятиокажется недостаточно (Дополнительно → Параметрыбыстродействия → Виртуальная память), сброс дампаокажется невозможным.

Если же система от загрузки отказывается, упорнозабрасывая вас голубыми экранами смерти, вспомнитео существовании клавиши <F8> и выберите пункт «Заг-рузка последней удачной конфигурации («Last KnownGood Configuration»). Более радикальной мерой являет-ся запуск системы в безопасном (safe) режиме с мини-мумом загружаемых служб и драйверов. Переустанов-ка системы – это крайняя мера и без особой нужды кней лучше не прибегать. Лучше войдите в «консоль вос-становления» и перетащите файл дампа на другую ма-шину для его исследования.

Подключение дампа памятиДля подключения дампа памяти к отладчику WindowsDebugger (windbg.exe) в меню «File» выберите пункт«Crash Dump» или воспользуйтесь горячей комбинацией<Ctrl-D>. В отладчике i386kd.exe для той же цели служитключ «–z» командной строки, за которым следует полныйпуть к файлу дампа, отделенный от ключа одним или не-сколькими пробелами, при этом переменная окружения_NT_SYMBOL_PATH должна быть определена и содер-жать полный путь к файлам символьных идентификато-ров, в противном случае отладчик аварийно завершитсвою работу. Как один из вариантов можно указать ккомандой строке ключ «–y», и тогда экран консоли бу-дет выглядеть так: «i386kd –z C:\WINNT\memory.dmp -yC:\WINNT\Symbols», причем отладчик следует вызыватьиз Checked Build Environment/Free Build Environment кон-соли, находящейся в папке Windows 2000 DDK, иначе увас ничего не получится.

Хорошая идея – ассоциировать dmp-файлы с отлад-чиком i386kd, запуская их одним ударом «Enter» из FAR.Впрочем, выбор средства анализа – дело вкуса. Кому-то нравится KAnalyze, а кому-то достаточно и простень-кого DumpChk. Выбор аналитических инструментовчрезвычайно велик (один лишь DDK содержит четыреиз них!), и чтобы хоть как-то определиться с выбором,мы остановимся на i386kd.exe, также называемомKernel Debugger.

Как только консоль отладчика появится на экране (аKernel Debugger – это консольное приложение, горячолюбимое всеми, кто провел свою молодость за текстовы-ми терминалами), курсор наскоро дизассемблирует теку-щую машинную инструкцию и своим тревожным мерца-нием затягивает нас в пучину машинного кода. «Ну что,глазки строить будем или все-таки дизассемблиро-вать?» – незлобно ворчим мы, выбивая на клавиатурекоманду «u», заставляющую отладчик продолжить дизас-семблирование.

Судя по символьным идентификаторам PspUnhandledExceptionInSystemThread и KeBugCheckEx, мы находимсяглубоко в ядре, а точнее – в окрестностях того кода, чтовыводит BSOD на экран:

В стеке ничего интересного также не содержится, су-дите сами (просмотр содержимого стека осуществляетсякомандной «kb»):

Такой поворот событий ставит нас в тупик. Сколькобы мы ни дизассемблировали ядро, это ни на йоту неприблизит нас к источнику критической ошибки. Что ж,все вполне логично. Текущий адрес (8045249Сh) лежитдалеко за пределами драйвера-убийцы (0BE80A00h).Хорошо, давайте развернемся и пойдем другим путем.Помните тот адрес, что высвечивал голубой экран смер-ти? Не помните – не беда! Если это только не запреще-но настройками, копии всех голубых экранов сохраня-ются в Журнале системы. Откроем его («Панель уп-равления» → »Администрирование» → »Просмотр со-бытий»):

Отталкиваясь от категории критической ошибки (0x1E),мы без труда сможем определить адрес инструкции-убий-цы – 0xBE80B000 (в приведенном выше листинге он вы-делен красным шрифтом). Даем команду «u BE80B000»для просмотра его содержимого и видим:

Ëèñòèíã 22. Ðåçóëüòàò äèçàññåìáëèðîâàíèÿ ïîäêëþ÷åííîãî äàìïàïàìÿòè ñ òåêóùåãî àäðåñà

8045249c 6a01 push 0x1kd>u_PspUnhandledExceptionInSystemThread@4:80452484 8B442404 mov eax, dword ptr [esp+4]80452488 8B00 mov eax, dword ptr [eax]8045248A FF7018 push dword ptr [eax+18h]8045248D FF7014 push dword ptr [eax+14h]80452490 FF700C push dword ptr [eax+0Ch]80452493 FF30 push dword ptr [eax]80452495 6A1E push 1Eh80452497 E8789AFDFF call _KeBugCheckEx@208045249C 6A01 push 18045249E 58 pop eax8045249F C20400 ret 4

Ëèñòèíã 23. Ñîäåðæèìîå ñòåêà íå äàåò íèêàêèõ íàìåêîâíà ïðèðîäó èñòèííîãî âèíîâíèêà

kd> kbChildEBP RetAddr Args to Childf403f71c 8045251c f403f744 8045cc77 f403f74c ↵

ntoskrnl!PspUnhandledExceptionInSystemThread+0x18f403fddc 80465b62 80418ada 00000001 00000000 ↵

ntoskrnl!PspSystemThreadStartup+0x5e00000000 00000000 00000000 00000000 00000000 ↵

ntoskrnl!KiThreadStartup+0x16

Ëèñòèíã 24. Êîïèÿ ãîëóáîãî ýêðàíà ñìåðòè, ñîõðàíåííàÿ â ñè-ñòåìíîì æóðíàëå

Êîìïüþòåð áûë ïåðåçàãðóæåí ïîñëå êðèòè÷åñêîé îøèáêè:0x0000001e (0xc0000005, 0xbe80b000, 0x00000000, 0x00000000).Microsoft Windows 2000 [v15.2195]Êîïèÿ ïàìÿòè ñîõðàíåíà: C:\WINNT\MEMORY.DMP.

Ëèñòèíã 25. Ðåçóëüòàò äèçàññåìáëèðîâàíèÿ äàìïà ïàìÿòèïî àäðåñó, ñîîáùåííîìó ãîëóáûì ýêðàíîì ñìåðòè

kd>u 0xBE80B000be80b000 a100000000 mov eax,[00000000]be80b005 c20800 ret 0x8be80b008 90 nop

Page 24: 013 Системный Администратор 12 2003

22

программирование

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

Хорошо, а как быть, если копии экрана смерти в на-шем распоряжении нет? На самом деле, синий экран все-гда с нами, надо только знать, где искать! Попробуйте от-крыть файл дампа в любом hex-редакторе, и вы обнару-жите следующие строки:

С первого же взгляда удается опознать все основ-ные Bug Check-параметры: 1E 00 00 00 – это код кате-гории сбоя 0x1E (на x86 процессорах наименее значи-мый байт располагается по меньшему адресу, то естьвсе числа записываются задом наперед); 05 00 00 C0 –код исключения ACCESS VIOLATION; а 00 B0 80 BE – и

есть адрес машинной команды, породившей это исклю-чение. В комбинации же 0F 00 00 00 93 08 легко узнает-ся номер билда системы, стоит только записать его вдесятичной нотации.

Для просмотра Bug Check-параметров в более удобо-читаемом виде можно воспользоваться следующей коман-дой отладчика: «dd KiBugCheckData»:

Другие полезные команды: «!drivers» – выводящаясписок драйверов, загруженных на момент сбоя,«!arbiter» – показывающая всех арбитров вместе с диа-пазонами арбитража, «!filecache» – отображающая инфор-мацию о кэше файловой системы и PT, «!vm» – отчиты-вающаяся об использовании виртуальной памяти и т. д. –всех не перечислишь! (полный перечень команд вы най-дете в руководстве по своему любимому отладчику).

Ëèñòèíã 27. Bug Check ïàðàìåòðû, îòîáðàæàåìûå â óäîáî÷èòà-åìîì âèäå

kd> dd KiBugCheckDatadd KiBugCheckData8047e6c0 0000001e c0000005 be80b000 000000008047e6d0 00000000 00000000 00000001 000000008047e6e0 00000000 00000000 00000000 000000008047e6f0 00000000 00000000 00000000 000000008047e700 00000000 00000000 00000000 000000008047e710 00000000 00000000 00000000 000000008047e720 00000000 00000000 00000000 000000008047e730 00000000 e0ffffff edffffff 00020000

be80b009 90 nopbe80b00a 90 nopbe80b00b 90 nopbe80b00c 90 nopbe80b00d 90 nop

Ëèñòèíã 26. Êîïèÿ ãîëóáîãî ýêðàíà â çàãîëîâêå äàìïà ïðîãðàììû

Page 25: 013 Системный Администратор 12 2003

23№12(13), декабрь 2003

программирование

Ðèñóíîê 7. windbg c çàãðóæåííûì äàìïîì ïàìÿòè. Îáðàòèòå âíèìàíèå: îòëàä÷èê ñàìîñòîÿòåëüíî âûñâå÷èâàåò Bug Check-êîäû, íåîæèäàÿ, ïîêà ìû îá ýòîì åãî ïîïðîñèì, à ïðè ïîïûòêå äèçàññåìáëèðîâàíèÿ èíñòðóêöèè, âîçáóäèâøåé èñêëþ÷åíèå, íà ýêðàíå âûñêàêè-âàåò «Module Load: W2K_KILL.SYS», ñîîáùàþùàÿ íàì èìÿ äðàéâåðà-óáèéöû. Âðîäå áû ìåëî÷ü, à êàê ïðèÿòíî!

Ðèñóíîê 6. Îòëàä÷èê i386kd çà ðàáîòîé. Íåñìîòðÿ íà ñâîþîòòàëêèâàþùóþ âíåøíîñòü, ýòî ÷ðåçâû÷àéíî ìîùíûé è óäîáíûé âðàáîòå èíñòðóìåíò, ïîçâîëÿþùèé ïðîâîðà÷èâàòü óìîïîìðà÷è-òåëüíûå ïàññàæè íàæàòèåì âñåãî ïàðû-òðîéêè êëàâèø (îäíà èçêîòîðûõ âûçûâàåò âàø ñîáñòâåííûé ñêðèïò)

Конечно, в реальной жизни определить истинного ви-новника краха системы намного сложнее, поскольку вся-кий нормальный драйвер состоит из множества сложновзаимодействующих функций, образующих запутанныеиерархические комплексы, местами пересеченные тунне-лями глобальных переменных, превращающих драйвер всамый настоящий лабиринт. Приведем только один при-мер. Конструкция вида «mov eax, [ebx]», где ebx == 0, ра-ботает вполне нормально, послушно возбуждая исклю-чение, и пытаться поговорить с ней по-мужски – бессмыс-ленно! Нужно найти тот код, который записывает в EBXнулевое значение, и сделать это непросто. Можно, конеч-но, просто прокрутить экран вверх, надеясь, что на дан-ном участке программный код выполнялся линейно, ноникаких гарантий, что это действительно так, у нас нет,равно как нет и возможности обратной трассировки(back trace). Грубо говоря, адрес предшествующей машин-ной инструкции нам неизвестен, и закладываться на про-крутку экрана нельзя!

Загрузив подопытный драйвер в любой интеллекту-альный дизассемблер, автоматически восстанавлива-ющий перекрестные ссылки (например IDA PRO), мыполучим более или менее полное представление о то-пологии управляющих ветвей программы. Конечно, ди-

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

Page 26: 013 Системный Администратор 12 2003

24

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Page 27: 013 Системный Администратор 12 2003
Page 28: 013 Системный Администратор 12 2003

26

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

РЕШЕНИЕ ЗАДАЧИНВЕНТАРИЗАЦИИ В СЕТИ

ИВАН КОРОБКО

Page 29: 013 Системный Администратор 12 2003

27№12(13), декабрь 2003

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

Опытный системный администратор сети, построенной наоснове Microsoft Windows 2000 и Windows XP, используетсценарии загрузки для решения различных задач. Однойиз таких задач является инвентаризация аппаратногообеспечения рабочих станций. Решение данной задачиактуально в компаниях с большим количеством рабочихстанций.

Решение задачи инвентаризации состоит из двух час-тей: первая часть – сбор информации с помощью сцена-рия загрузки, написанном на VBScript и сохранение полу-ченных данных в файл отчета на сервер в формате XML.Вторая часть – анализ полученных данных. В качествеинструмента для анализа данных предлагается создатьсайт на ASP, который позволит объединить в единое це-лое данные о конфигурации всех рабочих станций, осу-ществить поиск по заданному критерию; создать файл от-чета о проделанном поиске.

Обе части реализованы с помощью стандартныхсредств Microsoft Windows, что делает их надежными вработе, легко внедряемыми.

WMI. Основные понятияРешение задачи накопления и сохранения информации обаппаратной конфигурации рабочей станции обеспечивает-ся стандартными средствами Microsoft Windows. Одним изтаких средств является Microsoft Windows ManagementInstrument (WMI).

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

Теоретические сведенияо внутреннем устройстве WMIИсполняемым файлом, обеспечивающим функционирова-ние WMI, является файл winmgmt.exe, находящийся вMicrosoft Windows 200x каталоге c:\WINNT\system32\wbem\.

Механизм работы WMI следующий:� На первом этапе происходит подключение к службе

WMI локального или удаленного компьютера: при об-ращении приложения к WMI запросы приложения пе-ресылаются диспетчеру объектов CIM (CommonInformation Model (CIM) Object Manager). CIMOM обес-печивает первоначальное создание объектов и од-нообразный способ доступа к управляемым объек-там. Наиболее простым способом подключения кудаленному компьютеру является вызов функцииязыка VBScript GetObject(). Подключение к удален-ному компьютеру происходит с помощью протоколаwinmgmts.

� На втором этапе происходит проверка хранилищаобъектов. Затем запрос передается поставщику объек-та. Поставщик (provider) – это интерфейс между уп-равляемым устройством и диспетчером CIMOM. По-ставщик собирает информацию об устройствах и де-лает их доступными для диспетчера.

В состав WMI входит несколько поставщиков:

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

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

В приведенных примерах переменная strComputer со-держит имя удаленного компьютера. Если компьютер ло-кальный, то вместо имени указывается символ «.»:strComputer=”.”; Переменная strNameSpace содержит про-странство имен (см. таблицу 1). strClass – переменная, со-держащая название класса. Например, для Win32 Provider,одним из классов является Win32_BIOS, соответственно,переменная strNameSpace принимает значение Root\Cimv2.

Òàáëèöà 1

Øàáëîí 1. Ïîëó÷åíèå äîñòóïà ê WMI-îáúåêòàìÂàðèàíò1

strComputer=””strNameSpace=””strClass=””Set objElements = GetObject( "winmgmts:{ImpersonationLevel= ↵

Impersonate}!//" & strComputer & ”/ ” ↵& strNameSpace & ”: ” & strClass)

For each Element in objElementsTemp=Element.ValueNext

Âàðèàíò2

strComputer=””strNameSpace=””strClass=””Set objWMIService = GetObject( "winmgmts:{ImpersonationLevel= ↵

Impersonate}!//" & strComputer & ”/ ” ↵& strNameSpace)

Set colItems = objWMIService.InstancesOf(strClass )For Each objItem in colItemsTemp=Element.ValueNext

Âàðèàíò3

strComputer=””strNameSpace=””strClass=””Set objWMIService = GetObject("winmgmts:{ImpersonationLevel= ↵

Impersonate }!// " & strComputer & ”/ ” ↵& strNameSpace)

Set colItems = objWMIService.ExecQuery(“SELECT ïîëå_1, ↵ïîëå_2, …, ïîëå_n FROM” & strClass )

For Each objItem in colItemsTemp=Element.ValueNext

Page 30: 013 Системный Администратор 12 2003

28

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

Инстркуция {ImpersonationLevel=Impersonate}! заставляетвыполнить сценарий с привилегиями пользователя, вызы-вающего сценарий, а не с привилегиями пользователя,который в настоящий момент работает на рабочей стан-ции. Таким образом, осуществляется подстановка, кото-рая полезна при выполнении сценариев удаленного досту-па на таких ОС, как Microsoft Windows 200x. Инструкция{ImpersonationLevel=Impersonate}! в Microsoft Windows 200xявляется выражением подстановки по умолчанию, поэто-му для семейства Windows 200x ее можно опустить.

Варианты 1 и 2 шаблона 1 родственны и отличаютсялишь формой записи. В варианте 3 обращение к классустроится с помощью SQL-запроса, что позволяет эконо-мить трафик.

В общем случае запрос SQL выглядит следующим об-разом:

В поле SELECT указываются поля, по которым идетвыборка. Поля перечисляются через запятую, «пробелы»после запятой обязательны. Если выборка должна идтипо всем полям, то вместо названий полей указываетсясимвол «*». В поле FROM указывается один из ранее пе-речисленных поставщиков:

В зависимости от способа доступа к хранилищу раз-мер пересылаемых данных разный (см. таблицу 2).

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

Практика использования WMIДанная статья посвящена решению задачи инвентаризации.Как видно из таблицы 1, для решения этой задачи необхо-димо использовать Win32 Provider, которому соответствуетпространство имен Root\Cimv2. Win32 Provider соответству-ет массив, состоящий из двух частей: идентификатора и на-звания ресурса, которые разделены знаком подчеркивания.Идентификатором всегда является «WIN32». С объектноймоделью WMI можно ознакомиться с помощью утилиты WMIObject Browser (см. рис. 1), входящей в пакет WMI Tools. Наборутилит WMI Tools можно найти на сайте компании Microsoft:http://msdn.microsoft.com/developer/sdk/wmisdk/default.asp.

SELECT ïîëå_1, ïîëå_2, …, ïîëå_n FROM strClass

SELECT * FROM strClass

Òàáëèöà 2

Ðèñóíîê 1. Îáúåêòíàÿ ìîäåëü WMI

Page 31: 013 Системный Администратор 12 2003

29№12(13), декабрь 2003

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

Таким образом, вариант 3 шаблона 1 примет следую-щий вид:

Приведем пример получения информации о материн-ской плате на основе обобщенного варианта 3 рабочейстанции ComputerName (VBScript). Массив данных, в ко-тором содержится информация о материнской плате, на-зывается WIN32_BIOS:

Необходимо отметить, что переменная objItem.SMBIOS-BIOSVersion строковая (см. рис. 1). Если переменная яв-ляется числом, то ее необходимо преобразовать в стро-ковую переменную с помощью функции Сstr(). Если пе-ременная представляет собой массив, то необходимо про-читать элементы массива и преобразовать их в строки,если элементы массива не являются строковыми пере-менными.

Результатом выполнения данной программы будет со-общение вида:

Порядок работы сценария загрузкиСценарий загрузки, написанный на VBScript, работаетв соответствии со следующим алгоритмом. На первойстадии работы, для идентификации рабочей станции си-стемным администратором, сценарием загрузки опре-деляются следующие параметры: имя рабочей станции;домен, к которому принадлежит рабочая станция; вер-сия операционной системы, установленной на рабочейстанции, учетная запись пользователя; текущая дата.На втором этапе определяются аппаратные характери-стики рабочей станции с помощью WMI. На третьемэтапе формируется файл отчета в формате XML. Дан-ные, хранящиеся в XML, могут быть экспортированы дляпоследующей обработки в одно из следующих прило-жений: Microsoft Excel, Microsoft Access, Microsoft SQL

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

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

Формирование файла отчетаФайл отчета представляет собой текстовый файл в коди-ровке Unicode с данными, записанными в формате XML.Extensible Markup Language (XML) – это язык разметки до-кументов, созданный Microsoft, структурированного хра-нения информации. Полную спецификацию XML см. насайте: http://www.w3c.org/xml

Файл отчета формируется в течение всего временивыполнения сценария загрузки методом накопления. Оп-ределяя требуемые для отчета параметры по ходу выпол-нения сценария загрузки, происходит пополнение пере-менной. Для этого используют выражение вида:temp=temp+data, где выражение data строится по шабло-ну <раздел> значение </раздел>. Названия разделов чув-ствительны к регистру. В подтверждение приведем при-мер, в котором в раздел «Date» XML-файла помещаюттекущую дату и точное время запуска сценария загрузки:

В конце сценария загрузки открывается текстовыйфайл, в него записывается содержимое переменной temp:

Переменная FileName, фигурирующая в данном при-мере, состоит из двух частей – пути к папке на сервере, вкоторой будут храниться файлы отчетов со всех рабочихстанций; имени файла. Имя файла должно совпадать сименем рабочей станции. В папку, предназначенную дляхранения файлов отчетов, пользователи группы Everyoneдолжны иметь возможность записи. Второе требование кэтой папке – ее скрытость от всех пользователей. Исходяиз ранее сказанного, отметим, что переменная FileNameимеет следующий вид: \\server\folder$\PC_name.xml.

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

Øàáëîí 1. Îáîáùåííûé âàðèàíò 3

strComputer=””strNameSpace=” Root\Cimv2”strClass=”Win32_Value”Set objWMIService = GetObject( " winmgmts: // " & ↵

strComputer & ”/ ” & strNameSpace)Set colItems = objWMIService.ExecQuery(“SELECT ïîëå_1, ↵

ïîëå_2, …, ïîëå_n FROM” & strClass )For Each objItem in colItemsTemp=Element.ValueNext

Ïðèìåð 1. Ïîëó÷åíèå èíôîðìàöèè î ìàòåðèíñêîé ïëàòå ðàáî÷åéñòàíöèè

strComputer="."strNameSpace="Root\Cimv2"strClass="Win32_BIOS"Set objWMIService = GetObject("winmgmts://"&strComputer&"/ ↵

"& strNameSpace)Set colItems = objWMIService.ExecQuery("SELECT ↵

SMBIOSBIOSVersion FROM " & strClass )For Each objItem in colItemsMsgBox objItem.SMBIOSBIOSVersionNext

Ðèñóíîê 2. Èíôîðìàöèÿ î ìîäåëè ìàòåðèíñêîé ïëàòû

temp = temp + ”<Date>” + Date() + ”; ” + Time() + ”</Date>”

Ïðèìåð 2. Ôîðìèðîâàíèå ôàéëà îò÷åòà

Set fso = CreateObject("Scripting.FileSystemObject")Set f = fso.OpenTextFile(FileName, 2, True)f.Write "temp"f.Close

Page 32: 013 Системный Администратор 12 2003

30

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

Поскольку поля в разных классах разные, то использова-ние варианта 3 шаблона 1 становится невозможным – необ-ходимо использовать вариант 1 или 2. В шаблоне 2 строка:

заменяется на строку:

Приведем конкретный пример, в котором определимнекоторые данные о рабочей станции. Названия парамет-ров и соответствующие им названия WMI-классов приве-дены таблице:

Результатом данного сценария является файл в фор-мате XML. Формат файла совпадает с названием рабо-чей станции (см. рис. 3).

Полная версия сценария загрузки приведена в Прило-жении 1.

Обработка полученных данныхИнструмент, позволяющий обработать данные о рабочихстанциях, собранные в XML-файлы, представляет собойсайт, построенный на основе ASP. Выбор ASP обусловленего способностью работать с OLE-объектами. Инструментпредставляет сайт, точкой входа в который является стра-

Øàáëîí 2. Îáåñïå÷åíèå óíèâåðñàëüíîãî äîñòóïà ê íåñêîëüêèìêëàññàì WMI

dim strClassstrClass=Array(”Win32_Value1”, ”Win32_Value2”,… ↵

”Win32_Value?”)Set objWMIService = GetObject( " winmgmts: //./ ↵

Root\Cimv2 ")for a=0 to ?Set colItems = objWMIService.ExecQuery(“SELECT * ↵

FROM” & strClass(a) )For Each objItem in colItems

Select case aCase 0

b=b+1temp=temp+"<Parametr1" + cstr(b) +">"temp=temp+"<Parametr2" + cstr(objItem.Value1) +">"temp=temp+"<Parametr3" + cstr(objItem.Value2) +">"……………………………………………………temp=temp+"<Parametrµ" + cstr(objItem.Valueµ) +">"temp=temp+"</Parametr1" + cstr(b) +">"

Case1c=c+1

temp=temp+"<Parametr1" + cstr(c) +">"temp=temp+"<Parametr2" + cstr(objItem.Value1) +">"temp=temp+"<Parametr3" + cstr(objItem.Value2) +">"……………………………………………………temp=temp+"<Parametr?" + cstr(objItem.Value?) +">"temp=temp+"</Parametr1" + cstr(c) +">"………………………………………………………………………

Case ?y=y+1

temp=temp+"<Parametr1" + cstr(y) +">"temp=temp+"<Parametr2" + cstr(objItem.Value1) +">"temp=temp+"<Parametr3" + cstr(objItem.Value2) +">"……………………………………………………temp=temp+"<Parametr?" + cstr(objItem.Value?) +">"temp=temp+"</Parametr1" + cstr(y) +">"

End SelectNext

NextSet FileName=”\\server\folder”Set fso = CreateObject("Scripting.FileSystemObject")Set f = fso.OpenTextFile(FileName, 2, True)f.Write tempf.Close

Set colItems = objWMIService.ExecQuery(“SELECT * FROM” ↵& strClass(a))

Set colItems = objWMIService.InstancesOf(strClass(a))

Òàáëèöà 3

Ïðèìåð 3 Ñîçäàíèå XML-ôàéëà

dim strClassstrClass=Array("Win32_ComputerSystem", "Win32_BIOS", ↵

"Win32_CDROMDrive")Set objWMIService = GetObject("winmgmts://./Root\Cimv2")for a=0 to 2

Set colItems = objWMIService.InstancesOf(strClass(a))For Each objItem in colItems

select case a

case 0FileName="\\server\folder\" & cstr(objItem.Name) & ".xml"temp=temp + "<Computer><PCName>" + objItem.Name + ↵

"</PCName>" + chr(10)temp=temp + " <Domain> " + objItem.Domain + ↵

" </Domain>" + chr(10)temp=temp + "<User> " + objItem.Username + ↵

" </User>" + chr(10)temp = temp + "<Date>" + cstr(Date()) + "; ↵

" + cstr(Time()) + "</Date> </Computer>" + chr(10)

case 1temp=temp + "<MB> <Version> " + objItem.Version + ↵

" </Version>" + chr(10)temp=temp + "<Mbinfo> " + objItem.SMBIOSBIOSVersion + ↵

" </Mbinfo></MB>" + chr(10)case 2b=b+1

temp=temp + "<CD-ROM" + cstr(b) +"> <Model>" + ↵objItem.Caption + " </Model>" + chr(10)

temp=temp + "<Description>" + objItem.Description + ↵" </Description>" + chr(10)

temp=temp + "<Letter>" + objItem.Drive + ↵" </Letter> </CD-ROM" + cstr(b) +">" + chr(10)end selectNext

NextSet fso = CreateObject("Scripting.FileSystemObject")Set f = fso.OpenTextFile(FileName, 2, True)f.Write "<inf>" & temp & "</inf>"f.Close

Ðèñóíîê 3. Ïðèìåð XML-ôàéëà

Page 33: 013 Системный Администратор 12 2003

31№12(13), декабрь 2003

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

ница на языке HTML. Сайт создан на основе окон (Frameset):файл default.htm делит окно браузера на два столбца. Текстфайла default.htm (HTML) см. в Приложении 2.

Остальные страницы написаны на ASP и взаимосвя-заны друг с другом. Для их создания выбран VBScript.VBScript выбран потому, что является языком, поставля-емым с Microsoft Windows; обладает необходимыми воз-можностями для реализации данного проекта, имеет про-стой синтаксис.

С помощью файла xml_list.asp осуществляется чтениеXML-файлов в заданном каталоге, составляется списокрабочих станций или пользователей в домене. Выборсписка осуществляется в HTML-файле. Вторая задача, ре-шаемая этим файлом, – осуществление поиска по ука-занному значению. Поиск является сквозным, т.е. поискпроисходит по всем полям всех файлов. Результатом по-иска является таблица, левый столбец которой содержитв себе название рабочей станции, правый – значение па-раметра в контексте (см. рис. 5).

Второй ASP-файл – analyse.asp, предназначен для ото-бражения информации по интересующей системного ад-министратора рабочей станции.

Принцип работы файлаxml_list.asp

Чтение данных из XML-файлаПроцесс чтения значений параметров XML-файла, как идругих структурированных файлов, состоит из несколь-ких этапов:� получение списка файлов, которые необходимо обра-

ботать;� чтение полей и занесение их в массивы;� упорядочивание массивов по одному из полей;� отображение полученной информации.

Рассмотрим каждый из этих этапов подробнее.

Шаг 1. Получение списка файловв указанном каталогеПолучение списка файлов осуществляется с помощьюWindows Hosting Script (WSH). WSH был предложен в 1998году Microsoft в качестве инструмента разработки и вы-полнения сценариев для операционной системы MicrosoftWindows. Бесспорным достоинством WSH является тотфакт, что он входит в комплект поставки Microsoft Windowsи поддерживает два встроенных в Microsoft Windows язы-ка программирования – Microsoft Visual Basic Script Edition(VBScript) и Miscrosoft Java Script Edition(Jscript).

В приведенном ниже примере (VBScript), осуществля-ется чтение имен всех файлов, находящихся в каталоге,указанном в переменной Path, и вывод этой информациина экран:

Шаг 2. Чтение полей и занесение их в массивыЧтение полей XML-файла осуществляется с помощью объек-та Microsoft.XMLDOM. XML-файл представляет собой струк-турированную базу данных. Для чтения полей XML-файланеобходимо четко представлять принцип построения кар-ты XML-файла. Рассмотрим карту, представленную на ри-сунке 3: она имеет 4 раздела – Computer, MB, CD-ROM1 иCD-ROM2. Видно, что в ширину XML-файл имеет четыреячейки. Количество ячеек можно определить с помощьюфункции .childNodes.Lenght-1. Каждая из ячеек имеет глу-бину – второе измерение (см. рис. 3). Глубина одной ячейкиможет быть отлична от другой. В приведенном примере глу-бина каждой из ячеек различна. Например, глубина ячейкиComputer равна четырем – PCName, Domain, User, Data. Глу-бина ячейки определяется функцией функции .childNodes(i).childNodes.Lenght-1, где i – номер ячейки. Название ячейкиосуществляется с помощью функции .childNodes(i).child-Nodes(j).NodeName, где i – номер ячейки, j – ее глубина.Вызывая функция .childNodes(2).childNodes(0).NodeName длярис. 3, в результате получим «Model». Необходимо отметить,что нумерация и ширины поля XML и глубина ячеек начина-ются с нуля. Чтение значения параметра осуществляется спомощью функции .childNodes(i).childNodes(j).Text, где i и jимеют ту же смысловую нагрузку, что и ранее.

Необходимо отметить одну особенность: при чтении зна-чения уровня, ниже которого есть уровень, который такжесодержит значения, происходит логическое сложение дан-ных нижнего уровня и присовокупление их к верхнему. Рас-смотрим этот процесс на примере карты на рис. 3. Резуль-татом чтения .childNodes(3).Text будет выражение «SONYDVD-ROM DDU1211 CD-ROM Drive F:». Именно эта способ-ность сквозного просмотра ячейки до дна будет использо-вана при поиске по заданному значению. Приведем при-мер, который иллюстрирует эту особенность:

Зная основные принципы чтения XML-файла, приведемпример, в котором сначала происходит чтение списка изназваний файлов, находящихся в каталоге; затем чтениедвух полей в каждом файле – название рабочей станции иимени пользователя с последующим занесением в массивкаждого из параметров. Необходимо отметить, что в при-веденном примере переопределяется размер массивов, вкоторые в конце примера будут заноситься названия рабо-чих станций и имен пользователей. Переопределение раз-меров массивов осуществляется с помощью функции redimpreserve array_name(count), где array_name – название мас-

Ïðèìåð 4. ×òåíèå íàçâàíèé ôàéëîâ, ñîäåðæàùèõñÿ â êàòàëîãå

Path="\\Server\Folder"Set a=Wscript.CreateObject("Wscript.Shell")Set fso=CreateObject("Scripting.FileSystemObject")Set oFolder=fso.GetFolder(a.ExpandEnvironmentStrings(Path))

Set oFiles=oFolder.FilesFor each oFile in oFilestemp=temp+oFile.Name & chr(10)next

MsgBox temp

Ïðèìåð 5. Ñêâîçíîå ÷òåíèå ÿ÷åéêè XML-ôàéëà

<%@ Language=VBScript%><% path="xml\10000PC.xml"set xmlVisitor=server.CreateObject("Microsoft.XMLDOM")XMLFile=xmlVisitor.load(server.MapPath(path))With xmlVisitor.documentElement

response.write .childNodes(3).textEnd Withset xmlVisitor=Nothing %>

Page 34: 013 Системный Администратор 12 2003

32

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

сива, а count – новый размер массива. Полный листингфайла xml_list.asp см. в Приложении 2.

Шаг 3. Упорядочивание массивовпо одному из полейУпорядочивание массива является классической задачей,поэтому нет необходимости углубляться в то, как это де-лается. В данном случае применен пузырьковый методупорядочивания массивов. Следует отметить, что, читаяXML-файлы, формируются два массива. Задача состоитв том, чтобы упорядочить один из массивов, при этом ненарушить соответствия элементов второго массива пер-вому массив. Для достижения этой цели используетсятретий массив – array_sort(i), элементам которого присва-иваются в зависимости от поставленного условия элемен-ты первого или второго массивов.

Шаг 4. Отображение полученной информацииПосле упорядочивания массивов обработанная информа-ция готова к отображению в браузере. В зависимости отзначения параметра sort в HTML-файле, выводится либосписок пользователей, либо список рабочих станций до-мена. Оба списка упорядочены по алфавиту. Рассмотриммеханизм передачи данных из одной страницы в другую.Данные могут передаваться двумя способами: прямым икосвенным.

Прямой метод:В исходной странице создается форма, которая содержитполя для ввода информации и кнопку для отправки инфор-мации и загрузки страницы, принимающей данные (HTML):

В разделе FORM присутствуют следующие парамет-ры: ACTION, TARGET, METHOD. В параметре ACTION ука-зывается файл, в который будут передаваться данныепосле нажатия на кнопку.

Подразделом, который обязательно присутствует в раз-деле FORM, является INPUT. INPUT имеет следующие па-раметры: TYPE, NAME, VALUE. Параметр TYPE определя-ет вид приемника информации: кнопка (TYPE=«submit» или«reset»); окно для ввода текста (TYPE=«text»), значение поумолчанию; кнопка выбора одного параметра из группы(TYPE=«radio»). VALUE – название поля, отображаемое вобъекте. NAME – имя, которое участвует в формированиизапроса.

Запрос, который формируется с помощью метода GET,в общем виде выглядит следующим образом:

В приведенной строке присутствуют следующие обо-значения: П – параметр, З – значение.

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

если в строке было введено «value1».Рассмотрим «страницу-приемник»: для получения пе-

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

таким образом, параметр search_value=«value1».

Косвенный метод:Косвенный метод используется для передачи данных изодной ASP-страницы в другую. Он основан на том, что

Ïðèìåð 6. Ôîðìèðîâàíèå ìàññèâîâ èç íàçâàíèé ðàáî÷èõ ñòàíöèéè ó÷åòíûõ çàïèñåé ïîëüçîâàòåëåé

<%@ Language=VBScript%><% path="\\server\folder"Set a=CreateObject("Wscript.Shell")Set fso=CreateObject("Scripting.FileSystemObject")Set oFolder=fso.GetFolder(a.ExpandEnvironmentStrings(path))Set oFiles=oFolder.Files

set xmlVisitor=server.CreateObject("Microsoft.XMLDOM")dim array_pcname()dim array_username()redim preserve array_pcname(oFiles.count)redim preserve array_username(oFiles.count)

i=0For each oFile in oFiles

XMLFile=xmlVisitor.load(server.MapPath(path ↵& oFile.Name))

With xmlVisitor.documentElementUN=.childNodes(0).childNodes(2).textarray_filename(i)=oFile.Namearray_pcname(i)=.childNodes(0). ↵

childNodes(0).textarray_username(i)=right(UN, ↵

len(UN)-instr(UN,"\"))i=i+1

End WithNext

set xmlVisitor=Nothing %>

Ïðèìåð 7. Óïîðÿäî÷èâàíèå âçàèìîñâÿçàííûõ ìàññèâîâ

<%@ Language=VBScript%><% path="\\server\folder"…………………………………

'Âåðõíÿÿ ãðàíèöà ìàññèâîâ îïðåäåëÿåòñÿ ñ ïîìîùüþ ôóíêöèè'Ubound(). Óñëîâèå ñîðòèðîâêè ìàññèâà îñóùåñòâëÿåòñÿ ñ'ïîìîùüþ StrComp().

dim array_sort ()redim preserve array_sort(oFiles.count)size_array=ubound(array_sort)…………………………………

on error resume nextfor j=0 to size_array

for i=0 to size_arrayif strcomp(array_sort(i),array_sort(i+1),0)=1 then

temp=array_sort(i)array_sort(i)=array_sort(i+1)array_sort(i+1)=temptemp=array_pcname(i)array_pcname(i)=array_pcname(i+1)array_pcname(i+1)=temptemp=array_pcname(i)array_pcname(i)=array_pcname(i+1)array_pcname(i+1)=temp

end ifnext

next %>

Ïðèìåð 8. Ïðÿìîé ìåòîä ôîðìèðîâàíèÿ çàïðîñîâ

<FORM ACTION="printer_adsi.asp" TARGET="main" METHOD="get"> <INPUT TYPE="submit" VALUE="Ïîèñê"></INPUT> <INPUT NAME="Search_Text"></INPUT></FORM>

http://èìÿ_ñòðàíèöà.asp(htm)?Ï1=Ç1&Ï2=Ç2&...Ïn=Çn

http://printer_adsi.asp?Search_Text=value1

Set search_value= Request.QueryString(«Search_Text»)

Page 35: 013 Системный Администратор 12 2003

33№12(13), декабрь 2003

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

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

Поскольку очередью принтера невозможно управлять,если рассматривать принтер как сетевое устройство, тоиспользование протокола LDAP становится невозможным.Для доступа к очереди принтера, как ранее отмечалось,используется протокол WINNT. Для использования про-токола необходимо передавать 2 параметра: сетевое имяпринтера (Share Name) и название окна (Frame), в кото-ром необходимо вывести данную страницу. Опираясь наприведенные ранее примеры, данные будут передавать-ся на страницу View_Printer.asp, запрос будет иметь сле-дующий вид (ASP):

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

В приведенном примере определяется значение пара-метра sort. Если параметр sort=1, то перед сортировкоймассива происходит присвоение элементов массиваarray_pcname(i) массиву array_sort(i). В том случае, еслиsort=2, происходит присвоение элементов массиваarray_username(i).

Вывод информации осуществляется с помощью кон-струкции Response.Write «Value». Информация являетсягиперссылкой на второй фрейм. Название фрейма, в ко-тором будет загружаться HTML-страница, указывается впараметре target. Название фрейма задается в HTML-странице, которая является родительским объектом дляобоих ASP-страниц (см. Приложение 2, файл default.htm).В гиперссылке также формируется запрос, содержащийпараметр, значением которого является UNC-путь, вклю-чающий имя XML-файла, который необходимо прочитать.

Поиск данных в XML-файлеВторая задача, решаемая файлом xml_list.asp – осуще-ствление поиска по указанному значению. Поиск проис-ходит по всем полям всех файлов. Результатом поискаявляется таблица, левый столбец которой содержит в себеназвание рабочей станции, правый – значение парамет-ра в контексте. Рекурсивная передача данных в файлеxml_list.asp осуществляется с помощью прямого метода,который был рассмотрен в предыдущем разделе (см. при-мер 8). Методика поиска основана на использовании осо-бенности XML-файла – сквозного просмотра ячейки додна. Более подробную информацию и наглядный примериспользования этой особенности можно найти в преды-дущем разделе (см. пример 5). Приведем пример, демон-стрирующий реализацию процесса поиска. Параметрsearch_var содержит в себе искомое словосочетание:

Ïðèìåð 9. Êîñâåííûé ìåòîä ôîðìèðîâàíèÿ çàïðîñîâ

<% <A HREF=""View_Printer.asp?Printer_to=" & printer_name ↵& "" "target=""var"" > <IMG SRC =images\pr1.jpg ↵BORDER=0> </A> %>

Ïðèìåð 10. Ôîðìèðîâàíèå çàïðîñîâ â çàâèñèìîñòè îò çíà÷åíèÿïàðàìåòðà sort

<%@ Language=VBScript%><% path="\\server\folder"…………………………………

set sort_var = Request.QueryString("sort")select case sort_var

case 1for i=0 to size_arrayarray_sort(i) = array_pcname(i)next

case 2for i=0 to size_arrayarray_sort(i) = array_username(i)next

end select…………………………………

for i=0 to size_array-1select case sort_varcase 1

response.write "<a href=analyse.asp?FN=" & fname & ↵array_filename(i+1) & "&Sort=" & sort_var & " ↵target=""analyse"" title=""Èìÿ ïîëüçîâàòåëÿ - " & ↵array_username(i) &""" a>" & array_pcname(i) &"</a><BR>"

case 2response.write "<a href=analyse.asp?FN=" & fname & ↵

array_filename(i+1) & "&Sort=" & sort_var & " ↵

target=""analyse"" title=""Ðàáî÷àÿ ñòàíöèÿ - " & ↵array_pcname(i) &""" a>" & array_username(i) &"</a><BR>"

end select next …………………………………%>

Ïðèìåð 11. Ïðîöåäóðà ïîèñêà â XML-ôàéëàõ<%@ Language=VBScript%><%…………………………………XMLFile=xmlVisitor.load(server.MapPath(fname ↵

& oFile.Name))For each oFile in oFiles

With xmlVisitor.documentElementFor i=0 to .childNodes.length-1

if instr(Lcase(.childNodes(i).text),LCase(search_var)) thenResponse.Write " <TR> <TD width=100><H6><a ↵

href=analyse.asp?FN=" & fname & ofile.name & " ↵target=""analyse"">" & ↵left(oFile.Name,len(oFile.Name)-4)& " </a> </TD><H6> ↵<TD><H6>" & .childNodes(i).text & "</TD><H6></TR>"end if

NextEnd With

Next Response.Write "</Table>" …………………………………%>

Ðèñóíîê 4. Ðåçóëüòàò ïîèñêà

Page 36: 013 Системный Администратор 12 2003

34

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

Принцип работы файла analyse.asp

Стилизация оформления страницОбе ASP-страницы используют таблицу стилей и работа-ют в кодировке WIN-1251. Стили описываются в подклю-чаемом файле style.css (см. Приложение 2) .Файл стилейуказывается в разделе LINK, необходимая кодировка – вразделе META (HTML):

Параметр CHARSET отвечает за выбор кодировки, в ко-торой будет отображаться документ. После задания таблицыстилей и подключения этой таблицы в ASP или HTML-файле,можно приступить к использованию данной таблицы. Опи-раясь на приведенный пример таблицы стилей, в ASP- илиHTML-файле открывается и закрывается соответствующийраздел – тэг, например: <H4> «Hellow» </H4>. В приведенномпримере начертание слова Hellow будет выдержано в стиле<H4>, т.е. будет написано шрифтом Arial 11-го размера.

Формирование страницы отчетаПроцесс формирования страницы отчета состоит из двухэтапов:

� чтение переданного параметра из файла xml_list.asp,содержащего UNC-путь и название XML-файла;

� чтение параметров из XML-файла и формирование от-чета; вывод результата на экран. Чтение параметра осу-ществляется с помощью функции Request.QueryString(),которая была ранее многократно описана. Затем ука-занный в запросе XML-файл открывается для чтения.Чтение файла осуществляется по описанной ранее ме-тодике.

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

Внедрение сценария загрузкиВнедрение сценария загрузки состоит из нескольких этапов:� В свойствах каждого пользователя необходимо про-

писать в разделе Logon Script сценарий загрузки (см.рис. 6). Поскольку сценарий должен быть гибким, торекомендуется создать файл Script.bat и в нем пропи-сывать скрипты. Предлагаемое модульное решение вслучае сбоя позволит быстро справиться с возникшейпроблемой, при этом лишив пользователя минималь-ного количества сервисов, которые предлагаются на-бором сценариев загрузки.

Ïðèìåð 12. Óñòàíîâêà êîäèðîâêè è ÷òåíèå òàáëèöû ñòèëåé

<HEAD><LINK HREF="style.css" TYPE=text/css REL=stylesheet><META HTTP-EQUIV ="Content-Type" CONTENT="text/html;

CHARSET=windows-1251"></HEAD>

Ðèñóíîê 5. Ñòàòèñòèêà ïî ðàáî÷åé ñòàíöèè

Page 37: 013 Системный Администратор 12 2003

35№12(13), декабрь 2003

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

Естественно, что прописывать сценарий загрузки длякаждого пользователя вручную – занятие неблагодарное,поэтому предлагается скрипт, который позволит автомати-зировать данную задачу. Скрипт будет прописан всемпользователям домена, кроме тех, которые входят в группу.Название файла присваивается Logon Script (см. рис. 6).Приведенный скрипт перебирает учетные записи всехпользователей домена и проверяет членство пользователяв группе. Если пользователь не входит в группу, то в свой-ствах этого пользователя прописывается сценарий загруз-ки. Необходимо отметить, что сценарий загрузки самостоя-тельно определяет название домена, в котором находитсяпользователь, запускающий скрипт; скрипт должен бытьзапущен с правами администратора, т.к. изменения в ActiveDirectory могут быть внесены только системным админист-ратором; для увеличения скорости отработки скрипта реко-мендуется запускать сценарий на контроллере домена; груп-па, созданная для пользователей, которым сценарий заг-рузки не нужен, может быть создана в любом месте ActiveDirectory; группа должна быть глобальной; название группыи скрипта, который прописывается в свойствах пользовате-ля, могут быть изменены в ходе выполнения скрипта. Текстскрипта см. в Приложении 1 – файл auto_script.vsb.� Файл Script.bat (пример файла см. в Приложении 1) и

VBS-файл должны находиться в каталоге Netlogon кон-троллера домена. Физически эта папка находится в ка-талоге с установленной операционной системой в под-каталоге SYSVOL\Domain\Script\.

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

В разделе групповой политики «User Configuration» вамнеобходимо, соответственно, включить «Run legacy logon scriptsynhronously» (Запускать сценарий загрузки синхронно) и«Run legasy script hidden» (Запускать сценарий скрыто).

Установка сайта и особенностиконфигурирования IISДля работы ASP-страницы, созданный сайт необходимоопубликовать с помощью IIS на любом компьютере доме-на. Желательно, чтобы этим компьютером был компью-тер, который функционирует круглосуточно. Таким ком-пьютером является сервер. Теоретически просматриватьрезультаты могут все пользователи сети, однако это не-рационально. Необходимо назначить следующие правадоступа на папку, в которой опубликован сайт: группе«Domain Admins» необходимо предоставить уровень дос-тупа «Full Control» на папку с сайтом; остальные группы ипользователи должны быть удалены (см. рис. 8). В на-стройке IIS для данного сайта в его свойствах необходи-мо, как показано на рис. 9, войти во вкладку «AuthenticationMethods», нажав на кнопку «Edit». Затем выключить ано-нимный доступ (Anonnymos access), убрав галку напро-тив соответствующей записи. В разделе «Authenticatedaccess» необходимо установить галку только напротив«Basic authentication».

Желательно включить «Integrated Windows authentication»для того, чтобы системному администратору, который во-шел в сеть под своей учетной записью, не предлагалосьвводить пароль. Однако этот механизм доступа к сайтуневозможен по неизвестным причинам. Рекомендуется неставить эту галку.

Ðèñóíîê 6. Ñöåíàðèé çàãðóçêè

Ðèñóíîê 7. Ãðóïïîâûå ïîëèòèêè

Ðèñóíîê 8

Page 38: 013 Системный Администратор 12 2003

36

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

ЗамечаниеКомпания Microsoft утверждает, что корректно работатьс WMI можно только пользователю с административнымипривилегиями. Практика показывает, что более 90% па-раметров корректно определяются при работе с WMI безналичия административных привилегий и привилегийопытного пользователя. Замечено, что для пользовате-ля, не обладающего привилегиями, возникают проблемыпри определении биоса материнской платы и характери-стик жесткого диска. Возникшие проблемы решаются чте-нием соответствующих ветвей реестра с помощьюVBScript или WSH. Пользователи, имеющие привилегииопытного пользователя на локальной машине, не испы-тывают никаких неудобств.

Ðèñóíîê 9

Приложение 1

Sysinfo.VBS

dim strClassstrClass=Array("Win32_ComputerSystem", "Win32_BIOS", ↵

"Win32_Processor", "Win32_PhysicalMemory", ↵"Win32_SoundDevice", "Win32_VideoConfiguration", ↵"Win32_NetworkAdapter", "Win32_USBController", ↵"Win32_CDROMDrive", "Win32_DiskDrive", ↵"Win32_LogicalDisk", "Win32_DiskPartition")

Set objWMIService = GetObject("winmgmts://./Root\Cimv2")for a=0 to 11Set colItems = objWMIService.InstancesOf(strClass(a))

For Each objItem in colItemsselect case a

case 0FileName=objItem.Name & "_Ïðèëîæåíèå1.xml"temp=temp + "<Computer><PCName>" + objItem.Name + ↵

"</PCName>" + chr(10)temp=temp + " <Domain> " + objItem.Domain + " ↵

</Domain>" + chr(10)temp=temp + "<User> " + objItem.Username + ↵

" </User>" + chr(10)temp = temp + "<Date>" + cstr(Date()) + "; ↵

" + cstr(Time()) + "</Date> </Computer>" + chr(10)

case 1

temp=temp + "<MB> <Version> " + objItem.Version + ↵" </Version>" + chr(10)

temp=temp + "<Mbinfo> " + objItem.SMBIOSBIOSVersion + ↵" </Mbinfo></MB>" + chr(10)

+case 2

temp=temp + "<CPU> <Name> " + objItem.name + ↵" </Name>" + chr(10) ' CPU name

temp=temp + "<Description> " + objItem.Description + ↵" </Description>" + chr(10) ' Description

temp=temp + "<Socket> " + objItem.SocketDesignation + ↵" </Socket></CPU>" + chr(10) ' Socket type

case 3if b=0 thentemp=temp +"<Memory>"end if

b=b+1temp=temp+"<Device" + cstr(b) +">"temp=temp+" <Slot> " + objItem.DeviceLocator + " </Slot> "temp=temp+" <Capacity> " + objItem.Capacity + "</Capacity> "temp=temp+"</Device" + cstr(b) +">"

case 4if c=0 thentemp=temp +"</Memory>" & chr(10) &"<Audio>"end if

c=c+1temp=temp+"<Device" + cstr(c) + "> "temp=temp+"<Manufacturer> " + objItem.Manufacturer + ↵

" </Manufacturer> "temp=temp+"<Name> " + objItem.Name + " </Name> "temp=temp+"</Device" + cstr(c) + "> "

case 5if d=0 thentemp=temp +"</Audio>" & chr(10) &"<Video>"end if

d=d+1temp=temp+"<Device" + cstr(d) + "><Type> " + ↵

objItem.AdapterType+ " </Type> "temp=temp+"<Memory> " + cstr(objItem.AdapterRAM) + ↵

"</Memory> "temp=temp+ "<Resolution>"+ ↵

cstr(objItem.HorizontalResolution)+ ↵"x"+cstr(objItem.VerticalResolution)+ ↵"x"+cstr(objItem.BitsPerPixel)+"@"+ ↵cstr(objItem.RefreshRate)+"Hz</Resolution>"

temp=temp+"</Device" + cstr(d) + "> "

case 6if e=0 thentemp=temp +"</Video>" & chr(10) &"<NetCard>"end ife=e+1if objItem.MacAddress<>"" thenq=q+1temp=temp+"<Device" + cstr(q) + "> ↵

<Manufacturer>"+objItem.Manufacturer+"</Manufacturer>"temp=temp+"<Name>"+objItem.Name+"</Name>"temp=temp+"<MAC>"+objItem.MacAddress+"</MAC> ↵

</Device" + cstr(q) + "> "end if

case 7if g=0 thentemp=temp +"</NetCard>" & chr(10) & "<USB>"end if

if objItem.Name<>"" theng=g+1temp=temp + "<NameUSB" + cstr(g) +">" + objItem.Name + ↵

"</NameUSB" + cstr(g) +"> " + chr(10)' USB Controllerend if

case 8if h=0 thentemp=temp +"</USB>" & chr(10) & "<CD-ROM>"end if

if objItem.Caption<>"" thenh=h+1temp=temp + "<Device" + cstr(h) +"> <Model>" + ↵

objItem.Caption + " </Model>" + chr(10) ' Modeltemp=temp + "<Description>" + objItem.Description + ↵

Page 39: 013 Системный Администратор 12 2003

37№12(13), декабрь 2003

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

Script.BAT

AutoScript.VBS" </Description>" + chr(10) ' Descriptiontemp=temp + "<Letter>" + objItem.Drive + " </Letter> ì

</Device" + cstr(h) +"> " + chr(10) ' Letter

end if

case 9if i=0 thentemp=temp + "</CD-ROM>" & chr(10) & " <HDD>"end if

i=i+1temp=temp + "<Device" +cstr(i) +"> <Model>" + ↵

objItem.Caption + " </Model>" + chr(10) ' Modeltemp=temp + "<Description>" + objItem.Description + ↵

" </Description>" + chr(10) ' Descriptiontemp=temp + "<Size>" + cstr(objItem.Size) + ↵

" </Size>" + chr(10) ' Size of HDDtemp=temp + "<Number>" + cstr(objItem.Index) + ↵

" </Number>" + chr(10) ' Number of HDDtemp=temp + "<Partitions>" + cstr(objItem.Partitions) + ↵

" </Partitions> </Device" + cstr(i) +">" + ↵chr(10)' Number of partitions

case 10if k=0 thentemp=temp + "</HDD>" & chr(10) & " <Media>"end if

k=k+1temp=temp +"<Device" +cstr(k) +"> <Letter>" + ↵

objItem.Name + " </Letter>" + chr(10) ' Lettertemp=temp + "<Description>" + cstr(objItem.Description) + ↵" </Description>" + chr(10) ' Descriptionif objItem.FileSystem<>"" thentemp=temp + "<FullSize>" + objItem.Size + ↵

" </FullSize>" + chr(10) ' File Systemtemp=temp + "<FreeSize>" + objItem.FreeSpace + ↵

" </FreeSize>" + chr(10) ' File Systemend iftemp=temp +"</Device" + cstr(k) +"> "

case 11if l=0 thentemp=temp + "</Media> " & chr(10) & "<Partition>"end if

l=l+1temp=temp + "<Device" + cstr(l) +"> <Name>" + ↵

objItem.Name + " </Name>" + chr(10) ' Modeltemp=temp + "<Size>" + cstr(objItem.Size) + " </Size> ↵

</Device" + cstr(l) +">" + chr(10) ' Number of partitions

end selectNext

Next

temp=temp + "</Partition>"

Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.OpenTextFile(FileName, 2, True) f.Write "<inf>" & temp & "</inf>" f.Close

msgbox "end"

@ECHO OFF

if c:\%os%==c:\ goto win9xif not c:\%os%==c:\ goto winnt:winnt@echo Ïîäîæäèòå! Âûïîëíÿåòñÿ íàñòîéêà Âàøåãî êîìïüþòåðà.start /wait sysinfo.vbsgoto end:win9x@echo windows 9x%0\..\Script. sysinfo.vbsgoto end

:end@echo End Of Batch File

Set objNameSpace = GetObject("WinNT:")For Each Domain in objNameSpace

strDomain Domain.NameNext

Set Users_Domain = getobject("WinNT://" & strDomain)Users_Domain.Filter = Array("user")

strGroup="Skip"strGroup = InputBox("Group:", "Skip users", "Skip")

strScript="Script.bat"strScript=InputBox("Script:","Script Name", ↵

" Script.bat ")

For each user in users_domaini=0a=user.nameSet user_group = GetObject("WinNT://" & ↵

strDomain & "/" & strGroup)For each user_group in ↵

user_group.Membersb=user_group.name

if b=a theni=1end if

nextif i=0 then

User.LoginScript=strScriptUser.setinfo

End ifNext

Приложение 2

Default.HTM

Stylet.CSS

Xml_List.ASP

<HTML><HEAD><!-- Ëåâûé ñòîëáåö ñîñòàâëÿåò 30% îò øèðèíû âñåãî îêíà.Ëåâîå îêíî èìååò èäåíòèôèêàòîð «main», âòîðîå «var». --><TITLE>Ñïèñîê äîñòóïíûõ ñåòåâûõ ïðèíòåðîâ </TITLE><META HTTP-EQUIV ="Content-Type" CONTENT="text/html; ↵

CHARSET=windows-1251"></HEAD><!-- Åñëè ïàðàìåòð sort=1, îñóùåñòâëÿåòñÿ ñîðòèðîâêà ïîíàçâàíèþ ðàáî÷èõ ñòàíöèé, åñëè sort=2 – ñîðòèðîâêà èäåòïî èìåíè ïîëüçîâàòåëÿ». --><FRAMESET cols="30%,*" FRAMEBORDER="5" BORDER="yes" ↵

FRAMESPACING="5" ><FRAME SRC="xml_list.asp?sort=1&Search_Text=""" ↵

NAME="xml" SCROLLING="yes" ÌÀRGINHEIGHT=1 ><FRAME SRC ="about:blank" NAME="var"></FRAMESET ></HTML>

H4 {font-size:11; font-family:Arial;}H5 {font-size:10; font-family:Arial;}H6 {font-size:9; font-family:Arial;}

<%@ Language=VBScript CODEPAGE=1251%><HEAD><LINK href="style.css" type=text/css rel=stylesheet><meta http-equiv="Content-Type" content="text/html" ↵

charset=windows-1251><meta http-equiv="refresh" content=10 ></HEAD><BODY>

<H4><b><center>"Èíôîðìàöèÿ î ðàáî÷èõ ↵ñòàíöèÿõ"</center></H4> <br> <h6>

<FORM ACTION="xml_list.asp" target="xml" METHOD="get"><INPUT TYPE="submit" VALUE="Ïîèñê"></INPUT><INPUT NAME="Search_Text"></INPUT>

</FORM> </h6>

Page 40: 013 Системный Администратор 12 2003

38

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

<%set search_var = Request.QueryString("Search_Text")set sort_var = Request.QueryString("sort")

path="\\server\folder"Set a=CreateObject("Wscript.Shell")Set fso=CreateObject("Scripting.FileSystemObject")Set oFolder=fso.GetFolder(a.ExpandEnvironmentStrings(path))Set oFiles=oFolder.Files

set xmlVisitor=server.CreateObject("Microsoft.XMLDOM")

dim array_pcname()dim array_username()dim array_sort()dim array_filename()redim preserve array_pcname(oFiles.count)redim preserve array_username(oFiles.count)redim preserve array_sort(oFiles.count)redim preserve array_filename(oFiles.count)size_array=ubound(array_sort)i=0

For each oFile in oFilesXMLFile=xmlVisitor.load(server.MapPath(path ↵

& oFile.Name))

With xmlVisitor.documentElementUN=.childNodes(0).childNodes(2).textarray_filename(i)=oFile.Namearray_pcname(i)=.childNodes(0).childNodes(0).textarray_username(i)=right(UN, len(UN)-instr(UN,"\"))i=i+1

End Withnext

if search_var="" thenselect case sort_varcase 1

for i=0 to size_arrayarray_sort(i) = array_pcname(i)next

case 2for i=0 to size_arrayarray_sort(i) = array_username(i)next

end select

on error resume nextfor j=0 to size_array

for i=0 to size_arrayif strcomp(array_sort(i),array_sort(i+1),0)=1 then

temp=array_sort(i)array_sort(i)=array_sort(i+1)array_sort(i+1)=temp

temp=array_pcname(i)array_pcname(i)=array_pcname(i+1)array_pcname(i+1)=temp

temp=array_pcname(i)array_pcname(i)=array_pcname(i+1)array_pcname(i+1)=temp

temp=array_filename(i)

array_filename(i)=array_filename(i+1)array_filename(i+1)=temp

end ifnext

next

for i=0 to size_array-1select case sort_varcase 1

response.write "<a href=analyse.asp?FN=" & ↵fname & array_filename(i+1) & "&Sort=" & ↵sort_var & " target=""analyse"" ↵title=""Èìÿ ïîëüçîâàòåëÿ - " & ↵array_username(i) &""" a>" & ↵array_pcname(i) &"</a><BR>"

case 2response.write "<a href=analyse.asp?FN=" & ↵

fname & array_filename(i+1) & "&Sort=" & ↵sort_var & " target=""analyse"" ↵title=""Ðàáî÷àÿ ñòàíöèÿ - " & ↵array_pcname(i) &""" a>" & ↵array_username(i) &"</a><BR>"

end selectnext

<%@ Language=VBScript CODEPAGE=1251%><HEAD><LINK href="style.css" type=text/css rel=stylesheet><meta http-equiv="Content-Type" content="text/html" ↵

charset=windows-1251>

</HEAD><%set path=Request.QueryString("fn")set xmlVisitor=server.CreateObject("Microsoft.XMLDOM")XMLFile=xmlVisitor.load(server.MapPath(path))

With xmlVisitor.documentElement

Response.Write "<H4> Ðàáî÷àÿ ñòàíöèÿ</H4> ↵<table width=""100%"", Cellpacing=""0"">"

Response.Write " <TR> <TD width=300><H6> Ðàáî÷àÿ ñòàíöèÿ ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(0).childNodes(0).text & "</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ïîëüçîâàòåëü ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(0).childNodes(2).text & "</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Äîìåí </TD><H6> ↵<TD width=300><H6>" & ↵.childNodes(0).childNodes(1).text & "</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Äàòà ðåãèñòðàöèè ↵â ñåòè</TD><H6> <TD width=300><H6>" & ì.childNodes(0).childNodes(3).text & "</TD><H6></TR>"

Response.Write "</Table>"

Response.Write "<H4> Ìàòåðèíñêàÿ ïëàòà, ïðîöåññîð, ↵ïàìÿòü</H4> <table width=""100%"", Cellpacing=""0"">"

Response.Write " <TR> <TD width=300><H6> Ìàòåðèíñêàÿ ïëàòà ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(1).childNodes(1).text & "</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ìîäåëü BIOS ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(1).childNodes(0).text & "</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ïðîöåññîð ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(2).childNodes(0).text & "</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ïîêîëåíèå ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(2).childNodes(1).text & "</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ðàçúåì ïðîöåññîðà ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(2).childNodes(2).text & "</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ñëîò è òèï RAM ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(3).childNodes(0).childNodes(0).text & ↵"</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ðàçìåð, Ìá ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(3).childNodes(0).childNodes(1).text/(1000*1000) ↵& "</TD><H6></TR>"

Response.Write "</Table>"

Analyse.ASP

else

Response.Write "<table width=""100%"", Cellpacing=""0"">"Response.Write "<TR><TD width=150><H4> Ðåçóëüòàòû ïîèñêà ↵

ïî </H4></TD><TD> <H6>" & search_var & "</H6></TD></TR>"Response.Write "<table width=""100%"", Cellpacing=""0"">"

For each oFile in oFilesXMLFile=xmlVisitor.load(server.MapPath(path ↵

& oFile.Name))With xmlVisitor.documentElement

for i=0 to .childNodes.length-1if instr(Lcase(.childNodes(i).text),LCase(search_var)) then

Response.Write " <TR> <TD width=50><H6><a ↵href=analyse.asp?FN=" & fname & ↵ofile.name & " target=""analyse"">" & ↵left(oFile.Name,len(oFile.Name)-4)& " ↵</a> </TD><H6> <TD><H6>" & ↵.childNodes(i).text & "</TD><H6></TR>"

end ifnext

End Withnext

Response.Write "</Table>"end ifset xmlVisitor=Nothing %>

Page 41: 013 Системный Администратор 12 2003

39№12(13), декабрь 2003

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

Response.Write "<H4> Æåñòêèå äèñêè</H4> ↵<table width=""100%"", Cellpacing=""0"">"

q=9for i=0 to .childNodes(q).childNodes.length-1

Response.Write " <TR> <TD width=300><H6> <i>" & ↵.childNodes(q).childNodes(i).childNodes(1).text & ↵i+1 & "</i></TD><H6><TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(0).text & ↵"</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ðàçìåð, Ãá ↵</TD><H6> <TD width=300><H6>" & ↵round(.childNodes(q).childNodes(i).childNodes(2). ↵

text/(1000*1000*1000),1) & "</TD><H6></TR>"Response.Write " <TR> <TD width=300><H6> ↵

Ëîãè÷åñêèõ ðàçäåëîâ</TD><H6> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(4).text & ↵

"</TD><H6></TR>"next

Response.Write "</Table>"

Response.Write "<H4> CD-ROM</H4> <table width=""100%"", ↵Cellpacing=""0"">"

q=8for i=0 to .childNodes(q).childNodes.length-1

Response.Write " <TR> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(1).text & ↵i+1 & "</TD><H6><TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(0).text & ↵"</TD><H6></TR>"next

Response.Write "</Table>"

Response.Write "<H4> Çâóêîâàÿ ïëàòà</H4> ↵<table width=""100%"", Cellpacing=""0"">"

q=4for i=0 to .childNodes(q).childNodes.length-1

Response.Write " <TR> <TD width=300><H6> <i> Àäàïòåð" & ↵i+1 & "</i> </TD><H6> <TD width=300><H6></TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ïðîèçâîäèòåëü ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(0).text & ì"</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ìîäåëü ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(1).text & ↵"</TD><H6></TR>"next

Response.Write "</Table>"

Response.Write "<H4> Ãðàôè÷åñêèé àäàïòåð</H4> ↵<table width=""100%"", Cellpacing=""0"">"

q=5

for i=0 to .childNodes(q).childNodes.length-1Response.Write " <TR> <TD width=300><H6><i> Àäàïòåð ↵

</i>" & i+1 & "</TD><H6> <TD width=300><H6></TD><H6></TR>"Response.Write " <TR> <TD width=300><H6> Ìîäåëü ↵

</TD><H6> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(0).text & ↵"</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ïàìÿòü, Ìá ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(1). ↵

text/(1000*1000) & "</TD><H6></TR>"Response.Write " <TR> <TD width=300><H6> ↵

Õàðàêòåðèñòèêè ýêðàíà </TD><H6> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(2).text & ↵"</TD><H6></TR>"next

Response.Write "</Table>"

Response.Write "<H4> Ñåòåâîé àäàïòåð</H4> ↵<table width=""100%"", Cellpacing=""0"">"

q=6for i=0 to .childNodes(q).childNodes.length-1

Response.Write " <TR> <TD width=300><H6> <i> Àäàïòåð ↵</i>" & i+1 & "</TD><H6> <TD width=300><H6></TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ïðîèçâîäèòåëü ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(0).text & ↵"</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> Ìîäåëü ↵</TD><H6> <TD width=300><H6>" & v.childNodes(q).childNodes(i).childNodes(1).text & ↵"</TD><H6></TR>"

Response.Write " <TR> <TD width=300><H6> ÌÀÑ-àäðåñ ↵</TD><H6> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(2).text & ↵"</TD><H6></TR>"next

Response.Write "</Table>"

Response.Write "<H4> USB </H4> <table width=""100%"", ↵Cellpacing=""0"">"

q=7for i=0 to .childNodes(q).childNodes.length-1

Response.Write " <TR> <TD width=300><H6> Ïîðò " & i+1 & ↵" </TD><H6> <TD width=300><H6>" & ↵.childNodes(q).childNodes(i).childNodes(0).text & ↵"</TD><H6></TR>"next

Response.Write "</Table>"

End Withset xmlVisitor=Nothing%>

Page 42: 013 Системный Администратор 12 2003

40

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

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

КРЕПОСТЬ ДЛЯ ПИНГВИНА

Page 43: 013 Системный Администратор 12 2003

41№12(13), декабрь 2003

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

Сегодня, как никогда, особое внимание уделяется защитесерверов и персональных компьютеров от вторжения из-вне. Описание различных методов атак можно найти прак-тически везде, у нападающего способов пробраться в чу-жой компьютер немало, да и с желающими также проблемобычно не бывает. Но сисадмину или обычному пользова-телю от этого не легче, все больше и больше приходитсяуделять времени чтению документации, настройке систе-мы, но время, как правило, не на стороне обороняющего-ся, да и опыт приходит вместе с ошибками. Ситуация усу-губляется тем, что производители в последнее время вы-пускают дистрибутивы по типу «два в одном», которыемогут быть с одинаковым успехом установлены как на сер-вер, так и на персональный компьютер, причем, по моемумнению, все равно, для того чтобы привлечь большее ко-личество народа, упор делается все-таки на последний.А пользователю главное – удобство, естественно, оно дос-тигается и путем уменьшения требований к защите. Чтоделать в таком случае? Не ждать же в самом деле, покасисадмин будет готов к выходу в Интернет. Можно, конеч-но, пойти на курсы, может, и научат, но фактор времениостается. Существует множество различных утилит, так илииначе предназначенных для улучшения защиты Linux-сис-темы, в данной статье хочу обратить внимание на проектBastille Linux, домашняя страница которого находится поадресу: http://www.bastille-linux.org/.

Помимо главной задачи – укрепление установленнойсистемы – разработчики Bastille Linux преследовали и дру-гие не менее важные цели:� всесторонность – все, что описано в открытых источ-

никах по поводу усиления защиты Linux, нашло своюреализацию Bastille Linux. В основу легли разработкиДжея Била (Jay Beale) по укреплению Solaris и Linux,нашедших свое отражение в книге института SANS(SysAdmin, Audit, Network, Security) «Securing Linux Stepby Step», руководство Курта Сеифриеда (Kurt Seifried)Linux Administrator’s Security Guide Linux (http://www.seifried.org/lasg/) и другие источники;

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

� сообщество – после того как были сделаны началь-ные разработки, было создано сообщество разработ-чиков, которое совместными усилиями вносило изме-нение в Bastille.

При помощи программы настройки Bastille Linux с цельюулучшения общей безопасности настраиваются демоны, из-меняются некоторые системные параметры и firewall. Допол-нительно (при необходимости) отключаются ненужные сер-висы вроде печати, rcp и rlogin. С ее помощью можно со-здать среду «chroot jails», при помощи которой можно умень-шить уязвимость некоторых интернет-сервисов вроде Webи DNS. В настоящее время поддерживаются следующие ди-стрибутивы и системы RedHat, Debian, Mandrake, SuSE иTurboLinux, а также HP-UX и Mac OS X (поддержка после-дней добавилась совсем недавно).

УстановкаПри закачке необходимо по ссылке выбрать пакет дляиспользуемого дитсрибутива или исходные тексты дляпредпочитающих устанавливать из исходников. Кромеэтого потребуется интерпретатор Perl версии не ниже 5.6.1и для интерактивного режима потребуются на выбор: дляease-of-use X-Window Perl/Tk версии не ниже 800.23 (вер-сия для RedHat: ftp://ftp.redhat.com/pub/redhat/linux/7.1/en/DMA/CPAN/RPMS/perl-Tk-800.022-11.i386.rpm) и для тек-стового режима (recommended for high security) Perl/Cursesверсии 1.06 и выше (ftp://ftp.redhat.com/pub/redhat/linux/7.1/en/DMA/CPAN/RPMS/perl-Curses-1.05-10.i386.rpm).

Для установки при помощи rpm-пакетов необходимоввести все те же rpm -iv, а при установке из исходниковпосле распаковки архива заходим внутрь образовавше-гося каталога и вводим ./Instal.sh. После чего программаскопирует все файлы на свои места и установит необхо-димые для работы модули Perl. Теперь можно запускать.

Как уже говорил, программа может использоваться дву-мя способами: в интерактивном режиме и в неинтерактив-ном. В интерактивном режиме интерфейс пользователя по-зволяет объяснить системному администратору проблемы взащите и попутно позволяет их решить. Этот подход удобентем, что, с одной стороны, защищает систему, а с другой –обучает на конкретных примерах. Неинтерактивный режимпозволяет использовать уже готовые файлы конфигурации,изготовленные в интерактивном режиме для изменения па-раметров на других системах, что позволяет избегать повтор-ного прохождения всех этапов, т.к. для того, чтобы спокойнои обдуманно ответить на все вопросы, потребуется отвестиприличное время. При этом программа должна быть запуще-на каждый раз после установки нового ПО или установки пат-ча (для RedHat http://www.redhat.com/apps/support/errata/), ко-торые могли повлиять на ослабление защиты. Также могутбыть случаи, когда применение Bastille может вызвать побоч-ный эффект, когда блокируются ни в чем не повинные про-граммы, поэтому все-таки перед применением на рабочемкомпьютере поэкспериментируйте на тестовом.

Запустить программу конфигурации в интерактивномрежиме можно двумя способами. Первый состоит в запус-ке perl-скрипта InteractiveBastile, по умолчанию или с ука-занием дополнительного аргумента -х, используется Tk-интерфейс, требующий запуска Х-Window, что проверяет-ся установленным значением переменной $DISPLAY. Приэтом всегда можно вернуться к предыдущему пункту, чтопозволяет использовать выборочную конфигурацию, дляудобства обладающую статус-баром, позволяющим оце-нить «пройденное расстояние». Если же система исполь-зуется, например, на роутере и не имеет установленнойсистемы Х-Window, то с заданием ключа -с, bastille будетзапущен с текстовым интерфейсом Perl/Curses.

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

Ключи для выбора интерфейса в этом случае анало-гичны предыдущим.

# /usr/sbin/bastille

Page 44: 013 Системный Администратор 12 2003

42

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

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

Для того чтобы все-таки уговорить ее работать, зада-ем при помощи ключа –os название дистрибутива, выб-рав сокращенное название из приведенного выше спис-ка (только при первом запуске).

И в результате появится окно, представленное на рисун-ках. Выбрав интересуемую категорию, начинаем отвечать навопросы, в большинстве пунктов ответом будет выбор из двухвариантов – Yes или No, но, например, при вводе диапазоновпортов дополнительно активируется внизу экрана полоса«Answer», куда и следует вводить данные. При ответе на воп-росы можно использовать кнопку «Explain More/Explain Less»для более или менее подробного объяснения, правда, для не-которых пунктов доступен только один из вариантов подска-зок. К сожалению, русификацией Bastille Linux еще никто незанимался, поэтому, чтобы разобраться в вопросах, необхо-димо знание английского (оптом вопросы можно просмотреть,ознакомившись с файлом Questions.txt). После ответа на всевопросы в последнем пункте сохраняем конфигурацию.

Для неинтерактивного режима первоначально проделы-ваем все вышеописаное, для того чтобы содать необходи-мые файлы конфигурации, все ответы на вопросы находят-ся в /etc/Bastille/config. После этого устанавливаем Bastilleна каждую машину с такой же самой операционной систе-мой, как и та, в которой он был сделан. И вводим на каждой:

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

или вывод ошибок:

Дополнительно в файл /var/log/Bastille/TODO системазаносит оставшиеся действия, которые система не мо-жет выполнить автоматически и их пользователь долженвыполнить вручную (например, перезагрузка сервисов).

Возврат к предыдущему (до Bastill) состоянию можноосуществить при помощи опции -r (revert) или запускомотдельного скрипта RevertBastille.

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

Could not determine operating system version!Bastille does not work on this OS: unknownCurrently, Bastille works on the following:DB2.2 DB3.0 RH6.0 RH6.1 RH6.2 RH7.0 RH7.1 RH7.2 RH7.3 RH8.0RH9 MN6.0 MN6.1 MN7.0 MN7.1 MN7.2 MN8.0 MN8.1 HP-UX11.00HP-UX11.11 HP-UX11.22 HP-UX11.23 SE7.2 SE7.3 SE8.0 TB7.0OSX10.2.0 OSX10.2.1 OSX10.2.2 OSX10.2.3 OSX10.2.4

# /usr/sbin/bastille –os RH8.0

# /usr/sbin/bastille -b

# tail -f /var/log/Bastille/action-log

# tail -f /var/log/Bastille/error-log

# /usr/sbin/bastille -r

Page 45: 013 Системный Администратор 12 2003

43№12(13), декабрь 2003

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

Пользователю придется ответить не на один десяток воп-росов, чтобы иметь представление об основных разделахпрограммы. При этом разделы, которые касаются толькоодной из систем, помечены как HP-UX only или Linux only.

Пару слов о PSAD. Эта программа, написанная на Perl(http://www.cipherdyne.com), использует программы firewallдля анализа сканирования портов и методы обнаружениясигнатур, используемые в Snort Intrusion Detection System(http://www.snort.org). При этом обнаруживается большин-ство различных методов сканирования. Все интересныесобытия регистрируются при помощи syslog.

Как видите, Bastille Linux представляет собой легкий виспользовании, удобный и интуитивно понятный инстру-мент, позволяющий существенно поднять защищенностькомпьютера, будь то сервер или десктоп. И дополнитель-но является неплохим пособием по изучению защитыLinux-систем. Удачи.

Page 46: 013 Системный Администратор 12 2003

44

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

УЧЕТ РАБОТЫ DIALUP-ПОЛЬЗОВАТЕЛЕЙВ СИСТЕМЕ FreeBSD

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

Page 47: 013 Системный Администратор 12 2003

45№12(13), декабрь 2003

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

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

Безусловно, существует целый ряд готовых программ-ных продуктов, в той или иной степени решающих задачуучета (и тарификации) работы пользователей, выходящихв Интернет через модемный пул сервера. Однако для «ча-стного» использования вряд ли целесообразно «прикру-чивать» к вашей системе RADIUS или что-то подобное. Вданной статье мы попытаемся рассмотреть общие прин-ципы решения задачи учета работы «дайлапников», ска-жем так, подручными средствами. Конкретную реализа-цию оставим за рамками данной статьи.

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

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

Прежде всего это wtmp – файл, в котором хранитсяинформация о последних соединениях. Просмотреть со-держащуюся в нем информацию можно командой last. Каквидно, используя эту команду, можно получить подроб-ную информацию о моментах входа-выхода пользовате-ля в систему и о продолжительности соединения (last сключом -s (last -s) отображает продолжительность соеди-нения в секундах) за период с момента последней рота-ции (перезаписи) файла wtmp. Период ротации выбира-ется в зависимости от нагрузки на систему и задается стаким расчетом, чтобы его размер не достигал катастро-фических значений. Учитывая, что мы рассматриваем не-большую систему, обновлять файл wtmp достаточно еже-месячно (cкрипт, производящий обновление, в этом слу-чае скорее всего будет располагаться в /etc/periodic/monthly).

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

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

Итак, для начала рассмотрим способы, которыми мож-но определить момент входа пользователя в систему. Впростейшем случае, когда информация о работе пользо-вателей нужна нам «задним числом», вполне достаточнобудет анализа данных, возвращаемых командой last. На-пример, в конце месяца мы можем просто просуммиро-вать продолжительность соединений для каждого пользо-вателя, и выставить счета на основе этой информации(простейший скрипт lastreader.pl, выполняющий даннуюфункцию, представлен на вкладке).

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

Одним из самых очевидных способов является про-смотр списка находящихся в данный момент в системепользователей. Например, если запускать команду whoкаждые пять секунд, то мы сможем определить появле-ние в системе пользователя с точностью до этого значе-ния. Присутствие в системе пользователя можно опреде-лить и по команде last – подключенные в данный моментабоненты отмечены как «still logged in».

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

В данной статье остановимся на рассмотрении двухспособов входа в систему – pap- и login-аутентификации.В первом случае последовательность такова:

lastreader.pl:#!/usr/bin/perl –w

# îòêðûâàåì last íà ÷òåíèåopen(LAST, ‘last -s|’) || die ‘Error’;while(<LAST>) { chomp; if($_) {

# âûäåëÿåì èìÿ ïîëüçîâàòåëÿ è óñòðîéñòâî ($user, $tty) = split(/\s/);

# Äàëåå îáðàáàòûâàåì òîëüêî ìîäåìíûå ñîåäèíåíèÿ ttydX if($tty =~ /ttyd/) {

# âûäåëÿåì çíà÷åíèå â ñêîáêàõ – ïðîäîëæèòåëüíîñòü # ñîåäèíåíèÿ â ñåêóíäàõ

$_ =~ s/\(\s*(\d+)\)/$1/g; if(($user)&&($1) {

# ñóììèðóåì ïðîäîëæèòåëüíîñòè ïî ïîëüçîâàòåëÿì $totals{$user} += $1; } } }}close(LAST);

# ñîðòèðóåì ïî àëôàâèòó ïîëüçîâàòåëåé@res = sort keys %totals;foreach $item (@res) {

# âûâîäèì ðåçóëüòàò íà ýêðàí print “$item - $totals{$item}\n”;}exit(1);

Page 48: 013 Системный Администратор 12 2003

46

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

� после того, как модемы установят соединение, конк-ретное ttyd-устройство сопоставляется с интерфейсомpppX;

� запускается демон pppd, обслуживающий данное со-единение;

� выполняется pap-аутентификация пользователя;� отрабатывается скрипт auth-up (если есть), как прави-

ло, располагающийся в /etc/ppp;� отрабатывается скрипт ip-up (если есть), располагаю-

щийся там же, где и auth-up.

Скрипт ip-up вызывается со следующими параметрами:

где:� interface-name – имя интерфейса pppX,� tty-device – устройство tty, через которое осуществля-

ется соединение,� speed – скорость на порту (на tty-устройстве),� local-IP, remote-IP – соответственно локальный и уда-

ленный IP-адреса,� ipparam – дополнительные параметры.

Для нас интерес представляют первые два парамет-ра, передаваемые в скрипт. К сожалению, имя пользова-теля в ip-up не передается, и мы можем узнать только отом, что какой-то пользователь выполнил подключение.

Параметры вызова скрипта auth-up следующие:

где:� interface-name – имя интерфейса pppX,� peer-name – имя пользователя, установившего соеди-

нение,� user-name – пользователь, с чьими правами запущен

pppd (как правило, root),� tty-device – устройство tty, через которое осуществле-

но соединение,� speed – скорость на порту (на tty-устройстве).

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

Небольшая неприятность появляется в случае login-аутентификации (например, при входе в систему черезстандартный скрипт). Если в качестве стандартной обо-лочки пользователю задать pppd, то процесс входа в сис-тему будет следующим:� после того, как модемы установят соединение, конк-

ретное ttyd-устройство сопоставляется с интерфейсомpppX;

� проводится login-аутентификация;� запускается программа, указанная в /etc/passwd как

стандартная оболочка (в нашем случае это демон pppd);� отрабатывается скрипт ip-up (если есть), как правило,

располагающийся в /etc/ppp.

Поскольку аутентификация уже выполнена, то сред-ствами pppd она не осуществляется, и потому скрипт auth-up не отрабатывается. Таким образом, если мы попыта-емся использовать для регистрации входа пользователяв систему именно его, то при login-аутентификации пользо-ватель зарегистрирован не будет. Поэтому, если мы хо-тим оставить пользователю возможность устанавливатьсоединение и через стандартный скрипт (с помощью login-аутентификации), то для определения его входа в систе-му нам остается только скрипт ip-up, который отрабаты-вается в любом случае. Однако теперь мы знаем толькоустройство, через которое пользователь подключен, и нампридется сопоставить устройство с конкретным пользо-вателем самим. Для этого нам как раз и пригодится ко-манда who (например, имя пользователя возвратит сле-дующая команда:

где «Х» – номер нужного нам ttyd-устройства).Вторая задача – определение момента, когда пользо-

ватель покидает систему, – решается аналогично. Этоможет быть либо проверка подключенных пользователейпериодическим вызовом who, либо использование скрип-тов ip-down и auth-down. Первый отрабатывается при вы-ходе из системы пользователя, вошедшего через pap-аутентификацию (для которого отрабатывался скриптauth-up), второй – при завершении сеанса связи. Однаконужно иметь в виду, что в некоторых случаях «down-скрип-ты» могут не отрабатываться, например, при аварийнойперезагрузке системы.

Особо нужно отметить, что вышеописанные ppp-скрип-ты исполняются с правами суперпользователя (root). Содной стороны, это хорошо, поскольку позволяет нам со-вершать любые действия, но с другой – требует особойосторожности и аккуратности. Также не забывайте под-держивать права доступа к данным файлам как r-x------(на стадии отладки можно поставить rwx------, но потомвозможность записи необходимо снять).

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

Теперь несколько слов о том, как можно определитьобнуление счета абонента в процессе работы и соответ-ственно дальнейшую работу оного пресечь самым жес-токим образом. Основных способов здесь тоже два – по-стоянный (периодический) контроль остатка, и предвари-тельное вычисление остатка. В первом случае специаль-ный скрипт должен время от времени определять остатокна счете пользователя (который можно хранить в БД илитекстовом файле), вычитать из него стоимость наработ-ки на текущий момент и в случае отрицательной разно-сти давать команду на отключение пользователя. Сутьвторого способа заключается в следующем: при входе

ip-up interface-name tty-device speed local-IP remote-IP ipparam

auth-up interface-name peer-name user-name tty-device speed

who | grep “ttydX” | awk ‘{print $1;}’

Page 49: 013 Системный Администратор 12 2003

47№12(13), декабрь 2003

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

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

Для принудительного завершения работы пользовате-ля рекомендуется использовать утилиту killpppd (дляFreeBSD ее можно найти в коллекции портов). Принимаяв качестве параметров peer-name и tty-device, утилитаосуществляет корректное завершение работы всех про-цессов, связанных с данным устройством.

Если нам нужно еще и учитывать трафик, потребляе-мый пользователем, то самый простой вариант – исполь-зовать для этих целей ipfw (брандмауэр, входящий в со-став FreeBSD). При входе пользователя в систему запус-каем подсчет трафика на конкретном устройстве (еслиточнее, то подсчет трафика запускается на IP-адрес, од-нако определить адрес, присвоенный устройству, как пра-вило, проблемой не является):

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

Затем, когда пользователь отключается, считываемего наработку (ipfw show 10000) и удаляем правило (ipfwdelete 10000). А наработку, соответственно пишем в фай-лик для последующего предъявления.

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

Если нам нужны только сведения о том, сколькопользователь провел времени в Сети за месяц, оптималь-ным будет обработка результата, выдаваемого по last –s.

Если мы предоставляем доступ в Интернет только сиспользованием ppp-аутентификации (например, pap), тодля определения входа пользователя в систему вполнеможет служить скрипт auth-up. Если наш сервер будетподдерживать и login-аутентификацию, то придется ис-пользовать скрипт ip-up. В этом случае имя пользователяпридется определять вручную, основываясь на сведени-ях, предоставляемых командой who. Эту же команду, ви-димо, придется использовать и для определения момен-та отключения пользователя, поскольку метод, связанныйсо скриптами ip-down и auth-down, слишком ненадежен.Хотя в целях экономии ресурсов можно использовать ком-бинацию этих методов: отключение производить по ко-манде соответствующего скрипта, но выполнять контрольпо команде who через относительно большой промежу-ток времени (например, раз в 5 минут).

Конечно, для построения эффективной, точной и надеж-ной системы учета придется прибегнуть к программирова-нию на С, однако в большинстве случаев концепция оста-ется прежней – контроль файлов wtmp (last) и utmp (who).

Дополнительные материалы:1. man last(1) – команда last;2. man who(1) – команда who;3. man grep(1), man awk(1) – команды обработки тексто-

вых строк;4. man at(1) – отложенное выполнение команды;5. man pppd(8) – информация по auth-up, ip-up, auth-down,

ip-down;6. man ipfw(8) – информация по ipfw, в том числе по под-

счету трафика;7. man periodic(8) – дополнительные сведения по рота-

ции wtmp;8. man utmp(5) – обработка utmp на С;9. man wtmp(5) – обработка wtmp на С.

ipfw add 10000 count ip from any to 100.100.100.5 out

Page 50: 013 Системный Администратор 12 2003

48

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

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

Page 51: 013 Системный Администратор 12 2003

49№12(13), декабрь 2003

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

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

Первым делом хотелось бы научить Nagios «говорить»на чистом русском языке. Примерно девять месяцев назадя завершил работы по локализации Nagios версии 1.06 beta.Затем, по мере выхода новых версий продукта, та же судь-ба постигла официальные релизы 1.0 и 1.1. Методика ру-сификации для всех версий одинакова, поэтому я буду опи-сывать ее на примере версии 1.1 как наиболее свежей и,надеюсь, наиболее распространенной. Итак, что же намнужно сделать? Первым делом скачиваем дистрибутив вер-сии Nagios, которая установлена у вас с официального сай-та http://www.nagios.org. Здесь берем соответствующиефайлы локализации: htpp://onix.opennet.ru/files/.

Распаковываем дистрибутив и пакет локализации влюбое удобное место, например в директорию /tmp.

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

Я думаю, объяснять назначение ключей команды configureсмысла нет. Поэтому сразу же переходим к компиляции.

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

Вот теперь можно спокойно выполнять инсталляцию.

В результате файлы из директории дистрибутива дол-жны заменить те файлы, которые Nagios использовалдо сегодняшнего дня. Таким образом, файлы из /tmp/nagios-1.1/html должны попасть в /usr/local/nagios/share/,а скомпилированные файлы из /tmp/nagios-1.1/cgi в /usr/local/nagios/sbin/.

Снова запустив Nagios и обратившись к веб-интерфей-су, должны увидеть что-то вроде такой картинки:

# tar zxvf nagios-1.1.tar.gz# tar zxvf nagios_rus_1_1.tar.gz

# cp –R /tmp/nagios_rus_1_1/* /tmp/nagios-1.1/# cd nagios-1.1# ./configure --prefix=/usr/local/nagios ↵

--with-cgi-url=/nagios/cgi-bin --with-html-url=/nagios/ ↵--with-nagios-user=nagios --with-nagios-grp=nagios ↵--with-gd-lib=/usr/local/lib ↵--with-gd-inc=/usr/local/include/gd

# make all

/usr/local/etc/nagios.sh stop

# make install

Page 52: 013 Системный Администратор 12 2003

50

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

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

При попытке воспользоваться пунктами «Карта сети»(statusmap.cgi) и «3D карта сети» (statuswrl.cgi) на экраневместо карты обычно появляется такое меню:

Причин этому может быть две. Первая – не работает биб-лиотека GD, которую мы установили вместе с Nagios. И вто-рая – в используемом нами браузере отсутствует или непра-вильно работает подключаемый модуль для отображения vrml.

Итак, начнем с первой проблемы. Если вы помните,перед компилированием Nagios мы использовали командуconfigure. Следует обратить особое внимание на парамет-ры --with-gd-lib и --with-gd-inc, которые указывают на дирек-тории, где в нашей системе находятся заголовочные и биб-лиотечные файлы пакета GD. Команда configure пытаетсяавтоматически подключить нужные файлы к проекту, ноей не всегда это удается. Обычно в процессе конфигури-рования на экран выводятся соответствующие сообщения,но вся проблема в том, что туда же сыпется довольно мно-го прочих диагностических сообщений, и поэтому найти ипонять то, что нам нужно в этом винегрете, довольно слож-но. Для более точного диагностирования проблемы очис-тим дистрибутив от файлов конфигурации, созданных вовремя предыдущей компиляции командой:

Затем перенаправим все сообщения команды configureв файл make.log c помощью следующей конструкции:

Если во время компоновки gd не найден, то внутри фай-ла make.log среди всего прочего будут вот такие надписи:

Ну а в случае, если вам повезло и вы нашли в указан-ном выше файле вот такое:

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

По традиции начинаем с FreeBSD. Посмотреть, уста-навливалась ли библиотека GD в эту систему стандарт-ными средствами, то есть с помощью пакетов или пор-тов, можно командой:

Теперь мы знаем полное название пакета. Смотрим,куда установились его файлы.

Итак, судя по выводу, параметры команды configure,относящиеся к библиотке GD, должны выглядеть так:

Давайте посмотрим, как можно добиться подобногоэффекта для Linux-систем, основанных на rpm. В каче-стве примера возьмем ALT Linux.

# make clean

# ./configure --prefix=/usr/local/nagios ↵--with-cgi-url=/nagios/cgi-bin --with-html-url=/nagios/ ↵--with-nagios-user=nagios --with-nagios-grp=nagios ↵--with-gd-lib=/usr/local/lib ↵--with-gd-inc=/usr/local/include/gd > make.log

checking for gdImagePng in -lgd (order 1)... nochecking for gdImagePng in -lgd (order 2)... nochecking for gdImagePng in -lgd (order 3)... no

*** GD, PNG, and/or JPEG libraries could not be located... ****

Boutell's GD library is required to compile the statusmap,trends and histogram CGIs. Get it from http://www.boutell.com/gd/,compile it, and use the --with-gd-lib and --with-gd-inc argumentsto specify the locations of the GD library and include files.NOTE: In addition to the gd-devel library, you'll also need

to make sure you have the png-devel and jpeg-devellibraries installed on your system.

NOTE: After you install the necessary libraries on your system:1. Make sure /etc/ld.so.conf has an entry for the directoryin which the GD, PNG, and JPEG libraries are installed.2. Run 'ldconfig' to update the run-time linker options.3. Run 'make clean' in the Nagios distribution to cleanout any old references to your previous compile.4. Rerun the configure script.

NOTE: If you can't get the configure script to recognize theGD libs on your system, get over it and move on to otherthings. The CGIs that use the GD libs are just a smallpart of the entire Nagios package. Get everything elseworking first and then revisit the problem. Make sureto check the nagios-users mailing list archives forpossible solutions to GD library problems when you resumeyour troubleshooting.

********************************************************************

checking for gdImagePng in -lgd (order 1)... yesGD library was found!

# pkg_info | grep gdgd-1.8.4_6 A graphics library for fast image creation

# pkg_-L gd-1.8.4_6

Information for gd-1.8.4_6:

Files:/usr/local/bin/bdftogd/usr/local/bin/gd2copypal/usr/local/bin/gd2topng/usr/local/bin/gdparttopng/usr/local/bin/gdtopng/usr/local/bin/pngtogd/usr/local/bin/pngtogd2/usr/local/bin/webpng/usr/local/include/gd/gd.h/usr/local/include/gd/gd_io.h/usr/local/include/gd/gdcache.h/usr/local/include/gd/gdfontg.h/usr/local/include/gd/gdfontl.h/usr/local/include/gd/gdfontmb.h/usr/local/include/gd/gdfonts.h/usr/local/include/gd/gdfontt.h/usr/local/lib/libgd.a/usr/local/lib/libgd.so/usr/local/lib/libgd.so.2/usr/local/share/doc/gd/index.html

--with-gd-lib=/usr/local/lib ↵

--with-gd-inc=/usr/local/include/gd

# rpm -qa | grep gd

Page 53: 013 Системный Администратор 12 2003

51№12(13), декабрь 2003

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

В отличие от FreeBSD, в Linux-системах библиотекаGD обычно разделена на два отдельных пакета. Судя повсему, нас интересуют rpm-файлы libgd2 и libgd2-devel.Первый содержит динамически загружаемые библиоте-ки, ну а второй, соответственно, заголовочные файлы.

Ну и наконец, универсальный способ, подходящий длялюбой Unix-подобной операционной системы. Им можновоспользоваться в случае, если все предыдущие попыт-ки не дали никаких результатов. Нужно самостоятельноотыскать, где находятся файлы libgd.* и gd.h

Теперь вы можете уверенно сказать, чему должны бытьравны параметры --with-gd-lib и --with-gd-inc командыconfigure. Выполняем ее со всеми необходимыми настрой-ками и, как описано выше, проверяем, найдена ли биб-лиотека GD. И наконец, проводим компиляцию и инстал-ляцию, не забыв остановить демона Nagios. После этогокарта сети (statusmap.cgi) должна приобрести вид, при-мерно похожий на этот:

Теперь все те, кто ушли пить кофе, могут возвращать-ся. Сейчас мы начнем починку 3D-карты. Не работает онапо причине того, что ваш браузер не знает, что делать сvrml-файлом, который возвращается в ответ на запросык скрипту statuswrl.cgi. Для того чтобы все заработало какположено, нужно установить в используемый браузермодуль для работы с vrml или отдельную программу, пред-назначенную для тех же целей.

Программного обеспечения, подходящего для этого,написано воз и маленькая тележка. Как обычно, пальмапервенства по количеству экземпляров принадлежитWindows. Затем идет MAC OS и, наконец, бронзовое тре-тье место занимает Linux.

Итак, начнем с фаворита. При необходимости рабо-тать под управлением Windows и MAC-систем я предпо-читаю использовать Cortona VRML Client по той простойпричине, что он совместим с большинством наиболее рас-пространенных браузеров, к числу которых несомненноотносятся Internet Explorer, Netscape Navigator, Mozilla,iCab. Интересным фактом является то обстоятельство, чтоэтот подключаемый модуль можно использовать даже изофисных приложений Microsoft PowerPoint, Microsoft Word.К сожалению, разработчики Cortona почему-то решилиполностью проигнорировать Linux. Скачать дистрибутивможно с сайта http://www.parallelgraphics.com/products/cortona/download/. Что делать после совершения этогосакраментального действа, мы обсудим немного позднее.

Следующая достойная нашего внимания программа,называемая Cosmo player, живет по адресу: http://ca.com/cosmo/html/. Работает в виде отдельного приложения и,конечно же, только под Windows и MAC.

ExpressVR – конкурент Cortona для всем известной яб-лочной платформы. Под другими операционными система-ми не живет, попыток экспансии не предпринимает и, судяпо последним тенденциям, скорее всего через некотороевремя будет окончательно вытеснен своим многофункцио-нальным противником. Предназначен только для NetscapeNavigator и Internet Explorer. Скачать дистрибутив можно от-сюда: http://members.aol.com/maxmac/vrml/download.html.

FreeWRL – отдельное приложение, работающее в ка-честве самостоятельного vrml-браузера. Функционируетна платформах Linix и MAC и располагается по этому ад-ресу: http://www.crc.ca/FreeWRL/.

Следующий экземпляр в нашем списке называетсяVRwave и проживает тут: http://www.iicm.edu/vrwave. Пред-назначен для Linux и Windows. Замыкает стройные ряды vrml-клиентов OpenVrml, обитающий сугубо под Linux: http://sourceforge.net/project/showfiles.php?group_id=7151&release_id=192066. Кстати, стоит сделать маленькую ре-марку по ходу изложения. Практически все программы, ко-торые мы назвали предназначенными под Linux, теорети-чески должны работать и под другими Unix-подобными си-стемами, в состав которых входит графический сервер X11.

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

# rpm -ql libgd2/usr/lib/libgd.so.2/usr/lib/libgd.so.2.0.4

# rpm -ql libgd2-devel/usr/include/gd.h/usr/include/gd_io.h/usr/include/gdcache.h/usr/include/gdfontg.h/usr/include/gdfontl.h/usr/include/gdfontmb.h/usr/include/gdfonts.h/usr/include/gdfontt.h/usr/lib/libgd.so/usr/share/doc/gd-2.0.4/usr/share/doc/gd-2.0.4/index.html

#find / -name libgd.*/usr/lib/libgd.so.1.2/usr/lib/libgd.so.1/usr/lib/libgd.so

#find / -name gd.h/usr/include/gd.h

libgd2-devel-2.0.4-alt2gdm-2.4.4.5-alt1gdk-pixbuf-loaders-0.22.0-alt2gdk-pixbuf-0.22.0-alt2libgd2-2.0.4-alt2libgda2-1.0.0-alt1gnome2-utils-gdict-applet-2.4.0-alt2libgda2-devel-1.0.0-alt1

Page 54: 013 Системный Администратор 12 2003

52

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

� http://sourceforge.net� http://freshmeat.net� http://tucows.com� http://filesearch.ru

А здесь: http://www.chuvsu.ru/download/vrml/browsers/можно найти очень неплохую подборку vrml-клиентов дляWindows.

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

Теперь сделаем перерыв в изучении теории и попрак-тикуемся в том, как правильно провести инсталляцию ииспользование Cortona VRML Client в связке с браузеромMicrosoft Internet Explorer. Сделать это можно двумя спо-собами. Начнем с самого простого.

С помощью браузера идем по адресу: ht tp:/ /www.parallelgraphics.com/products/cortona/download/ и,выбрав нужный тип браузера, пользуемся кнопкой«online install».

Обратите внимание на пустой прямоугольник в цент-ре страницы. Его появление означает, что в вашем брау-зере нет vrml-модуля. Нажимаем на кнопку «Install Now».После того как процесс скачивания закончится, переднами появится следующее окно:

Жмем «Yes» в знак того, что мы доверяем цифровойподписи ParallelGraphics LTD. Подобный механизм циф-ровых подписей для всех скачиваемых программ помога-ет избежать подмены или порчи дистрибутива во времяего путешествия через сеть.

На следующем экране выставляем во всех окошкахгалочки. Таким образом, мы назначаем vrml-клиентапрограммой по умолчанию для обработки файлов wrl,wrml и wrz.

По окончании инсталляции текущая страница в брау-зере должна обновиться. И в центре нее появится враща-ющийся куб.

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

Итак, переходим ко второму способу инсталляции.Скачиваем дистрибутив, подходящий для нашего брау-зера. После запуска принимаем лицензионное соглаше-ние и несколько раз жмем кнопку «Next». После распа-ковки файлов на экране должно появиться что-то вродетакой картинки:

Система может задуматься на минуту-другую, а затемснова очнется и начнет задавать вопросы.

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

Page 55: 013 Системный Администратор 12 2003

53№12(13), декабрь 2003

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

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

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

Вслед за нажатием кнопки «Next» на экране появит-ся 3D-сцена, изображающая постепенно расцветающуюрозу.

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

Для того чтобы избавиться от этой надоедливой по-мехи, закрываем окно консоли и щелкаем правой клави-шей мыши в середине окна с 3D-сценой.

В открывшемся меню выберем пункт «Preferences». Азатем, воспользовавшись вкладкой «Render», выбираемальтернативный механизм рендеринга.

Думаю, вы сможете легко самостоятельно разобрать-ся с настройками и изучить способы перемещения в трех-мерном виртуальном пространстве. Теперь можно посмот-реть на 3D-карту Nagios.

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

А теперь вновь одним прыжком вернемся к плоскойкарте сети statusmap.cgi.

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

Page 56: 013 Системный Администратор 12 2003

54

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

У нас есть две отдельные подсети, созданные на ос-нове управляемых коммутаторов 3com. Каждому из нихвыдан собственный IP-адрес. Таким образом, мы имеемвозможность проверять их работоспособность с помощьюподключаемого модуля check_ping. Внутренняя сеть вклю-чает в себя следующие компьютеры:� Nagios – система мониторинга;� Linux – рабочая станция на основе Linux;� Win_2000 – рабочая станция на основе Windows 2000

Professional.

Вторая сеть у нас используется как демилитаризован-ная зона. В нее включены серверы c именами WWW иMail. Думаю, названия говорят сами за себя, и поэтомунеудивительно, что на них запущены сервисы IMAP, POP3,SMTP и HTTP. Между собой сети соединены с помощьюмашины, фигурирующей под именем Inner_Firewall. Вы-ход в Интернет защищает аппаратный межсетевой экран,называемый Outer_Firewall. В файле hosts.cfg содержат-ся следующие данные, полностью описывающие нашусеть и ее хосты:

Я думаю, что цитировать файл services.cfg с описани-ем сервисов нужды нет, потому что в нем нет ничего ин-тересного, да и для повествования он некритичен, крометого, каждый из вас может заполнить его нужными све-дениями за пять минут. Если же у кого-то из читателейэто действо вызывает затруднение, то тогда им прямаядорога в первую статью о Nagios. Прочитать ее можно в [1]либо на моем сайте: http://www.onix.opennet.ru.

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

define host{name generic-hostnotifications_enabled 1event_handler_enabled 1flap_detection_enabled 1process_perf_data 1retain_status_information 1retain_nonstatus_information 1register 0}

define host{use generic-hosthost_name Win_2000alias Standard Windows Serveraddress biancaparents 3com_Lancheck_command check-host-alivemax_check_attempts 10notification_interval 120notification_period 24x7notification_options d,u,r}

define host{use generic-hosthost_name Linuxalias Linux Serveraddress liraparents 3com_Lancheck_command check-host-alivemax_check_attempts 10notification_interval 120notification_period 24x7notification_options d,u,r}

define host{use generic-hosthost_name 3com_Lanalias 3COM inner Lan switchaddress 3com-lancheck_command check-host-alivemax_check_attempts 10notification_interval 120notification_period 24x7notification_options d,u,r}

define host{use generic-hosthost_name Inner_Firewallalias Firewall PCparents 3com_Lanaddress inner-firewall

check_command check-host-alivemax_check_attempts 10notification_interval 120notification_period 24x7notification_options d,u,r}

define host{use generic-hosthost_name 3com_Dmzalias 3COM dmz switchaddress 3com-dmzparents Inner_Firewallcheck_command check-host-alivemax_check_attempts 10notification_interval 120notification_period 24x7notification_options d,u,r}

define host{use generic-hosthost_name Mailalias Mail Serveraddress mailerparents 3com_Dmzcheck_command check-host-alivemax_check_attempts 10notification_interval 120notification_period 24x7notification_options d,u,r}

define host{use generic-hosthost_name WWWalias WWW Serveraddress webparents 3com_Dmzcheck_command check-host-alivemax_check_attempts 10notification_interval 120notification_period 24x7notification_options d,u,r}

define host{use generic-hosthost_name Outer_Firewallalias Hardware Firewalladdress outer-firewallparents 3com_Dmzcheck_command check-host-alivemax_check_attempts 10notification_interval 120notification_period 24x7notification_options d,u,r}

Page 57: 013 Системный Администратор 12 2003

55№12(13), декабрь 2003

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

тическом состоянии хостов Inner_Firewall, WWW, Mail,3com_Dmz и Outer_Firewall. Хотя на самом деле не рабо-тает только первый из всех вышеперечисленных компью-теров. Получается, что администратор должен самостоя-тельно догадаться, что привело к таким массовым сбоям.Для того чтобы впредь избежать подобных неприятнос-тей, нам необходимо объяснить Nagios, как построенанаша сеть и каким образом добираться до ее самых уда-ленных уголков. Делается это с помощью создания отно-шений «родитель» – «потомок» между всеми нашими хо-стами. После таких изменений критические уведомлениябудут приходить только для компьютера Inner_Firewall, всеостальные машины, задействованные в данной пробле-ме, получат статус «недоступно». Согласитесь, это все-таки более соответствует действительному положениювещей в контролируемых сетях.

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

Для правильной диагностики неполадок иерархия дол-жна выглядеть так, как изображено на предыдущей схе-ме. С точки зрения Nagios бывают два вида хостов – «ло-кальные» и «удаленные». Локальными считаются те, ктонаходится в том же сетевом сегменте, что и система мо-ниторинга. Между ними не должно быть ни маршрутиза-торов, ни межсетевых экранов. Если бы у нас были неуп-равляемые коммутаторы, не поддающиеся мониторингу,то локальными хостами считались бы Linux и Win_2000.Но в связи с тем, что между ними есть промежуточноезвено в виде коммутатора 3com_Lan, который можно под-вергнуть мониторингу, они переходят в разряд удаленных.А единственным локальным становится 3com_Lan.

Добиться этого можно применением тега parents в оп-ределении хостов. Стоит обратить внимание на тот стран-

ный факт, что фирменная документация в разделе«Determining Status and Reachability of Network Hosts» этоттег почему-то называет parent_hosts. Хотя если покопатьсяв исходных текстах Nagios, то понимаем, что на самомделе должен быть просто parents. Если в описании хос-тов неукоснительно придерживаться указания использо-вать тег parent_host, то при попытке сделать nagios reloadдля того, чтобы применить изменения в конфигурации,получим вот такие ошибки:

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

Машины, считающиеся локальными по отношению кNagios, находятся на одну ступеньку ниже в иерархии, и по-этому не должны использовать тег parents в своем описа-нии. Все остальные машины, относящиеся к группе удален-ных, в вышеуказанном теге пишут имя ближайшего родите-ля. Таким образом, для хостов Inner_Firewall, Linux и Win_2000родителем является 3com_Lan. В свою очередь, Inner_Firewallуказан родителем для 3com_Dmz. А 3com_Dmz выполняетту же роль для хостов WWW, Outer_Firewall, Mail.

Итак, разобравшись с понятием иерархии, посмотрим,как оно влияет на отображение наших сетей на карте.

Running configuration check...Nagios 1.1Copyright (c) 1999-2003 Ethan Galstad ([email protected])Last Modified: 06-02-2003License: GPL

Reading configuration data...

Error: Could not add object property in file'/usr/local/nagios/etc/hosts.cfg' on line 74.

***> One or more problems was encountered while processingthe config files...

Check your configuration file(s) to ensure that they containvalid directives and data defintions. If you are upgradingfrom a previous version of Nagios, you should be aware thatsome variables/definitions may have been removed or modifiedin this version. Make sure to read the HTML documentation onthe main and host config files, as well as the 'Whats New'section to find out what has changed.

failed - aborting reload.

Page 58: 013 Системный Администратор 12 2003

56

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

Думаю, выглядит довольно впечатляюще. Какой изспособов отображения карты будет использоваться поумолчанию, указывает параметр default_statusmap_layout.Для трехмерной карты такой параметр называется соот-ветственно default_statuswrl_layout. Оба этих параметраскрываются внутри файла cgi.cfg. Кроме заметного с пер-вого взгляда лоска, мы к тому же приобрели более точ-ное диагностирование сетевых неполадок.

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

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

Кстати, не забудьте скачать отсюда: http://nagios.org/download/extras.html файлы с коллекциями иконок, обыч-но называемые image packs.

Итак, начнем с файла hostextinfo.cfg.

define hostextinfo{# Òåã, ñ êîòîðîãî äîëæíî íà÷èíàòüñÿ îïèñàíèå õîñòà

host_name 3com_Lan# Èìÿ õîñòà, ê êîòîðîìó îòíîñèòñÿ îïèñàíèå

icon_image 3Com.png# Èìÿ ôàéëà èêîíêè, êîòîðàÿ áóäåò îòîáðàæàòüñÿ ðÿäîì ñ èìåíåì# õîñòà. Èêîíêà ìîæåò áûòü â ôîðìàòå GIF, PNG èëè JPG. Ìîæåò# ñîäåðæàòü âíóòðè ñåáÿ ïðîçðà÷íûå îáëàñòè. Æåëàòåëüíî,# ÷òîáû èêîíêè áûëè ðàçìåðîì 40x40 ïèêñåëåé. Ðàñïîëàãàòüñÿ# îíè äîëæíû â äèðåêòîðèè logos. Îáû÷íî ýòà äèðåêòîðèÿ# íàõîäèòñÿ â /usr/local/nagios/share/images/logos

icon_image_alt 3Com LAN Switch# Íàäïèñü, îòîáðàæàåìàÿ, åñëè âåá-ñåðâåðó íå óäàåòñÿ# çàãðóçèòü èêîíêó

vrml_image 3Com.png# Èìÿ ôàéëà, êîòîðûé áóäåò èñïîëüçîâàòüñÿ êàê òåêñòóðà äëÿ êóáà,# èçîáðàæàþùåãî õîñò íà òðåõìåðíîé êàðòå. Ìîæåò áûòü â ôîðìàòå# PNG, JPG, GIF. Êàðòèíêà íå äîëæíà ñîäåðæàòü ïðîçðà÷íûõ# îáëàñòåé, èíà÷å ýòî áóäåò âûãëÿäåòü î÷åíü ñòðàííî. Äîëæíà# õðàíèòüñÿ â òîé æå äèðåêòîðèè, ÷òî è èêîíêà, îïèñàííàÿ# òåãîì icon_image

statusmap_image 3Com.gd2# Èìÿ ôàéëà, ãäå õðàíèòñÿ èçîáðàæåíèå, êîòîðîå áóäåò# èñïîëüçîâàòüñÿ êàê èêîíêà õîñòà íà ïëîñêîé ñåòåâîé êàðòå.# Ìîæåò áûòü â ôîðìàòå PNG, JPG, GIF, íî âñå-òàêè ëó÷øå,# åñëè äëÿ ýòîãî ôàéëà áóäåò èñïîëüçîâàòüñÿ ôîðìàò GD2, ïîòîìó# ÷òî äëÿ êàæäîãî öèêëà ðèñîâàíèÿ êàðòû èêîíêà áóäåò ñíîâà# è ñíîâà ïðèâîäèòüñÿ ê âèäó, óäîáíîìó äëÿ áèáëèîòåêè GD.# À ýòî çíà÷èò, ÷òî ìû áóäåì çðÿ âûïîëíÿòü îäíè è òå æå# áåñïîëåçíûå âû÷èñëåíèÿ. Ìîæåò ñîäåðæàòü âíóòðè ñåáÿ# ïðîçðà÷íûå îáëàñòè. Æåëàòåëüíî ÷òîáû èêîíêè áûëè ðàçìåðîì# 40x40 ïèêñåëåé. Ðàñïîëàãàòüñÿ îíè äîëæíû â äèðåêòîðèè logos.# Îáû÷íî ýòà äèðåêòîðèÿ íàõîäèòñÿ â /usr/local/nagios/share/# images/logos

2d_coords 160,99# Äâóìåðíûå êîîðäèíàòû òî÷êè, â êîòîðîé áóäåò íàõîäèòüñÿ öåíòð# èêîíêè õîñòà íà ïëîñêîé êàðòå. Ìîãóò áûòü òîëüêî# ïîëîæèòåëüíûìè ÷èñëàìè. Ðèñîâàíèå êàðòû íà÷èíàåòñÿ èç òî÷êè# 0,0 êîòîðàÿ ÿâëÿåòñÿ âåðõíèì ëåâûì óãëîì êàðòû. Êîîðäèíàòû# ïåðå÷èñëÿþòñÿ â ñëåäóþùåì ïîðÿäêå x, y3d_coords 20.0,32.0,6.0# Êîîðäèíàòû öåíòðà êóáà, ñèìâîëèçèðóþùåãî õîñò â ïðîñòðàíñòâå# òðåõìåðíîé êàðòû. Ìîãóò áûòü êàê ïîëîæèòåëüíûìè, òàê è# îòðèöàòåëüíûìè ÷èñëàìè. Ðàçìåð îäíîé ñòîðîíû êóáà 0.5 åäèíèö.# Îòðèñîâêà êàðòû íà÷èíàåòñÿ öåíòðà òðåõìåðíîé êàðòû, êîòîðûé# íàõîäèòñÿ â òî÷êå ñ êîîðäèíàòàìè 0.0, 0.0, 0.0.# Êîîðäèíàòû ïåðå÷èñëÿþòñÿ â ñëåäóþùåì ïîðÿäêå x, y, znotes_url http://192.168.80.2/nagios/notes/3com_lan.txt# Ññûëêà íà àäðåñ, ïî êîòîðîìó ëåæèò ôàéë c äîïîëíèòåëüíûìè# ñâåäåíèÿìè î õîñòå. Ïðè ùåë÷êå íà ñïåöèàëüíûé çíà÷îê# â áðàóçåðå áóäåò îòêðûò ýòîò ôàéë. Ýòî ïîëåçíî äëÿ çàïèñè# ðàçëè÷íûõ ñâåäåíèé, êîòîðûå íå âîøëè â ñòàíäàðòíûé øàáëîí# îïèñàíèÿ õîñòà Nagios. Íàïðèìåð, òàì ìîæíî íàïèñàòü äàííûå,# îòâå÷àþùèå íà âîïðîñ, êòî èç àäìèíèñòðàòîðîâ îòâå÷àåò# çà óïðàâëåíèå ýòèì ñåðâåðîì, ê êîìó îáðàùàòüñÿ â ñëó÷àå ïðîáëåì.# Îáðàòèòå âíèìàíèå íà URL, èñïîëüçóåìûé äëÿ óêàçàíèÿ ïóòü# ê ôàéëó. Äëÿ òîãî ÷òîáû ôàéëû ñ çàïèñêàìè ìîæíî áûëî õðàíèòü# íà òîì æå õîñòå, ÷òî è Nagios, ÿ ñîçäàë äèðåêòîðèþ# /usr/local/nagios/share/notes, è ïîýòîìó ìû òåïåðü ìîæåì# ïîëó÷èòü ê íåé äîñòóï èìåííî ïî òàêîìó URL.}

define hostextinfo{host_name Win_2000notes_url http://listios.lan.domain.ru/Win_2000.html# Êñòàòè, ñòîèò îòìåòèòü, ÷òî äîáàâî÷íûå çàïèñêè î õîñòàõ ìîãóò# õðàíèòü íå òîëüêî íà òîì æå õîñòå, ãäå ðàáîòàåò Nagios, íî è íà# ëþáîì äðóãîì. Ãëàâíîå, ÷òîáû òàì ðàáîòàë âåá-ñåðâåð è URL

Page 59: 013 Системный Администратор 12 2003

57№12(13), декабрь 2003

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

Теперь пришло самое время обсудить содержимоефайла serviceextinfo.cfg. Принципы построения обоих фай-лов довольно схожи.

Для того чтобы Nagios увидел созданные нами файлыhostextinfo.cfg, serviceextinfo.cfg, нужно внести в файл cgi.cfgследующие директивы.

Я думаю, вы сможете самостоятельно положить фай-лы иконок в директорию /usr/local/nagios/share/images/logos/. Кстати, стоит обязательно убедиться, что все фай-лы, создаваемые вами, принадлежат пользователю, отимени которого работает Nagios, иначе вы будете оченьдолго недоумевать, почему никаких изменений в картахне видно, хотя все сделано так, как в этой статье. К такимфайлам относятся hostextinfo.cfg serviceextinfo.cfg иконки,записки и прочая мелкая живность.

Кстати, создавать самостоятельно файлы иконок в фор-мате библиотеки GD довольно просто. Мы говорили об этихфайлах во время обсуждения тега statusmap_image фай-ла hostextinfo.cfg. Для этого нужно взять файлы иконки вформате png и преобразовать его в формат GD с помо-щью утилиты pngtogd2, поставлявшейся вместе с библио-текой GD. Желательно, чтобы создаваемый файл былсохранен без компрессии изображения. Это позволит уве-личить скорость работы функций библиотеки GD, отве-чающих за загрузку в память и рисование иконок внутри

# áûë ïðàâèëüíî ïðîïèñàíicon_image win40.pngicon_image_alt Windows workstationvrml_image win40.pngstatusmap_image win40.gd22d_coords 163,1953d_coords 15.0,38.0,6.0}

define hostextinfo{host_name Linuxnotes_url http://10.10.5.7/hostinfo.pl?host=Linux1#  êà÷åñòâå URL äëÿ õðàíåíèÿ äîáàâî÷íûõ çàïèñîê ìîæíî èñïîëüçîâàòü# äàæå CGI.  çàâèñèìîñòè îò äàííûõ, ïåðåäàííûõ â çàïðîñå, âû áóäåòå# ïîëó÷àòü ñâåäåíèÿ î òîì èëè èíîì õîñòå.icon_image_alt Linux Workstationvrml_image mandrake.gd2statusmap_image mandrake.gd22d_coords 60,1983d_coords 30.0,38.0,6.0}

define hostextinfo{host_name Mailnotes_url http://192.168.80.2/nagios/notes/mail.htmlicon_image MailServer.pngicon_image_alt Mail Servervrml_image MailServer.pngstatusmap_image MailServer.gd22d_coords 520,1833d_coords 20.0,44.0,6.0}

define hostextinfo{host_name WWWnotes_url http://192.168.80.2/nagios/notes/www_notes.htmlicon_image openbsd.pngicon_image_alt WWW Servervrml_image openbsd.gd2statusmap_image openbsd.gd22d_coords 439,1863d_coords 20.0,54.0,6.0}

define hostextinfo{host_name Inner_Firewallnotes_url http://192.168.80.2/nagios/notes/

inner_fw_notes.htmlicon_image freebsd40.pngicon_image_alt Inner Firewallvrml_image freebsd40.pngstatusmap_image freebsd40.gd22d_coords 326,963d_coords 17.0,55.0,6.0

}

define hostextinfo{host_name Outer_Firewallnotes_url http://192.168.80.2/nagios/notes/

outer_fw_notes.htmlicon_image firebox_small.pngicon_image_alt Outer Firewallvrml_image firebox_small.pngstatusmap_image firebox_small.gd22d_coords 620,803d_coords 16.0,42.0,6.0}

define hostextinfo{host_name 3com_Dmznotes_url http://192.168.80.2/nagios/notes/3com_dmz.htmlicon_image 3Com.pngicon_image_alt 3Com DMZ LAN Switchvrml_image 3Com.pngstatusmap_image 3Com.gd22d_coords 480,733d_coords 14.0,56.0,6.0}

define serviceextinfo{

xedtemplate_config_file=/usr/local/nagios/etc/hostextinfo.cfgxedtemplate_config_file=/usr/local/nagios/etc/serviceextinfo.cfg

host_name WWW# Èìÿ õîñòà, íà êîòîðîì ðàáîòàåò ñåðâèñservice_description HTTP# Èìÿ ñåðâèñà èç ôàéëà services.cfgnotes_url http://192.168.80.2/nagios/notes/service_www.html# Óæå ìíîãîêðàòíî âèäåííûé íàìè URL äëÿ äîïîëíèòåëüíûõ çàïèñîêicon_image apache.png# Èìÿ ôàéëà èêîíêè, êîòîðàÿ áóäåò îòîáðàæàòüñÿ ðÿäîì ñ èìåíåì# ñåðâèñà. Èêîíêà ìîæåò áûòü â ôîðìàòå GIF, PNG èëè JPG. Ìîæåò# ñîäåðæàòü âíóòðè ñåáÿ ïðîçðà÷íûå îáëàñòè. Æåëàòåëüíî, ÷òîáû# èêîíêè áûëè ðàçìåðîì 40x40 ïèêñåëåé. Ðàñïîëàãàòüñÿ îíè äîëæíû# â äèðåêòîðèè logos. Îáû÷íî ýòà äèðåêòîðèÿ íàõîäèòñÿ â# /usr/local/nagios/share/images/logosicon_image_alt Web Service# Íàäïèñü, îòîáðàæàåìàÿ, åñëè âåá-ñåðâåðó íå óäàåòñÿ çàãðóçèòü# èêîíêó, ïðèâÿçàííóþ ê ñåðâèñó}

define serviceextinfo{host_name WWWservice_description SMTPnotes_url http://192.168.80.2/nagios/notes/service_www.htmlicon_image apache.pngicon_image_alt Web Service}

define serviceextinfo{host_name Mailservice_description SMTPnotes_url http://192.168.80.2/nagios/notes/service_smtp.htmlicon_image smtp.pngicon_image_alt Web Service}

define serviceextinfo{host_name Mailservice_description POP3notes_url http://192.168.80.2/nagios/notes/service_pop3.htmlicon_image pop3_imap.pngicon_image_alt Web Service}

define serviceextinfo{host_name Mailservice_description IMAPnotes_url http://192.168.80.2/nagios/notes/service_imap.htmlicon_image pop3_imap.pngicon_image_alt Web Service}

Page 60: 013 Системный Администратор 12 2003

58

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

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

Например, для конвертации файла www.png в www.gd2нужно подать следующую команду:

Я думаю, с первыми двумя параметрами все ясно.Третий указывает размер порции кодирования, и четвер-тый – наличие компрессии.

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

И не забудьте подать процессу nagios команду «reload»,которая заставит его обновить конфигурацию. Во FreeBSDэто обычно делается так: /usr/local/etc/rc.d/nagios.sh reload.

Если есть желание, можно нарисовать свои собствен-ные иконки и использовать их вместо стандартных. Я имен-но так поступил с сервисами HTTP, SMTP, POP3 и IMAP.Для HTTP использовалось перо, потерянное индейцемApache, а для всех остальных изображение открытого изакрытого почтового конверта. И хотя картинки получилисьразмером чуть более, чем 40x40 пикселей, Nagios работал

с ними довольно хорошо. Полюбоваться на результат мож-но на следующей картинке.

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

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

Координаты точек, в которых должны рисоваться икон-ки и объекты наших хостов на плоской и трехмерной кар-тах сети, не будут использоваться Nagios до тех пор, покамы не выставим вот таким образом значения теговdefault_statusmap_layout и default_statuswrl_layout в фай-ле cgi.cfg.

$ /usr/local/bin/png2gd2 www.png www.gd2 4000 1

default_statusmap_layout=0

default_statuswrl_layout=0

Page 61: 013 Системный Администратор 12 2003

59№12(13), декабрь 2003

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

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

Впечатляет, не правда ли?

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

Значит, вы что-то напутали с тегами координат отрисовки.Еще одной из полезных возможностей, которую мы

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

Все заголовки страниц и вставки делятся на глобаль-ные и локальные. Глобальные действуют на все страни-цы cgi, а локальные только на те, для которых они былиопределены. Тексты, записанные в файлах заголовков иразрывов страниц, вставляются в начало и конец тега<BODY> </BODY>страницы, создаваемой cgi.

Обычно текст страницы после обработки выглядит так:

Давайте посмотрим, что нужно сделать для того, что-бы это работало на примере файла status.cgi. В директо-рии /usr/local/nagios/share/ssi нужно создать следующиефайлы:� common-footer.ssi – файл глобального заголовка� common-header.ssi – файл глобальной вставки� status-footer.ssi – файл локального заголовка� status-header.ssi – файл локальной вставки

Я думаю, все уже сообразили, что имя для файловлокального заголовка и локальной вставки образуется спомощью сращивания имени подопытного файла cgi снадписями -footer.ssi и -header.ssi. Нужно помнить, чтосодержимое всех вышеперечисленных файлов перед до-бавлением в целевой файл никак не обрабатывается, тоесть создать динамические заголовки и вставки без бе-зумных ухищрений не получится, потому что нет возмож-ности использовать в качестве генератора данных cgi иличто-либо другое. Получается, что включаемые файлыдолжны содержать в себе только чистый html.

Давайте рассмотрим содержимое всех файлов, при-менявшихся в этом примере:

Как вы могли убедиться, все это работает довольнопросто. Еще одной вкусностью, которой я с вами поде-люсь, будет способность привязывать проигрывание зву-ковых файлов к определенным событиям. Например, моясистема мониторинга при умирании какого-либо сервисаначинает изображать жалобно мычащую корову. Такаявозможность очень полезна для администраторов, кото-рые не хотят постоянно смотреть на веб-интерфейс Nagiosили ежеминутно проверять свой почтовый ящик на пред-мет уведомлений о проблемах. Нужно всего лишь открытьв браузере или прикрепить на Active Desktop одну из этихстраниц tac.cgi, status.cgi. После этого можно минимизи-ровать браузер и заниматься своими делами. Как толькослучится какое-либо интересующее нас событие, Nagiosначнет воспроизводить звук, связанный с ним. Для осу-ществления наших желаний есть следующие теги:

You have not supplied any host drawing coordinates, so youcannot use this layout method. Read the FAQs for more informationon specifying drawing coordinates or select a different layoutmethod.

<BODY>ãëîáàëüíûé çàãîëîâîêëîêàëüíûé çàãîëîâîê

ïåðâîíà÷àëüíûé òåêñò

ãëîáàëüíàÿ âñòàâêàëîêàëüíàÿ âñòàâêà</BODY>

Ôàéë common-footer.ssi<p><center><h2> Ïî âîïðîñàì òåõïîääåðæêè îáðàùàòüñÿ íà [email protected]èëè<a href="http://onix.opennet.ru">http://onix.opennet.ru</a> </h2></center></p>

Ôàéë common-header.ssi<p><center><img src="../images/onix.png" border="0" alt="Nagios"></center></p>

Ôàéë status-footer.ssi<p><center><h2> Ðàçäåëèòåëü ñòðàíèöû status.cgi</h2></center></p>

Ôàéë status-header.ssi<p><center><h2>Òåñòîâûé çàãîëîâîê status.cgi</h2></center></p>

Page 62: 013 Системный Администратор 12 2003

60

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

� host_unreachable_sound – хост недоступен;� host_down_sound – хост не работает;� service_critical_sound – сервис в критическом состоя-

нии;� service_warning_sound – сервис в состоянии предупреж-

дения;� service_unknown_sound – состояние сервиса неизвес-

тно;� normal_sound – все работает отлично, нет никаких про-

блем.

Опцию normal_sound практически никто не использу-ет. Но на всякий случай я решил ее упомянуть.

Для того чтобы звуковое оповещение заработало, нуж-но поместить файлы звуков в формате wav внутрь дирек-тории /usr/local/nagios/share/media/, как всегда, не забытьо правах пользователя и принадлежности файлов. А за-тем добавить следующие записи в файл cgi.cfg.

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

легко: нужно просто войти в режим управления сервисомили хостом и подать команду подтверждения проблемы.

После подобной обработки записи в таблице серви-сов или хостов примут вот такой вид:

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

host_unreachable_sound=hostunreachable.wavhost_down_sound=host down.wavservice_critical_sound=servicecritical.wavservice_warning_sound=servicewarning.wavservice_unknown_sound=service unknown.wavnormal_sound=noproblem.wav

Литература:1. Бешков А. Установка Nagios. – //Журнал «Системный администратор» №2(3), февраль 2003 г. – 6-14 с.2. Бешков А. Мониторинг Windows-серверов с помощью Nagios. Часть 1. – //Журнал «Системный администратор»

№7(8), июль 2003 г. – 12-19 с.3. Бешков А. Мониторинг Windows-серверов с помощью Nagios. Часть 2. – //Журнал «Системный администратор»

№8(9), август 2003 г. – 12-23 с.

Page 63: 013 Системный Администратор 12 2003
Page 64: 013 Системный Администратор 12 2003

62

hardware

ВТОРАЯ ЖИЗНЬ МОДЕМОВВТОРАЯ ЖИЗНЬ МОДЕМОВ

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

Page 65: 013 Системный Администратор 12 2003

63№12(13), декабрь 2003

hardware

Лирическое отступлениеЕсли на обычном, пользовательском компьютере у васстоит два модема, то это, наверное, уже много, а вот еслиговорить о серверах, то модемов много не бывает. Про-стой пример: распределённая сеть узлов, единый центр.Узлы связываются с центром и/или центр с узлами. Нацентральный узел осуществляется DDoS-атака. Как в этомслучае связываться и передавать данные? Хорошо, еслиэто происходит в Москве или другом крупном городе, гдепальцем ткни, попадёшь в какого-нибудь провайдера. Не-сколько тысяч долларов, и у вас будет несколько резерв-ных каналов связи на такой случай. Усугубим проблему,а если узлы находятся в других городах? Вот и получает-ся, что самое оптимальное и по цене, и по реализациирешение, если нет необходимости в создании видеокон-ференций, – создание резервной модемной сети связи.По моему мнению, даже в простой маленькой сетке дол-жен быть на сервере модем, например, на случай пере-дачи срочной почты, если упадёт основной канал подклю-чения к Интернету.

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

Во многих корпоративных сетях, если пропускная спо-собность подключения к Интернету мала и не предвидит-ся её увеличения, многие пользователи на своих рабо-чих местах имеют модемы, предпочитая соединяться поdial-up, когда общий интернет-доступ совсем не работа-ет [5, стр. 208-209]. Если в организации имеется центра-лизованная политика безопасности, контролируются всеподключения к Интернету, то такого быть не должно. Зло-умышленники и так постоянно пытаются обойти средствазащиты, а тут появляется удобная лазейка для них. За-чем пытаться взломать МЭ снаружи, когда можно с боль-шой лёгкостью взломать внутреннего модемного пользо-вателя, установить у него cниффер и получить пароли длядоступа к МЭ. Конечно, есть пользователи, которые мо-гут настроить свой персональный МЭ для модема не хужеобщего, но согласитесь, что это скорее исключение.

Случаев неконтролируемого применения модемов до-вольно много, многие из них описаны в литературе, в ча-стности А.Лукацкий [5] пишет: «В процессе проведенияаудита безопасности в одном из московских банков былообнаружено несколько компьютеров, к которым были под-ключены модемы. В процессе разбирательств выясни-лось, что только на одном из компьютеров применениемодема было «узаконено» (для доступа к обновлениямбаз данных юридической консультационной системы).Другие модемы были установлены сотрудниками, которыеиспользовали их для доступа в Интернет в обход МЭ ло-кальной сети банка. В одном случае на компьютере с под-ключённым модемом была найдена программа pcAnywhere,которая позволяла сотруднику работать с конфиденциаль-ными данными из собственного дома».

Всё это говорит о том, что если системный админис-тратор или администраторы не успевают за новыми и

старыми техническими решениями, то за них это дела-ют пользователи. В конкретном примере выше это «от-ставание» было в вопросах организации резервной сетисвязи, выделения более широкого канала доступа к Ин-тернету и организации безопасного удалённого досту-па. Нередко администраторы вообще не знают о том, чтоопределённые виды трафика разумнее делать более при-оритетными по сравнению с другими. (Например, с по-мощью битов поля TOS в заголовках IP-пакетов.)

Чтобы такого не происходило и администратор былвсегда «на высоте», рассмотрим несколько вопросов, свя-занных с использованием модемов.

Какие задачи можно решатьс помощью модемов?1. Можно организовать резервную сеть связи. Если у

организации несколько филиалов в разных городах,то это вполне здравое решение. Оплатить межгородможет оказаться дешевле, чем заказать иные виды ре-зервной связи. Следует отметить, что если и имеетсятенденция к замене АТС на более современные циф-ровые, то темпы замен заметно отстают от последнихмодемных решений. Это означает, что для связи с ка-ким-нибудь сельским районом совсем не нужен самыйпоследний протокол v.92. Что и говорить, если посто-янно появляются небольшие заметки, как эти v.92 илиv.90 отключить. Даже v.34 (28800) в условиях исполь-зования нескольких ретрансляторов междугороднейсвязи может оказаться завышенным требованием.

2. Можно организовать резервную сигнальную сеть. Еслиденег нет на мобильные терминалы [6], нет денег наИнтернет, либо деньги на Интернет есть, но ищетсяболее надёжное решение (с меньшим числом исполь-зуемых элементов), то возможна организация отправ-ки пейджинговых сообщений с помощью тональногонабора.

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

4. Можно использовать функцию «автоответчика» и со-путствующие ей. Голосовая почта и автоответчик мо-гут зарегистрировать нужные звонки, проинформи-ровать клиентов о часах работы вашей организации,рассказать о наличии ресурсов в сети Интернет. Дажепри небольшом умении может прайс-лист по запросузачитываться по телефону. Если во времена 286-хбыли отечественные программки вроде spp.exe(www.samag.ru/sourse/spp.zip) порядка 44 Kб, которыемогли на PC Speaker читать понятно, без особой ин-тонации, при этом различая обычную интонацию ивопросительную, то сейчас, я думаю, вообще не про-блема научить компьютер читать текстовые файлы.

Page 66: 013 Системный Администратор 12 2003

64

hardware

5. Можно сделать BBS (Bulletin Board System). Хотя пос-ледний раз я коннектился к BBS и провёл нескольконочных часов уже как лет 7 назад, не меньше, так чтоне знаю, актуальны они ещё или нет.

6. Можно сделать почтовый (UUCP) сервер. До сих пор естьпровайдеры, которые помимо обычного набора протоко-лов для организации доступа и работы с почтой tcp/ip/ppp+ pop3/imap/smtp позволяют почту забирать по UUCP. А вшколе, где я учился, и по сегодняшний день висит UUCP-почта для внутреннего обмена сообщениями, поднятаямоим бывшим одноклассником на базе Red Hat Linux v.5.2.Uptime-системы уже исчисляется тысячами дней.

Замечание: имеется неплохой клиент для приёма и ре-дактирования сообщений для DOS. Так что, имея загру-зочную дискету, 286, хоть с монохромным CGA-монитором,и модем можно быть равноправным участником почтовогообмена и по сей день!7. Можно сделать ФИДО-шный почтовый сервер (node).

Для этого, правда, если не изменились порядки, дляначала придётся побыть обычным пользователем ФИДО(point) порядка полгода.

8. Можно поднять dial-in-сервер, скажем, для доступа вИнтернет.

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

10.Можно объединить частично или полностью вышеупо-мянутые возможности.

Какой модем купить?По поводу подключения нескольких модемов и модемныхпулов мы поговорим ниже. А пока заметим, что не все пун-кты реализуемы всеми модемами, поэтому для решениятой или иной задачи лучше остановить выбор на лучшихмоделях. Каждый волен выбирать, что ему больше нравитсяи больше подходит по цене. Я свой выбор остановил настарых профессиональных модемах фирмы ZyXEL серии1496. Что ни говори, а стоечные версии и модемные пулыдороги, посему лучше выбирать профессиональные моде-ли ближе к пользовательскому классу. На мой взгляд, та-ковыми являются три модели: ZyXEL U-1496B+, U-1496E+,U-1496S+, либо без «+».

Именно доступность на рынке (цены порядка $7-20),высокое качество и широкий набор услуг обусловили мойвыбор. Конечно, можно было взять и другие модели. Нотут критерий выбора был таков: если модемы ZyXEL, вчастности U-1496S+ и USR Courier используются в банко-матах, то на них и стоит ставить свой выбор по надёжно-сти. Касаемо хорошо работающих Courier, так они доро-ги, и я встречал глючные Courier, купленные дороже чем$150, может, это было исключение, но реализация тогоже ZyXEL под шину ISA (с определителем и голосовымифункциями) обойдётся куда дешевле ($7-10). Конечно,шина ISA сейчас не везде есть, но зато те, у кого она есть,могут в полной мере получить от неё пользу. За $100 мож-но собрать неплохо работающий сервер с не одним моде-мом на базе какого-нибудь Pentium.

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

* From : Anton Loginov, 2:5024/11.30@fidonet=============================================================================

Áûëà òàêàÿ ïðîãðàììà – spp.exe, êîòîðàÿ çàñòàâëÿëà êîìïüþ-òåð ïðîèçíåñòè ñïèêåðîì ôðàçó, çàäàííóþ â êîìàíäíîé ñòðîêå.Ïðè ýòîì îíà ðàçëè÷àëà îáû÷íóþ èíòîíàöèþ è âîïðîñèòåëüíóþ.Ïðîãðàììà áûëà ðóññêàÿ. Ñðåäè ïðî÷èõ áóêâ îíà çíàëà è ðàçíûåñèìâîëû, íàïðèìåð íà $ ãîâîðèëà «äîëëàðû».Èòàê – íî÷ü, ëóíà, çà êîìïüþòåðîì ñèäèò óñòàëûé ñèñòåìíûéîïåðàòîð, è ðàçáèðàåò User's UpLoad íà ñâîåé BBS. Âèäèò –ïðîãðàììà spp.exe áåç êîììåíòàðèÿ. Õîòåë îí å¸ óæå F8, íîëþáîïûòíî ñòàëî – ÷òî îíà äåëàåò?Ñîñòîÿëñÿ ñëåäóþùèé äèàëîã:Ñèñòåìíûé îïåðàòîð: spp.exeÊîìïüþòåð: "ïøø-ñññ..." – ëåãêîå øèïåíèå ñïèêåðà, òèïà õî-òåë ãîâîðèòü, à íå÷åãî!Ñèñòåìíûé îïåðàòîð: spp.exe /?Êîìïüþòåð, ãîëîñîì ðîáîòà ñ ë¸ãêèì ãðóçèíñêèì àêöåíòîì:KÎÑÀß ÑKÎÁKÀ ?Ñèñòåìíîãî îïåðàòîðà ÷óòü óäàð íå õâàòèë – äóìàë ãëþêè óíåãî íà÷àëèñü... Âîò êàê áûâàåò.

Ðèñóíîê 1. Âíåøíèé âèä ìîäåìîâ:a) U-1496B+á) U-1496E+â) U-1496S+(U-1496+)

Page 67: 013 Системный Администратор 12 2003

65№12(13), декабрь 2003

hardware

Организация постоянной памяти

ПЗУПЗУ – постоянное запоминающее устройство, оно же ROM,Read Only Memory. Рассмотрим на пальцах работу даннойсхемы. В первом приближении для организации такой па-мяти ничего сложного не надо – простые перемычки, и ус-тройство готово.

При подаче напряжения на вход, например, логичес-кой «1», на выходах, соединённых с входом, появится тоже«1». На неподключенных выходах (болтающихся в возду-хе) будет «0». Если надо запомнить два байта, берём дватаких устройства, если нужно запомнить n2 байт, берёмn2 таких устройств. Легко заметить, что подобная линей-ная организация неудобна и избыточна, поэтому на прак-тике используется двухмерная реализация, когда для сня-тия данных используются одни и те же выводы. Потеряпропускной способности (нельзя параллельно считыватьвсе ячейки) компенсируется значительным упрощениемсхемы. Для того чтобы сигналы с разных ячеек не меша-ли друг другу, используются диоды.

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

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

Если на диоды, используемые при выборе какой-то ячей-ки памяти, посмотреть внимательно, то можно заметить,что у всех у них используется общий анод (или катод, еслимодифицировать схему). То же самое можно сказать пролюбую ячейку, у диодов, ответственных за её выбор, име-ются общие выводы. Если взять половину транзистора, необращая внимания на всё остальное, то это по сути тот жесамый p-n переход. На практике, при реализации схемы винтегральном исполнении, оказывается более выгоднымвместо отдельных групп диодов создавать n-p-n транзис-торы с несколькими эмиттерами. Поэтому нередко ту жесамую электрическую схему организации ПЗУ можно уви-деть с транзисторами в следующем виде.

Ðèñóíîê 2. Âíóòðåííåå óñòðîéñòâî îäíîé ÿ÷åéêè ïàìÿòè íà 8 áèò.Çàïèñàííîå ÷èñëî (01101011)

Ðèñóíîê 3. Âíóòðåííåå óñòðîéñòâî 2-õ ÿ÷ååê ïàìÿòè (4 + 4 áèòà),çàïèñàíî: 1101 è 0101à) íåóäîáíûé ñïîñîá èçîáðàæåíèÿá) óäîáíûé ñïîñîá èçîáðàæåíèÿ

Ðèñóíîê 4. Ñõåìà ÏÏÇÓ ïîñòðîåííàÿ:a) íà äèîäàõá) íà ìíîãîýìèòòåðíûõ òðàíçèñòîðàõ

Page 68: 013 Системный Администратор 12 2003

66

hardware

При занесении информации через диоды или эмитте-ры шин с информационными нулями пропускаются боль-шие токи, выжигающие плавкие перемычки. При подачеадресного импульса сигналы появляются только на техвыводах, где перемычки сохранены. Так как прошивкаданного вида ПЗУ возможна один раз в жизни, то в зару-бежной литературе данный вид ПЗУ помимо ROM имеетещё одно название OTP ROM (One-Time ProgrammableROM), иногда One-Time опускают и получается ещё одноболее общее название PROM (Programmable ROM).

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

ППЗУППЗУ – перепрограммируемое ПЗУ, ППЗУ с УФ-стирани-ем, EPROM (Erasable, Programmable, Read-Only Memory),UV-EPROM (UltraViolet EPROM). Несколько более доро-гая технология, чем одноразовые ПЗУ, имеющая некото-рые преимущества. В случае выполнения определённыхдействий позволяющая стирать старые и записывать но-вые данные. По внутреннему устройству данная памятьотличается от обычных ПЗУ. Вместо диодов и многоэмит-терных транзисторов используются специальные полевыеМДП (металл-диэлектрик-проводник)-транзисторы, в ча-стности МОП (металл-оксид кремния(окисел)-проводник)c плавающим затвором.

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

Ðèñóíîê 5. Îäèí èç âàðèàíòîâ îðãàíèçàöèè ýëåìåíòà ïàìÿòèñ ïîìîùüþ ïîëåâîãî òðàíçèñòîðà

Ðèñóíîê 6. Ïîëåâîé òðàíçèñòîð ñ ïëàâàþùèì çàòâîðîì (ÏËÌÎÏ)

Ðèñóíîê 7. Òðàíçèñòîð, âûïîëíåííûé ïî ÌÍÎÏ-òåõíîëîãèè

этот затвор не будет помещён заряд. Для этого между исто-ком и стоком прикладывается напряжение около 30 В, приэтом происходит лавинный пробой, на затворе образуетсяостаточный заряд достаточный для образования канала подзатвором. Положительный заряд на затворе притягивает сво-бодные электроны из подложки, а притянутые электронысоздают канал, способный проводить электрический ток.Транзистор становится проводящей цепью. Если заряды наплавающем затворе не накоплены, то данный транзисторток не проводит. Таким образом можно различать логичес-кие «1» и «0». Для стирания данных с ПЗУ необходимо уда-лить накопленный на плавающем затворе заряд. Для этогоиспользуют ультрафиолетовое излучение. Микросхемы дан-ного вида памяти имеют прозрачные окошечки, выполнен-ные из кварцевого стекла. Обычно они заклеены чем-то не-прозрачным. (Данные микросхемы мы встретим далее в мо-демах ZyXEL.) Ультрафиолетовое излучение за счёт попа-дания на кристалл и его ионизации позволяет постепеннорастечься накопленному заряду. В зависимости от интен-сивности УФ-излучения процесс стирания может колебать-ся от 10 минут и выше. Несмотря на то что для стираниярекомендуется использовать освещённость порядка 100 Вт/м2 при времени экспозиции 1 час, редко кто оказывается всостоянии ждать такое количество времени.

Срок хранения информации в ПЛМОП ППЗУ практи-чески бесконечен – постоянная времени утечки заряда со-ставляет десятки лет. У данной технологии также есть иминусы: малое число возможных циклов перепрограмми-рования, примерно порядка 10, плюс для стирания необхо-димо наличие источника УФ-излучения и другие связан-ные с этим неудобства. Так как у ПЛМОП-транзисторов нетзатвора, то для выбора одного элемента памяти, как одиниз вариантов, последовательно с ними включаются обыч-ные полевые транзисторы, что, несомненно, усложняет схе-му. Следующая технология лишена этих недостатков.

ЭС ППЗУЭлектрически стираемые ППЗУ, EEPROM, E2PROM(Electrically Erasable PROM), как легко предположить из на-звания, вместо ультрафиолетового излучения для стира-ния используется электрический ток. В районе 1967 годадля решения вышеописанных неудобств с УФ ППЗУ, в ча-стности, невозможности электрического стирания, былипридуманы новые решения. В качестве ячейки памяти былопредложено использовать транзисторы, выполненные поновой на то время МНОП (металл – нитрид кремния – оксидкремния(окисел) – полупроводник) или МАОП (металл –алунд – оксид кремния – полупроводник)-технологии.

Page 69: 013 Системный Администратор 12 2003

67№12(13), декабрь 2003

hardware

Транзистор, выполненный по МНОП-технологии, пред-ставляет из себя обычный МДП-транзистор, в котором ди-электрик состоит из двух слоёв. Поверх обычного диок-сида кремния, используемого в МОП-транзисторах, нане-сён ещё слой нитрида кремния. Нитрид кремния облада-ет очень высоким сопротивлением, значительно большим,чем диоксид кремния. Эффект памяти в МНОП-транзис-торах основан на изменении порогового напряжения тран-зистора при наличии захваченного в подзатворном диэ-лектрике положительного или отрицательного заряда,который хранится на глубоких (1.3-1.5 эВ) ловушках, внитриде кремния вблизи границы SiO2-Si3N4 [11]. (В тран-зисторах памяти фирмы Hitachi толщина слоя окисла со-ставляет порядка 20 ангстремов, а нитрида кремния –порядка 300-500 ангстремов [12].) Если на затвор податьнапряжение порядка 30 В относительно подложки, то втечение 5 мс между тонким слоем окиси кремния и слоемнитрида кремния под затвором за счёт туннельного эф-фекта появятся неподвижные заряды. На образование то-копроводящего канала между истоком и стоком будетвлиять суперпозиция двух полей, от затвора и от накоп-ленных в ловушках зарядах. Этим и объясняется следую-щая ВАХ МНОП-транзистора.

Разность пороговых напряжений транзистора в ВАХ ификсирует запись логических «0» или «1» в ЭС ППЗУ.Для того чтобы снять накопленные заряды (стереть запи-санную информацию), необходимо на затвор подать на-пряжение порядка 30 В обратной полярности. В МНОПколичество циклов перезаписи очень велико, однако об-ращения для чтения после записи постепенно уменьша-ют заряды, поэтому длительность сигналов чтения лими-тирована. Как правило, ЭС ППЗУ допускает 1011-1012 об-ращений, пока заряд начинает заметно снижаться.

В некоторых ЭС ППЗУ этого типа вместо нитридакремния используется аналогичный по свойствам оксидалюминия (алунд), при этом технология называетсяМАОП и получаются не p-канальные, а n-канальные при-боры, причём нормально открытые. При записи их поро-говое напряжение не снижается, а повышается. Боль-шим преимуществом МАОП и МНОП ЭС ППЗУ являетсяналичие у запоминающих транзисторов внешнего управ-ляющего затвора, с помощью которого и производитсявыборка ячейки.

Flash-памятьТо, что у каждой ячейки ЭС ППЗУ имеется возможностьзаписи и удаления одного бита за одну операцию, это хо-рошо, но реально на практике это порождает много про-блем и замедляет процесс перезаписи. Если ёмкость ПЗУ

составляет 128 Кб, то это означает, что следует выпол-нить порядка одного миллиона стираний. Следует отме-тить, что это не самый большой размер встречающейсяна сегодня памяти. Для упрощения процесса стирания,чтобы это можно было сделать одной или несколькимикомандами, схема ЭС ППЗУ была немного внутренне ус-ложнена и появилась на свет так называемая flash-EEPROM-память или flash-память. В технологии непосред-ственного хранения и записи информации во flash-памя-ти ничего нового не появилось. Сейчас это наиболее хо-довая и удобная память, используемая в компьютерной ибытовой технике. Технология выпуска flash-памяти не-сколько дороже всех предыдущих, но получаемые преиму-щества с лихвой окупают повышение затрат.

Замечание 1: в некоторой литературе flash-EEPROM пе-реводится как мигающий-EEPROM, моё мнение, что это несовсем правильно, если дословно перевести слово flash, тополучится вспышка. Скорее всего, этот смысл и закладыва-ли разработчики данной технологии, насколько быстравспышка, настолько быстро и осуществляется стирание дан-ных из памяти. Помимо этого, если посмотреть на техноло-гию стирания УФ ППЗУ, о которой написано чуть выше, тоименно вспышка как раз лучше всего подходит по смыслу.

Замечание 2: в иностранной литературе наблюдаетсянекоторая путаница, так, у них имеется ещё одно сокра-щение для обозначения ЭС ППЗУ, а именно EAROM(Electrically Alterable ROM). По сути ничего нового не при-думано, однако имеются два различных способа обозна-чений, частично противоречащих друг другу: часто схе-мы запоминающих устройств с более высокой ёмкостьюобозначают как EEPROM, а с меньшей как EAPROM. Так-же через EEPROM иногда обозначают схемы запоминаю-щих устройств, которые стираются целиком или поблоч-но, как flash-память, а под EAPROM понимают запомина-емые устройства, стираемые только по битам, либо побайтам. В плане внесения путаницы в обозначения мытакже не стоим на последнем месте, иногда под ПЗУ унас понимается любое ПЗУ из вышеописанных, в том чис-ле и flash-память.

Все описанные выше типы памяти имеют одинаковоеобозначение на электрических схемах, за исключениемслучаев, если используется функция записи. Выпуск па-мяти как отечественными, так и импортными производи-телями, производится в вариантах, сопрягаемых с ТТЛ, n-МОП и КМПОП-схемами. Это означает, что в пределах од-ной логики микросхемы памяти взаимозаменяемы. Сдела-но это целенамеренно с целью удешевления производствана этапах перехода к более массовому выпуску. Факт, чтомикросхемы памяти можно менять, нам пригодится при пе-репрошивке модемов ZyXEL в следующем разделе.

Перепрошивка модемов,использующих ПЗУИтак, после того как у меня появились вышеописанныемодемы ZyXEL и возникла идея подключить их к Linux-серверу, я подумал, что неплохо было бы поменять в нихпрошивку на более современную перед установкой, бла-го, что такое ПЗУ я себе представлял довольно чётко. Дляэтого два внешних модема пришлось разобрать.

Ðèñóíîê 8. ÂÀÕ (âîëüò-àìïåðíàÿ õàðàêòåðèñòèêà) ÌÍÎÏ-òðàíçèñòîðà

Page 70: 013 Системный Администратор 12 2003

68

hardware

Во всех трёх встретились две микросхемы ПЗУ с вер-сиями. Это были ППЗУ с УФ-стиранием.

Именно заменой их мы и займёмся сейчас.Счастлив тот, у кого есть программатор, кварцевая лам-

па и два настроенных устройства /dev/hands и /dev/head.Менее часа, и проблема смены версии более не существу-ет. К сожалению, первого устройства у меня под руками неоказалось, да и взять ненадолго не у кого тоже было, посе-му я пошёл по пути, описанному ниже.

Преамбула: несколько лет назад один из моих знако-мых, перепрошивая модем Acorp-56EMS на своём компь-ютере, имел возможность на практике подтвердить одиниз законов Мерфи: «Если какая-то неприятность можетслучиться, то она случается». Как назло во время пере-прошивки на время пропало электричество. Модем умер,он отказывался вообще себя как-либо идентифицировать,мигать лампочками и подавать какие-либо признаки жиз-ни. После был куплен новый модем, а сломанный долговалялся у знакомого в ящике, после чего был подарен мнекак «радиогубителю со стажем» в надежде, что мне он при-несёт большую пользу, чем если бы он продолжал пылить-ся. Расчёт оказался как никогда точен. Модем переехал комне. Где-то через пару месяцев, в очередной раз, когда уменя появился блеск в глазах и желание чего-то покрутить,я взял отвёртку и разобрал модем. См. рисунок 11.

Ðèñóíîê 9. Ðàçáîð ìîäåìîâ. Âèä ñíèçó:a) U-1496B+á) U-1496S+

Ðèñóíîê 10. Âíóòðåííèé âèä ìîäåìîâ, ÷àñòü, ãäå íàõîäèòñÿ ÏÇÓ.a) U-1496B+á) U-1496E+â) U-1496S+

Ðèñóíîê 11. Ðàçîáðàííûé ìîäåì Acorp-56EMS

Page 71: 013 Системный Администратор 12 2003

69№12(13), декабрь 2003

hardware

Схема модема оказалась самой обычной, ПЗУ (flash),как полагается, стояла на панельке.

Преамбула к преамбуле: незадолго до этого я на сво-ём Pentium-100 на Asus P/I-P55TP4N как раз занимался тем,что перепрошивал себе BIOS с целью: замены логотипа наболее приятный моему глазу и отвоёвывания у жадногокомпьютера разницы между 9.1 Гб и 8.4 Гб, так как мойновый винт не хотел видеться в полном объёме. Мой школь-ный друг, зашедший ко мне тогда в гости, вдохновился тем,какие неизведанные возможности может сулить обновле-ние версии BIOS (перед этим я с полгода жил, не исполь-зуя свой диск в полном объёме по причине обычной не-хватки времени) и решил повторить у себя операцию с об-новлением и перепрошивкой BIOS. Пытаясь залить болеесовершенный BIOS от Pentium-II объёмом 256 Кб в ПЗУобъёмом 128 Кб на материнской плате первого Pentium,знакомый не знал тогда, что его ждёт неудача и поход комне с ПЗУ и винтом, так как на последний, а не на диске-ту была сохранена старая прошивка перед записью но-вой. Что делать, не пропадать же другу? Была выполненаизвестная операция перепрошивки «на лету», из работа-ющего компьютера я вытащил свою ПЗУ, вставил его изашил обратно ему его версию. Всё прошло на ура.

Припоминая свой недавний успех, я, недолго думая,решил вытащить flash из модема с целью её изучения ивозможной прошивки в материнской плате. Но как выяс-нилось позже, это и не понадобилось, включив ради инте-реса модем без микросхемы памяти, оказалось, что он жив!Загорелись лампочки и на команду «AT» модем бодро от-вечал «ok», правда, ничего более, кроме как «AT», он непонимал. На включённом модеме я воткнул ПЗУ обратно,модем продолжил жить своей жизнью. После этого я под-ключился к Интернету (хорошо, когда есть несколько мо-демов в компьютере) и нашёл там много информации поперепрошивке модемов Acorp и саму прошивку. Нам пона-добится только одна ссылка – [13]. В процессе перепро-шивки модему безразлично, что вы на нём прошиваете, толи его родную прошивку, то ли что-то другое, главное, что-бы прошиваемая микросхема поддерживалась модемом,проверки содержимого прошиваемой программы нет.

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

Далее, я зашёл на сайт фирмы ZyXEL и скачал оттудапоследние версии прошивок для модемов. Для сокращениястатьи я буду писать лишь про прошивку только одного мо-дема ZyXEL U-1496+ (он же U-1496S+), так как прошивкадвух других ничем не отличается, разве что версии программдля каждого типа модема свои. Воспользовавшись инфор-мацией из [13], я вставил в модем чистую микросхему flash-памяти, включил модем и набрал команду AT. Модем выдал«ok». Если у вас модем не включается, то, возможно, вампридётся вставлять микросхему памяти при включённомпитании, но об этом и возможных проблемах далее.

(Набор программ по прошивке можно скачать тут: [16].)Для записи новой прошивки необходим специальный заг-рузчик (flash loader). Так как передавать напрямую двоич-ные файлы, особенно с помощью стандартных термина-лов, невозможно (часть символов будут считаться служеб-ными командами), были придуманы несколько альтерна-тивных, в том числе и текстовых, форматов. (Например,существует формат sb7. Этот формат прошивок, предназ-наченных для заливки во flash ПЗУ модемов DiamondSupra.) Наибольшее распространение получил текстовыйформат S37, понимаемый модемами Acorp. Соответствен-но, имеются утилиты конвертации s37 ↔ bin, которые безпроблем можно найти в Интернете. Программа загрузчи-ка, загрузившись на модем, может позволить вам загру-жать прошивки по более удобному протоколу X-modem.Хотя, если у вас есть конвертор (bin → s37), то эта возмож-ность может вам и не понадобиться.

Если вы встретите файл формата s37, то его содер-жимое будет примерно следующее:

Создавать свой загрузчик, может, и интересно, но зачемизобретать велосипед, берём готовый файл hsloader.s37 насайте журнала: www.samag.ru/sourse/hsloader.37.zip (это до-работанный загрузчик от [email protected]). Вместо hsloader.s37 можно взять uploader.s37из [16]. Далее выполняем следующие действия по загруз-ке, краткая инструкция (модем у нас к этому моменту вклю-чён, ПЗУ вставлена и на команду AT он выдаёт «ok»):1. Даём модему команду AT**.2. Загружаем hsloader.s37 по протоколу ASCII, либо

вставляем из буфера чтобы не набирать руками.3. Загружаем прошивку в формате s37, также по прото-

колу ASCII.

В некоторых случаях загрузчик не грузится без род-ной ПЗУ модема, поэтому смену ПЗУ на flash следуетпроизводить на лету после пункта 2. После замены сле-дует нажать «G» (большое!) и перейти к пункту 3.

Замечание: описанные выше инструкции я выполнил усебя с небольшим исключением, вместо AT**, я набиралAT**2, разницы между этими командами я для себя не уяс-нил, похоже, что можно прошивать разные микросхемы, нетолько flash, если кто знает – поделитесь, пожалуйста, ин-Ðèñóíîê 12. Äâå ìèêðîñõåìû flash-ïàìÿòè AM29F010B

S308000080004C0380A8S3150000800378B2D533B20090C900F00287908AD05374S3150000801398D050B79027907A68C900F011C901F03B....S31500008CC2C947D0ED6820D383600000000000000091S70500000000FA

Page 72: 013 Системный Администратор 12 2003

70

hardware

формацией. Вместо hsloader.s37 я использовал uploader.s37.Скачанный с ZyXEL файл: http://www.zyxel.ru/public/u-series/1496/firmware/6.22/rm622sp1.zip с нужной версией прошив-ки я успешно разархивировал и два файла rm622sp1.u24 иrm622sp1.u25 сконвертировал и прошил в две миросхемыflash памяти. После успешной прошивки я увидел надпись«Upload successfully completed».

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

Далее две прошитые микросхемы с новой версией ясобрался установить в модем. При старой версии про-граммы:

модем выдавал:

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

На данном этапе задача номер 1 по обновлению про-граммного обеспечения модемов была успешно намивыполнена.

Замечание 1: при попытке прошить на модели с плю-сом версию от модели без плюса всё прекрасно проши-валось. При попытке вставить в модем не его версию онругался, выдавая надпись на экранчике о несоответствииверсии.

Замечание 2: после перепрошивки у меня модем U-1496S+ отказался общаться с терминальной програм-мой, хотя на индикаторе показывал успешно пройден-ные тесты и функционировал при управлении им черезклавиши меню. Как выяснилось, произошло это пото-му, что почему-то в ячейке Character Length вместо зна-чения 10 байт, обычно используемых по умолчанию,оказалось записано значение 8. Я перепроверил все ос-тальные настройки и сохранил профиль. После этогодаже после ATZ и выключения питания модем оставал-ся в здравом смысле.

Замечание 3: не знаю уж, насколько у меня плохаясвязь, но попытки установить связь с каким-либо из мос-ковских интернет-провайдеров не дали успеха, модем нив какую не хотел соединяться. Понимая, что такого бытьв принципе не может и проблема, видимо, в настройках,я покопался в инструкции [7], так как я далёк от всякихтреллис-кодирований и полного досконального понима-ния происходящих явлений при установке соединений,я методом перебора выяснил что оптимальными настрой-ками для соединения по моей линии (декадно-шаговаяАТС) оказались команды:� AT&N19 – выбор протокола v.32bis 7200/4800 для ус-

тановления связи;� AT&K4 – выбор протокола сжатия v.42bis и коррекции

ошибок v.42;� AT*E1 – устанавливать связь только с использовани-

ем протокола коррекции ошибок; ATX7 – выбор болееинформативной строки CONNECT при установке со-единения.

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

Для работы определителя номера советую дать коман-ду AT&I4 – включить АОН, информация об определившем-ся номере будет выдаваться как до установки соедине-ния, так и в строке CONNECT. Это очень удобно: знатьномер звонящего при использовании модема для входя-щей связи.

Замечание 4: скорость работы COM-порта следуетвыбирать 57600, ZyXEL серии 1496 не поддерживает ра-боту на 115200. (Если хочется больше, можно попробо-вать 76800.)

Замечание 5: дополнительная информация c [13] дляжелающих поэкспериментировать со своим модемом ввопросах перепрошивки:

Во время перепрошивки не забудьте о необходимос-ти сигнала WE на 31 выводе Flash. Во время замены ПЗУ,надо вытаскивать её аккуратно, если у вас нет соответ-ствующего прибора, то, используя отвёртку, старайтесь

Ðèñóíîê 13. Âèä òåðìèíàëüíîé ïðîãðàììû ïîñëå óñïåøíîéïåðåïðîøèâêè

ATI1

61694U1496S V 6.12 POK

60837U1496S V 6.22 P

Ðèñóíîê 14. Íàäïèñü íà èíäèêàòîðå ïåðåïðîøèòîãî ìîäåìà«U1496S V 6.22 P»

Page 73: 013 Системный Администратор 12 2003

71№12(13), декабрь 2003

hardware

вытаскивать ПЗУ равномерно. Имеется опасность пе-рекоса ПЗУ в последний момент, когда она уже выни-мается легко, и отгибания вбок крайних ног. Несмотряна то, что при перекосах возможны проблемы по опытуDmitry. [email protected] вставлятьflash надо начиная с 16-17 ног таким образом, чтобыпитание, т.е. 32 и 1 ноги попадали последними. В об-щем, вставлять её под небольшим наклоном. Вытаски-вать ПЗУ соответственно наоборот, если же вставлятьflash по-другому, то наблюдается в лучшем случае за-висание терминальной программы, в худшем помогаеттолько кнопочка reset. (Лично у меня, даже при нали-чии желания что-то повесить, такого не происходило,возможно, мне повезло.)

Переставляя микросхемы подобным образом, вы може-те испортить модем или Flash, так что вся ответственностьза те или иные эксперименты лежит только на вас. Для тогочтобы свести риск к минимуму, нужно либо установить ZIF-socket вместо вашей панельки под ПЗУ, либо соорудить кон-струкцию, подобную той, что описывает Dmitry Gzhibovsky([email protected]).

Берётся любая микросхема с «работающей» прошив-кой (хоть родное одноразовое ПЗУ), на неё сверху напа-ивается панель для flash. 22-ые ноги верхней панели иПЗУ отгибаются и через резисторы сопротивлением по-рядка 10 КОм подключаются к +5 В. Далее, с 22-ой ногипанели, которая стоит в модеме, сигнал подается напереключатель. С переключателя сигнал идёт на те же22-ые ноги ПЗУ и верхней панели, то есть переключа-тель подает сигнал с модемной панели или на ПЗУ, илина верхнюю панель, куда собственно flash-память и ста-вится. Далее вся эта конструкция втыкается в модем,переключатель в режим «ПЗУ», включаем питание, at**,заливаем специально доработанный для этих целейuploader, переключатель в положение «flash», нажима-ем на клавиатуре «G», uploader просит залить прошив-ку, что с радостью и делаем.

После того как все модемы оказались перепрошитына новые версии, передо мной встала задача номер 2, аименно как подключить 3 или 4 модема к компьютеру изаставить их вместе работать под ОС Linux.

Несколько модемовКупить модемный пул на 8/16/32 и более модемов или со-ответствующую многопортовую плату от фирм Digiboard,Eqiunox, Granato, Cyclades, Moxa могут позволить себе невсе, да и как-то бессмысленно покупать столь хитрые идорогие устройства, если вам надо подключить всеголишь 3 модема, а не 16 или 32. Можно обойтись покупкойодного или нескольких переходников USB-COM. Хотя поцене не скажу, что выйдет дешевле. Также можно поис-кать старые дешёвые мультикарты, позволяющие гибконастраивать параметры встроенных в неё COM-портов,но это будет то же самое решение, что мы рассмотримниже. Физически нам ничего не мешает воткнуть в ком-пьютер один или два внутренних модема и к двум вне-шним портам подключить ещё два внешних модема. Ноработать вместе без особой настройки данный квартетили трио не будут.

А в чём собственно проблема? Поняв суть проблемы,может, мы сможем решить или обойти её. Изучив по это-му вопросу литературу, можно хорошую инструкцию откакого-нибудь модема или [17], мы можем выяснить, чтодля работы COM-порта, к которому подключаются моде-мы, либо которые встроены в сам модем, если он внут-ренний, необходимо иметь адрес, по которому будут про-изводиться операции чтения и записи и прерывание, че-рез которое будет регулироваться этот процесс. Надеюсь,что все понимают, что с точки зрения повышения произ-водительности асинхронная запись оказывается болеевыгодной, чем синхронная. В своей основе это и порож-дает необходимость в существовании прерываний и вы-текающие из этого проблемы.

В наследство от MS-DOS стандартная настройка COM-портов оказывается следующей:

Замечание: для меня, кстати, до сих пор является сек-ретом, почему в моей любимой терминальной программеTelemate под DOS имеется возможность выбора COM1-COM8. Мне интересно понять, как разработчикам виде-лось использование, скажем, COM7 или COM8.

Если вы уже заметили, то прерывания у COM1 и COM3,COM2 и COM4 совпадают. В этом как раз и состоит ос-новная проблема. Из-за существующих ограничений всилу особенностей реализации ранее придуманной AT/ISAархитектуры одно прерывание нормально не может ис-пользоваться одновременно двумя или несколькими COM-портами. Если же подключить несколько СОМ-портов наодно прерывание и попытаться работать с ними всеми од-новременно, возникнут сбои, ошибки и зависания. Дан-ные ограничения можно обойти путём использования спе-циальных многопортовых карт, о которых я упомянулвыше. Эти карты умеют делить одно прерывание междунесколькими портами. Кстати, большинство из них под-держивается Linux/FreeBSD. Соответственно правильнымрешением, по которому мы пойдём, является поиск сво-бодных прерываний и развод модемов, чтобы используе-мые ими прерывания не пересекались.

Обычно старые внутренние модемы имеют разъёмISA 8-bit (именуемый также PC). Выбор прерывания натакой шине значительно ограничен по сравнению с пол-ной ISA (16-bit). А с учётом, что не все прерывания могутбыть использованы, модемы очень редко предоставля-ют возможность выбора большего, чем 4 числа преры-ваний. При этом используются прерывания по умолча-нию, закреплённые за параллельными и последователь-ными портами:

У ZyXEL 1496E+ с помощью перемычек (jumpers) мож-но выбрать следующие параметры:

/dev/ttys0 (COM1), port 0x3f8, irq 4/dev/ttys1 (COM2), port 0x2f8, irq 3/dev/ttys2 (COM3), port 0x3e8, irq 4/dev/ttys3 (COM4), port 0x2e8, irq 3

IRQ 3: COM2IRQ 4: COM1IRQ 5: LPT2IRQ 7: LPT1

Page 74: 013 Системный Администратор 12 2003

72

hardware

Если же вам повезло и у вас модем более продвину-тый, а ещё и 16-битный, то вам станут доступны все пре-рывания, в том числе верхние 10-15. Не все прерыванияможно выбрать и использовать, поэтому, скорее всего,для вас окажется более полезной следующая информа-ция по выбору прерываний.

Стандартное использование прерываний следующее:� IRQ 0 – Таймер, канал 0.� IRQ 1 – Клавиатура.� IRQ 2 – Cascade for controller 2.� IRQ 3 – Последовательный порт 2 (COM2).� IRQ 4 – Последовательный порт 1 (COM1).� IRQ 5 – Параллельный порт 2 (LPT2).� IRQ 6 – Накопитель на гибких дисках.� IRQ 7 – Параллельный порт 1 (LPT1).� IRQ 8 – Часы реального времени.� IRQ 9 – Перенаправлено на IRQ2.� IRQ 10 – Не назначено.� IRQ 11 – Не назначено.� IRQ 12 – Не назначено.� IRQ 13 – Математический сопроцессор.� IRQ 14 – Первый контроллер жёстких дисков.� IRQ 15 – Второй контроллер жёстких дисков.

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

Давайте рассмотрим, чем мы можем смело пользо-ваться, а от чего придётся воздержаться. Без сомнения,прерывание 0 использовать не получится. Прерывание 1при особых усилиях можно попытаться использовать. За-чем на сервере клавиатура, ибо можно подключить еёпо USB, либо вообще управлять компьютером по сети.Однако столь радикальные меры можно позволить надавно отлаженных системах, где клавиатура точно ненужна. Посему для большинства это прерывание такжеокажется закрытым для использования. Прерываниеномер 2 зарезервировано за неким хитрым устройством,которого, как и людей, его использующих, я никогда невидел. Так что вполне можно использовать это преры-вание для своих нужд. Следует учесть, что 2-е и 9-е пре-рывание в силу особенностей реализации идентичны

друг другу, если не сказать честно, что это одно и то жепрерывание, а поэтому использовать их вместе никакне получится. Прерывания 3 и 4 у нас уже заняты двумявнешними COM-портами, к которым мы уже подключи-ли два модема. IRQ 5 – редко кто у себя на компьютереиспользует его по прямому назначению, а именно дляорганизации второго параллельного порта. Хотя, несом-ненно, это удобно – развести устройства в случае, еслиу вас на одном параллельном порту висят одновремен-но: ФАКС (комбайн), принтер, card reader и сканер. По-явление USB частично решило эту проблему, однаконикто же не будет бесплатно менять все используемыеустройства на их USB-аналоги, а также переписыватькоды предыдущих версий ОС, в которых нет поддержкиUSB. Иногда на это прерывание вешают звуковую кар-ту. Если у вас нет ничего из вышеописанного, то это пре-рывание для вас открыто. IRQ 6 используется дисково-дом. Не секрет, что многие, покупая новые компьютеры,не ставят туда дисковод не потому, что им жалко лиш-ние 180 рублей, а потому, что он им не нужен. На серве-рах можно также обойтись без дисковода. Посему, еслиотключить соответствующий контроллер в BIOS, дан-ным прерыванием можно смело пользоваться. IRQ 7 –это скорее принтерное прерывание, лишь потому, чточаще всего на первый параллельный порт, использующийэто прерывание, устанавливают принтер. Соображениятут аналогичны LPT2. Если у вас порт не используется, топрерывание можно смело использовать. IRQ 8 – часы ре-ального времени, использовать это прерывание врядли получится. IRQ 9 – см. IRQ 2. IRQ 10-12 если не ис-пользуются, то мы можем забрать их под свои нужды.IRQ 13 отвечает за математический сопроцессор. Есливаш процессор более чем 486 DX2, то есть имеет встро-енный сопроцессор, то вряд ли вы сможете использо-вать это прерывание, однако если у вас стоит какая-нибудь 386 или 486 без сопроцессора, то это прерыва-ние для вас открыто. IRQ 14 – вряд ли вы обойдётесьбез жёсткого диска, поэтому данное прерывание ско-рее всего будет для вас занято. Хотя, если пользовать-ся только дисководом (дискетные версии Linux или дру-гих ОС), либо сетевой картой (полная загрузка по сети)или отдельным SCSI-котроллером, то при особых уси-лиях можно это прерывание задействовать для своихнужд. IRQ 15 – если у вас не используется и отключёнвторой контроллер IDE (CD-ROM и винчестер висят наодном шлейфе), то без проблем можно использовать иэто прерывание.

В общем, не пусто, но и не густо. В целом, если невдаваться в описанную выше экзотику, то с большой ве-роятностью вы не сможете использовать IRQ 0, 1, 6, 8, 13или 14. Они будут использоваться вашей материнской пла-той. Используя их необдуманно и не по назначению, выможете заработать множество неприятностей. Когда вызакончите ваши эксперименты, посмотрите в /proc/interrupts (если в ядре есть поддержка /proc) и удостоверь-тесь, что конфликтов нет. Выбрав для себя, что для тре-тьего модема следует использовать IRQ 5, я установилперемычки на модеме ZyXEL в следующее положение ивставил модем в компьютер.

Ðèñóíîê 15. Ñõåìà âûáîðà àäðåñà COM-ïîðòà è ïðåðûâàíèÿñ ïîìîùüþ ïåðåìû÷åê íà ìîäåìàõ ZyXEL U1496B+

Page 75: 013 Системный Администратор 12 2003

73№12(13), декабрь 2003

hardware

В BIOS внешние COM1 и COM2 я назначил стандарт-но. В результате у меня получилась следующая «желез-ная» конфигурация:

Соответственно, если первые два порта Linux опреде-лит сам, так как они стандартны, то что же касаемо COM3,то ядру Linux надо будет дать пояснение, чтобы оно зна-ло, где именно искать наш COM3. В качестве программы,объясняющей ядру, что и где из COM-портов находится, вLinux используется setserial. Следует заметить, что этапрограмма ничего не устанавливает сама, она простосообщает ядру о тех настройках, о которых вы её попроси-те. Файл конфигурации последовательных портов в неко-торых версиях Linux по умолчанию находится в директо-рии /etc и называется serial.conf. Для описанной выше кон-фигурации у меня он получился следующего содержания:

Заглянув в директорию с документацией от Red HatLinux v.7.3 /usr/share/doc/setserial-2.17q, можно увидеть тамдва файла: README и rc.serial, вот поистине правда: RTFMи станете умнее.

Естественно, что в случае нестандартной конфигура-ции запускать setserial во время начальной загрузки вампридётся постоянно. Запускать его руками не есть хоро-шее решение, прописывать файл в /etc/rc.d/rc.local тожене стоит, поэтому наиболее элегантным решением будетиспользование уровней загрузки и rc?.d директорий. ВREADME написано, что файл rc.serial следует поместитьв /etc/rc.d/init.d (переименовав просто в serial) и сделатьна него ссылки из rc?.d либо руками, либо командой:

У второго способа есть особенности. При запуске /etc/rc.d/init.d/serial с параметром stop или save осуществляетсязапись существующей конфигурации в /etc/serial.conf, при-чём туда попадают и все лишние устройства. Мне это пока-залось не очень удобным, поэтому я удалил файлы /etc/rc.d/rc?.d/K??serial, осуществляющие ненужное мне сохранение,и удалил лишние сохранённые строчки из /etc/serial.conf.Конечно, сделав так, через годик-другой можно забыть проэту особенность, но будьте начеку и тренируйте память.Очень плохо, когда всегда и все настройки идут по шабло-ну, даже там, где это особо не нужно.

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

Сменяющая стандартно ассоциированное IRQ 4 для COM3на выбранное мной IRQ 5. Следующие команды проверя-ют правильность установки (выводят настройки на экран,чтобы вы могли их проверить сами) и сохраняют имею-щуюся конфигурацию, как это было описано выше:

У меня получилась следующая конфигурация:

Замечание 1: пока я в BIOS не проассоциировал рука-ми прерывание номер 5 с шиной ISA, в которую был уста-новлен модем, модем не виделся.

Замечание 2: запуск программы kudzu, осуществляю-щей поиск нового оборудования, следует производить пос-ле установки параметров последовательных портов, тоесть после serial, чего при установке по умолчанию не на-блюдается. Если вы хотите, чтобы kudzu обнаружил мо-дем, запущенный у вас нестандартно на COM3 и послене терял его, сообщая вам, что устройство удалено из ком-пьютера, то вам придётся поменять номер запуска kudzuна более высокий, например, с 05 на 51. Сделать это мож-но просто, удалив старые ссылки, запустив для этого:

Затем подправив 05 на 51 в /etc/rc.d/init.d/kudzu и создавновые ссылки:

Ðèñóíîê 16. Âûáîð êîíôèãóðàöèè àäðåñ=3E8, IRQ 5 ñ ïîìîùüþïåðåìû÷åê

COM1 - Port: 0x03f8, IRQ: 4 (/dev/ttyS0)COM2 - Port: 0x02f8, IRQ: 3 (/dev/ttyS1)COM3 - Port: 0x03e8, IRQ: 5 (/dev/ttyS2)

/dev/ttyS0 uart 16550A port 0x03f8 irq 4 baud_base ↵115200 spd_normal skip_test

/dev/ttyS1 uart 16550A port 0x02f8 irq 3 baud_base ↵115200 spd_normal skip_test

/dev/ttyS2 uart 16550A port 0x03e8 irq 5 baud_base ↵115200 spd_normal skip_test

# chkconfig --add serial

# setserial /dev/ttyS2 irq 5

# setserial /dev/ttyS0# setserial /dev/ttyS1# setserial /dev/ttyS2# /etc/rc.d/init.d/serial stop

COM1 /dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4COM2 /dev/ttyS1, UART: 16550A, Port: 0x02f8, IRQ: 3COM3 /dev/ttyS2, UART: 16550A, Port: 0x03e8, IRQ: 5

Ðèñóíîê 17. Çàêðåïëåíèå ïðåðûâàíèÿ íîìåð 5 çà óñòðîéñòâàìèøèíû ISA

# chkconfig --del kudzu

# chkconfig --add kudzu

Page 76: 013 Системный Администратор 12 2003

74

hardware

Если данное решение неудобно, то можно просто ру-ками переименовать все файлы S05kudzu в директори-ях /etc/rc.d/rc?.d на S51kudzu. Скорее всего, изменениеуровня запуска kudzu ни на что другое не повлияет. Убе-диться в том, что все модемы установлены и доступныдля дальнейшей настройки использующих их приложе-ний, можно с помощью стандартной терминальной про-граммы minicom. Если модем будет правильно реагиро-вать на передаваемые ему команды, скорее всего, онработает. Для большей надёжности в правильной рабо-те всех модемов, несомненно, следует проверять рабо-ту всех модемов одновременно, но из-за сложности по-добной реализации мы опустим этот тест, ограничив-шись проверкой на жизнеспособность каждого модемапо отдельности.

Если у вас не установлена терминальная программаminicom, установите её (или используйте свою). В RedHatLinux v.7.3 она находится на 2-м диске (RHL v.9 – на 1-м).

Запустите:

в появившемся меню:

Выберите Serial port setup, у вас выскочит новое окно:

Нажав «A», исправьте используемый вами порт на нуж-ный и установите скорость на 57600. Нажмите «Enter» длявыхода из подменю. В случае необходимости сохранитеконфигурацию – пункт «Save setup as dfl» и, нажав «ESC»,запустите терминал. На некоторое время у вас выскочитнадпись Initializing Modem. После чего у вас должна по-явиться строка, где, как обычно, можно набирать AT-ко-

манды. (Например, ATI или ATI1.) Выход из терминала«CTRL-A, Q».

Повторив вышеописанные операции по отношению ковсем остальным модемам, можно также убедиться, чтоони работают. Если это так, то значит подключение 3 мо-демов прошло у вас успешно и далее вы можете настра-ивать другие программы, прописывая в них модемы про-сто как устройства /dev/ttyS0, /dev/ttyS1, /dev/ttyS2.

Литература, ссылки:1. Хоровиц П., Хилл У. Искусство схемотехники: Пер. с

англ. – Изд. 6-е – М.: Мир, 2003.2. Гальперин М.В. Электронная техника: Учебник. – М.:

ФОРУМ: ИНФРА-М, 2003.3. Фрике К. Вводный курс цифровой электроники – М.:

Техносфера, 2003.4. Жеребцов И.П. Основы электроники – 5-е изд., пере-

раб. и доп. – Л.:Энергоатомиздат. Ленинградское от-деление, 1989. – 122-123 с.

5. Лукацкий А.В. Обнаружение атак. – СПб: БХВ-Петер-бург, 2001. – 624 с.

6. Закляков П. Плохое электропитание, или «Грабли» сUPS. //журнал «Системный администратор», №8(9),2003 г. – 52-61 с.

7. Руководство для пользователей. Универсальный мо-дем серии U-1496. Документ № 83011501, Версия2.21 ZyXEL Communications Corporation и АО МКЦ«Вариант»

8. Доска объявлений по купле/продаже/обмену: http://www.komok.com

9. Доска объявлений по продаже.(интернет-аукцион):http://www.molotok.ru

10.Каталог продукции фирмы ZyXEL: http://www.zyxel.ru/techsup/zyx_fil.asp

11.Учебник по теме «Микропроцессоры». Постоянные за-поминающие устройства. http://docs.lab127.karelia.ru/hardware/microcpu/pam1.htm

12.Информация о некоторых видах памяти. ht tp://digital5.ece.tntech.edu/Public/611/Clements%20CDROM/DATA/HITACHI/A_RAM.PDF

13.Как менять прошивку на модемах Acorp: http://pirogoff.chat.ru/rockwell/firm.htm

14.Официальный сайт Митинского городского радиорынка(г. Москва): http://www.tkmitino.ru/

15.Сайт сети магазинов «Чип и Дип» по продаже элект-ронных компонентов, цены, наличие, справочная ин-формация. http://www.chip-dip.ru

16.Набор программ для прошивки flash-памяти в Acorpмодемах: http://pirogoff.chat.ru/files/firmware.zip

17.man setserial

# minicom -s

Ðèñóíîê 18. Îêíî êîíôèãóðàöèè ïîñëå çàïóñêà "minicom -s"

Ðèñóíîê 19. Íàñòðîéêà ïàðàìåòðîâ COM-ïîðòà

Page 77: 013 Системный Администратор 12 2003
Page 78: 013 Системный Администратор 12 2003

76

web

АЛЕКСЕЙ МИЧУРИН

Page 79: 013 Системный Администратор 12 2003

77№12(13), декабрь 2003

web

Постановка задачи. Или в чем проблема?Многие веб-мастера часто сталкиваются с задачей конвер-тирования файлов Microsoft Excel в другие форматы. Не-редко это сопряжено с трудностями, так как формат xls,как все прекрасно знают, не документирован.

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

За примером далеко ходить не надо. Множество фирм,которые имеют свои веб-страницы и периодически их об-новляют, ведут свои дела с использованием Excel. Передвеб-мастером при каждом обновлении информации на сер-вере возникает задача конвертирования. Причём задачаможет осложняться следующими аспектами:

Во-первых, это изменение дизайна. Price-list, подготов-ленный в Excel, обычно рассчитан на распечатку на чёрно-белом принтере. Price-list на веб-сайте – нет. Хотя бы по-этому простое «Сохранить как веб-страницу» не подходит(я уж молчу о том, какого качества получается HTML-кодпри таком сохранении).

Во-вторых, при конвертировании необходимо учесть спе-цифику Excel. Например, очень многие люди, редактирую-щие price-list, широко применяют команду «Формат/строка/скрыть». При этом высота строки становится нулевой, и стро-ка как бы исчезает с экрана и на печати. Понятно, что и навеб-сайт такие строки попасть не должны. Однако они пре-восходно сохраняются в других форматах и ничем не отли-чаются от обычных, не скрытых, строк. Это приводит к тому,что доктрина «Сохранить как текст с разделителями и обра-ботать» не даёт удовлетворительных результатов.

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

Итак, наша задача состоит в том, чтобы корректно кон-вертировать документ из формата xls в формат HTML сучётом форматирования исходного документа и при этомобойтись «малой кровью».

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

Первую задачу (экспорт) я предлагаю решить средства-ми Excel. Тут у нас фактически нет выбора, формат xlsможет обработать только то единственное на свете при-ложение, которое его понимает. Это диалектика.

Вторую задачу я предлагаю решить средствами языкаPerl. Почему? Потому, что этот язык ориентирован на рабо-ту со строками и на решение задач, подобных нашей (Perl –Practical Extraction and Report Language – то, что надо). Пото-

му, что этот язык знает достаточно много программистов,связанных с веб-разработками (если вы не относитесь к ихчислу и планируете заниматься web, то искренне рекомен-дую обратить внимание на Perl). Потому, что этот язык бес-платен и доступен любому пользователю на любой платфор-ме. И потому, что мой код на Perl можно будет потом легкомодифицировать, заставив его, допустим, помещать каж-дый раздел price-list в отдельный файл, различным образомсортировать позиции прайса, отслеживать обновления идинамику цен, снабжать каждую позицию полями HTML-форм для on-line заказа в веб-магазине... В конце концов,мой скрипт легко превратить в CGI-приложение для адми-нистрирования веб-сервера.

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

Давайте оттолкнёмся от конкретного примера. В каче-стве «подопытного кролика» предлагаю следующий прайс:

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

Экспорт данных из ExcelПриступим к решению первой задачи. Для экспорта дан-ных из Excel я предлагаю несложный макрос на Visual Basic(номера строк приведены только для удобства комменти-рования):

1: Sub table2table()2: '3: ' ìàêðîñ, ñîõðàíÿþùèé âûäåëåííûé ôðàãìåíò òàáëèöû4: ' â òåêñòîâîì ôîðìàòå ñ îòìåòêàìè î ôîðìàòèðîâàíèè5: '6: With ActiveWindow.RangeSelection7: c1 = .Columns.Column8: c2 = .Columns.Count - 1 + c19: r1 = .Rows.Row10: r2 = .Rows.Count - 1 + r111: End With12: If (r1 - r2 = 0 And c1 - c2 = 0) Then13: MsgBox _14: "÷òî-òî ìàëî âûäåëåíî (äëÿ ñîõðàíåíèÿ) ,-)", _15: vbCritical, "ñîîáùåíèå ìàêðîñà"16: End If17: fileSaveName = Application.GetSaveAsFilename( _18: InitialFileName:="file", _19: fileFilter:="Text Files (*.txt), *.txt", _20: Title:="ñîõðàíåíèå ñòðàíèöû â íàøåì ôîðìàòå")21: If fileSaveName = False Then

Page 80: 013 Системный Администратор 12 2003

78

web

Этот макрос сохраняет выделенную часть прайса в за-данный файл. Макрос можно добавить к рабочей версиипрайса и сделать для его вызова кнопку (вне области пе-чати), а можно хранить в отдельном файле. Поместитьего в документ очень просто: вызовите редактор VisualBasic (меню: сервис → макрос → редактор Visual Basic;или Alt-F11), создайте новый модуль (меню: вставить →модуль) и введите приведённый здесь текст (без номе-ров строк). Теперь можно нарисовать кнопку (инструментна панели «Формы») и назначить ей макрос.

Давайте вкратце рассмотрим, как работает этот код.Первая строка – объявление макроса. Как видите, я

назвал его незамысловато table2table, вы можете наречьего более звучно.

В строках с 6 по 11 мы определяем границы выделен-ной части документа (ведь мы будем сохранять тольковыделенную часть). Теперь c1 и c2 – номера первого ипоследнего столбца, а r1 и r2 – первой и последней стро-ки выделенной области.

Далее, в строках с 12 по 16 проверяем, а была ли выде-лена область или нашему макросу предстоит работать толь-ко с одной ячейкой. Этого, конечно, можно и не делать, новедь, скорее всего, запускать этот макрос будете не вы, аменеджеры, редактирующие прайс, на их аккуратность невсегда можно рассчитывать. Итак, если ничего не было вы-делено, то наш макрос выдаст предупреждение:

В строках с 17 по 20 мы вызываем диалог Application.GetSaveAsFilename, чтобы пользователь мог выбрать имяфайла:

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

В строках с 21 по 42 следует конструкция if-then-else спроверкой, было ли указано имя файла для сохраненияили пользователь нажал кнопку «Отмена» диалога «Со-хранить как...».

Если пользователь отказался от сохранения, то выда-ётся соответствующее сообщение (строки с 22 по 24), еслиимя файла указано, то начинается самое интересное –сохранение данных.

Но прежде чем обсудить процедуру сохранения (стро-ки с 26 по 41), давайте скажем пару слов о том, в какомже именно формате мы намерены сохранять данные.Предлагаю самый простой для обработки формат: ASCII-текст. Каждая строка соответствует строке сохраняемойтаблицы. Поля разделены односимвольными разделите-лями. Первое поле – высота строки (эта информация не-обходима, чтобы отфильтровать «скрытые» строки). Всепоследующие поля – содержимое ячеек, но каждое из этихполей содержит несколько под-полей, разделённых свои-ми разделителями. Под-поля несут различную информа-цию о ячейке: содержание, параметры форматирования.

У нас разделители полей и под-полей задаются ASCII-ко-дами в строках 26 и 27 соответственно. Вы можете выбратьболее удобные разделители. Например, если вы уверены, чтов ваших данных никогда не встречается символ «:», то можновзять его в качестве разделителя или под-разделителя.

Далее (строка 28) открываем файл.Организуем цикл по строкам (строка 29).Для каждой строки вычисляем высоту. Заодно начина-

ем готовить строку для сохранения в файл в переменной l(строка 30 листинга).

В цикле (строка листинга 31) по ячейкам сохраняемойстроки таблицы добавляем к строке l всю интересующуюнас информацию о ячейках, снабжая её разделителями.

Какие свойства ячейки мы сохраняем?Первым делом – текст ячейки. Обратите внимание, что

мы используем именно свойство .Text, а не свойство .Value.Это не случайно. Свойство .Value возвращает истинное со-держимое ячейки, свойство .Text возвращает тот текст, ко-торый отображается на мониторе и выводится на печать.Эти две величины могут не совпадать (и обычно не совпа-

22: MsgBox _23: "ôàéë-òî íå âûáðàí. íèêàêèõ äåéñòâèé íå ïðåäïðèíÿòî.", _24: vbCritical, "ñîîáùåíèå ìàêðîñà"25: Else26: sep = Chr(9) ' ðàçäåëèòåëü27: subsep = Chr(8) ' ïîä-ðàçäåëèòåëü28: Open fileSaveName For Output As #129: For r = r1 To r230: l = CStr(Rows(r).RowHeight)31: For c = c1 To c232: With Cells(r, c)33: l = l + sep + CStr(.Text) + _34: subsep + CStr(.MergeCells) + _35: subsep + CStr(.Font.Bold) + _36: subsep + CStr(.Font.Strikethrough)37: End With38: Next39: Print #1, l40: Next41: Close #142: End If43: End Sub

Page 81: 013 Системный Администратор 12 2003

79№12(13), декабрь 2003

web

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

Свойство .MergeCells говорит о том, является ли ячей-ка частью группы объединённых ячеек.

Свойство .Font.Bold отражает жирность текста в ячейке.Свойство .Font.Strikethrough говорит о том, был ли

текст оформлен как зачёркнутый.Для нашего примера нам, пожалуй, больше ничего не

потребуется. Однако не могу не отметить ряд полезныхсвойств, которые могут вам пригодиться. Имена этих свойствдостаточно красноречивы, и я не буду их комментировать,ограничусь перечислением:� .Font.Name� .Font.FontStyle� .Font.Size� .Font.Underline� .Font.ColorIndex� .Font.Italic� .HorizontalAlignment� .VerticalAlignment� .ColorIndex� .Pattern

Обратите внимание, все свойства явно приводятся кстрочному типу функцией CStr (строки с 33 по 36). Это весь-ма полезная процедура, навсегда избавляющая вас от го-ловной боли о преобразованиях типов.

Здесь следует сделать важную оговорку. Дело в том,что функция CStr не в состоянии обработать неопределён-ные значения. Если таковые будут встречаться в вашихдокументах, то вместо CStr вы можете использовать соб-ственную функцию преобразования величин в текстовыйформат. Например, safeCStr:

(Должен отметить, что сам я никогда не сталкивался стакими ситуациями, но научно-технический консультант жур-нала без труда нашёл в Интернете прайс-лист, в некоторыхячейках которого свойство .Font.Bold было не определено.Я полагаю, что такие документы могут возникать в резуль-тате экспорта данных из других приложений. Например, про-дукты 1C допускают экспорт данных в Excel. Одним словом,такая ситуация возможна. – Примечание автора.)

Вот почти и всё. Осталось сохранить готовую строку l вфайл (строка 39 листинга) и закрыть файл по завершениивсего цикла по строкам (строка 41).

Итак, вы выделяете сохраняемую область (в нашем при-мере это первые три столбца таблицы, строки с 4 по 21),нажимаете созданную вами кнопку, выбираете имя фай-ла, и файл сохранён. Что с ним делать дальше?

Создание HTML-страницыпо экспортированным даннымС этим файлом можно сделать всё что угодно, потому чтоего формат нам полностью известен (приятно это осоз-навать). Я приведу пример генерации HTML-страницы.

Как я и говорил, предлагаю скрипт на Perl:

1: Function safeCStr(p As Variant) As String2: If IsNull(p) Then safeCStr = "" Else safeCStr = CStr(p)3: End Function

1: #!/usr/bin/perl -w2:3: #use strict;4:5: # my ($TRUE, $FALSE)=('Èñòèíà', 'Ëîæü');6: my ($TRUE, $FALSE)=('True', 'False');7:8: sub qtnum {9: my $t=shift;10: $t=~s|,(\d+)|,<small>$1</small>|;11: return $t;12: }13:14: sub qtstring {15: my $t=shift;16: $t=~s/\&/\&amp;/g;17: $t=~s/\"/\&quot;/g;18: $t=~s/\>/\&gt;/g;19: $t=~s/\</\&lt;/g;20: return $t;21: }22:23: print <<'TEXT';24: <html>25: <head>26: <title>ïðàéñ íåêîé ôèðìû</title>27: <style type="text/css">28: <!--29: .al {background-color: #FFFFFF}30: -->31: </style>32: </head>33: <body bgcolor="#E8E8E8">34: <table cellspacing="0" cellpadding="1" border="0">35: <tr><td colspan="3" height="1" bgcolor="#8F0000" ↵

nowrap></td></tr>36: <tr>37: <th colspan="3" bgcolor="#FFFFFF"><big>ïðàéñ íåêîé ↵

ôèðìû</big></th>38: </tr>39: <tr><td colspan="3" height="1" bgcolor="#8F0000" ↵

nowrap></td></tr>40: <tr>41: <th rowspan="3">íàèìåíîâàíèå òîâàðà</th>42: <th colspan="2"><small>öåíà</small></th>43: </tr>44: <tr><td colspan="2" height="1" bgcolor="#8F0000" ↵

nowrap></td></tr>45: <tr>46: <th><small>ó.å.</small></th>47: <th><small>ðóá.</small></th>48: </tr>49: <tr><td colspan="3" height="1" bgcolor="#8F0000" ↵

nowrap></td></tr>50: TEXT51:52: while (<>) {53: s/[\x0A\x0D]+$//;54: my @f=split /\x09/;55: my $lh=shift @f;56: my ($name, $usd, $rub)=map {[split /\x08/]} @f;57: if ($lh) {58: if ($name->[1] eq $TRUE) { # îáðàáîòêà çàãîëîâêà ðàçäåëà59: print '<tr><th colspan="3" bgcolor="#FFFF00">' .60: $name->[0] .61: "</th>\n";62: } else { # îáðàáîòêà îáû÷íîé ñòðîêè63: print <<'TEXT' .64: <tr65: onMouseOver="this.className='al';"66: onMouseOut="this.className = '';"><td>67: TEXT68: ($name->[3] eq $TRUE?'<font ↵

color="#888888"><strike>':'') .69: qtstring($name->[0]) .70: ($name->[3] eq $TRUE?'</strike></font>':'') .71: qq|</td>\n<td align="right">| .72: ($usd->[2] eq ↵

$TRUE?'<font color="#880000"><b>':'') .73: qtnum($usd->[0]) .74: ($usd->[2] eq $TRUE?'</b></font>':'') .75: qq|</td>\n<td align="right">| .76: ($rub->[2] eq ↵

$TRUE?'<font color="#880000"><b>':'') .77: qtnum($rub->[0]) .

Page 82: 013 Системный Администратор 12 2003

80

web

Скрипт принимает входные данные из файла, указан-ного как параметр командной строки, или со стандартно-го ввода и выдаёт HTML-код на стандартный выход. Тоесть запускать его можно так:

или, например, так:

Разберёмся, как работает этот скрипт (я буду предпо-лагать, что читатель немного знаком с Perl).

Первая строка – стандартная магическая строка любогоUNIX-сценария. Пользователи Windows могут её проигно-рировать. В третьей строке – закомментированная инструк-ция use strict. Она будет полезна вам только при отладке.

В строках 5 и 6 мы определим переменные $TRUE и$FALSE, которые будут содержать значения истины и лжи,выдаваемые Excel. Дело в том, что русский Excel использу-ет русские слова, европейский – английские. Откомменти-руйте подходящую вам строку и закомментируйте лишнюю.

Процедура qtnum (с 8 по 12 строки) добавляет к запи-си числа теги, превращая «3,14» в «3,<small>14</small>».То есть центы и копейки будут отображаться меньшимшрифтом. Это чисто косметическая мера.

Процедура qtstring (строки с 13 по 21) квотирует «небе-зопасные» символы: & (and), “ (двойная кавычка), < (боль-ше), > (меньше). Это, как вы понимаете, обязательная мера.

В строках с 23 по 50 печатается «шапка» HTML-доку-мента.

В цикле while (строки с 52 по 88) мы считываем пост-рочно входной файл, преобразуем его в HTML-документи выдаём в стандартный поток вывода stdout.

В строке 53 от очередной считанной строки отрезаетсясимвол(ы) конца строки. Я не использую стандартные фун-кции Perl chop и chomp, потому что обрабатываемый файлсоздаётся под Windows, а обработчик (наш сценарий наPerl) может работать и под UNIX. Файл же может переда-ваться весьма экзотическими путями. Например, наверня-ка многие захотят чуть доработать мой код и превратитьего в CGI-приложение для администрирования их родногосервера. Поэтому я не полагаюсь на стандартные функ-ции, а прописываю явно, что мне необходимо удалить всесимволы \x0A и \x0D в конце строки.

Далее строка разделяется на поля (строка 54). Здесь

используется тот же разделитель, что и в макросе на VisualBasic (строка макроса 26).

Первое поле – высота строки – сохраняется в перемен-ной $lh (строка 55). Все остальные поля разделяются на под-поля. В результате переменным $name, $usd, $rub присваи-ваются указатели на массивы, содержащие всю необходи-мую информацию о содержимом и форматировании соот-ветствующей ячейки. $name – ячейка с наименованием то-вара, $usd – ячейка с ценой в долларах, $rub – ячейка с це-ной в рублях. Делается это одной-единственной строкой 56.

Если высота строки не равна нулю, то выполняем блокс 58 по 84 строки. В противном случае выдаём предупреж-дение в стандартный поток ошибок stderr о том, что обна-ружена и проигнорирована скрытая строка (строка 86).

Обработка строк таблицы только на первый взглядможет показаться сложной.

Прежде всего мы выясняем, с чем мы имеем дело: встроке 58 проверяем истинность свойства .MergeCells ячей-ки с наименованием товара. Если эта ячейка объединена,то это заголовок раздела, тогда выполняется код генери-рующий заголовок (строки с 59 по 61).

Если оказывается, что мы имеем дело с обычной стро-кой, то выполняется блок else (строки с 63 по 79). Здесьформируется строка HTML-таблицы, в которую вставля-ются дополнительные элементы форматирования (для техстрок таблицы, где это необходимо).

Обратите внимание, что мы встроили в наш документэлементарный DHTML-приём. В таблице всегда подсве-чивается строка, на которой находится указатель мыши.Это упрощает чтение таблицы. Согласитесь, что добить-ся такого эффекта средствами Excel (путём сохранениядокумента как веб-страницы) затруднительно.

В строках 90–94 выводим завершающие теги докумен-та. Обратите внимание, что в конце файла с программойобязательно должна быть пустая строка. Иначе последнееслово («TEXT») (строка 94) не будет правильно обрабо-тано интерпретатором Perl.

То что получается на выходе, смотрите на рисунке(стр. 82).

Согласитесь, было за что биться!

BUGS. Что ещё можно добавить?Я не сомневаюсь, что хотя мои примеры полностью рабо-тоспособны, мало кто будет использовать их без малей-ших модификаций. Хочу подбросить пару мыслей о том,что можно улучшить в этих скриптах, чтобы при их моди-фикации вы не делали лишней работы, а убивали сразукак можно больше зайцев.

По сценарию на Visual BasicЗдесь вам скорее всего придётся изменить набор сохра-няемых параметров ячейки. Список наиболее полезных япривожу в обсуждении этого сценария. Если вам понадо-бится какая-нибудь экзотика, обращайтесь к документа-ции Microsoft, свойства объекта Range.

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

78: ($rub->[2] eq $TRUE?'</b></font>':'') .79: "</td>\n";80: }81: print <<'TEXT';82: </tr>83: <tr><td colspan="3" height="1" bgcolor="#8F0000" ↵

nowrap></td></tr>84: TEXT85: } else {86: warn 'hidden line: '.$name->[0]."\n";87: }88: }89:90: print <<'TEXT';91: </table>92: </body>93: </html>94: TEXT

perl file2html.pl file.txt >file.html

cat file.txt | perl file2html.pl >file.html

Page 83: 013 Системный Администратор 12 2003
Page 84: 013 Системный Администратор 12 2003

82

web

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

Наконец, читатель может справедливо спросить, зачеммакрос для Excel сохраняет скрытые строки, ведь их можноотсеять уже на стадии экспорта? Снимаю шляпу перед вни-мательностью читателя (втайне надеясь на ответный жест вадрес моей проницательности). Сохранять скрытые строкидействительно совсем не обязательно, просто я привык со-хранять всё. Причины? Возможно, скрытые строки всё-такипонадобятся. Или вы захотите точно знать, какие строки былипроигнорированы (мой Perl-сценарий, как вы помните, со-общает о каждой скрытой строке). Кроме того, информацияо высоте строк может быть критерием для идентификациизаголовков... Хотя, конечно, вы можете слегка модифици-ровать VB-код и не сохранять скрытые строки.

По скрипту на PerlКонечно, весь HTML-код (а это большая часть скрипта)вы скорее всего значительно измените. Конечно, вам при-дётся изменить количество столбцов, шапку, многие уда-лят из HTML-кода мои пустые строчки-разделители, на-крутят вложенных таблиц, изменят DHTML-функции, до-бавят CSS-таблицы... Но это не самое главное и не прин-ципиальное изменение.

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

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

Я бы советовал организовать подобные процедуры (неотносящиеся непосредственно к HTML-вёрстке) в виде от-дельных программ или модулей. Кстати, часть работы поHTML-вёрстке можно доверить механизму SSI, а скриптпусть собирает SHTML-документ. Набор простых инстру-ментов всегда удобнее, гибче и управляемее, чем одинуниверсальный. Держитесь подальше от грабель, по ко-торым гуляют создатели телефона-микроволновки и те-левизора-зубной щётки.

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

Page 85: 013 Системный Администратор 12 2003
Page 86: 013 Системный Администратор 12 2003

84

образование

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

Page 87: 013 Системный Администратор 12 2003

85№12(13), декабрь 2003

образование

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

Все ОС Unix и подобные операционные системы из-начально отлично подготовлены для полноценной рабо-ты в среде клиент-сервер. Даже X-Window не удалосьизбежать данной участи. Это сетевой продукт, одна частькоторого (сервер) взаимодействует непосредственно спользователем с помощью клавиатуры, мыши и мони-тора, она обрабатывает команды пользователя и фор-мирует соответствующие запросы на их выполнение. Ре-зультаты работы программ передаются также непосред-ственно ему. А другая (клиент) уже обрабатывает резуль-таты запросов и запускает запрошенные программы, азатем передает результат выполнения обратно серверу.Основой взаимодействия графических приложений ссервером является протокол Х, который реализован так,что ему абсолютно не важно, где находится клиент исервер. В самом общем случае они работают на одномкомпьютере, но ничто, повторяю, ничто не мешает раз-местить их на разных компьютерах, ну разве что отсут-ствие какой-либо связи между ними.

Такая организация позволяет эффективно использо-вать компьютерный парк организации: все ресурсоемкиеоперации выполняются на специально выделенном мощ-ном компьютере. То есть имеется несколько более сла-бых компьютеров, за которыми работают пользователи.Такие компьютеры используют Unix с установленным сер-вером X-Window. Операционная система обрабатываетзапросы, создаваемые пользователем, и передает егосерверу, который в свою очередь возвращает результат.Эти компьютеры принято называть Х-терминалами. А ком-пьютер, выполняющий основную наиболее трудоемкую ра-боту, называют сервером графических приложений. Ко-нечно же, к ресурсам такого компьютера предьявляютсяособые требования, особенно это относится к объему опе-ративной памяти, которой должно теперь хватать на всех,и к скорости дисковых операций. А вот к рабочим стан-циям пользователя требования уже гораздо ниже. С воз-лагаемой на них задачей спокойно могут справиться и«четверки».

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

Оказывается, можно. Открытость Linux-систем поро-дила вокруг себя довольно много полезных проектов, ичасто для решения какой-нибудь проблемы необходимопросто найти подходящий. Решением вопроса загрузкибездисковых терминалов занимается LTSP (Linux TerminalServer Project).

В чем же преимущество компьютера без диска:� Подвижность пользователя, ведь как уже отмечалось,

пользователь не связан с конкретным компьютером.� Снижение стоимости и упрощение операции обновле-

ния программного обеспечения, так как это произво-дится только на одном компьютере.

� Резервирование, восстановление данных будет про-исходить также только на одном компьютере.

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

� UPS можно предоставить только серверу.� Также будет существенно ниже общая цена – эконо-

мия = (стоимость жесткого диска + стоимость CD-ROM+ стоимость флоппи-дисковода) ∗ количество компь-теров.

� Защищать от вирусов необходимо только сервер, таккак другие компьютеры не имеют жесткого диска.

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

� Большая долговечность клиентских машин как мораль-ная, так и физическая.

� Возможность работы в запыленных помещениях (здесьжелателен «холодный» процессор типа VIA C3, ЖК мо-нитор).

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

После включения питания управление передается, какобычно BIOS, который в свою очередь выполняет инициа-лизацию, проверку POST (Power-On-Self-Test) и анали-зирует порты на наличие дополнительных устройств. Входе последней обнаруживается установленная сете-вая карта, в энергонезависимой памяти которой обна-руживается код, начинающий выполняться после завер-шения теста.

Дальнейшую работу условно можно разделить на триэтапа: получение IP-адреса, получение образа операци-онной системы и собственно работа с данными. Чтобыполучить IP-адреса, программа загрузки инициализиру-

Page 88: 013 Системный Администратор 12 2003

86

образование

ет широковещательный запрос (для нашего примера192.168.0.255, по умолчанию используется порт 68, про-токол UDP), в котором указывается свой уникальный длякаждой сетевой карты МАС-адрес. Для динамическогораспределения IP-адреса между компьютерами в сетииспользуется служба DHCP. DHCP-сервер, приняв зап-рос, находит конфигурацию, соответствующую данномуМАС-адресу, и возвращает cледующие данные:� IP-адрес рабочей станции.� Маску сети.� Путь к загружаемому ядру ОС.� Путь к каталогу, который монтируется в качестве кор-

невого.

Переговоры между клиентом и сервером можно вос-произвести примерно так.

Клиент: «Привет, мой аппаратный адрес 00-02-44-07-FC-C4, дай мне мой IP-адрес».

Сервер: «(Ищет адрес в базе данных.) Ваше имя –aldebaran, ваш IP-адрес – 192.168.0.100, ваш сервер –192.168.0.1, файл, от которого вы загружаетесь, нахо-дится в /tftpboot/ltsp/vmlinuz-2.4.21-ltsp-1 и остальная ин-формация).

Естественно, в сети должен находиться один такой сер-вер, иначе они передерутся между собой, и, конечно же,необязательно он должен быть нашим сервером графи-ческих приложений. После получения адреса клиент дол-жен загрузить ядро операционной системы. Для этого ис-пользуется протокол TFTP (тривиальный протокол пере-дачи файлов). Это просто облегченная версия протоколаFTP, которая не требует идентификации и используетUDP-протокол вместо TCP. Ну а чтобы пользоваться фай-ловой системой, на другом компьютере на сервере долж-на быть настроена служба NFS. После загрузки ядра оно,уже как и положено, берет бразды правления в свои руки.Вот вкратце и все.

Теперь займемся практической реализацией. Длятого чтобы было возможным загружаться описаннымвыше способом, необходимо записать образ загрузчи-ка, поддерживающего определенную сетевую карту вEPROM (Erasable Programmable Read-Only Memory – пе-резаписываемая память). Для этого заходим на сайтhttp://rom-o-matic.net/ и в выпадающем списке «ChooseNIC/ROM type» выбираем марку чипа на сетевой кар-те. Здесь я допустил ошибку, помня, что сетевая картаNE2000 совместимая, просто скачал образ для NE. Ивполне естественно, при загрузке получил что-то вро-де «не могу найти NE*-карту». Пришлось раскрыватькорпус одного из компьютеров и смотреть, что там та-кое установлено, заодно и сам узнал марку чипа –rtl8029. В меню «Choose ROM output format» выберитеинтересующий формат. Доступны следующие вариан-ты образов:� Floppy Bootable ROM Image (.lzdsk) – загрузчик с дис-

кеты (на первом этапе лучше воспользоваться имен-но им).

� Binary ROM Image (.lzrom) – прошивка ПЗУ сетевой карты.� LILO Bootable ROM (.lzlilo) – загрузка с использованием

LILO.

� DOS Executable ROM Image (.com) – DOS-загрузчиктоже подходит, только уберите загрузку himem.sys иemm386.exe, а то работать, скорее всего, не будет, идобавьте соответствующие строки в файл config.sysдля загрузки.

� PXE loadable ROM Image (.lzpxe) – то же, что и второйпункт, но разработки Intel.

Выбираем вариант Floppy Bootable ROM Image, принажатии на кнопку «Get ROM» вы получаете нужный об-раз. Чтобы перезаписать его на дискету, воспользуйтесьпрограммой rewrite под Windows, которая входит в составпрактически каждого дистрибутива Linux, а в Linux дайтеследующую команду:

или

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

Отправная точка в Интернете для поиска необходимойинформации и программ – официальный сайт проектаhttp://www.ltsp.org.

Конфигурация сервера Athlon 1.3 Гц, 256 Мб, 10 Mбитсетевая карта. Пять клиентов Pentium-100, 16 Мб, VideoS3 Trio 3D 4 Мб. Все это настраивалось под операцион-ными системами Linux Mandrake 8.0 и Red Hat 7.3. Длятого чтобы это все работало на данных системах, былиустановлены следующие сервисы: dhcp, nfs, portmap, tftp(клиент и сервер), если понадобится telnet-сессия, то иtelnet-сервер и запущена служба xinetd. На установкевыше перечисленных сервисов я останавливаться небуду, хотя бы потому, что большинство их входит в со-став соответствующих дистрибутивов, и если нет в стан-дартной поставке, то их всегда можно найти на соответ-ствующем сайте.

Для настройки ltsp нам понадобятся следующие паке-ты, которые можно взять с http://prdownloads.sourceforge.net/ltsp/, все они доступны как в виде перекомпилированныхпакетов в формате rpm или deb, так и в виде исходников.Какие устанавливать – дело вкуса и опыта. Я скачал вформате tgz. Итак, какие необходимо скачать пакеты (вер-сию не указываю специально, так как к моменту выходастатьи все может измениться, плюс уже давно ходит вбетах версия 4):� ltsp_core – основной пакет, необходимый для работы;� ltsp_kernel – ядро, загружаемое на клиентский компьютер;� ltsp_x_core – пакет, необходимый для запуска X-

Window версии 4.х на клиентском компьютере;� ltsp_x_fonts – пакет со шрифтами (скачал по рекомен-

дации на сайте, но вполне можно обойтись и без него).

#cat your_image.lzdsk > /dev/fd0

#dd if=/path/to/rom-image of=/dev/fd0 bs=1024

Page 89: 013 Системный Администратор 12 2003

87№12(13), декабрь 2003

образование

Если видеокарта не поддерживается в версии 4.х, не-обходимо дополнительно выбрать пакет с версией сер-вера 3.3.6 применительно к видеокарте, установленнойна ваших клиентских компьютерах (в моем случае этоltsp_x336_s3), или, если нет, то ltsp_x336_svga, но приэтом не будут работать TrueType-шрифты и сглажива-ние. На сайте также доступны пакеты для поддержкизвука, сканера, веб-камер и wireless-устройств на тер-минале, пакеты для организации Windows-терминала иеще много чего. Первым обязательно должен быть ус-тановлен пакет ltsp_core. Установка заключается в рас-паковке (tar xvzf) и запуске инсталляционного скрипта(cd ltsp_ххх, ./install.sh). Остальные устанавливаютсяаналогично. Для rpm-пакетов просто дайте команду:

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

После установки всех пакетов перейдите в каталог /opt/ltsp/templates/ и запустите скрипт ./ltsp_initialize, которыйвнесет необходимые изменения в конфигурационные фай-лы вышеперечисленных сервисов. Внимательно читайтевыходные данные, если что-то у вас не установлено, тоскрипт выдаст сообщение об ошибке. Теперь давайте пе-рейдем к ручной доводке сервисов.

Сервис dhcp настраивается в файле /etc/dhcpd.conf,который при установке в большинстве дистрибутивов несоздается, поэтому первоначально может потребоватьсяего создать:

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

Для начала о некоторых допущениях, связанных с кон-фигурацией локальной сети. В сети 192.168.0.0/255.255.255.0для бездисковых терминалов выделены адреса с192.168.0.100 по 192.168.0.254. Серверы DHCP и LTSPнаходятся на компьютере 192.168.0.1. Тогда файл /etc/dhcpd.conf будет иметь такой вид:

Небольшое пояснение. В начале конфигурационногофайла расположены инструкции, относящиеся ко всемкомпьютерам сети. Их смысл очевиден. Поскольку натерминалах нет жесткого диска, то демону журналиро-вания syslogd в строке option log-servers 192.168.0.1 ука-зывается удаленный сервер, который будет записыватьот него сообщения. Для того чтобы демон syslogd на сер-вере мог принимать сообщения от терминалов, в файлеконфигурации /etc/sysconfig/syslog, должен использо-ваться ключ -r:

Далее идут индивидуальные настройки для каждо-го компьютера клиента. Здесь можно переопределитьнастройки сервера индивидуально. В строке hardwareethernet 00-02-44-07-FC-C4 указывается аппаратныйМАС-адрес сетевой карты, а в строке fixed-address192.168.0.100 за ним статически закрепляется IP-адрес.Теперь при запросе клиента с указанным МАС-адресомему всегда будет выдаваться IP-адрес 192.168.0.100.Остальным же он будет назначаться на общих прави-лах, из таблицы свободных адресов. Строка option root-path указывает на раздел, который будет смонтированв качестве корневого с помощью службы NFS, его мож-но прописать и в глобальной секции, но только в томслучае, если в данной сети используются только без-дисковые станции, иначе ноутбук шефа будет загружатьчто попало. Для того чтобы данный ресурс был виден всети, необходимо в файле /etc/exports сервера LTSP ука-зать каталоги, доступные для сетевого монтирования:

Слева указаны каталоги, которые экспортирует сер-вер, первая строка – корневую систему, а вторая – раз-дел свопирования, если в нем есть необходимость. Спра-ва указаны опции. Флаги ro и rw указывают на доступ толь-

Good! We have found RedHat version 7.3About to install LTSP, using the following settings:# êàòàëîã, â êîòîðûé óñòàíàâëèâàþòñÿ ïàêåòûLTSP_DIR = /opt/ltspSWAP_DIR = /var/opt/ltsp/swapfiles# êàòàëîã äëÿ çàãðóæàåìîãî ÿäðàTFTP_DIR = /tftpboot# àäðåñ ñåòèIP_NETWORK = 192.168.0.0# àäðåñ ñåðâåðàIP_SERVER = 192.168.0.1# ìàñêà ñåòèIP_NETMASK = 255.255.255.0# øèðîêîâåùàòåëüíûé àäðåñ ñåòèIP_BROADCAST = 192.168.0.255

#touch /etc/dhcpd.conf

# Options to syslogd# -m 0 disables 'MARK' messages.# -r enables logging from remote machines# -x disables DNS lookups on messages recieved with -r# See syslogd(8) for more detailsSYSLOGD_OPTIONS="-m 0 -r "

/opt/ltsp/i386 192.168.0.0/255.255.255.0 (ro, no_root_squash)/var/opt/ltsp/swapfiles (rw, no_root_squash)

# rpm -ivh ltsp_core-3.0.9-0.i386.rpm

subnet 192.168.0.0 netmask 255.255.255.0 {range 192.168.0.2 192.168.0.100;option subnet-mask 255.255.255.0;option broadcast-address 192.168.0.255;option routers 192.168.0.1;option domain-name-servers 192.168.0.1;option domain-name "server.org";option log-servers 192.168.0.1;

host term1 {hardware ethernet 00-02-44-07-FC-C4;fixed-address 192.168.0.100;option host-name "term1";option root-path "192.168.0.1:/opt/ltsp/i386";filename "lts/vmlinuz-2.4.21-ltsp-1";}

Page 90: 013 Системный Администратор 12 2003

88

образование

ко для чтения и для записи и чтения соответственно. Аno_root_squash заменяет пользователя root более безо-бидным nobody. Параметры ro и no_root_squash, исполь-зуются в файле по умолчанию, и поэтому их можно смелоопустить, но так как-то нагляднее.

Ядро может автоматически определить только PCI се-тевую карту, если у вас ISA, то добавьте следующие стро-ки для каждого описываемого клиента.

Здесь хочется отметить, что «option-128» в этом слу-чае не является mac-адресом, это специальный ключ длязагрузки Etherboot. Параметр «option-129» указываетядру, какой именно драйвер сетевой карты необходимозагружать. Параметр filename указывает путь к ядру,который необходимо загружать. Пакет LTSP поставля-ется с двумя ядрами, поддерживающими большинствосетевых карт: одно описано выше, а второе с префик-сом lpp (Linux Progress Patch) в имени. При использова-нии последнего ядра на компьютере клиента при загрузкеотображается статус-бар, данное ядро рекомендуетсяиспользовать, после того как удалось все настроить изагрузиться с обычного.

Дополнительно может понадобиться для экспорта до-машних каталогов пользователей /home добавить следу-ющие строки в файл /etc/exports:

а в файл /opt/ltsp/i386/etc/fstab:

И обязательно добавьте в файл /etc/hosts описаниекомпьютеров сервера и клиентов для нормальной рабо-ты службы NFS. Например:

Теперь необходимо перезапустить сервис dhcpd:

На этом настройку dhcpd можно считать законченной.Теперь о настройках остальных сервисов. Общим длянекоторых из них является то, что если сервис запускает-ся с помощью xinetd (tftp, telnet), то он обязательно дол-жен быть разрешен (в файлах /etc/xinet.d/tftp и /etc/xinet.d/telnet), для этого требуется заменить disable = yes наdisable = no. Также в целях улучшения безопасности мо-гут быть определены IP-адреса, с которых разрешен дос-туп к данному сервису (по умолчанию localhost), т.е. в на-шем случае only_from = 192.168.0.0. Кстати, вообще вы-шеописанное желательно проводить в сетях, в которых

вы полностью доверяете всем компьютерам, а от внешнихсобратьев закрыться firewall.

Файл /etc/xinet.d/tftp будет иметь такой вид:

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

Имя файла указано так потому, что корневой каталогдля этого сервиса определен в файле /etc/xinet.d/tftp какserver_args= -s /tftpboot, т.е. каталог /tftpboot делается кор-невым (chroot), и поэтому если указать полный путь, тосервер просто не найдет необходимый файл.

Меньше всего возни с настройкой сервера шриф-тов было в дистрибутиве Red Hat. А с настройкой в ос-тальных мне очень помог разобраться документ http://www.ltsp.org/contrib/AbiWordfont.txt. В файле /etc/X11/fs/config в строке «client-limit = 10» установите число компь-ютеров клиентов, рекомендуемое не более сорока. В фай-ле /etc/X11/XF86Config (или XF86Config-4, если вы исполь-зуете четвертую версию сервера) замените строку:

на

А в файле /etc/rc.d/init.d/xfs замените строку:

на

и строку:

на

Перезапустите сервер и проверьте, слушает ли он портпод номером 7100. Для того чтобы терминалы могли зап-

/home 192.168.0.0/255.255.255.0 (rw)

ltsp-server:/home/ /home nfs defaults,rsize=8192,wsize=8192 0 0

/etc/hosts127.0.0.1 localhost.localdomain localhost…192.168.0.1 server.org192.168.0.100 term1

[root@grinder etc]# /etc/init.d/dhcpd restart Îñòàíàâëèâàåòñÿ dhcpd: [ ÑÁÎÉ ]Çàïóñêàåòñÿ dhcpd: [ ÎÊ ][root@grinder etc]# /etc/init.d/dhcpd statusdhcpd (pid 979) âûïîëíÿåòñÿ...

FontPath "unix/:-1"

FontPath "tcp/localhost:7100"

daemon --check xfs xfs -port -1 -daemon -droppriv -user xfs

daemon --check xfs xfs -port 7100 -daemon -droppriv -user xfs

daemon --check xfs su xfs -c \"xfs -port -1\" -s /bin/sh

option option-128 e4:45:74:68:00:00;option option-129 "NIC=ne IO=0x300";

service tftp{

socket_type = dgramprotocol = udpwait = yesuser = rootserver = /usr/sbin/in.tftpdserver_args = -s /tftpbootdisable = noper_source = 11cps = 100 2

}

[root@grinder root]# tftp grinder tftp> get lts/vmlinuz-2.4.21-ltsp-1Received 1062469 bytes in 0.9 secondstftp> quit

daemon --check xfs su xfs -c \"xfs -port 7100\" -s /bin/sh

Page 91: 013 Системный Администратор 12 2003

89№12(13), декабрь 2003

образование

рашивать у сервера сеанс XDM, требуемый для регист-рации пользователя и запуска пользовательской сессии,необходимый при использовании X-Window, требуется вконфигурационном файле /etc/X11/xdm/xdm-config на сер-вере LTSP внести соответствующие изменения:

И остался «последний и решительный бой». Правкасамого главного конфигурационного файла LTSP /opt/ltsp/i386/etc/lts.conf. Наиболее подробную информациюо настройках тех или иных параметров можно узнатьиз файла /opt/ltsp/i386/etc/lts.conf.readme. Данный файлсостоит из раздела [Default], в котором определяютсяобщие для всех клиентов параметры, и разделов, оп-ределяющих индивидуальные для каждого клиента, вних при необходимости можно переопределить те илииные глобальные установки. Благодаря такой схемепоявляется возможность более гибкой адаптации к ап-паратной конфигурации терминалов. Итак, пример фай-ла lts.conf:

И секция для клиента. В качестве ее названия можетвыступать имя хоста, МАС- или IP-адрес, т.е. [term1],[192.168.0.100] или [00-02-44-07-FC-C4].

Уровень инициализации (RUNLEVEL) 3 загружает ко-мандную строку bash_shell в консоли, этот параметр же-лательно установить первым для отладки работы серви-сов, и если все получилось, то использовать либо 4 дляtelnet-сессии, позволяющей открывать несколько терми-налов на сервере и переключаться между ними по Alt-F1до Alt-F9, либо 5 для автоматического старта X-Windows.Для каждого клиента, как видите, есть возможность оп-ределить индивидуальные параметры Х-сервера в сек-ции, но возможен и другой вариант, он особенно удо-бен, если имеется несколько клиентов с одинаковымивидеокартами.

Для этого необходимо указать в параметреXF86CONFIG_FILE = XF86Config.term1 имя конфигура-ционного файла для данного клиента и поместить егов каталог /opt/ltsp/i386/etc/X11/ (предварительно создавкаталог Х11). Мне в этом смысле немного повезло, наодном из клиентских компьютеров до этого стоял Linux,поэтому генерировать данный файл заново не при-шлось. Если у вас другая ситуация, то попробуйте ис-пользовать программу /usr/X11R6/bin/xf86config на сер-вере, установив туда нужную видеокарту (не забудьтесохранить при этом оригинальные файлы). Дополни-тельно можно переопределить параметры клавиатуры,используемые по умолчанию. Для этого предназначе-ны следующие опции:� XkbModel – модель клавиатуры, наиболее распрост-

раненные – pc 101, pc 102, pc 105;� XkbLayout – раскладка клавиатуры, например us (по

умолчанию), ru, ru(winkeys);� XkbSymbols – таблица скан-кодов, по умолчанию

«us(pc 101)», но можно заменить, например на«us(pc105) + ru».

Раз уже коснулись раскладки клавиатуры, то два сло-ва о том, как использовать русскую. Для установки и пе-реключения на русский вариант (в рассматриваемом слу-чае) раскладки клавиатуры в XFree86 применяется двапараметра XkbLayout и XkbOptions. Первый, как уже от-мечалось, можно переопределить, а вот для того чтобыбыла возможность переключаться между раскладками,необходимо выполнить еще некоторые действия. Все на-стройки, касающиеся параметров XFree86 во всех Linuxпроизводятся в файле XF86Config для версии 3 и вXF86Config-4 для четвертой версии. Но для терминаловтаких файлов изначально не существует, они генериру-ются динамически при запуске. Для этих целей использу-ется скрипт /opt/ltsp/i386/etc/rc.setupx3 для клиентов с вер-сией 3 и /opt/ltsp/i386/etc/rc.setupx для четвертой версии,которые, кстати, берут основные параметры для настрой-ки из файла lts.conf. Так вот, для того чтобы переключа-тель заработал, необходимо после строки XkbLayout«${XkbLayout}» для rc.setupx3 или Option «XkbLayout»«${XkbLayout:-»us»}» для rc.setupx прописать параметр,

[Default] SERVER = 192.168.0.1# êîìïüþòåð, âûñòóïàþùèé â ðîëè ñåðâåðà ãðàôè÷åñêèõ ïðèëîæåíèé XSERVER = auto# óêàçûâàåò íà òî, ÷òî ñèñòåìà ñàìà îïðåäåëÿåò òèï çàãðóæàåìîãî# XFree86-ñåðâåðà X_MOUSE_PROTOCOL = "IMPS/2"# íàçâàíèå ïðîòîêîëà ìàíèïóëÿòîðà ìûøè# â äàííîì ñëó÷àå èñïîëüçóåòñÿ ìûøü ñî ñêðîëëèíãîì, åñëè# îáûêíîâåííàÿ ìûøü ïîäêëþ÷àåìàÿ ê ïîðòó PS/2, òî ïîïðîáóéòå# ïðîñòî PS/2 X_MOUSE_DEVICE = "/dev/psaux"# óêàçûâàåò íà ïîðò PS/2 X_MOUSE_RESOLUTION = 50 X_MOUSE_BUTTONS = 3 LOCAL_APPS = N USE_XFS = Y # èñïîëüçóåòñÿ ñåòåâîé ñåðâåð øðèôòîâ RUNLEVEL = 5 SOUND = Y VOLUME = 75

[term1] XSERVER = XF86_SVGA# Òèï X-ñåðâåðà, êîòîðûé áóäåò âûïîëíÿòüñÿ íà êëèåíòñêîé# ñòàíöèè. Äëÿ ÷åòâåðòîé âåðñèè óêàçûâàåòñÿ âèäåîìîäóëü,# íàïðèìåð nv. Äëÿ XFree86 3.3.6 óêàçûâàåòñÿ èìÿ ñåðâåðà# XF86_SVGA, XF86_S3 è ò.ä.

X_MODE_0 = 800x600 40 800 840 968 1056 600 601 605 628 ↵+hsync +vsync

# óñòàíîâêà ïàðàìåòðîâ âûâîäà íà ýêðàí, èõ ìîæåò áûòü# íåñêîëüêî îò X_MODE_0 äî X_MODE_10

X_VIDEORAM = 4096 # êîëè÷åñòâî âèäåîïàìÿòèX_MOUSE_PROTOCOL = "Microsoft"

# ìûøü ñ ïîñëåäîâàòåëüíûì èíòåðôåéñîìX_MOUSE_DEVICE = "/dev/ttyS0"

# ìûøü, ïîäêëþ÷àåìàÿ ê ïàðàëëåëüíîìó ïîðòóX_MOUSE_RESOLUTION = 50

! SECURITY: do not listen for XDMCP or Chooser requests! Comment out this line if you want to manage X terminals with xdm# ýòîò ïóíêò îáÿçàòåëüíî çàêîììåíòèðîâàòü! DisplayManager.requestPort: 0# Ýòó ñòðî÷êó äîáàâèòü, ïðàâäà íåîáÿçàòåëüíî. Îñòàëüíûå# ìîæíî íå òðîãàòü.DisplayManager.*.setup:/etc/X11/xdm/Xsetup_workstationÑêðèïò Xsetup_workstation èìååò òàêîé âèä: #! /bin/sh/usr/X11R6/bin/xsetroot -solid "#356390"if [- x /usr/bin/xsri]; then

/usr/bin/xsri -geometry +5 +5 -avoid 300x250 ↵-keepaspect /etc/X11/xdm/ltsp.gif

fi

X_MOUSE_BUTTONS = 2 # êîëè÷åñòâî êíîïîê ìûøè# âêëþ÷åíèå ýìóëÿöèè òðåòüåé êíîïêè ìûøè# (íàæàòèåì äâóõ èìåþùèõñÿ îäíîâðåìåííî)

X_MOUSE_EMULATE3BTN = YX_MOUSE_BAUD = 1200RUNLEVEL = 3

Page 92: 013 Системный Администратор 12 2003

90

образование

устанавливающий комбинацию для изменения расклад-ки, например:� XkbOptions «grp:caps_toggle» – переключение по Caps

Lock;� XkbOptions «grp:alt_shift_toggle» – более привычное для

пользователей Windows переключение по Alt + Shift.

Вот и все. Самое интересное, что это действительноработает. На клиентском компьютере загрузить дажеKDE с OpenOffice и причем с вполне терпимой скорос-тью, после перехода на оконный менеджер IceWM и за-пуска аналога OpenWritera от GnomeOffice – AbiWord си-стема вообще летала. Конечно, при увеличении количе-ства клиентов до 10 желателен сервер помощнее, какминимум оперативной памяти 512 Мб. Наиболее очевид-ное применение данной технологии – это наши учебныезаведения со старыми компьютерными классами, где до-бавление одного мощного компьютера позволит рабо-тать с современным ПО. В организации интернет-кафес помощью технологии LTSP поможет скрипт: http://prdownloads.sourceforge.net/ltsp/ltsp_phpSiCafe-0.0.1.tgz,назначение которого – учет времени, проведенногопользователями за компьютером. Заинтересовавшимсясоветую также заглянуть еще на два сайта. Первыйhttp://k12ltsp.org/, этот проект предназначен для уста-новки терминального сервера, разработанного для школ,базируется на дистрибутиве Red Hat. Второй http://www.ltsp.ru/, как видно из названия, русский сайт проек-та. Здесь уже можно найти переводную документациюпо работе с бездисковыми станциями, описание установ-ки виртуальной машины VMWare для запуска приложе-ний, написанных под Windows.

Все это, конечно, интересно и работает уже болеегода, но совсем недавно познакомившись с проектомOpenMosix (http://openmosix.sourceforge.net/), предлага-ющим OpenSource-решение создания кластерных сис-тем на основе компьютеров, соединенных в единую сеть.OpenMosix представляет собой расширение к обычномуядру Linux, при его установке узлы в кластере начинают«общаться» с друг другом, и кластер адаптирует себя крабочей нагрузке. Процессы, обрабатывающиеся на лю-бом из узлов, при увеличении нагрузки данного компь-ютера по сравнению с другими способны передаватьсяна любой другой компьютер кластера. OpenMosix посто-янно пытается оптимизировать распределение ресурсамежду машинами, при этом новый узел может быть до-бавлен «на лету» и автоматически будет подхвачен кла-стером. Так как все openMosix расширения выполняют-ся внутри ядра, каждое из приложений, автоматическиизвлекает выгоду из распределенной вычислительнойконцепции openMosix. Кластер ведет себя фактическикак многопроцессорная система, правда без ограниче-ния на их максимальное число. И естественно возникложелание испытать это все в деле, тем более что боль-шая часть работы уже проделана.

Как и в приведенном выше примере, один из компь-ютеров играет роль главного (master), а остальные,сколько есть, подчиненные (slave). Для работы понадо-бятся сами ядра с патчем от openMosix и инструменты

для работы openmosix-tools. Все это можно найти настранице http://prdownloads.sourceforge.net/openmosix/,где доступны как сами патчи, так и уже перекомпили-рованые (серверные) ядра для разных платформ, при-чем уже доступны патчи для ядер серии 2.6. Мы будемустанавливать при помощи патча, самостоятельно ком-пилируя все ядра.

Для этого берем ядро 2.4.22:

Теперь все разархивируем:

Теперь заходим в него:

Конфигурируем серверное ядро:

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

И компилируем новое ядро:

Для ядер серии 2.6 достаточно ввести make all.Копируем ядро на свое место:

Конфигурируем загрузчик для работы с новым ядром,и после перезагрузки система будет готова. Если уста-новка производится при помощи перекомпилированныхпакетов, все вышеописанное (кроме настройки загруз-чика) будет в систему добавленно автоматически. Дляэтого вводим:

# wget -c http://www.kernel.org/pub/linux/kernel/v2.4/ ↵linux-2.4.22.tar.bz2

# wget -c http://tab.tuxfamily.org/download/openmosix/ ↵patch-2.4.22-om-20030811.bz2

# tar -xjvf - linux-2.4.22.tar.bz2# cd linux-2.4.22# bzcat ../patch-2.4.22-om-20030825.bz2|patch -p1# ln -sf /path/to/linux-2.4.22 /usr/src/linux

# cd /usr/src/linux

# make xconfig {menuconfig, gconfig}

openMosix ---openMosix process migration supportopenMosix File-System

Networking options ---Packet SocketSocket FilteringTCP/IP networkingIP: multicasting

File systems ---/proc file system support

Network File Systems ---NFS file system supportNFS server supportProvide NFSv3 server support

# make dep# make bzImage && make modules && make modules_install

# mv arch/i386/boot/bzImage /boot/vmlinuz-openmosix

# rpm -ivh openmosix-kernel-2.4.22-openmosix1.i686.rpm

Page 93: 013 Системный Администратор 12 2003

91№12(13), декабрь 2003

образование

Установка slave-ядраДля начала сохраняем конфигурационный файл основ-ного ядра.

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

Следующие опции нужно включить в ядро.

Но получившееся в результате ядро копируем в дру-гое место, а именно в каталог /tftpboot. Например:

И настраиваем его загрузку описанным выше спосо-бом. В принципе для этого не обязательно иметь установ-ленный полный пакет ltsp, а все необходимое создать вруч-ную, как это все сделать, можно найти в дополнительнойлитературе, указаной в конце статьи. Но все равно, для тогочтобы избежать большого количества ручной работы, сове-тую в таком случае скачать файл ltsp_initrd_kit и ltsp_util_src(http://prdownloads.sourceforge.net/ltsp/ltsp_initrd_kit-3.0.11-i386.tgz и http://prdownloads.sourceforge.net/ltsp/ltsp_util_src-3.0.0-i386.tgz).

Все, что мы делали до сих пор, фактически не отличаетсяот предыдущего варианта ядра. Чтобы заставить компьюте-ры работать в одной связке и обмениваться нагрузкой, необ-ходимо установить пакет openmosix-tools. Его также можнополучить уже в виде перекомпилированных пакетов или всеэто проделать самому. Ничего особенного в компиляции нет:

Флагом -with-kerneldir указываем путь к исходным фай-лам ядра, по умолчанию /usr/src/linux-openmosix:

Или строим пакет для rpm-based дистрибутивов:

После окончания установки приступаем к настройке.Для начала в файле /etc/openmosix.map, определим узлы,

которые будут задействованы в кластере. Каждая строкав этом файле состоит из трех частей:

Первым идет openMosix node-number узла в указанномдиапазоне, второй строкой – IP-адрес или имя, описанное вфайле /etc/hosts, и третьей – количество узлов в этом диа-пазоне. В данном примере нашему серверу присвоенopenMosix node-number 1, а десяти узлам в диапазоне192.168.0.100-192.168.0.109, номера 2-11. Если бы IP-ад-реса шли подряд, то можно было бы обойтись и однойстрокой. После правки файла делаем его доступным идругим узлам.

Туда же копируем и бинарные файлы openmosix-tools.

И запускаем openМosix:

После перезагрузки slave-узлов работу можно прокон-тролировать при помощи утилиты mosctl, введя номернужного:

А в файле /etc/inittab рекомендуется строку:

заменить на:

Чтобы избежать проблем при использовании сервисаSSH в файле /etc/rc.d/init.d/sshd в функции start(), добавь-те следующую линию:

Вот и все. Остается пожелать успехов, и я надеюсь,эта статья кому-то поможет.

Кроме документации на сайтах проектов LTSP и openMosixсоветую просмотреть еще и следующие документы:1. Колисниченко Д. Загрузка по сети. – //журнал «Сис-

темный администратор», №9(10), 2003 г. – 47-49 с.2. LTSP + openMosix: Integration How-To:

http://home.onestop.net/jjensen/ltsp-om5r3c.html3. openMosix and Diskless Nodes:

http://www.gentoo.org/doc/en/openmosix-howto.xml

# ./configure –with-kerneldir=/usr/src/linux

# make && make install

# rpmbuild -ta openmosix-tools-0.3.4.tar.gz

1 192.168.0.1 12 192.168.0.100 10

# mosctl status 2

si::sysinit:/etc/rc.d/rc.sysinit

si::sysinit:/bin/mosrun -h /etc/rc.d/rc.sysinit

test -f /proc/$$/lock && echo 0 > /proc/$$/lock

# cp /usr/src/linux/arch/i386/boot/bzImage ↵/tftpboot/lts/vmlinuz-openmosix-slave

# /etc/init.d/openmosix start

openMosix ---openMosix process migration supportopenMosix File-System

Networking options ---TCP/IP networkingIP: kernel level auto-configurationIP: DHCP supportIP: BOOTP support

File systems ---/proc file system support

Network File Systems ---NFS file system supportProvide NFSv3 client supportRoot file system on NFS

# cp /etc/openmosix.map /opt/ltsp/i386/etc/

# cp /sbin/setpe /opt/ltsp/i386/sbin/# cp /bin/mosrun /opt/ltsp/i386/bin/# cp /bin/mosmon /opt/ltsp/i386/bin/# cp /bin/mosctl /opt/ltsp/i386/bin/# cp /bin/migrate /opt/ltsp/i386/bin/# cp /etc/rc.d/init.d/openmosix /opt/ltsp/i386/etc/rc.openmosix

# cp /usr/src/linux/.config /usr/src/linux/.config_master

Page 94: 013 Системный Администратор 12 2003

92

cодержание журнала за 2003 год

Содержание журнала

FreeBSD. Компиляция Александр Прокошев №4(5)Ipfw и управление трафиком в FreeBSD Игорь Чубин №6(7)IPSec через NAT: проблемы и решения Татьяна Антипова №3(4)IRC-сервер Александр Слободской №7(8)Milter = Mail + Filter Роман Сузи №2(3)NetBSD: установка и настройка Андрей Бешков №8(9)OpenBSD. Первые шаги Денис Назаров №8(9)Postfix+...+SpamAssassin. Mini-howto Андрей Мозговой №9(10)Python в администрировании сервера: почему бы и нет? Роман Сузи №1RADIUS Всеволод Стахов №4(5)SMTP AUTN in da Postfix + ... Андрей Мозговой №10(11)TACACS Всеволод Стахов №3(4)Windows Server 2003: взгляд системного администратораАлексей Доля, Михаил Мельников №11(12)Абсолютно все о ATM Сергей Ропчан №4(5)Абсолютно все о Frame Relay Сергей Ропчан №3(4)Абсолютно все о Х.25 Сергей Ропчан №1(2)Абсолютно все о технологии ISDN Сергей Ропчан №2(3)Архитектура файловой системы ext2 Владимир Мешков №11(12)Аудит учетных записей пользователей в Active Directory Максим Костышин №11(12)Борьба за системные ресурсы Денис Колисниченко №4(5)Введение в OpenBSD Денис Назаров №6(7)Виртуальный компьютер Денис Колисниченко №6(7)Виртуальный полигон для администратора и разработчика Андрей Бешков №9(10)Виртуальный полигон для разработчика и администраторана основе Linux и VMWare Андрей Бешков №11(12)Восстановление данных с лазерных дисков Крис Касперски №8(9)Восстановление загрузки операционной системы Linux Андрей Шевченко №2(3)Дистанционное управление в Linux Денис Колисниченко №5(6)Загрузка по сети Денис Колисниченко №9(10)Империя Cisco Денис Еланский №2(3)Интеграция SQUID + LDAP Марк Кричмар №11(12)Искажение TOC как средство борьбы с несанкционированнымкопированием диска Крис Касперски №9(10)Использование IPSec в Windows 200x Максим Костышин №6(7)Использование LVM Сергей Яремчук №10(11)Использование бездисковых маршрутизаторов Андрей Мозговой №11(12)Как бороться с баннерами в ICQ Дмитрий Репин №10(11)Как выключить ESMTP-команды в Exchange 2000 Server Татьяна Антипова №3(4)Как пингвин говорит по телефону, или Настройка dialin-серверадля доступа Интернет и аварийной консоли Андрей Мозговой №2(3)Контроль последовательных портов в Linux Денис Колисниченко №7(8)Конфигурирование DHCP Денис Колисниченко №5(6)Крепость для пингвина Сергей Яремчук №12(13)Маленький Linux в качестве firewall Сергей Яремчук №9(10)Мечта сисадмина Сергей Яремчук №10(11)Миграция с Windows на Linux Дмитрий Галышев №1Мифы и легенды современной ОCологии…или «ОС – это большой полосатый мух?» Александр Потемкин №2(3)Мониторинг Windows-серверов с помощью Nagios. Часть 1 Андрей Бешков №7(8)Мониторинг Windows-серверов с помощью Nagios. Часть 2 Андрей Бешков №8(9)Настраиваем ASPLinux 7.3 Server Edition Александр Шибенко №10(11)Настройка Incoming Connection в Linux Сергей Ропчан №4(5)Настройка сервера SSH Денис Колисниченко №7(8)Новые средства OC FreeBSD 5 Всеволод Стахов №8(9)Организация доступа в Интернет на предприятиях Алексей Федоров №5(6)Осваиваем Nagios Андрей Бешков №12(13)Пингвин с одного пинка Сергей Яремчук №8(9)

АДМИНИСТРИРОВАНИЕ №Построение программных RAID-массивов в Linux Дмитрий Рожков №5(6)Почтовая система для среднего и малого офиса Андрей Бешков №5(6)Практика OpenSSL Всеволод Стахов №2(3)Процессы и нити Всеволод Стахов №5(6)Разводной мост на Linux (Bridging Firewalls) Павел Закляков №4(5)Решение задач инвентаризации в сети Иван Коробко №12(13)Свой собственный модуль Денис Колисниченко №10(11)Система фильтрации интернет-трафика Андрей Бешков №4(5)Скрипты для подсчета трафика: пример реализации в FreeBSDДенис Пеплин №6(7)Создаем VPN на основе vtun Андрей Бешков №4(5)Создание PDC (основного контроллера домена) для Windowsна базе SAMBA 2.2.5 Андрей Гуселетов №1(2)Создание загрузочных дискет и CD-дисков Linux Всеволод Стахов №6(7)Создание простейшей биллинговой системы Денис Мясниченко №2(3)Стартовые скрипты FreeBSD Денис Пеплин №7(8)Статическая маршрутизация в Linux iproute2. Часть1 Всеволод Стахов №5(6)Статическая маршрутизация в Linux iproute2. Часть2 Всеволод Стахов №6(7)Теория и практика OpenSSL Всеволод Стахов №1(2)Удаленное резервное копирование: пример реализации в FreeBSDДенис Пеплин №5(6)Удобная почтовая система Вячеслав Калошин №1Управление сетевыми принтерами домена Иван Коробко №10(11)Устанавливаем Multiple-Device-дозвон в Windows XP Татьяна Антипова №2(3)Установка FreeBSD Сергей Яремчук №3(4)Установка IMAP4-сервера на базе cyrus-imapd + sendmail Денис Шергин №10(11)Установка Nagios Андрей Бешков №2(3)Установка и настройка сервера Jabber на платформе Linux Сергей Индлин №4(5)Учет работы Dialup-пользователей в системе FreeBSD Сергей Супрунов №12(13)Учет трафика с помощью программ MRTG и LAN Billing Денис Колисниченко №6(7)Файловые системы Linux Сергей Яремчук №11(12)Хеви Хардвэр. Установка и настройка коммутаторов CISCO CATALYSTсерий 2900XL и 3500 Всеволод Стахов №1Что такое SAMBA? Сергей Яремчук №1Ы.Ы.Р. Особенности работы и настройки протокола SSH Всеволод Стахов №1(2)Это должен знать каждый, или Четыре базовых принципавыбора коммутатора ЛВС Геннадий Карпов №5(6)Эффективная почтовая система на базе Exim Денис Мысенко №8(9)

NETFILTER Владимир Мешков №8(9)Powerline: Интернет из розетки Денис Колисниченко №7(8)Анализатор сетевого трафика Владимир Мешков №1Дальняя связь. Как это бывает Денис Еланский №6(7)Планируем переезд сети Вячеслав Калошин №7(8)Программирование сокетов Всеволод Стахов №1Протокол V.90 Денис Колисниченко №8(9)Сканер портов: пример реализации Владимир Мешков №1

LIDS Сергей Яремчук №4(5)OpenLDAP и защита данных Всеволод Стахов №2(3)SELinux Сергей Яремчук №5(6)Анализ защиты программ и рекомендации по ее усилению Станислав Гошко №10(11)Атака на переполнение буфера через неисполнимый стекв Windows NT/2000/XP Станислав Гошко №9(10)Безопасность технологии виртуальных карт Сергей Ропчан №2(3)Борьба с вирусами: опыт контртеррористических операций Крис Касперски №10(11)Защитим электронную почту! Всеволод Стахов №1(2)

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

СЕТИ №

Page 95: 013 Системный Администратор 12 2003

93№12(13), декабрь 2003

содержание журнала за 2003 год

за 2003 год

Защитник сети Сергей Яремчук №11(12)Киберкоп, или Конец виртуального мира Дмитрий Аксенов №1(2)Контрольная сумма на защите Linux/FreeBSD Сергей Яремчук №6(7)Минимум усилий на защиту DNS Сергей Ропчан №1(2)Неявный самоконтроль как средство создания неломаемых защитКрис Касперски №7(8)Обнаружение телекоммуникационных атак: теория и практика, snortПавел Закляков №10(11)Общий обзор наиболее часто применяемых техник компьютерных атаки защиты от них Александр Потемкин №1(2)Очередная веская причина задуматься о переходес ОС Windows на альтернативу Виктор Игнатьев №9(10)Переполнение буфера в Windows NT/2000/XP Станислав Гошко №8(9)Перехват Shell через YaBB Виктор Игнатьев №6(7)Построение переносимого Shell-кода для Windows-систем Станислав Гошко №9(10)Система криптографической защиты информации Владимир Мешков №4(5)Советы по безопасной веб-аутентификации Игорь Тетерин №5(6)Сравнение сетевых сканеров безопасности Дмитрий Никсов, Петр Рудель №1(2)Технологии протоколирования Honeypot в обеспечениибезопасности сетевых Unix-систем Антон Даниленко №5(6)Три составных части защиты Сергей Яремчук №7(8)Удобнее, эффективнее, лучше: snort + MySQL Павел Закляков №11(12)

Вторая жизнь модемов Павел Закляков №12(13)Глубоководное погружение в чипсет Intel 875P Крис Касперски №6(7)Основы систем хранения данных Алексей Серебряков №3(4)Плохое электропитание, или «Грабли» с UPS Павел Закляков №8(9)Работа с жестким диском на программном уровне Владимир Мешков №9(10)

ColdFusion или, возможно, лучшее решение для созданиядинамических сайтов Александр Меженков №1Java - магия отражений Даниил Алиевский №1Javа: магия отражений. Часть II. ClassLoader – скрытые возможностиДаниил Алиевский №1(2)Java: магия отражений. Часть III. Компиляция Java средствами JavaДаниил Алиевский №2(3)Java: работа с файлами Даниил Алиевский №7(8)Python глазами DBA Олег Попов №7(8)Брандмауэр Владимир Мешков №1(2)Брандмауэр. Часть II Владимир Мешков №2(3)История одной разработки, или Как мы делали siteMETA Андрей Коваленко №1(2)Итоги акции «Задай свой вопрос разработчикам поисковых систем»,проводимой совместно с Всероссийским Клубом Веб-разработчиков №3(4)Можно ли защитить веб-страницы от анализа исходного кода?Даниил Алиевский №3(4)Некоторые недокументированные функции Java Даниил Алиевский №3(4)Пакетный фильтр Владимир Мешков №2(3)Перехват системных вызовов в ОС Linux Владимир Мешков №3(4)Перехват системных вызовов в ОС Linux. Часть 2 Владимир Мешков №5(6)Практические советы по восстановлению системы в боевых условияхКрис Касперски №12(13)Программирование сервисов в Windows 2000 Всеволод Стахов №1Работа с базами данных на Perl Владислав Гошко №9(10)Работа с текстом, или философия Perl Коновалов Евгений №1Регулярные выражения и поиск текста в Perl Владислав Гошко №8(9)Стеммер. Морфологический анализ для небольших поисковых системАндрей Коваленко №1

Управление сессиями в ColdFusion, или Здравствуйте, я – ваша тетяАлександр Меженков №1(2)Эффективное использование памяти в Perl при работес большими строками Даниил Алиевский №1

CommerceML – стандарт обмена коммерческой информациейв формате XML Елена Ртищева №1LTSP – вторая жизнь старых компьютеров Сергей Яремчук №12(13)Mac OS X или То, что должен знать каждый про Macintosh, Appleи операционные системы Александр Потемкин №7(8)Взаимные функциональные зависимости Андрей Филиппович №1Доступный Linux в каждую школу! Виктор Мельников, Андрей Шевченко №1(2)Коды Рида-Соломона в практических реализациях, или Информация,воскресшая из пепла III Крис Касперски №11(12)ЛВС: управляемость, надежность, масштабируемость Денис Еланский №3(4)Могущество кодов Рида-Соломона, или Информация,воскресшая из пепла Крис Касперски №8(9)Обучающие ситуационные центры Андрей Филиппович №5(6)Обучение через Интернет – это возможно? Ольга Игошина №7(8)Пингвин идет в школу Сергей Голубев №1(2)Полиномиальная арифметика и поля Галуа, или Информация,воскресшая из пепла II Крис Касперски №10(11)Скупой платит дважды, а умный использует GNU Public LicenseПавел Закляков №9(10)

Fusebox в помощь веб-программисту Андрей Уваров, Дмитрий Горяинов №11(12)PHP Сергей Яремчук №5(6)Выбор веб-сервера: почему Apache? Дмитрий Галышев №4(5)Интернет-операционные системы Игорь Тетерин №4(5)Конвертирование из Excel в HTML: корректно, качественно, простоАлексей Мичурин №12(13)

Вооруженное до зубов перемирие, или Я – то, чего не может быть!Татьяна Ильченко №10(11)Почему OpenSource? (Точка зрения разработчика) Владимир Попов №3(4)Рецепты правильного трудоустройства Крис Касперски №9(10)Этика сисадмина Андрей Гуселетов №2(3)

Кто предупрежден – тот вооружен Михаил Торчинский №11(12)

Каким видится хороший системный администратор Вячеслав Калошин №7(8)

Воспоминания замечательных дней: заря компьютеризации Россиии борцы с железными конями той эпохи… Алексей Костромин №11(12)

Почему мало женщин в компьютерных компаниях Вячеслав Михалев №1Уступите место женщине Евгения Саблина №1

ОБРАЗОВАНИЕ №

WEB №

IMHO №

ПОЛЕЗНЫЕ СОВЕТЫ №

ИЗ ЛИЧНОГО ОПЫТА №

КАК ЭТО БЫЛО №

HARDWARE №

ПРОГРАММИРОВАНИЕ №

ЖЕНЩИНА И КОМПЬЮТЕР №

Page 96: 013 Системный Администратор 12 2003
Page 97: 013 Системный Администратор 12 2003

95№12(13), декабрь 2003

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

Единыйподписнойиндекс:

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

Продолжается подписка на I полугодие 2004 г.Более подробная информация на сайте www.samag.ru

в разделе «Подписка»

подписка

Page 98: 013 Системный Администратор 12 2003

96

СИСТЕМНЫЙ АДМИНИСТРАТОР№12(13), Декабрь, 2003 год

РЕДАКЦИЯИсполнительный директорВладимир ПоложевецОтветственный секретарьНаталья Хвостова[email protected]Технический редакторВладимир ЛукинНаучно-технические консультантыДмитрий ГоряиновРуслан ИвановВалерий Цуканов

РЕКЛАМНАЯ СЛУЖБАтел.: (095) 928-8253 (доб. 112)факс: (095) 928-8253Константин Меделянreс[email protected]

Верстка и оформление[email protected][email protected]Дизайн обложкиНиколай Петрочук

103012, г. Москва,Ветошный переулок, дом 13/15тел.: (095) 928-8253 (доб. 112)факс: (095) 928-8253Е-mail: [email protected]: www.samag.ru

РУКОВОДИТЕЛЬ ПРОЕКТАПетр ПоложевецУЧРЕДИТЕЛИВладимир ПоложевецАлександр Михалев

ИЗДАТЕЛЬЗАО «Издательский дом«Учительская газета»

Отпечатано типографиейООО «Мастер Печати»Тираж 5700 экз.Журнал зарегистрированв Министерстве РФ по делам печати,телерадиовещания и средств мас-совых коммуникаций (свидетельствоПИ № 77-12542 от 24 апреля 2002г.)

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

ЧИТАЙТЕВ СЛЕДУЮЩЕМНОМЕРЕ:

Наши партнерыНаши партнерыНаши партнерыНаши партнерыНаши партнеры

Использование SQLiteи PHP 5Из-за лицензионной политики поддер-жка MySQL может быть не включена вокончательную версию PHP5. Поэтому,если мы планируем перейти на PHP5,обладающий расширенными возмож-ностями благодаря новому «движку» –Zend Engine 2.0, нам стоит задуматьсяо достойной замене MySQL. Конечно,для профессиональных целей следуетиспользовать PostgreSQL или Sybase,поддержка которых есть в PHP. Но еслинам для небольшого проекта, напри-мер, гостевой книги или интерактивно-го прайс-листа, необходим небольшойи быстрый сервер баз данных, нам необойтись без SQLite.

Rule Set Based AccessControl для LinuxLinux-системы, как многие другие вUnix-семействе, имеют известныйнедостаток в управлении доступом.Прежде всего это малое количествоконтролируемых прав доступа, со-стоящих в разрешении чтения, запи-си и возможности выполнения, иправа эти можно установить толькодля владельца файла, членов груп-пы-владельца и всех остальных.Иногда очень трудно вместить впредложенные ограничения дажепару десятков человек, при этомтребуется более широкие возможно-сти по описанию доступа к конкрет-ному файлу. Дополнительно всепрограммы, работающие от именипользователя, имеют такие же пра-ва, как и сам пользователь, при этомсовсем не учитывается важностьсамого объекта и необходимость ра-боты с ним программы. Сам пользо-ватель файла решает, являются лиданные файлы секретными или бу-дут доступными остальным пользо-вателям. Отсюда получается, что за-пущеная от имени суперпользовате-ля программа имеет неограничен-ные возможности в системе и дос-туп к любому объекту (эту модельеще называют одноуровневой). Всехорошо, пока она не скомпромети-рована, и тогда такое упрощениестановится уже большим недостат-ком. Такая модель доступа называ-ется Discretionary Access Control(DAC) и позволяет создавать систе-мы, защищенные по классу С1.

Эффективная работас портами в FreeBSDМатериал полностью посвящен портамв FreeBSD, хотя большинство приме-ров актуальны и для других *BSD. Си-стема портов конкурирует с прекомпи-лированными rpm- и deb-пакетами,являясь более удобным средством дляустановки и удаления программ, об-новления как отдельных, так и всехкомпонентов системы (стоит отме-тить, что порты не предоставляют аль-тернативу и являются ОС-зависимы-ми). Все основные системы BSD-се-мейства (NetBSD, OpenBSD, ну и конеч-но, FreeBSD) оснащены своими коллек-циями потов. Аналогом портов облада-ют все «source-based» дистрибутивыGNU/Linux, самый известный из кото-рых – Gentoo (http://gentoo.org) со сво-ей системой портежей («portage»).