98
№7(20) июль 2004 подписной индекс 81655 www.samag.ru Почтовая система на базе MTA exim Обзор системы поддержки списков рассылок GNU Mailman Как различать и считать маркированный трафик? FreeBSD tips: ARP в «заморозке» Строим шлюз с Luinux CrossOver и лицензионный вопрос Упрощаем себе жизнь с Webmin PostgreSQL: первые шаги HA-кластер LifeKeeper компании SteelEye Русификация FreeDOS Metro Ethernet Почтовая система на базе MTA exim Обзор системы поддержки списков рассылок GNU Mailman Как различать и считать маркированный трафик? FreeBSD tips: ARP в «заморозке» Строим шлюз с Luinux CrossOver и лицензионный вопрос Упрощаем себе жизнь с Webmin PostgreSQL: первые шаги HA-кластер LifeKeeper компании SteelEye Русификация FreeDOS Metro Ethernet №7(20) июль 2004

020 Системный Администратор 07 2004

Embed Size (px)

DESCRIPTION

Обзор системы поддержки списков рассылок GNU Mailman Обзор системы поддержки списков рассылок GNU Mailman Русификация FreeDOS Русификация FreeDOS Строим шлюз с Luinux Строим шлюз с Luinux Упрощаем себе жизнь с Webmin Упрощаем себе жизнь с Webmin CrossOver и лицензионный вопрос №7(20) июль 2004 №7(20) июль 2004

Citation preview

№7(20) июль 2004подписной индекс 81655

www.samag.ru

Почтовая система на базе MTA exim

Обзор системы поддержкисписков рассылок GNU Mailman

Как различать и считатьмаркированный трафик?

FreeBSD tips: ARP в «заморозке»

Строим шлюз с Luinux

CrossOver и лицензионный вопрос

Упрощаем себе жизнь с Webmin

PostgreSQL: первые шаги

HA-кластер LifeKeeperкомпании SteelEye

Русификация FreeDOS

Metro Ethernet

Почтовая система на базе MTA exim

Обзор системы поддержкисписков рассылок GNU Mailman

Как различать и считатьмаркированный трафик?

FreeBSD tips: ARP в «заморозке»

Строим шлюз с Luinux

CrossOver и лицензионный вопрос

Упрощаем себе жизнь с Webmin

PostgreSQL: первые шаги

HA-кластер LifeKeeperкомпании SteelEye

Русификация FreeDOS

Metro Ethernet№7(

20)

ию

ль 2

004

1№7(20), июль 2004

оглавление

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

Почтовая система на базе MTA exim

Всеволод Стахов[email protected] 6

Настройка почтовой системы на базеPostfix + Dovecot + PostgreSQL +Amavisd-new + SpamAssassin + ClamAV

Рустам Атнагулов[email protected] 14

«Кто стучится в дверь ко мне…»Обзор системы поддержки списковрассылок GNU Mailman

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

Как различать и считатьмаркированный трафик?

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

PostgreSQL: первые шаги

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

Упрощаем себе жизнь с Webmin

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

Вежливый отказ

Александр Шибенко[email protected] 50

Управление файловыми серверами

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

Русификация FreeDOS

Вадим Дружин[email protected] 59

«Стальной глаз на страже жизни».HA-кластер LifeKeeper компании SteelEye

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

IMHO

Есть такая профессия

Алексей Коршунов[email protected] 4

FreeBSD tips: ARP в «заморозке»

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

Строим шлюз с Luinux

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

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

Техника внедрения кода в РЕ-файлыи методы его удаления

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

СЕТИ

Metro Ethernet

Денис Еланский[email protected] 84

ОБРАЗОВАНИЕ

Второе начало термодинамики – гарантуспеха систем с открытым исходнымкодом

Алексей Мичурин[email protected] 91

3№7(20), июль 2004

конкурс

С 24 июня по 3 августа 2004 года на страницах популяр-ного каталога программного обеспечения [email protected](http://soft.mail.ru) проводится конкурс «Сисадмин – тожечеловек», посвященный Международному дню системно-го администратора (30 июля). Конкурс организован ком-панией SoftLine и интернет-холдингом Mail.Ru.

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

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

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

Открытки разместятся на сайте Открытки@Mail.Ru(http://cards.mail.ru). С этого сайта все желающие смогутпослать поздравления своим знакомым сисадминам. Каж-дая открытка будет создаваться автором в честь одногоиз сисадминов, оставивших свое сообщение в книге жа-лоб. Победитель среди сисадминов будет определятьсяпо числу размещенных в его честь открыток. Чем раньше

вы разместите свое сообщение, тем больше пользовате-лей его прочитает и тем больше у вас шансов победить.

Итоги конкурса будут подведены 3 августа. Системно-го администратора, чье сообщение будет пользоватьсянаибольшим вниманием пользователей и авторов откры-ток, ждет главный приз от генерального спонсора конкур-са «Сисадмин – тоже человек» – Учебного Центра SoftLine(http://softline.ru/edu). Это программа подготовки MicrosoftCertified Systems Administrator (MCSA 2003). Программапредставляет собой трек продолжительностью 17 дней,состоящий из набора полезных курсов:! управление и поддержка среды Windows Server 2003;! установка, настройка и администрирование Windows

XP Professional;! внедрение сетевой инфраструктуры Windows Server

2003: сетевые узы;! внедрение, управление и сопровождение сетевой ин-

фраструктуры Windows Server 2003: сетевые службы;! установка и управление Microsoft Internet Security and

Acceleration Server 2000.

Победитель может заменить входящие в трек MCSA2003 курсы на аналогичные по стоимости и длительностикурсы Microsoft. Сисадминов-победителей ждут фирмен-ные призы от Mail.Ru, а также бесплатная подписка навторое полугодие 2004 года на журнал «Системный ад-министратор» от редакции журнала. Авторы лучших от-крыток получат ценные призы от интернет-магазинаAllsoft.ru (http://www.allsoft.ru) компании SoftLine, главныйиз которых – графический планшет Wacom. А 30 июля – вМеждународный день сисадмина – всех участников кон-курса ждет приятный сюрприз.

Официальная страничка конкурса в Интернете – http://soft.mail.ru/competitions/sysadmin.

По адресу [email protected] вы можете задать любыевопросы, связанные с проведением конкурса, а также при-слать ваши предложения и пожелания.

С уважением организаторы конкурса – компании SoftLineи Mail.Ru.

4

IMHO

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

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

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

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

Любой специалист-сисадмин на пальцах разложит идокажет, что такое утверждение не верно в принципе.

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

Первое, что приходит в голову, – это повышение про-фессионального уровня. Прохождение курсов и получе-

ЕСТЬ ТАКАЯПРОФЕССИЯ

АЛЕКСЕЙ КОРШУНОВ

5№7(20), июль 2004

IMHO

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

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

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

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

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

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

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

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

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

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

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

Мне приходилось слышать уверения вроде «я большеничего делать не умею». Думаю, нетрудно вспомнить, чтокогда-то вы и UNIX не смогли бы установить. Или вы ро-дились, зная, как работать в шелле? Сомневаюсь.

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

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

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

6

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

ВСЕВОЛОД СТАХОВ

ПОЧТОВАЯ СИСТЕМА НА БАЗЕ MTA EXIM

7№7(20), июль 2004

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

В этой статье пойдет речь о создании эффективного по-чтового сервера на базе MTA exim. Первый вопрос, кото-рый, конечно же, приходит в голову – «Почему именноexim?». Отвечают на этот вопрос по-разному, поэтому яскажу, что меня так привлекает в exim:! логичная схема обработки почты;! высокая скорость работы;! удобный формат конфигурационного файла;! широчайшие возможности по поиску каких-либо зна-

чений в файлах, СУБД, LDAP;! встроенная поддержка smtp-аутентификации;! небольшое число найденных уязвимостей (фактичес-

ки я знаю только об одной, найденной недавно, она ка-салась версий exim до 4.20 включительно);

! очень большое количество возможностей, а такжечрезвычайная гибкость;

! возможность полной замены sendmail (т.е. можно сде-лать):

На мой взгляд, exim является весьма и весьма удач-ным продуктом, не зря он используется по умолчанию вОС Debian GNU Linux. Два больших минуса exim состоят втом, что отсутствует качественная документация на рус-ском языке (этот недостаток я, возможно, постараюсь вскором времени исправить написанием книги, посвящен-ной целиком и полностью этому замечательному MTA) инеобходимость правки Makefile для включения тех илииных возможностей exim.

Итак, для начала подумаем, что должна содержать«идеальная» с точки зрения удобства администрированияи использования почтовая система. Сформулируем рядтребований к почтовой системе:! простота управления пользователями;! возможность предоставления доступа для отправки по-

чты пользователям локальной сети и мобильным поль-зователям (при помощи smtp-аутентификации);

! максимальная защита от хакерских атак, вирусов и спа-ма.

Базовой системой для установки MTA явилась FreeBSD5.2.1, что обусловило определенные особенности установ-ки. Перечислю весь набор программного обеспечения дляорганизации mail-сервера:! exim-4.34;! MTA (mail transfer agent – агент передачи почты);! courier-3.0.4 – imap-сервер для доступа к почте поль-

зователей, не имеющих локальных пользовательскихучетных записей (виртуальные пользователи);

! ClamAV – для поиска вирусов;! SpamAssasin – для поиска спамерских писем;! PostgreSQL-7.4.2 – для хранения всех данных о пользо-

вателях почтовой системы;! SquirrelMail – просто приятный веб-интерфейс для по-

чты (требует веб-сервер и php).

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

первых, надо очень четко представлять порядок сборкиразличных компонентов. Во-вторых, необходимо разби-раться в куче опций для связки различных библиотек. В-третьих, надо четко представлять себе все пути и знать,каких пользователей надо добавлять. Ну и в-четвертых,это дело очень сложно обновлять. Потому мы воспользу-емся услугами системы портов (если у вас, например,Debian GNU Linux, то нужный пакет называется exim4-daemon-heavy).

Для этого ставим следующие порты:

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

при компиляции опять же указываем:

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

Итак, начнем с настройки СУБД PostgreSQL, как осно-вы для построения почтовой системы. Во-первых, PostgreSQL работает с правами системного пользователя pgsql(обратите внимание, этот пользователь имеет реальныйshell и домашний каталог – /usr/local/pgsql). Поэтому дляначала задаем пароль для данного пользователя:

Далее делаем su pgsql и начинаем создание базы дан-ных:

Вводим пароль пользователя pgsql и попадаем в ко-мандную строку SQL-запросов. Для подробного ознаком-ления с возможностями СУБД советую обратиться к ру-ководству или же одной из книг. Создаем БД:

Присоединяемся к данной БД:

Создаем таблицу пользовательских аккаунтов, а так-же constraint для нее:

ln -sf /usr/local/sbin/exim /usr/libexec/sendmail

databases/pogstgresql7mail/exim

make WITH_PGSQL=yomail/p5-Mail-SpamAssassinsecurity/clamavmail/courier-imap

make WITH_CRAM=yo WITH_POSTGRESQL=yomail/squirrelmail

# passwd pgsql

# su pgsql% psql

CREATE DATABASE users;

\c users

CREATE TABLE accounts ( uid serial NOT NULL, login character varying(128), "password" character varying(128), maildir character varying(255), gecos character varying(255),

8

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

Создаем таблицу алиасов:

Поясню назначение таблиц и полей:! таблица accounts предназначена для хранения данных

о виртуальных пользователях почтовой системы, на-значение полей:! uid – уникальный номер пользователя, имеет авто-

инкрементный тип;! login – строка, содержащая имя пользователя в фор-

мате «имя@домен» для возможности доставки по-чты для пользователей различных доменов;

! password – пароль в открытом виде (для возможно-сти безопасной cram-md5 аутентификации);

! maildir – путь к почтовому ящику в формате maildir -gecos – комментарий (для чего-нибудь да пригодит-ся);

! gid – идентификатор группы (не нужен реально, нозачем-то требуется для courier);

! home – аналогично gid;! mailquota – число в мегабайтах, указывающее кво-

ту для пользователя;! таблица aliases представляет собой просто замену /etc/

aliases, содержит два поля – mail (исходный адрес) иalias (адрес для перенаправления).

После этого будем считать, что PostgreSQL у нас ра-ботает. Однако для полного использования возможностейэтой СУБД лучше почитать документацию.

Далее перейдем к настройке собственно MTA exim.Конфигурационный файл для версии «из портов» хранит-ся в /usr/local/etc/exim/configure. Для начала я бы хотелпояснить значение некоторых терминов и рассказать обазовых принципах работы exim.

Представим себе путь прохождения любого почтовогосообщения. Любое письмо состоит из так называемого кон-верта и собственно данных. То, с чем мы привыкли рабо-тать в почтовых клиентах, как раз является «данными» ине имеет к конверту никакого отношения. В конверте опи-сываются 2 параметра: mail from: и rcpt to:, которые указы-вают отправителя и получателей соответственно. Сеансработы с MTA может предваряться «приветствием» – стан-дартным (HELO) и расширенным (EHLO). В приветствиидолжно указываться FQDN клиента, хотя по ряду причинне стоит слишком строго следить за именно FQDN, т.к.многие машины могут находиться за NAT. MTA в ответ наHELO или EHLO сообщает о своих возможностях, обеспе-чивая тем самым синхронизацию клиента и сервера. Да-лее exim осуществляет проверку целевых адресов на пред-

мет их допустимости для данного сервера. Этот этап мо-жет предваряться аутентификацией и установкой TLS-сес-сии. Если пользователь прошел какой-либо из этих этапов,ему присваиваются определенные флаги, которые в даль-нейшем могут использоваться на этапе проверки конвер-та. По умолчанию exim осуществляет проверку недопусти-мых символов в адресах и позволяет отправлять почту толь-ко из локальных доменов и только на локальные домены.Кроме того, при успешной аутентификации письмо прохо-дит и в Интернет. Для остальных писем релей (передачаписем) запрещена. Все проверки в exim4 осуществляютсяна основании механизма acl (access control list – списокдоступа). Также может осуществляться проверка данных(этот механизм добавляется при установке патча exiscan,который при установке портов уже ставится). После успеш-ного прохождения этого этапа exim просматривает rewrite-правила для переписывания отдельных частей конверта(может использоваться в целях перенаправления всех пи-сем на какой-либо смарт-хост, например). Далее письмопопадает на цепочку так называемых роутеров, которыеопределяют, как именно доставлять письмо. Среди роуте-ров фигурирует dnslookup, доставляющий письма на осно-вании MX-записей в DNS, проверка файла алиасов и.forward-файлов, ну и локальная доставка. Каждый роутеримеет некое условие срабатывания и соответствующийтранспорт. При выполнении условия exim выбирает указан-ный транспорт для доставки письма, иначе письмо прохо-дит на следующий роутер (поэтому важен порядок описа-ния роутеров в конфигурационном файле). Транспорты жеопределяют порядок доставки письма. Таким образом,настройка exim состоит из нескольких частей:! настройка глобальных параметров;! настройка acl’s;! настройка роутеров;! настройка транспортов;! настройка аутентификаторов;! настройка очереди;! настройка rewrite-правил.

В настройке exim широко используются различныесписки (hostlist, domainlist и dnslist) и так называемыеlookup, при помощи которых exim извлекает данные извнешних источников.

Многие мои знакомые, пытаясь освоить exim, считалиlookup самой запутанной темой, потому я остановлюсь наэтом вопросе чуть подробнее. Существует два типа поис-ка: поиск по одному ключу (single-key) и поиск по запросу(query). Первый используется для поиска в локальныхфайлах, а второй – в различного рода базах (sql, ldap ипрочее). Любые lookup могут быть вложенными, то есть водном поиске используются результаты другого.

Поиск на основе single key строится примерно так:

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

${lookup{$var_to_search}lsearch{/path/to/file}}

gid integer DEFAULT 150, home character varying(255), mailquota integer DEFAULT 20);ALTER TABLE ONLY accounts ADD CONSTRAINT uid_k PRIMARY KEY (uid);ALTER TABLE ONLY accounts ADD CONSTRAINT login_k UNIQUE (login);

CREATE TABLE aliases ( mail character varying(128) NOT NULL, alias character varying(128));ALTER TABLE ONLY aliases ADD CONSTRAINT mail_k PRIMARY KEY (mail);

9№7(20), июль 2004

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

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

При этом сам файл, в котором осуществляется поиск,должен выглядеть так:

Приведу более конкретный пример – построение спис-ка доменов из файла на основании адреса отправителя(пример из документации):

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

При этом поиск осуществляется по первому полю. Отли-чие query-style-поиска в том, что мы явно не обозначаем,что искать, указывая вместо этого запрос. Так выглядиттипичный запрос к SQL-базе:

Например:

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

Несколько пугающими бывают запросы к LDAP. Раз-беру их поподробнее. Указание сервера и порта LDAP выг-лядит следующим образом:

Запросы к директории выглядят так:

Форма запроса описана в стандарте, но, думаю, ее сто-ит дополнительно пояснить. В запросе мы указываем ад-рес LDAP-сервера (ldap://ldap.test.ru/), basedn для поиска(dc=${domain},ou=mail,o=tehnopark), значение, котороенужно вернуть (mail), описание запроса (также в постфик-сной форме, характерной для функциональных языков:(&(objectClass=inetOrgPerson)(mail=${local_part}@${domain}))).

Когда требуется аутентификация на сервере, тогдапросто указываем нечто вроде:

Заметьте необходимость замены пробелов на %20, кактого требует стандарт. Более подробно обо всем этомможно узнать на http://www.exim.org/exim-html-4.30/doc/html/spec_9.html#CHAP9. Думаю, для дальнейшего пони-мания статьи этого вполне достаточно.

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

$ñïèñîê -> ${lookup ñïèñîê} -> ${lookup {$var_to_search} ↵↵↵↵↵driver{driver_arguments}}

$var_to_search: çíà÷åíèå

domainlist domains = ${lookup{$sender_host_address} ↵↵↵↵↵lsearch{/some/file}}

192.168.3.4: domain1 : domain2 : ...192.168.1.9: domain3 : domain4 : ...

${lookup driver{query}{action_if_query_succeed} ↵↵↵↵↵{action_if_query_failed}}

domainlist domains = ${lookup pgsql{select domains from ↵↵↵↵↵domains where sender='$sender_host_address'}{$value}fail}

ldap_default_servers = 127.0.0.1::389

${lookup ldap{ldap://ldap.test.ru/dc=${domain},ou=mail, ↵↵↵↵↵o=tehnopark?mail?sub?(&(objectClass=inetOrgPerson) ↵↵↵↵↵(mail=${local_part}@${domain}))}{$value} fail}

${lookup ldap{user="cn=manager,o=tehnopark of innovation,c=RU" pass=secretldap:///o=tehnopark%20of%20innovation,c=RU?sn?sub?(cn=foo)}{$value}fail}

########################################################### Runtime configuration file for Exim ############################################################ Çäåñü ìû îïðåäåëÿåì ìàêðîñû, îïèñûâàþùèå ðàçëè÷íûå ïóòèCONFIG_PREFIX=/usr/local/etc/eximACL_PREFIX=CONFIG_PREFIX/aclsCERTDIR=CONFIG_PREFIX/certs# Çäåñü ìû óêàçûâàåì, ãäå íàõîäèòü íàø PostgreSQL-ñåðâåð,# ñîåäèíåíèå îñóùåñòâëÿåòñÿ ÷åðåç ëîêàëüíûé ñîêåò, êîìàíäà# hide ïîìîãàåò ñïðÿòàòü ýòó íàñòðîéêó ïðè âûçîâå exim -bP,# êîãäà exim âûâîäèò âñå êîíôèãóðàöèîííûå îïöèè â ñòàíäàðòíûé# âûâîä. Ó÷òèòå, ÷òî ñàì /usr/local/etc/exim/configure äîëæåí# èìåòü âëàäåëüöà root:wheel è èìåòü ïðàâà äîñòóïà 0600, ÷òî# îòëè÷àåòñÿ îò òîãî, ÷òî ïðèíÿòî ïî óìîë÷àíèþ (0644)hide pgsql_servers = (/tmp/.s.PGSQL.5432)/users/pgsql/pAsSwOrD# Òóò ìû îïèñûâàåì ñïèñêè äîìåíîâ# Local_domains âêëþ÷àåò äîìåíû, ñ÷èòàþùèåñÿ ëîêàëüíûìè, òî# åñòü òå äîìåíû, äëÿ êîòîðûõ exim äåëàåò ëîêàëüíóþ äîñòàâêó,# äëÿ îñòàëüíûõ äîìåíîâ ïî÷òà äîñòàâëÿåòñÿ ïî MX çàïèñÿì â DNS.# Îáðàòèòå âíèìàíèå íà äîïîëíèòåëüíûå ôàéëû ACL_PREFIX/localdomains# è ACL_PREFIX/hostingdomains, â êîòîðûõ ïåðå÷èñëåíû äîìåíû,# ðàçäåëåííûå ïåðåâîäîì ñòðîêè (òî åñòü ïî îäíîìó äîìåíó íà# êàæäóþ ñòðîêó)domainlist local_domains = unona.test.ru : ↵↵↵↵↵

ACL_PREFIX/localdomains : ACL_PREFIX/hostingdomains# Äîïîëíèòåëüíàÿ íàñòðîéêàdomainlist hosting_domains = ACL_PREFIX/hostingdomains# Ñïèñîê õîñòîâ, ïî÷òó íà êîòîðûå ìû ÿâíî îòâåðãàåìhostlist host_reject = ACL_PREFIX/hostrejectdomainlist relay_to_domains =# Ñïèñîê àäðåñîâ, ñ êîòîðûõ ðàçðåøåíà ïåðåäà÷à ïî÷òû âî# âíåøíèé ìèðhostlist relay_from_hosts = localhost : 192.168.1.0/24 : ↵↵↵↵↵

ACL_PREFIX/relayfromhosts# Ïðîâåðêà ïîëó÷àòåëÿacl_smtp_rcpt = acl_check_rcptú# Ïðîâåðêà mime ñîäåðæèìîãîacl_smtp_mime = acl_check_mime# Ïðîâåðêà íà ñïàì è âèðóñûacl_smtp_data = acl_check_virus# Çäåñü ìû îïèñûâàåì íàø àíòèâèðóñav_scanner = clamd:127.0.0.1 3310# È spamassasinspamd_address = 127.0.0.1 783# Íàñòðîéêè ïîëüçîâàòåëÿ è ãðóïïû ïî óìîë÷àíèþexim_user = mailnullexim_group = mail# Íèêîãäà íå îñóùåñòâëÿåì äîñòàâêó ïîä ðóòîì - root äîëæåí# áûòü àëèàñîì íà äðóãîãî ëîêàëüíîãî ïîëüçîâàòåëÿ. Êñòàòè,# ýòî îáÿçàòåëüíîå óñëîâèå, çàäàííîå åùå íà ýòàïå êîìïèëÿöèènever_users = root# Íàñòðîéêè äèðåêòîðèè äëÿ î÷åðåäèspool_directory = /var/spool/exim# Ðàçäåëÿåì spool_directory íà íåñêîëüêî áîëåå ìàëåíüêèõ,# àíàëîã õåø-òàáëèöû, óñêîðÿåò îáðàáîòêó spoolsplit_spool_directory# Ïûòàåìñÿ ñäåëàòü ñîîòâåòñòâèå ïðÿìîé è îáðàòíîé çîíû DNS# äëÿ êàæäîãî õîñòà. Íåñêîëüêî çàòðàòíî, íî âåñüìà ïîëåçíîhost_lookup = *# Óáèðàåì ïðîâåðêó identd íà êëèåíòñêîé ñòîðîíå. Èç-çà# íåïðàâèëüíî íàñòðîåííûõ firewall ýòî ÷àñòî âûçûâàåò# äëèòåëüíûå òàéì-àóòû, êðîìå òîãî, ýòîò ñåðâèñ ïîäíÿò# íå ó ìíîãèõrfc1413_query_timeout = 0s# Óêàçûâàåì êîå-êàêèå ëèìèòû (èõ íàçíà÷åíèå ÿñíî èç íàçâàíèÿ)

10

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

# Ïðèíèìàåì ëþáûå ñîåäèíåíèÿ, êîòîðûå áûëè óñïåøíî# àâòîðèçîâàíûaccept authenticated = *# Ðåàëèçàöèÿ íàøåãî áàí-ëèñòàdeny hosts = +host_reject

message = You are banned. Go away.# Çàïðåùàåì âñå, ÷òî íå ðàçðåøåíî, çàêðûâàÿ òåì ñàìûì ðåëåé# äëÿ ñïàìåðîâdeny message = relay not permitted

# Ñïèñîê äîñòóïà äëÿ ïðîâåðêè mime-÷àñòåé ñîîáùåíèÿacl_check_mime:# Ïðîèçîäèì äåêîäèðîâàíèå mime-ñîîáùåíèé. Ïîëåçíî äëÿ# äàëüíåéøåé ïðîâåðêè íà âèðóñûwarn decode = default# Ìîæíî î÷åíü áûñòðî îòñåÿòü ñîîáùåíèÿ, ïðîñòî çàïðåòèâ# íåêîòîðûå mime-âëîæåíèÿ, ÷àùå âñåãî ñîäåðæàùèå âèðóñû,# õîòÿ, êîíå÷íî, ýòî íå ïàíàöåÿdeny message = Blacklisted file extension detected

condition = ${if match {${lc:$mime_filename}} ↵↵↵↵↵{\N(\.wav|\.cpl|\.pif| ↵↵↵↵↵\.bat|\.scr|\.lnk| ↵↵↵↵↵\.com)$\N} {1}{0}}

# Ìíîãî ëè ó íàñ ëþäåé, çíàþùèõ êèòàéñêèé? À âîò êèòàéñêîãî# ñïàìà ýòî ïîóáàâèòdeny message = Sorry, noone speaks chinese here

condition = ${if eq{$mime_charset}{gb2312}{1}{0}}accept# Ïðîâåðêà ñîäåðæèìîãî íà âèðóñû è ñïàìacl_check_virus:# Ìû íå çàïðåùàåì ïèñüìà ñî ñïàìîì, à ïðîñòî äîáàâëÿåì# çàãîëîâîê, ñîäåðæàùèé êîëè÷åñòâî ñïàìåðñêèõ î÷êîâ,# à ïîëüçîâàòåëü íà ñâîåé ñòîðîíå óæå ïðîñòî íàñòðàèâàåò# ñâîè ôèëüòðû. Òàê ìû èñêëþ÷àåì æàëîáû ñî ñòîðîíû# ïîëüçîâàòåëåé î ïîòåðÿííûõ ïèñüìàõ

warn message = X-Spam-Score: $spam_score ($spam_bar)spam = nobody:true

# Äîáàâëÿåì çàãîëîâêè, óêàçûâàþùèå, ÷òî ïèñüìà áûëè ïðîâåðåíû# SpamAsssasin

warn message = X-Spam-Scanned: Yeswarn message = X-Spam-Scanner: SpamAssassin running ↵↵↵↵↵

on mail.test.ru# Âîò ÷òî-÷òî, à âèðóñû íàì íå íóæíû deny message = Message rejected: virus found.

Your message was successfully trashed.

hosts = *malware = *

accept

########################################################### ROUTERS CONFIGURATION ## Specifies how addresses are handled ############################################################ THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT!## An address is passed to each router in turn until it is ## accepted. #######################################################################begin routers# Ðîóòåð, îñóùåñòâëÿþùèé ïîèñê ïî MX-çàïèñÿì â DNSdnslookup: driver = dnslookup domains = ! +local_domains transport = remote_smtp ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 no_more# Âñå îñòàíëüíûå ðîóòåðû îáñëóæèâàþò äîñòàâêó ëîêàëüíîé ïî÷òû# Äðàéâåð àëèàñîâ ïîëüçîâàòåëÿ. Îáðàòèòå âíèìàíèå íà lookup# â pgsql-áàçå. ×òî èíòåðåñíî, ýòîò lookup ðàáîòàåò äàæå äëÿ# èåðàðõè÷åñêèõ àëèàñîâ, íàïðèìåð, postmaster -> root -># cebka -> [email protected] Òàêæå îïðåäåëÿþòñÿ òðàíñïîðòû# äëÿ ïåðåäà÷è ïî÷òû â ôàéë (>/path/to/file) è â pipe# (|/usr/local/libexec/slocal)system_aliases: driver = redirect

smtp_accept_max = 50smtp_connect_backlog = 40smtp_accept_max_per_host = 10smtp_accept_queue = 22smtp_accept_queue_per_connection = 10recipients_max = 16recipients_max_reject = truemessage_size_limit = 16Maccept_8bitmime# Èãíîðèðóåì ñîîáùåíèÿ, êîòîðûå ïðèõîäÿò íàì æå, äàâíîñòü# êîòîðûõ áîëåå 12 ÷àñîâignore_bounce_errors_after = 12h# Óäàëÿåì çàìîðîæåííûå ñîîáùåíèÿ, äàâíîñòü êîòîðûõ áîëüøå# íåäåëè.timeout_frozen_after = 7d# Íàñòðîéêè TLStls_certificate = CERTDIR/mailed.crttls_privatekey = CERTDIR/mailed.keytls_advertise_hosts = *tls_verify_certificates = *# Ñëåäóþùàÿ îïöèÿ çàêîììåíòèðîâàíà, íî âåñüìà ïîëåçíà,# ïîçâîëÿÿ àâòîðèçèðîâàòüñÿ# òîëüêî ÷åðåç áåçîïàñíûé ssl-êàíàë#auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}

########################################################### ACL CONFIGURATION ## Specifies access control lists for incoming SMTP mail #######################################################################begin acl# Ýòîò ñïèñîê äîñòóïà îïèñûâàåò ïðîâåðêè, îñóùåñòâëÿåìûå# ïðè âûçîâå ëþáîé RCPT-êîìàíäûacl_check_rcpt:# Âíà÷àëå ïðîâåðÿåì äîñòîâåðíîñòü îòïðàâèòåëÿrequire verify = sender# Ïðèíèìàåì ñîåäèíåíèÿ îò ëîêàëüíûõ MUA (òî åñòü íå ÷åðåç TCP/IP) accept hosts = :########################################################### Ïðîâåðêà ñîîòâåòñòâèÿ ïî÷òîâîãî àäðåñà ñòàíäàðòódeny message = Restricted characters in address

domains = +local_domainslocal_parts = ^[.] : ^.*[@%!/|]

accept domains = +local_domains# Çäåñü ïðîïèñàíû òàê íàçûâàåìûå dnsbl, òî åñòü ÷åðíûå# ñïèñêè MTA ñ îòêðûòûì ðåëååì, ìû ïðîâåðÿåì IP-àäðåñ# îòïðàâèòåëÿ íà ñîîòâåòñòâèå òàêèì ñïèñêàì è áëîêèðóåì ïèñüìî,# åñëè îòïðàâèòåëü áûë íàéäåí â òàêîì ñïèñêådeny message = host is listed in $dnslist_domain

dnslists = blackholes.mail-abuse.org: ↵↵↵↵↵dialups.mail-abuse.org: ↵↵↵↵↵relays.mail-abuse.org: ↵↵↵↵↵relays.ordb.org: ↵↵↵↵↵work.drbl.caravan.ru: ↵↵↵↵↵dul.ru:sbl.spamhaus.org

# Ïðàâèëî íà ïðîâåðêó âñåõ ïî÷òîâûõ àäðåñîâ, êðîìå ëîêàëüíûõ# (ìåíåå ñòðîãîå) deny message = Restricted characters in address

domains = !+local_domainslocal_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./

########################################################### Ïðèíèìàåì ïî÷òó äëÿ ïîëüçîâàòåëÿ postmaster ëîêàëüíûõ# äîìåíîâ, íå âçèðàÿ íà îòïðàâèòåëÿaccept local_parts = postmaster

domains = +local_domains# Deny unless the sender address can be verifiedaccept domains = +local_domains

endpassverify = recipient

# Åñëè äîìåí â ñïèñêå relay_to_domains, òî ðàçðåøàåì ðåëåéaccept domains = +relay_to_domains

endpassverify = recipient

accept domains = +hosting_domainsendpassverify = recipient

accept hosts = +relay_from_hosts

11№7(20), июль 2004

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

allow_fail allow_defer data = ${lookup pgsql{select alias from aliases where ↵↵↵↵↵

mail ='$local_part@$domain'}{$value}fail} user = mailnull group = mail file_transport = address_file pipe_transport = address_pipe# Äëÿ ëîêàëüíûõ ïîëüçîâàòåëåé òàêæå ñîçäàåì âîçìîæíîñòü# ïåðåíàïðàâëåíèÿ ïî÷òû ÷åðåç ~/.forward-ôàéë. Åñëè âêëþ÷åíà# äèðåêòèâà allow_filter, òî â .forward-ôàéëå ìîæíî# èñïîëüçîâàòü ÿçûê sieve-ôèëüòðîâ. Äëÿ ïîäðîáíîñòåé# ñì. äîêóìåíòàöèþ íà www.exim.org, ò.ê. íà ðàññìîòðåíèå# ýòîé òåìû óéäåò ñëèøêîì ìíîãî âðåìåíèuserforward: driver = redirect check_local_user file = $home/.forward no_verify no_expn check_ancestor# allow_filter file_transport = address_file pipe_transport = address_pipe reply_transport = address_reply condition = ${if exists{$home/.forward} {yes} {no} }# Ëîêàëüíàÿ äîñòàâêà, åñëè äàííûé ïîëüçîâàòåëü íàéäåí â áàçålocaluser: driver = accept condition = ${lookup pgsql {select uid from accounts where ↵↵↵↵↵

login = '$local_part@$domain'}{yes}{no}} transport = local_delivery cannot_route_message = Unknown user

########################################################### TRANSPORTS CONFIGURATION ######################################################################## ORDER DOES NOT MATTER ##Only one appropriate transport is called for each delivery.#######################################################################begin transports# Äðàéâåð äëÿ äîñòàâêè ÷åðåç ñîåäèíåíèÿ ñ óäàëåííûìè# smtp-ñåðâåðàìèremote_smtp: driver = smtp# Ýòîò òðàíñïîðò äîñòàâëÿåò ïî÷òó â ëîêàëüíûå maildir. Ïóòü# ê maildir õðàíèòñÿ îïÿòü æå â òàáëèöå accounts. Ðàçðåøåíèÿ# íà äèðåêòîðèþ 0700 äëÿ âîçìîæíîñòè ðàáîòû ñ äàííûìè# äèðåêòîðèÿìè imap-ñåðâåðà. Ïðè ýòîì âëàäåëüöåì ÿâëÿåòñÿ# ãðóïïà è ïîëüçîâàòåëü èç accounts (ïîòîìó ïðè âêëþ÷åíèè# çàïèñåé â ýòó òàáëèöó íàäî íà÷èíàòü çíà÷åíèÿ uid# ñ äîñòàòî÷íî áîëüøîãî ÷èñëà, íàïðèìåð, 2000 è ïåðåñåêàòüñÿ# ñ ðåàëüíûìè ïîëüçîâàòåëÿìè îíî äîëæíî, òîëüêî åñëè ðåàëüíîìó# ïîëüçîâàòåëþ íóæåí ëîêàëüíûé äîñòóï ê maildir).# Òàêæå èç òàáëèöû accounts èçâëåêàþòñÿ äàííûå î ðàçìåðå# êâîòû, è óñòàíàâëèâàåòñÿ ïîðîã â 75% îò êâîòû, êîãäà# ïîëüçîâàòåëþ ïîñûëàåòñÿ óêàçàííîå ïðåäóïðåæäåíèå îá ïîäõîäå# ê ïîðîãó êâîòûlocal_delivery: driver = appendfile directory = ${lookup pgsql{select maildir from accounts ↵↵↵↵↵

where login = '$local_part@$domain'}{$value}fail} create_directory directory_mode = 0770 maildir_format delivery_date_add envelope_to_add return_path_add group = ${lookup pgsql{select gid from accounts where ↵↵↵↵↵

login = '$local_part@$domain'}{$value}fail} user = ${lookup pgsql{select uid from accounts where ↵↵↵↵↵

login = '$local_part@$domain'}{$value}fail} mode = 0660 no_mode_fail_narrower quota = ${lookup pgsql{select mailquota from accounts ↵↵↵↵↵

where login = '$local_part@$domain'}{$value}fail}M quota_warn_message = "\

To: $local_part@domain\n\From: [email protected]\n\Subject: Your maildir is going full\n\This message is automaticaly gnerated by your mail ↵↵↵↵↵

server.\n\This means, that your mailbox is 75% full. If you would \n\override this limit new mail would not be delivered ↵↵↵↵↵to you!\n"

quota_warn_threshold = 75%# Òðàíñïîðò, îñóùåñòâëÿþùèé äîñòàâêó â pipeaddress_pipe: driver = pipe return_output# Òðàíñïîðò, îñóùåñòâëÿþùèé äîñòàâêó ïðÿìî â ôàéëaddress_file: driver = appendfile delivery_date_add envelope_to_add return_path_add# Ýòîò òðàíñïîðò èñïîëüçóåòñÿ äëÿ àâòîìàòè÷åñêîãî îòâåòà íà# ñîîáùåíèÿ îá îøèáêàõaddress_reply: driver = autoreply

########################################################### RETRY CONFIGURATION ###########################################################begin retry# Íàñòðîéêè ïî óìîë÷àíèþ, êîòîðûå ÿ íå òðîãàë, óïðàâëÿþò# èíòåðâàëîì ïîâòîðíîé ïåðåäà÷è ñîîáùåíèé# This single retry rule applies to all domains and all# errors. It specifies retries every 15 minutes for 2 hours,# then increasing retry intervals, starting at 1 hour and# increasing each time by a factor of 1.5, up to 16 hours,# then retries every 6 hours until 4 days have passed since# the first failed delivery.# Address or Domain Error Retries# ----------------- ----- -------* * F,2h,15m; G,16h,1h,1.5; F,4d,6h

########################################################### REWRITE CONFIGURATION ###########################################################begin rewrite# Ñîçäàåì ïðàâèëî ïî ïåðåïèñûâàíèþ çàãîëîâêà To: ñ *@test.ru# íà ëîêàëüíûé smart-host - @unona.test.ru. Ýòî áûëî ñäåëàíî# äëÿ ëîêàëüíûõ ïîëüçîâàòåëåé, ïî èäåå ñ õðàíåíèåì# ïîëüçîâàòåëåé â postgres óæå íå íóæíî, ïîêàçàíî äëÿ ïðèìåðà.*@test.ru [email protected] T

########################################################### AUTHENTICATION CONFIGURATION ############################################################ Îïèñàíèÿ àóòåíòèôèêàöèèbegin authenticators# CRAM-MD5-àóòåíòèôèêàöèÿ, òðåáóåò íàëè÷èÿ ïàðîëÿ â îòêðûòîì# âèäå, èìÿ ïîëüçîâàòåëÿ äîëæíî áûòü â ôîðìàòå user@domain,# êàê îíî õðàíèòñÿ â òàáëèöå accountslookup_cram:

driver = cram_md5public_name = CRAM-MD5server_secret = ${lookup pgsql {select password from ↵↵↵↵↵

accounts where login='$1'}{$value}fail}server_set_id = $1

# LOGIN-àóòåíòèôèêàöèÿ - íå òðåáóåò õðàíåíèÿ ïàðîëÿ# â îòêðûòîì âèäå, îäíàêî, ïî ñåòè ïàðîëü ïåðåäàåòñÿ# â îòêðûòîì âèäå - òðåáóåòñÿ ëèøü âûïîëíåíèå óñëîâèÿ# server_condition - $1 - èìÿ ïîëüçîâàòåëÿ, à $2 - ïàðîëü.# LOGIN áåçîïàñåí òîëüêî ïðè óñòàíîâëåíèè ssl-ñîåäèíåíèÿ.login:

driver = plaintextpublic_name = LOGINserver_prompts = Username:: : Password::server_condition = ${lookup pgsql {select login from ↵↵↵↵↵

accounts where login='$1' and password='$2'}{yes}{no}}server_set_id = $1

12

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

Далее необходимо создать сертификат для smtp-сер-вера. В ходе эксплуатации выяснилось, что некоторые кли-енты, например, The Bat!, требуют, чтобы в CN-сертифика-те (подробнее о сертификатах и способах их генерации мож-но прочитать в моей статье из данного журнала, распола-гающейся по адресу http://cebka.pp.ru/my/openssl.txt) содер-жалось имя (FQDN) сервера. Например, для сервера наmail.test.ru серификат должен содержать CN: mail.test.ru.Содержание остальных полей некритично. Создать сер-тификат можно, например, так:

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

и понаблюдать за выводимыми сообщениями. Чтобы вклю-чить exim вместо sendmail, выполняем следующие дей-ствия: в файле /etc/rc.conf нужны строки:

Затем настраиваем доставку почты для локальных при-ложений через exim, для чего файл /etc/mail/mailer.conf унас должен выглядеть следующим образом:

После этого перейдем к настройке ClamAV: заходим в/usr/local/etc/ и копируем clamav.conf.sample в clamav.confи правим его таким образом, чтобы он принимал соеди-нения через tcp/ip, а не через локальный сокет, для чего вclamav.conf нужны следующие строки:

Далее копируем freshclam.conf.sample в freshclam.conf.

Этот файл указывает настройки для программы freshclam,использующейся для обновления антивирусных баз ClamAV.

SpamAssassin работает без дополнительных настроек.

Перейдем к следующей части – настройка courier. Этотimap-сервер для своей работы использует несколько про-цессов, которые, в свою очередь, настраиваются из раз-личных конфигурационных файлов. В моем примере за-пущено 3 процесса – authdaemon, courier-imapd и courier-imapd-ssl. Причем во внешний мир открыт только courier-imapd-ssl. Для начала создадим сертификат для imapd-sslи для TLS-соединений с imapd: правим файл /usr/local/etc/couier-imap/imapd.cnf на предмет своего dn для сертифи-ката, для чего в части req_dn прописываем свои настрой-ки (не забудьте, что cn должен совпадать с FQDN imap-сервера):

[ req_dn ]C=RUST=Moskow regionL=MoskowO=TehnoparkOU=Internet [email protected]

########################################################### CONFIGURATION FOR local_scan() ############################################################ If you have built Exim to include a local_scan() function# that contains tables for private options, you can define# those options here. Remember to uncomment the "begin"# line. It is commented by default because it provokes# an error with Exim binaries that are not built with# LOCAL_SCAN_HAS_OPTIONS set in the Local/Makefile.# begin local_scan

# End of Exim configuration file

# openssl genrsa -out mailed.key 2048# openssl req -new -x509 -key mailed.key -days 365 -out mailed.crt

exim -bd -d+all

sendmail_enable="NONE"exim_enable="YES"# À òàêæå äëÿ spamassasin è clamav:clamav_clamd_enable="YES"spamd_enable="YES"

sendmail /usr/local/sbin/eximsend-mail /usr/local/sbin/eximmailq /usr/local/sbin/eximnewaliases /usr/local/sbin/eximhoststat /usr/local/sbin/eximpurgestat /usr/local/sbin/exim

TCPSocket 3310TCPAddr 127.0.0.1

13№7(20), июль 2004

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

или из-под непосредственно DocumentRoot самого apache.Вот в принципе, и все.

Есть некоторые особенности запуска SquirrelMail привключенном safe_mode в php. Во-первых, все php-файлы икаталоги SquirrelMail должны принадлежать тому пользова-телю, из-под которого работает apache (настройка VirtualHostили глобальная, по умолчанию – www:nogroup). Кроме того,необходимо сменить разрешения в /var/spool/squirrelmail:

Ну и владельца установить того же, что и на /usr/local/www/squirrelmail.

Комментарии вы можете присылать на [email protected].

Cписок полезных ссылок:1. http://www.exim.org – сайт MTA exim, очень хорошая и

подробная документация;2. ftp://ftp.exim.org/pub/exim/config.samples.tar.bz2 – приме-

ры разнообразных конфигурационных параметров, по-лезно для ознакомления;

3. http://duncanthrax.net/exiscan-acl/ – патч exiscan с сопут-ствующей документацией;

4. http://www.clamav.net – сайт свободного антивирусаClamAV;

5. http://www.spamassasin.org – официальный сайтSpamAssasin;

6. http://www.courier-mta.org – ресурс courier продуктов, втом числе и courier-imap;

7. http://www.squirrelmail.org – сайт web-mail-системыSquirrelMail;

8. http://www.nixp.ru/cgi-bin/go.pl?q=articles;a=mta-home –exim+mutt+bmx – для домашней почтовой системы (хо-рошая и интересная статья);

9. http://tomster.org/geek/freebsdcookbook/ – альтернатив-ный вариант реализации почтовой системы, где вмес-то courier используется cyrus imapd;

10. http://cebka.pp.ru/samag/clamstat.tar.bz2 – скрипт стати-стики ClamAV;

11. http://cebka.pp.ru/samag/uidchk.pl – скрипт проверкипересечения uid из БД и системных.

Далее генерируем сертификат специальным скриптом:

После чего настроим imap-аутентификацию:

Далее в authdaemonrc заменяем список модулей дляаутентификации на:

Теперь courier знает, что ему нужно аутентифициро-ваться через pgsql. Надо только настроить сам pgsql-мо-дуль, настройки которого хранятся в authpqsqlrc. Он дол-жен содержать следующее:

Перейдем к настройке непосредственно imapd: скопири-уем imapd.dist в imapd. Правим следующие строчки (для ос-тальных настроек вполне подходят значения по умолчанию):

Этих настроек в принципе хватает. Далее копируемimapd-ssl.dist в imapd-ssl и правим следующие строчки:

После чего делаем запуск courier-imap при старте сис-темы. Для этого заходим в /usr/local/etc/rc.d и снова не-много попереименовываем файлы:

После этого считаем, что наша почтовая система прак-тически готова. Нужно только немного понастраиватьSquirrelMail, для чего заходим в /usr/local/www/squirrelmailи запускаем скрипт ./configure. В принципе интерфейс кон-фигурации понятен без лишних пояснений, потому я небуду особо останавливаться на этой проблеме (не забудь-те, главное, указать imap- и smtp-сервера). Делаем сим-линк на /usr/local/www/squirrelmail из какого-либо VirtualHost

cd /usr/local/share/courier-imap/./mkimapdcert

cd /usr/local/etc/courier-imap/cp authdaemonrc.dist authdaemonrc

authmodulelist="authpgsql"

IMAPDSSLSTART=YES

# mv courier-imap-imapd-ssl.sh.sample courier-imap-imapd-ssl.sh# mv courier-imap-imapd.sh.sample courier-imap-imapd.sh

# Ñîåäèíÿåìñÿ ñ ÑÓÁÄ ÷åðåç ëîêàëüíûé ñîêåò (íå óêàçàí àäðåñ)PGSQL_PORT 5432PGSQL_USERNAME pgsqlPGSQL_PASSWORD pAsSwOrDPGSQL_DATABASE users# Íàñòðîéêè òàáëèöû äëÿ àóòåíòèôèêàöèè, çäåñü ìû óêàçûâàåì,# â êàêèõ ïîëÿõ òàáëèöû õðàíÿòñÿ ðàçëè÷íûå ïîëüçîâàòåëüñêèå# äàííûå:PGSQL_USER_TABLE accountsPGSQL_CLEAR_PWFIELD passwordDEFAULT_DOMAIN test.ruPGSQL_UID_FIELD uidPGSQL_GID_FIELD gidPGSQL_LOGIN_FIELD loginPGSQL_HOME_FIELD homePGSQL_NAME_FIELD gecosPGSQL_MAILDIR_FIELD maildir

# imapd ñëóøàåò òîëüêî íà ëîêàëüíîì àäðåñå, äëÿ âíåøíèõ# ñîåäèíåíèé ìû áóäåì èñïîëüçîâàòü imapd-sslADDRESS=127.0.0.1# Ïî óìîë÷àíèþ â NO, äåëàåì â YES, ÷òîáû imapd ìîã çàïóñêàòüñÿIMAPDSTART=YES

# chmod 1777 /var/spool/squirrelmail/attach# chmod 1777 /var/spool/squirrelmail/pref

14

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

Создадим пользователя mailuser в базе данных PostgreSQL, c правами которого Postfix и Dovecot будут подклю-чаться к базе данных и выполнять запросы:

Устанавливаем пароль пользователю mailuser:

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

База данных mails создана. Далее создаем в ней таб-лицы. Есть 2 способа: писать SQL-команды руками в кли-енте postgresql или приготовить файл с SQL-запросом, апотом создать структуру таблиц, выполнив этот самыйзапрос.Я выбираю последний способ. Создаем файлcreatetables.sql:

Итак, посмотрим, для чего предназначен каждый из этихкомпонентов! Postfix (http://postfix.org) – это популярный MTA (Mail

Transfer Agent), позволяющий эффективно передаватьписьма адресатам.

! Dovecot (http://dovecot.org) – Secure IMAP server. IMAP-сервер, рассчитанный на максимальную безопасностьи надежность. Преимуществом этой программы явля-ется то, что для поиска в больших файлах применяетсябинарный древовидный индекс. Как указывает авторэтого сервера, он тестировал его с 367 000 почтовымиучетными записями и не обнаружил проблем. Также про-грамма может обслуживать запросы пользователей спомощью протоколов imap, imaps, pop3, pop3s.

! ClamAV (http://clamav.sourceforge.net) – opensource-ан-тивирус.

! SpamAssasin (http://spamassasin.org) – почтовый фильтр.Предназначен для борьбы со спамом.

! Amavisd-new (http://www.ijs.si/software/amavisd) – высо-коэффективный и надежный интерфейс между MTA иодним или несколькими фильтрами содержимого: ви-русные сканеры, спам-фильтры (в нашем случае SpamAssassin). Amavisd-new написан на Perl, обеспечиваю-щим высокую надежность, мобильность и ремонтоп-ригодность. Он взаимодействует с MTA через (E) SMTPили LMTP или при использовании программ-посред-ников.

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

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

PostgreSQLНастройку и конфигурирование PostgreSQL не привожу,т.к. информации об этом предостаточно.

РУСТАМ АТНАГУЛОВ

НАСТРОЙКА ПОЧТОВОЙ СИСТЕМЫ НА БАЗЕPostfix + Dovecot + PostgreSQL + Amavisd-new +SpamAssassin + ClamAV

В данной статье будет рассмотрена установка почтового сервера на базе AltLinux Master 2.2с использованием пакетов из репозитария Sisyphus. Наша система обеспечит поддержку виртуальныхдоменов в связке Postfix + Dovecot + PgSQL с защитой от спама и вирусов с помощью SpamAssasinи ClamAV.

[root@mosqit /]# apt-get install postfix postfix-pgsql ↵↵↵↵↵postgresql postgresql-server dovecot amavisd ↵↵↵↵↵clamav spamassasin

[root@mosqit /]# groupadd -g 5000 mailuser[root@mosqit /]# adduser -d /var/spool/mail -M -g mailuser ↵↵↵↵↵

-s /sbin/nologin -u 5000 mailuser

[root@mosqit /]# createuser -U postgres

[root@mosqit /]# psql -U postgres template1

[root@mosqit /]# createdb -U postgres mails

CREATE TABLE "public"."users" ( "userid" VARCHAR(128) NOT NULL, "password" VARCHAR(128), "realname" VARCHAR(128), "uid" INTEGER NOT NULL, "gid" INTEGER NOT NULL, "home" VARCHAR(128) NOT NULL, "mail" VARCHAR(255), CONSTRAINT "users_pkey" PRIMARY KEY("userid")) WITHOUT OIDS;

15№7(20), июль 2004

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

Структура таблиц создана:

Запускаем PostgreSQL:

PostfixПереходим к правке конфигурационного файла main.cf,который находится в /etc/postfix.main.cf. Он хорошо коммен-тирован, поэтому внимательно вчитываемся в описание инастраиваем согласно своим требованиям. У меня main.cfвыглядит так:

Остальные параметры по умолчанию, но их можно из-менить по собственному усмотрению.

Далее редактируем конфигурационный файл master.cf:

И соответственно создаем файлы aliases.pgsql,maibox.pgsql, transport.cf:

[root@mosqit /]# /usr/bin/psql -U postgres mails < createtable.sql

[root@mosqit /]# service postgresql start

main.cf:# Çàäàåì èìÿ íàøåãî ïî÷òîâîãî óçëàmyhostname = testdomain.ru# Èìÿ íàøåãî äîìåíà, åñëè íå óêàçûâàòü, òî ïî óìîë÷àíèþ# âûñòàâèòñÿ ìèíóñ ïåðâûé êîìïîíåíò èìåíè óçëàmydomain = testdomain.rumyorigin = $myhostname# RECEIVING MAIL# Çäåñü çàäàåì, íà êàêèõ ñåòåâûõ èíòåðôåéñàõ áóäåò ðàáîòàòü# Postfix, â ìîåì ñëó÷àå íà âñåõinet_interfaces = all# Ñïèñîê äîìåíîâ, íà êîòîðûå áóäåò îñóùåñòâëÿòüñÿ äîñòàâêà# ÷åðåç local transportmydestination = localhost, $myhostname, ↵↵↵↵↵

localhost.$mydomain, $config_directory/mydestination# REJECTING MAIL FOR UNKNOWN LOCAL USERS# Çäåñü ìû óêàçûâàåì, ÷òî ïîëüçîâàòåëåé testdomain.ru íóæíî# ïðîñìàòðèâàòü â $virtual_maibox_mapslocal_recipient_maps = $virtual_maibox_mapsunknown_local_recipient_reject_code = 550# TRUST AND RELAY CONTROL# çäåñü óêàçûâàåì, êîìó ðàçðåøåí relay, ò.å. ïîëüçîâàòåëÿì# îáñëóæèâàåìîé ñåòèmynetworks = 127.0.0.0/8, 10.70.1.0/24# Çàäàåì äèðåêòîðèþ, ãäå áóäåò õðàíèòüñÿ ïî÷òàmail_spool_directory = /var/spool/mailmailbox_command = /usr/bin/procmail -a $DOMAIN -d $LOGNAME# Íàø ïî÷òîâûé ñåðâåð òðåáóåò ñíà÷àëà êîììàíäó helosmtpd_helo_required = yestransport_maps = hash:/etc/postfix/transport.cf# Çàäàåì äèðåêòîðèþ, ãäå áóäåò õðàíèòüñÿ ïî÷òà# èç âèðòóàëüíûõ äîìåíîâvirtual_mailbox_base = /var/spool/mail/# Ïðîñìîòð òàáëèö ñ öåëüþ ïðîâåðêè äåéñòâèòåëüíîñòè àäðåñàvirtual_mailbox_maps = pgsql:/etc/postfix/mailbox.pgsqlvirtual_alias_maps = pgsql:/etc/postfix/aliases.pgsql# Èñïîëüçóþ ñòàòè÷åñêèå uid & gid; 5000 � ýòî mailuservirtual_uid_maps = static:5000virtual_gid_maps = static:5000virtual_minimum_uid = 5000# INSTALL-TIME CONFIGURATION INFORMATIONreadme_directory = /etc/postfix/README_FILESsample_directory = /etc/postfix/samplessendmail_path = /usr/sbin/sendmailsetgid_group = postdropcommand_directory = /usr/sbinmanpage_directory = /usr/share/mandaemon_directory = /usr/lib/postfixnewaliases_path = /usr/bin/newaliasesmailq_path = /usr/bin/mailq

grant select on users to mailuser;CREATE TABLE "public"."aliases" ( "alias" VARCHAR(128) NOT NULL, "dest" VARCHAR(128) NOT NULL, "comment" TEXT DEFAULT ''::text) WITH OIDS;grant select on aliases to mailuser;

queue_directory = /var/spool/postfixmail_owner = postfix# Ýòîò ïàðàìåòð îòíîñèòñÿ ê Amavisd# Ïîêà êîììåíòèðóåì, ÷òîáû ìîæíî áûëî ïðîâåðèòü# ðàáîòîñïîñîáíîñòü postfix.#content_filter=smtp-amavis:[127.0.0.1]:10024

master.cf:

# äàëåå îòíîñèòñÿ ê Amavisd

-o smtp_data_done_timeout=1200-o smtp_send_xforward_command=yes-o disable_dns_lookups=yes

-o content_filter=-o relay_recipient_maps=-o smtpd_restriction_classes=-o smtpd_client_restrictions=-o smtpd_helo_restrictions=-o smtpd_sender_restrictions=-o smtpd_recipient_restrictions=permit_mynetworks,reject-o mynetworks=127.0.0.0/8-o strict_rfc821_envelopes=yes-o smtpd_error_sleep_time=0-o smtpd_soft_error_limit=1001-o smtpd_hard_error_limit=1000

aliases.pgsql:hosts = localhostuser = mailuserpassword = topsecretdbname = mailstable = aliasesselect_field = destwhere_field = aliasmailbox.pgsql:hosts = localhostuser = mailuserpassword = topsecretdbname = mailstable = usersselect_field = homewhere_field = useridtransport.cf:testdomain.ru virtual:another.domain.ru virtual:

16

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

В transport.cf указываем, каким образом будут обра-батываться домены, наши домены – через virtual, в про-тивном случае они будут обработаны с помощью local_transport.

Запускаем postfix:

Проверяем работу нашего сервера:

Работает, иначе смотрим лог-файлы в /var/log/maillog.

Создание учетных записейпользователейДля этого я написал пару простейших скриптов на bash:

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

Создаем почтового пользователя [email protected]:

Выполняем инструкции, которые выводятся на экран.Далее проверяем, как Postfix доставляет почту:

Обращаю внимание на точку c новой строки после test

[root@mosqit /]# service postfix start

[root@mosqit /]# telnet 127.0.0.1 25

add_mailuser.bash:#! /bin/bashbasedir=/var/spool/mailecho "Ââåäèòå e-mail â âèäå name@domain"read emailpos=`expr match "$email" '[a-z1-9A-Z.]*@'`if [ $pos = "0" ] then echo "Íåïðàâèëüíîå èìÿ ïîëüçîâàòåëÿ" exitfidomain=${email:$pos}name=${email:0:($pos-1)}cd $basedir/$domain/$name &> /dev/nullif [ $? = "0" ]; then echo 'Òàêîé ïîëüçîâàòåëü ñóùåñòâóåò !! ' exitficd $basedir/$domain &> /dev/nullif [ $? = "1" ]; then echo 'Òàêîãî äîìåíà íå ñóùåñòâóåò' exitfiecho "Ââåäèòå ïîëíîå èìÿ "read fullnameecho "Ââåäèòå ïàðîëü "read passecho "ïàðîëü $pass"echo -E "INSERT INTO public.users (userid, password, ↵↵↵↵↵

realname, uid, gid, home, mail) VALUES ('$email', '$pass', ↵↵↵↵↵'$fullname', '42', '42','$domain/$name/inbox', NULL);" ↵↵↵↵↵| /usr/bin/psql -U postgres mails

mkdir $basedir/$domain/$nametouch $basedir/$domain/$name/inboxchmod 600 $basedir/$domain/$name/inboxchmod 700 $basedir/$domain/$namechown postfix:postfix $basedir/$domain/$name -Rls $basedir/$domain/$name/inbox &> /dev/nullif [ $? = "1" ]; then echo 'Îøèáî÷êà âûøëà! ' exitfiecho "Ïîëüçîâàòåëü ñîçäàí óñïåøíî"del_mailuser.bash:#! /bin/bashbasedir=/var/spool/mailecho "Ââåäèòå e-mail, êîòîðûé õîòèòå óäàëèòü â âèäå name@domain"

[root@mosqit /]# add_mailuser.bash

[root@mosqit /]# service postfix restart[root@mosqit /]# telnet 127.0.0.1 25

read emailpos=`expr match "$email" '[a-z1-9A-Z.]*@'`if [ $pos = "0" ] then echo "Íåïðàâèëüíîå èìÿ ïîëüçîâàòåëÿ" exitfidomain=${email:$pos}name=${email:0:($pos-1)}cd $basedir/$domain/$name &> /dev/nullif [ $? = "1" ]; then echo 'Òàêîé ïîëüçîâàòåëü íå ñóùåñòâóåò !! ' exitfiecho "DELETE from public.users where userid='$email';" | ↵↵↵↵↵

usr/bin/psql -U postgres mailsrm -rf $basedir/$domain/$name &> /dev/nullcd $basedir/$domain/$name &> /dev/nullecho $?if [ $? = "0" ]; then echo 'Îøèáî÷êà âûøëà! ' exitfiecho "Ïîëüçîâàòåëü óäàëåí óñïåøíî"add_alias.bash:#! /bin/bashecho "Ââåäèòå aliasname âèäå name@domain"read aliasnamepos=`expr match "$aliasname" '[a-z1-9A-Z.]*@'`if [ $pos = "0" ] then echo "Íåïðàâèëüíûé aliasname" exitfiecho "Ââåäèòå destination â âèäå name@domain"read destpos=`expr match "$dest" '[a-z1-9A-Z.]*@'`if [ $pos = "0" ] then echo "Íåïðàâèëüíûé destination" exitfiecho "Ââåäèòå êîììåíòàðèé"read commentecho -E "INSERT INTO public.aliases (email, alias, comment) ↵↵↵↵↵

VALUES ('$aliasname', '$dest', '$comment');" ↵↵↵↵↵| /usr/bin/psql -U postgres mails

echo "Alias ñîçäàí óñïåøíî"

17№7(20), июль 2004

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

message, это означает, что передача данных завершена.Далее идем в каталог /var/spool/mail/testdomain/test и

смотрим содержимое файла inbox, в нем и должно нахо-диться наше сообщение. Если файл пуст, то опять же смот-рим лог-файл (maillog).

ClamAVИдем в /etc/clamav.conf и находим строчку ScanMail и рас-комментируем ее, для того чтобы антивирус проверялфайлы формата mailbox. Запускаем ClamAV:

Amavisd-newДалее настраиваем /etc/amavis/amavisd.conf по своемуусмотрению, конечно же, перед этим прочитав докумен-тацию. Лично я ничего не изменял, но скорее всего со вре-менем придется внести коррективы.

Запускаем Amavisd-new:

Проверяем его работу:

Раскомментируем строчку: filter=smtp-amavis:[127.0.0.1]:10024 в файле main.cf. Перезапускаем Postfix, запускаемClamaV, Amavisd:

Как и ранее, проверяем с помощью telnet работоспо-собность postfix. Если все нормально, то переходим к на-стройке Dovecot.

DovecotДалее редактируем файл настроек dovecot /etc/dovecot.conf.Так же внимательно вчитываемся в комментарии к пара-метрам.

После этого нам требуется сгенерировать SSL-сер-тификат, т.к. у нас заявлены протоколы imaps и pop3s(s – secure).

Для этого правим файл /etc/dovecot/dovecot-openssl.cnf:

Запускаем скрипт для генерации сертификата.

Правим файл /etc/dovecot/pgsql.conf, в котором указы-ваем, как Dovecot будет подключаться и забирать данные.

Все настройки произведены, можно испытать работо-способность нашего pop3-сервера:

Настраиваем наш почтовый клиент и проверяем, дос-тавляется почта или нет. Имя пользователя указываетсяполное, т.е. [email protected], а не test.

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

Используемая литература:1. Postfix Documentation: http://postfix.org/documentation.html2. Documentation: http://dovecot.org/documentation.html3. DovecotPostgresql: http://wiki.dovecot.org/moint.cgi/Dovecot

Postgresql

[root@mosqit /]# service clamd start

[root@mosqit /]# service amavisd start

[root@mosqit /]# telnet 127.0.0.1 10024

[root@mosqit /]# service postfix restart

dovecot.conf:# Ïðîòîêîëû, êîòîðûå ìû èñïîëüçóåìprotocols = imap imaps pop3 pop3s## IMAP login processlogin = imap## POP3 login processlogin = pop3## Mail processesfirst_valid_uid = 5000# Ïóòü ê äèðåêòîðèè, ãäå õðàíèòñÿ ïî÷òà, ãäå %d �# èìÿ äîìåíà, %n � èìÿ ïîëüçîâàòåëÿdefault_mail_env = mbox:/var/spool/mail/%d/%n/: ↵↵↵↵↵

INDEX=/var/spool/mail/%d/%nmbox_locks = fcntl flock## Authentication processesauth = defaultauth_mechanisms = plainauth_userdb = pgsql /etc/dovecot/pgsql.confauth_passdb = pgsql /etc/dovecot/pgsql.conf# root ò.ê. èñïîëüçîâàòü ïîðòû äî 1024 ïîðòà ìîæåò òîëüêî root

[ req ]default_bits = 1024encrypt_key = yesdistinguished_name = req_dnx509_extensions = cert_typeprompt = no[ req_dn ]# country (2 letter code)C=RU# State or Province Name (full name)ST=Bashkortostan# Locality Name (eg. city)L=Ufa# Organization (eg. company)O=Home Organizations.# Organizational Unit Name (eg. section)OU=POP3 IMAP server# Common Name (*.example.com is also possible)CN=testdomain.ru# E-mail [email protected][ cert_type ]nsCertType = server

[root@mosqit /]# /usr/share/dovecot/mkcert.sh

connect = host = localhost dbname = mails user = mailuser ↵↵↵↵↵password = secret

default_pass_scheme = PLAINpassword_query = SELECT password FROM users WHERE userid = '%u'user_query = SELECT '/var/spool/mail/'|| home, uid, gid ↵↵↵↵↵

FROM users WHERE userid = '%u'

[root@mosqit /]# service dovecot start

auth_user = root

18

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

Нет, это, конечно, не милиция (надеюсь, вы не использу-ете знания, полученные со страниц журнала, в целях, про-тиворечащих вашему местному законодательству). Речьпойдет об открытом программном продукте, предназна-ченном для создания собственных списков рассылки –Mailman (в переводе с англ. – почтальон). Сей продуктрасположился в глобальной паутине по адресу http://www.list.org. Mailman распространяется в соответствии сGeneral Public License. Используется в своих рассылкахтакими маститыми IT-компаниями, как Red Hat, AppleComputer, Dell Computers и большим числом GNU-проек-тов, включая The XFree86 Project, Samba, Exim, XEmacs.Со списком сайтов, где используется рассматриваемыйпродукт, можно ознакомиться по ссылке http://www.list.org/inthenews.html.

Программа обладает обширным списком возможнос-тей. Вот некоторые из них:! Управление списками, подпиской и пользовательской

конфигурацией через веб-интерфейс.! Модерирование рассылок, поддержка открытых и зак-

рытых списков рассылки, фильтров.! Поддержка архивов списков рассылки.! Автоответчик.

Прежде чем приступить к установке, ознакомимся стребованиями к системе, на которую ставится Mailman:! Естественно, должен присутствовать почтовый сервис.

Mailman работает с Sendmail, Postfix, Exim и qmail. Намоей тестовой системе стоял Sendmail, поэтому на негои буду ориентироваться в описании.

! Веб-сервер с поддержкой CGI/1.1 API.! GCC 2.8.1 или выше.! Интерпретатор Python, на котором, собственно, и на-

писана система (с небольшими кусочками кода на C).Поддерживаются версии 2.1 и выше.

Я проверял установку системы на дистрибутиве WhiteBox Enterprise Linux 3 (http://www.whiteboxlinux.org/), которыйявляется версией Red Hat Enterprise Linux 3, заново собран-ной из свободно доступных исходников.

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

УстановкаСкачиваем с сайта проекта либо с одного из зеркал ар-хив mailman.tar.gz. Последняя версия «почтальона» на

момент написания статьи была 2.1.5. Конечно, можно былобы найти и поставить Mailman из rpm-файла. Так было быпроще, но, учитывая, что не все читатели используют си-стемы на основе менеджера пакетов rpm, рассмотрим ус-тановку из исходных текстов. Разархивируем скачанныйфайл в каталог /tmp.

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

В дистрибутивах, основывающихся на Red Hat Linuxэто делается одной командой:

Теперь создаем директорию, в которую будет установ-лен Mailman и даем на нее права:

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

Теперь проверим корректность разрешений на файлыпри помощи специального скрипта, входящего в пакет:

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

Далее, даем команду exit, и уже под пользователем rootправим httpd.conf, добавив туда строчки:

Таким образом, мы предписываем Apache, что из ука-занного каталога разрешается выполнять CGI-скрипты, со-

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

«КТО СТУЧИТСЯВ ДВЕРЬ КО МНЕ…»ОБЗОР СИСТЕМЫ ПОДДЕРЖКИСПИСКОВ РАССЫЛОК GNU MAILMAN

gunzip mailman.tar.gztar �xvf mailman.tar

useradd mailman

mkdir /usr/local/mailmanchgrp mailman /usr/local/mailmanchmod a+rx,g+ws /usr/local/mailman

cd /tmp/mailman-2.1.5/./configure --with-cgi-gid=apache --with-mail-gid=mailmake install

cd /usr/local/mailman./bin/check_perms

ScriptAlias /mailman/ /usr/local/mailman/cgi-bin/Alias /pipermail/ /usr/local/mailman/archives/public<Directory �/usr/local/mailman/archives/public/�>

AddDefaultCharset Off</Directory>

19№7(20), июль 2004

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

здаем алиас для /archives/public/ и выключаем для этогокаталога кодировку «по умолчанию».

Потом копируем логотипы Mailman, Python, GNU Logoв доступное вашему веб-серверу место, и не забываемперезапустить сам веб-сервер:

Создаем служебный «site-wide»-список под названи-ем mailman:

По запросу вводим mail ведущего список и пароль (наэтот адрес будет выслано письмо с подтверждением иуказанным паролем).

Теперь, согласно инструкциям, выданным после отра-ботки команды, добавляем в /etc/aliases псевдонимы (вкачестве примера был создан список под именем test):

Если ваш Sendmail идет с включенной по умолчаниюопцией smrsh, ограничивающей исполнение скриптов че-рез MTA (а в случае использования дистрибутивов, не ба-зирующихся на Red Hat Linux, это именно так), то вам необ-ходимо в каталоге /etc/smrsh/ создать симлинк на mailman:

Следующий шаг – создание списка периодически вы-полняемых задач при помощи crontab (например, опове-щение администратора о запросах на включение пользо-вателей в список рассылки):

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

Проверьте правильность выставленных значений пере-менных DEFAULT_EMAIL_HOST и DEFAULT_URL_HOST вфайле ./Mailman/Defaults.py. Они должны содержать пол-ное имя вашего почтового и веб-сервера.

Далее применяем шаблон сайта (его можно было пред-варительно отредактировать, но мы все оставим по умол-

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

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

Если в процессе конфигурирования у вас что-то пой-дет не очень гладко, рекомендую просмотреть FAQ по ад-ресу: http://www.python.org/cgi-bin/faqw-mm.py?req=index.Также обратите внимание на логи «почтальона», ведущи-еся в каталоге /usr/local/mailman/logs/, и возможные бло-кировки в /usr/local/mailman/loсks/.

Создаем список рассылкиТеперь у нас все готово для создания первого списка рас-сылки. Идем по ссылке: http://сервер.домен.ru/mailman/create, и заполняем поля: имя списка, пароль, почтовыйящик владельца, язык. В самом последнем поле вводимпароль администратора сайта, который мы задавали ко-мандой mmsitepass.

После успешного создания списка вам придет письмос подтверждением, и будет доступна ссылка: http://сервер.домен.ru/mailman/admin/имя_списка, по которойможно вызвать интерфейс администратора. А по http://сервер.домен.ru/mailman/listinfo/имя_списка можно подпи-саться на список. Также по http://сервер.домен.ru /mailman/listinfo приведен общий перечень всех списков рассылки,существующих на сайте. Естественно, в нем пока присут-ствует только один элемент.

Протестировать новый список, предварительно подпи-савшись на него, можно, отправив письмо на адрес имя_списка@сервер.домен.ru.

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

cp /usr/local/mailman/icons/* /var/www/iconsservice httpd restart

./bin/newlist mailman

test: "|/usr/local/mailman/mail/mailman post test"test-admin: "|/usr/local/mailman/mail/mailman admin test"test-bounces: "|/usr/local/mailman/mail/mailman bounces test"test-confirm: "|/usr/local/mailman/mail/mailman confirm test"test-join: "|/usr/local/mailman/mail/mailman join test"test-leave: "|/usr/local/mailman/mail/mailman leave test"test-owner: "|/usr/local/mailman/mail/mailman owner test"test-request: "|/usr/local/mailman/mail/mailman request test"test-subscribe: "|/usr/local/mailman/mail/mailman ↵↵↵↵↵

subscribe test"test-unsubscribe: "|/usr/local/mailman/mail/mailman ↵↵↵↵↵

unsubscribe test"

cd /etc/smrsh/ln �s /usr/local/mailman/mail/mailman mailman

cd /usr/local/mailman/croncrontab �u mailman crontab.incd ..

./bin/mailmanctl startcp scripts/mailman /etc/init.d/mailmanchkconfig �add mailman

./bin/config_list �I data/sitelist.cfg mailman

./bin/mmsitepass

20

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

КАК РАЗЛИЧАТЬ И СЧИТАТЬМАРКИРОВАННЫЙ ТРАФИК?

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

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

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

Если выяснение перемещения атомов – задача ско-

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

21№7(20), июль 2004

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

1 Изотопы: (от изо... и греч. topos – место ), разновидности одного химического элемента, занимающее одно место впериодической системе элементов Менделеева, но отличающиеся массами атомов. Химические свойства атомов, т.е.принадлежность атома к тому или иному химическому элементу, зависят от числа электронов и их расположения вэлектронной оболочке атома. Место химического элемента в периодической системе элементов определяется его по-рядковым номером Z, равным числу электронов в оболочке атома или, что то же самое, числу протонов, содержащихсяв атомном ядре. Кроме протонов, в ядро атома входят нейтроны, масса каждого их которых приблизительно равна массепротона. Количество нейтронов N в ядре атома с данным Z может быть различным, но в определённых пределах... Отсоотношения чисел протонов и нейтронов в ядре зависят различные свойства атомов. Атомы с одинаковым Z, но сразличным числом нейтронов N обладают идентичными химическими свойствами... и также называются изотопами.Большая Советская Энциклопедия, том 10, М.: Издательство «Советская энциклопедия»,1972, стр 109.

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

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

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

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

Узнав, откуда приходит трафик, можно нежелательныйограничить и платить меньше.

Логичным и давно используемым решением даннойпроблемы служит маркировка трафика. Под маркировкой

следует понимать изменение значений определённых би-тов в пакетах в соответствии с принятыми договорённос-тями. По идее можно менять что угодно, как угодно и гдеугодно, однако в большинстве случаев это негативно ска-жется на правильной работе тех или иных уже существу-ющих протоколов, поэтому согласно RFC791 (InternetProtocol) было решено использовать для целей маркиров-ки только один, второй байт в заголовке IP-пакетов, име-нуемый ToS, сокращённо от Type of Service, изменения врамках которого должны пониматься всеми корректно.

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

Первые три бита с 0 по 2 – это поле Precedence. Всегоможет быть 8 комбинаций значений этих битов:! 111 – Network Control! 110 – Internetwork Control! 101 – CRITIC/ECP! 100 – Flash Override! 011 – Flash! 010 – Immediate! 001 – Priority! 000 – Routine

Несмотря на то что согласно рекомендации полеPrecedence входит в состав поля ToS, иногда под полем ToSподразумевают всё, что идёт после поля Precedence, невключая его и зарезервированные 2 бита, а встречающие-ся далее в нём биты имеют следующее предназначение.Бит 3 (буква D (Delay) на рис. 2) отвечает за задержку тра-фика и рекомендует в случае, если в этом поле стоит 1минимизировать задержку (0 = Normal Delay, 1 = Low Delay).Бит 4 (буква T (Throughput) на рис. 2) отвечает за пропуск-ную способность: 0 – обычная (Normal Throughput), 1 – повозможности, повышенная (High Throughput). Бит 5 отве-чает за надёжность передачи: 0 – обычная надёжность(Normal Reliability), 1 – повышенная (High Reliability). Биты 6 и

Ðèñóíîê 1. Çàãîëîâîê IP-ïàêåòà. Êðàñíûì âûäåëåíî ïîëå, îáû÷íîèñïîëüçóåìîå äëÿ ìàðêèðîâêè ïàêåòîâ

Ðèñóíîê 2. Ðàçäåëåíèå ïîëÿ ToS íà áèòû ñîãëàñíî RFC791

22

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

7 не используются и зарезервированы для будущих целей.Замечание. Согласно RFC 792 (Internet Control Message

Protocol), так как у ICMP-пакетов используется заголовок,идентичный протоколу IP, то в них также может использо-ваться маркировка. Программа sing [9] не только показы-вает значение поля ToS приходящих пакетов, но и позво-ляет с помощью параметров менять это поле у отправля-емых ею пакетов. Использование маркировки IP-пакетовв поле ToS было задумано в 1979 году с самого началапоявления этого протокола, определяемого устаревшимна сегодня документом IEN 123.

Появившиеся вместо него документы RFC 760 (1980 г.)и RFC 791 (1981 г.) не изменили ситуацию существеннымобразом.

Последний документ действует и поныне, однако че-рез 10 лет после появления протокола IP вышел RFC 1122(Requirements for Internet Hosts – Communication Layers),который включил два зарезервированных бита в TOS, иразделение полей стало выглядеть так:

Чуть позже, когда назначение сети Интернет смести-лось в коммерческую область, да и многие другие вещистали замещаться денежными эквивалентами, в 1992 годук вопросу о маркировке пакетов вышло дополнение – RFC1349 (Type of Service in the Internet Protocol Suite), соглас-но которому у поля ToS был отобран последний бит, и онополучило следующую трактовку битов.

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

В 1993 году вышел RFC 1455, который предлагал ва-риант использования поля TOS (биты 3-6) для заданиягарантированного уровня безопасности соединений.

С появлением IP-телефонии и других сервисов, став-ших доступными в сети, в декабре 1998 года вышел RFC2474 (Definition of the Differentiated Services Field (DS Field)in the IPv4 and IPv6 Headers), согласно которому значениеполя ToS целиком должно быть заменено полем DS (fordifferentiated services). После чего значения поля ToS, от-меченного на рис. 1, приобрели следующие значения.

Cвято место пусто не бывает, через месяц, в январе1999-го, неиспользуемые два бита CU изменили своё на-звание на ECN и получили другое назначение, котороестал определять документ RFC 2481 (A Proposal to addExplicit Congestion Notification (ECN) to IP).

В сентябре 2001 вышел RFC 3168 (The Addition of ExplicitCongestion Notification (ECN) to IP), который был нацеленна то, чтобы внести стабильность в поле маркировки изакрепить сложившуюся ситуацию, обозначенную в уста-ревшем RFC 2481. Новая рекомендация заменила старыеRFC 2481 и RFC 2474 и внесла поправки в некоторые дру-гие документы.

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

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

Маркировка и подсчёт различных видовтрафика на практикеНасколько мне известно, провайдеров, использующих раз-дельную тарификацию, мало [2], а использующих марки-ровку – вообще один – ИМТЦ «МГУ». Помимо маркиров-ки существуют и другие способы решения проблемы раз-дельной тарификации. Например, упомянутая мной в [2]сеть gagarino.net, как было недавно выяснено, не исполь-зует маркировку трафика для абонентов, а используетсписки доступа [3]. При этом договорённость с вышестоя-щим провайдером у них близка по политике к провайдеруZenon N.S.P., когда не важно, как пришли пакеты, еслиони из сети, принадлежащей списку [3], то тогда они счи-таются российскими. Такая система разделения трафи-ка, с точки зрения конечных пользователей наиболее бла-гоприятна, конечно после полностью безлимитного Интер-нета. Даже не смотря на частичную безлимитность, поль-зователь, поставивший скачиваться десяток-другой филь-мов на ночь из российского сегмента сети, может спатьспокойно. Если вдруг на каких-то участках сети нарушит-ся связанность и пакеты начнут приходить из-за рубежа,то на тарификации это не отразится.

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

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

Например, если российскими из всего списка [3] будуттолько две сети 217.26.176.0/20 и 217.146.192.0/20, а вхо-дящим интерфейсом будет eth0, то вышесказанное наязыке iptables будет выглядеть так:

iptables -A PREROUTING -t mangle -i eth0 -j MARK --set-mark 6iptables -A PREROUTING -t mangle -i eth0 -s 217.26.176.0/20 ↵↵↵↵↵

-j MARK --set-mark 7

Ðèñóíîê 5. Ðàçäåëåíèå ïîëÿ DS (áûâø. ToS) íà áèòû ñîãëàñíî RFC 2474DSCP: differentiated services codepointCU: currently unused

Ðèñóíîê 3. Ðàçäåëåíèå ïîëÿ ToS íà áèòû ñîãëàñíî RFC 1122

Ðèñóíîê 4. Ðàçäåëåíèå ïîëÿ ToS íà áèòû ñîãëàñíî RFC 1349

Ðèñóíîê 6. Ðàçäåëåíèå ïîëÿ DS (áûâø. ToS) íà áèòû ñîãëàñíî RFC 2481

23№7(20), июль 2004

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

Естественно, цель MARK должна поддерживаться яд-ром.

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

а российского:

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

С финансовой точки зрения для провайдера даннаясхема не очень удобна, особенно если пользователей упровайдера тысячи. В этом случае лучше разграничитьответственность таким образом, чтобы проблемы нару-шения связанности каких-то участков сети переложить наплечи пользователей. А именно, провайдер не гарантиру-ет идентичность маршрутов доставки трафика от однихузлов к другим и не занимается вопросами минимизациистоимости. Если пакеты от некоторых российских узловпо каким-то причинам начинают приходить с зарубежно-го интерфейса и их стоимость значительно увеличивает-ся, то в этом случае затраты пользователей растут. Ми-нимизировать затраты один раз и навсегда невозможно.Пользователи, если желают экономить, должны сами ог-раничивать нежелательный трафик, выделяя его из об-щего числа косвенными способами, например, отслежи-вая маршруты движения пакетов с помощью traceroute,либо анализируя запоздавшую статистику уже пришед-ших пакетов. Такая схема используется некоторыми про-вайдерами, упомянутыми мной в [2]. Нельзя сказать, что-бы это было совсем нечестно по отношению к конечному

пользователю, тут есть своя логика. Несомненно, болееправильно при такой схеме дополнительно для удобствапользователей маркировать, например, зарубежный тра-фик. ИМТЦ «МГУ» маркирует трафик в поле Precedenceустановкой 1-го и 2-го битов (Flash)(ToS=0x60) [4].

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

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

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

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

При подсчёте внешне маркированного трафика с по-мощью iptables первое, что приходит в голову – это вос-пользоваться расширением dscp:

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

Например, если поле dscp будет содержать значение19 (биты 01 1001), то формально биты платности будут втаком пакете установлены, но считаться вышеустановлен-ным правилом он уже не будет. Получится, что для под-счёта всех возможных случаев потребуется 16 правил (ос-тавшихся битов 4, 24=16), что не очень-то и удобно, еслиучесть, что эти правила надо будет создавать на каждыйадрес. От того, чтобы не писать так много правил, можнозастраховаться. Например, перед проверкой дополнитель-но потребовать, чтобы пакеты, идущие на правило под-счёта, имели другие биты равными нулю.

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

iptables -A FORWARD -d 192.168.0.5 -m mark --mark 6

iptables -A FORWARD -d 192.168.0.5 -m mark --mark 7

tc filter add dev eth0 parent 1:0 prio 0 protocol ip ↵↵↵↵↵handle 6 fw flowid 1:6

tc filter add dev eth0 parent 1:0 prio 0 protocol ip ↵↵↵↵↵handle 7 fw flowid 1:7

iptables -A FORWARD -d 192.168.0.5 -m dscp --dscp 0x18

Ðèñóíîê 7. Ïîääåðæêà öåëè MARK â ÿäðå

iptables -A PREROUTING -t mangle -i eth0 -s 217.146.192.0/20 ↵↵↵↵↵-j MARK --set-mark 7

Ðèñóíîê 8. Ìàðêèðîâêà ïëàòíîãî òðàôèêà ÈÌÒÖ "ÌÃÓ" â ïîëå ToS

24

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

iptables -N user-chainiptables -A FORWARD -d 192.168.0.5 -m tos ↵↵↵↵↵

--tos Normal-Service -j user-chainiptables -A FORWARD -d 192.168.0.5 -m dscp --dscp 0x18

iptables -t mangle -A PREROUTING -j TOS --set-tos 0iptables -t mangle -A FORWARD -j TOS --set-tos 0

iptables -A FORWARD -d 192.168.0.5 -m dscp --dscp 0x18

Однако толку от таких конструкций не будет, так какпакеты с ToS, не равным нулю, и так бы не посчиталисьпоследним правилом. Чтобы в правилах, описанных вышепоявился смысл, их надо изменить таким образом, чтобыво всех приходящих пакетах насильно в поле ToS выстав-лялось нулевое значение (Normal-service). Например, так:

Тогда подсчитывающему правилу:

не понадобятся никакие другие усложняющие конструк-ции. Этот метод прост и хорош, и, возможно, даже не по-требует перекомпиляции ядра, так как большинство ядер,по умолчанию поставляемых с системами, уже знает происпользуемые нами модули и осуществляет их поддерж-ку. (Для тех, кто будет компилировать ядро самостоятель-но, поддержку DSCP и TOS следует включить, см. рис. 7.)Но в то же время такой способ решения проблемы неуда-чен, потому что требует очень больших ресурсов. Еслипользователь Вася настраивает правила у себя на домаш-нем компьютере, то скорее всего, как бы он ни старался,у него не получится более 100 правил. Его система заве-домо справится со всеми пакетами без потерь и задер-жек. Но если речь идёт о маршрутизации на уровне не-большого или среднего провайдера, то все ресурсы насчету. Правил может быть больше тысячи, к тому же насервере могут работать другие задачи. Если в каждомпакете придётся менять какие-то биты, обнулять что-то вполе ToS, то непременно придётся у всех этих пакетовпересчитывать контрольную сумму, что может значитель-но загрузить систему.

Поэтому лучше и красивее использовать другой спо-соб подсчёта. Наложить на ядро патч u32 [6, 7] от patch-o-matic, написанный Don Cohen ([email protected]).

Для этого, как обычно, скачиваем последние версииядра (http://www.ru.kernel.org/pub/linux/kernel/v2.4/linux-2.4.26.tar.gz), patch-o-matic (http://www.iptables.org/files/patch-o-matic-ng-20040302.tar.bz2) и заодно iptables (http://www.iptables.org/files/iptables-1.2.9.tar.bz2). Затем, распа-ковав исходники, следует наложить на них патч.

Особенность patch-o-matic состоит в том, что предла-гаемые патчи, хотя и были написаны отнюдь не дурака-ми, всё же могут содержать неумышленные ошибки. Так-же никто не гарантирует совместимость всех патчей меж-ду собой. Поэтому, чтобы лишний раз не понижать надёж-ность системы, следует устанавливать только те патчи,которые вам реально необходимы. В нашем случае этоu32. Наложение патча несколько отличается от обычногосинтаксиса команды patch, поэтому об этом чуть подроб-нее. Прочитав прилагающийся файл README, можно уз-нать, что следует запустить файл runme с ключом extra.Затем программа проверит значения переменных окру-

жения, в которых указано местонахождение исходниковядра и iptables. Если они окажутся пустыми, то нам будутзаданы соответствующие вопросы. После ответа на нихвам будут предлагаться на выбор различные патчи с ихкратким описанием и примерами. Следует выбирать «n»до тех пор, пока у вас на экране не появится запрос наустановку u32.

После этого выбираем «t» (test), и в случае успешноготестирования устанавливаем патч выбором «y». Далеепоявится предложение установить следующий патч и т. д.Чтобы не выбирать много раз «n», можно сразу выйти спомощью «q» (quit). По окончании вы увидите сообщениео том, что исходники готовы к компиляции.

Далее следует выполнить конфигурацию и компиля-цию ядра и модулей обычным образом. Следует обратитьвнимание, что после наложения патча в разделе Networkingoptions IP: Netfilter Configuration должен появиться пукт«U32 match support», который следует выбрать.

После установки нового ядра, а также компиляции иинсталляции iptables, можно приступать к написанию пра-вил с использованием нового фильтра u32. К сожалению,

Ðèñóíîê 9. Ïðèãëàøåíèå, ïðåäëàãàþùåå óñòàíîâèòü ïàò÷ u32

Ðèñóíîê 10. Ñîîáùåíèå: èñõîäíèêè ãîòîâû ê êîìïèëÿöèè

Ðèñóíîê 11. Ïóíêò U32 match support

25№7(20), июль 2004

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

документация, подготовленная автором модуля (DonCohen) и поставляемая в комплекте очень слаба, поэтомулучше воспользоваться руководством, написанным WilliamSteams [7].

Краткий формат написания правил для u32 таков:

где Start – это то, что будет сравниваться, Mask – маскатех битов, которые будут сравниваться, Range – сравни-ваемое значение, если оно совпадёт с тем что будет в па-кете, то правило «сработает».

Из-за особенностей реализации u32 в Start указывает-ся не абсолютное значение байта в пакете, начиная с нуле-вого, а относительное, смещённое на -3 байта от его ре-ального месторасположения. Например, если вы хотитефильтровать пакеты с TTL<4, то глядя на рис. 1, вы опреде-ляете, что полю TTL в заголовке соответствует 8-й байтпакета (вначале пакета идёт заголовок). После чего можноподсчитать (8-3=5), что в поле Start следует указать число5. Для сравнения следует учитывать все биты, поэтому ис-пользуемая маска будет 1111 1111 (0xFF). Значения мень-ше 4 – это те, что принадлежат отрезку значений [0, 3].Полученное таким образом правило будет выглядеть так:

при этом оно будет аналогично правилу:

Так как переменная Start не может быть меньше 0, тополучить вышеописанным образом доступ к первым трёмбайтам не получится. Для доступа к ним используется бо-лее сложная конструкция со сдвигом. Подробнее об этомможно прочитать в [7]. Так как маркируемые биты нахо-дятся во втором байте заголовка (2-3=-1), то простым об-разом обратиться к ним не получится. КонструкцияStart&Mask позволяет считать первые 4 байта сразу безсдвига с помощью «0&0xFFFFFFFF», конструкция, считы-вающая второй по счёту (первый по нумерации, начинаяс нуля) байт выглядит так «0&0x00FF0000». Фактическиэто то, что нам нужно. Уже сейчас можно написать аналогприменяемого нами ранее правила:

который будет выглядеть так:

Это правило полностью аналогично, то есть оно содер-жит все те недостатки, что были обсуждены ранее. Однакотеперь их можно исправить, используя для сравнения не всебиты, а только те, которые нас интересуют 0110000 (0x60).

Такая конструкция полностью делает всё от неё ожи-

iptables ... -m u32 --u32 "Start&Mask=Range"

iptables ... -m u32 --u32 "5&0xFF=0:3"

iptables ... -m ttl --ttl-lt 4

iptables -A FORWARD -d 192.168.0.5 -m dscp --dscp 0x18

iptables -A FORWARD -m u32 --u32 "0&0x00FF0000=0x00600000" ↵↵↵↵↵-d 192.168.0.5

iptables -A FORWARD -m u32 --u32 "0&0x00600000=0x00600000" ↵↵↵↵↵-d 192.168.0.5

iptables -A FORWARD -m u32 --u32 "0&0x00600000>>16=0x60" ↵↵↵↵↵-d 192.168.0.5

даемое, хотя и не очень удобна в том плане, что сравни-ваемое значение приходится окружать большим количе-ством нулей. Куда разумнее оба сравниваемых значениясдвинуть на 2 байта (16 бит) вправо, тогда лишних нулейможно будет избежать, при этом правило для iptables бо-лее элегантно можно будет записать так:

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

Замечание 1. Вадимом Беркгаутом было обнаружено,что маршрутизаторы Cisco (в частности 7206) помечают невсе пакеты в поле DSCP. Почему-то не помечаются пакетыс установленными флагами SYN или FIN и иногда некото-рые пакеты, идущие перед последним. Также не всегда по-мечаются и ICMP-пакеты. Если на счёт SYN- и FIN-пакетовесть некоторые соображения, то по поводу случайной немаркировки некоторых ICMP-пакетов сделать выводы слож-но. В частности, есть предположение, что существуют теили иные RFC, которые рекомендуют так поступать. Напри-мер, RFC 2873 (TCP Processing of the IPv4 Precedence Field),указывающий, что во время установки соединения полеprecedence должно игнорироваться обеими сторонами. Этозначит, что Cisco может думать так: «а зачем маркироватьпакеты, если поле всё равно игнорируется». Возможно, чтоэто особенности конкретного экземпляра, если кто-то изчитателей знает, почему так происходит и как ведут себядругие маршрутизаторы, буду рад услышать ваше мнение.

Замечание 2. Если поле ToS (DSСP+ECN по современ-ной трактовке) никак не используется в сети и не обнуля-ется на межсетевом экране, а при этом есть возможностьсвободному выходу определённых пакетов из сети (в сеть),то создаётся хорошая лазейка для скрытной передачи ин-формации. Много передать по такому каналу не получит-ся, но можно без особых усилий отправлять небольшиесообщения, не привлекая к происходящему процессу вни-мания.

Спасибо Павлу Янченко за ответы на некоторые моивопросы по теме данной статьи.

Литература, ссылки:1. Список документов RFC: http://www.rfc-editor.org/rfc-

index.html2. Закляков П. Пиринг. – Журнал «Системный админист-

ратор» №6(19), июнь 2003 г. – 82-87 с.3. IP-адреса Российских сетей по данным gagariono.net:

http://www.gagarino.net/ips.txt4. ИМТЦ «МГУ» тарифы и маркировка трафика: http://

www.direct.ru/internet/index_line.html5. Classifying packets with filters: http://www.tldp.org/

HOWTO/Adv-Routing-HOWTO/lartc.qdisc.filters.html6. Расширение u32 для iptables: http://www.iptables.org/

patch-o-matic/pom-base.html#pom-base-u327. William Steams IPTables U32 Match Tutorial: http://

www.sans.org/rr/special/iptables_u32.pdf8. Страница со ссылками для скачивания iptables и patch-

o-matic: http://www.iptables.org/downloads.html9. Сайт проекта sing: http://sourceforge.net/projects/sing

26

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

Все примеры в данной статье приведены для FreeBSD 5.2и PostgreSQL 7.4.2, однако в принципиальном отношениивсе изложенное остается верным и для других актуаль-ных сегодня операционных систем и версий. Статья но-сит обзорный характер и предназначена прежде всего ад-министраторам, желающим познакомиться с этой СУБДи оценить ее возможности для решения тех или иных за-дач. Предполагается, что читатель знаком с такими ве-щами, как реляционная база данных, СУБД, а также с ба-зовыми понятиями и операторами языка SQL.

PostgreSQL – это объектно-реляционная система уп-равления базами данных, работающая как клиент-сервер-ная система. Основываясь на базовых понятиях реляци-онных БД, PostgreSQL поддерживает и ряд «объектных»операций, например наследование. PostgreSQL соответ-ствует базовой спецификации SQL99 и поддерживает боль-шое число возможностей, описанных стандартом SQL92.

Может возникнуть вопрос – почему именно PostgreSQL?Лучше всего ответить на него, сравнив этот продукт с неменее популярным и, пожалуй, более известным – MySQL.Моей целью не является доказательство, что один из нихлучше другого – это несколько разные продукты, областиприменения которых во многом пересекаются, но отнюдьне совпадают, и сравнением я хочу определить нишу

PostgreSQL: первые шаги

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

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

PostgreSQL, те категории задач, для которых эта СУБДболее эффективна.

Прежде всего следует отметить различия в организа-ции данных. Если в MySQL каждая таблица заносится всобственный файл (для большинства типов БД), то PostgreSQL организует единую файловую структуру, в которойотдельные файлы не соответствуют непосредственно таб-лицам или другим объектам базы данных. То есть в MySQLвы можете создать резервную копию лишь части БД, со-хранив соответствующие файлы. Для PostgreSQL такойномер пройдет только для всей структуры, включающей всебя все обслуживаемые сервером БД базы. Как след-ствие – MySQL полагается при организации БД на файло-вую систему ОС, в то время как PostgreSQL зависит от нееменьше, но требует дополнительного обслуживания – пе-риодической дефрагментации базы данных командойVACUUM.

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

27№7(20), июль 2004

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

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

Типовая установкаДля установки PostgreSQL во FreeBSD лучше всего вос-пользоваться системой портов (/usr/ports/databases/postgresql7 или другая актуальная версия). Однако в дан-ном случае установка по умолчанию, скорее всего, васне устроит, поскольку в ней отсутствует поддержка рас-ширенных кодировок, а следовательно, операции сорти-ровки данных, хранимых в кириллической кодировке (на-пример, KOI8-r), будут работать неправильно.

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

Параметр --enable-locale необходим для поддержкиспецифических для страны настроек (так называемой ло-кали), --enable-recode включает поддержку перекодиров-ки (данный параметр для описываемого варианта, в кото-ром везде используется только KOI8-r, необязателен, нозачастую может быть весьма полезен). Параметр --enable-multibyte собственно и включает поддержку кодировкиKOI8-r. Если вы предпочитаете работать с другой кодо-вой таблицей, укажите ее в качестве аргумента. Параметр,заданный без аргумента, включит поддержку всех муль-тибайтовых кодировок.

Таким же образом вы можете добавить другие нуж-ные вам опции или изменить поведение СУБД по умолча-нию. Например, изменить номер порта, которыйPostgreSQL будет прослушивать в ожидании запросов,можно с помощью параметра --with-pgport=NUM (по умол-чанию – 5432). А ключ --with-perl позволит в дальнейшемиспользовать процедурный язык PL/Perl для разработкихранимых процедур в дополнение к PL/pgSQL. Для полу-чения информации по всем ключам запустите configure --help.

После того как в Makefile внесены все нужные парамет-ры конфигурации, установка выполняется как обычно:

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

И затем, убедившись в успешности тестирования, вы-полнить установку:

Существуют также различия в реализации некоторыхSQL-функций (PostgreSQL лучше соответствует стандар-там), в наборе типов данных и т. д. Как видно из таблицы,разработчики MySQL делают акцент на наилучшую ско-рость чтения (выборки) данных, чем и объясняется попу-лярность этой СУБД в среде веб-разработчиков, где вы-борка – основная операция. Достигается это отсутствиемтранзакций (они реализованы только для некоторых ти-пов таблиц, например InnoDB, BerkleyDB) и многопоточ-ной работой, однако это же и является причиной несколь-ко меньшей надежности данной СУБД. В плане прав дос-тупа MySQL несколько превосходит PostgreSQL, позволяязадавать права доступа не только на уровне таблицы, нои на уровне столбца, однако в PostgreSQL это с лихвойкомпенсируется возможностью создавать пользователь-ские представления («view»).

Наиболее острый вопрос, вызывающий нескончаемыеспоры, – сравнение скоростных характеристик этих двухпакетов. Результаты тестов, доступные в Интернете, весь-ма противоречивы, что говорит об отсутствии явного ли-дерства той или иной СУБД. Кроме того, результаты бу-дут сильно зависеть от конкретной реализации теста, пре-обладания тех или иных операций и нагрузки на систему.В одних случаях первенство будет за MySQL, в других –за PostgreSQL.

Также PostgreSQL часто сравнивают с коммерческойСУБД Oracle. Oracle несколько превосходит PostgreSQL втаких вопросах, как использование индексов, репликацияи восстановление данных, да и вообще инструменты ад-министрирования Oracle более развиты (но вместе с теми более сложны). С другой стороны, PostgreSQL предос-тавляет возможность использовать в качестве процедур-ного языка помимо PL/pgSQL (очень схожего с PL/SQL,используемым в Oralce) также PL/Perl, PL/Python, PL/Tcl,что позволяет разработчику выбрать более привычныйинструмент.

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

CONFIGURE_ARGS+= --enable-locale --enable-multibyte=KOI8 ↵↵↵↵↵--enable-recode

# make && make install

# make �DWITH_TESTS

# make install

28

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

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

Ну и любителям прекомпилированных RPM-пакетов нуж-но будет найти пакет, собранный с требуемыми опциями.

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

Обратите внимание, что инициализацию БД нужно вы-полнять с правами того пользователя, от имени которогопроцесс будет в дальнейшем запускаться, и это не дол-жен быть root. Если вы ставили PostgreSQL из коллекциипортов, то для этих целей автоматически будет созданпользователь pgsql, чье имя мы и указываем в командеsu как аргумент ключа –l. Если же вы собирали системусамостоятельно, то этого пользователя вам придется со-здать вручную и позаботиться о правах доступа к нужнымисполнимым файлам, библиотекам и каталогам данных.

Обратите внимание на ключ –E команды initdb. Он по-зволяет задать кодировку по умолчанию, с которой будетсоздана база данных. Поддержка указываемой как аргу-мент кодировки должна быть включена во время сборкипакета.

В процессе инициализации в папке /usr/local/pgsql бу-дет создан каталог data со структурами двух БД – template0и template1. Изменить путь к БД можно с помощью ключа–D команды initdb:

По умолчанию для FreeBSD установка исполнимыхфайлов происходит в папку /usr/local/bin. Если вы измени-ли это и новый путь не включен в переменную PATH, топотребуется указать полный путь к файлу initdb.

По окончании инициализации вам будет предложенодва способа запуска процесса postmaster, который явля-ется сервером СУБД:

или

В первом случае запускается непосредственно процессpostmaster. Причем он будет выполняться в интерактив-ном режиме, то есть все его сообщения будут выдаватьсяна терминал запустившего его пользователя. Прерыва-ние процесса приведет к остановке сервера СУБД (подсервером здесь понимается процесс postmaster, а не самкомпьютер).

Такой режим работы может быть удобен на стадии от-

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

В обоих вариантах ключ –D позволяет задать каталог,в котором хранятся данные. Каталог должен быть иници-ализирован командой initdb, как описывалось ранее. Впринципе ничто не мешает инициализировать несколькокаталогов данных и запустить одновременно несколькопроцессов postmaster (при этом также нужно позаботить-ся о том, чтобы каждый из них прослушивал свой порт).Один процесс может одновременно обслуживать толькоодин каталог данных.

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

Если вы получили приветствие Интерактивного Терми-нала PostgreSQL, значит, БД проинициализировалась исервер запущен правильно. А если это сообщение еще ина русском языке, то вообще замечательно. Если же нет,то убедитесь, что переменная окружения LANG соответ-ствует выбранной кодировке:

В случае возникновения проблем проанализируйтеполученные сообщения об ошибках, поступающие на эк-ран и в журнальные файлы (в зависимости от характераошибки это могут быть файлы /var/log/pgsql, /var/log/messages и т. п.). Убедитесь, что вы запускаете PostgreSQLот имени созданного ранее пользователя pgsql (впрочем,имя может быть иным, например postgres). Запустите про-цесс postmaster в интерактивном режиме, как было опи-сано выше. Если анализ диагностических сообщений непозволяет выявить источник проблем, может помочь воз-врат на стадию инсталляции и выполнение регрессион-ных тестов.

Итак, мы подключились к БД, интерактивный клиентобщается с нами на нашем родном (или, по крайней мере,на очень знакомом) языке. Еще одна вещь, которую же-лательно дополнительно проверить, – кодировка, с кото-рой БД была инициализирована. Для этого в терминалевыполните команду \l, которая выводит список всех БД:

./configure --enable-locale --enable-multibyte=KOI8 ↵↵↵↵↵--enable-recode .

# su �l pgsql �c �initdb �E KOI8�

# su �l pgsql �c �initdb �E KOI8 �D /var/databases/postgres/data�

$ /usr/local/bin/postmaster �D /usr/local/pgsql/data

$ /usr/local/bin/pg_ctl �D /usr/local/pgsql/data �l logfile start

$ psql �U pgsql template1

29№7(20), июль 2004

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

Поскольку у нас все работает, как и ожидалось, тотеперь можно позаботиться об автоматической загрузкесервера PostgreSQL при старте системы. Если вы стави-ли СУБД из коллекции портов, то беспокоиться вам не очем – в папке /usr/local/etc/rc.d уже есть файл 010.pgsql.sh,который и будет отвечать за запуск и останов сервераСУБД. Если же установка выполнялась вручную, то вамнужно будет перенести в соответствующий каталог (/etc/rc.d, /usr/local/etc/rc.d) сценарий автозапуска, соответ-ствующий вашей операционной системе, из подкатало-га contrib/start-scripts той папки, куда был распакован ди-стрибутив.

Что еще важно иметь в виду: пользователь pgsql явля-ется администратором СУБД, то есть его полномочия поотношению к базам PostgreSQL практически ничем неограничены.

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

Для выполнения этих операций, как и всех остальных,будем использовать терминал psql:

Теперь у нас есть база данных, с которой в дальней-шем и будем экспериментировать. Обратите внимание,что нового пользователя мы создавали с опциямиnocreatedb и nocreateuser, то есть он не будет иметь правна создание баз и пользователей. В дальнейшем следуетподключаться под этим пользователем к вновь созданнойбазе test:

Чтобы не указывать имя пользователя и базу каж-дый раз при вызове терминала, вместо базы test и поль-зователя test создайте базу и пользователя с именем,совпадающим с вашим системным именем. В этом слу-чае запуск клиента можно осуществлять просто коман-дой psql.

Хотя это и достаточно очевидно, все же следует ука-зать, что пользователи СУБД и системные пользовате-ли – не одно и то же.

Наверняка вас удивило, что при подключении к БД неуказывается пароль. Действительно, настройка PostgreSQLпо умолчанию позволяет пользователям подключаться с

хоста localhost без ввода пароля, поскольку этот хост оп-ределен как доверенный (trust). Если вы – единственныйпользователь, имеющий терминальный доступ к серверу(например, PostgreSQL установлена на вашей машине дляизучения), то это можно не менять. Но поскольку никогданельзя быть уверенным, что злоумышленник не получитдоступ к командной оболочке, то лучше не пренебрегатьдополнительной защитой.

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

Пример простой базы данных(основам SQL посвящается…)Решим простейшую задачу: создадим телефонныйсправочник, который технически будет реализован какодна таблица с тремя полями (ФИО, должность, теле-фон). Вся работа будет показана как листинг одногосеанса.

Создаем таблицу с полями person, post и phone:

Просмотр списка таблиц в базе:

Просмотр структуры таблицы:

Добавляем запись:

Смотрим, что получилось:

Добавляем еще одну запись. Как видно, после именитаблицы не обязательно перечислять заполняемые поля.В этом случае поля будут заполняться значениями по по-рядку:

$ psql �U test test

30

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

Команда \h позволяет получить подсказку по любойSQL-команде:

Так можно просмотреть все команды интерактивной обо-лочки (здесь приведены наиболее часто используемые):

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

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

Удалим одну из записей. Отсутствие предложения whereочистит всю таблицу:

Наигравшись, удаляем таблицу phbook.

Выходим:

Вот так мы познакомились с интерактивным термина-лом и убедились, что с PostgreSQL вполне можно общать-ся на языке SQL. Обратите внимание на синтаксис при-глашения. Оно состоит из имени базы данных (в нашемслучае – test). Далее следует символ «=», если редакти-руется новая строка; «--», если продолжается ввод коман-ды, начатый на предыдущей строке; или «(», если продол-жается ввод и в предложении имеется незакрытая скоб-ка. Завершает приглашение символ «#», если текущийпользователь является владельцем подключенной БД, или«>» в противном случае. Каждая вводимая SQL-командадолжна завершаться точкой с запятой. Для команд тер-минала это не требуется.

Специфика PostgreSQLТеперь более подробно рассмотрим конкретные особен-ности PostgreSQL. Было бы жестоко пытаться втиснутьвесь материал в одну журнальную статью, поэтому этотраздел будет носить скорее обзорный характер. А наибо-лее интересным особенностям постараюсь посвятить не-сколько отдельных статей.

Сперва – о типах данных. Помимо стандартных, соответ-ствующих SLQ99 и SQL92 (numeric, char, varchar, bool и т. д.),поддерживается и ряд специфических, например, геомет-рические типы данных (point, line, box, circle, polygon), сете-вые типы (cidr – спецификация сети IP, inet – IP-адрес,macaddr – MAC-адрес) и т. д. Конечно, дополнительные типыданных не являются незаменимыми, но в ряде случаев су-щественно упрощают логику и структуру базы. Например,геометрические типы могут оказаться весьма полезнымипри разработке картографических приложений.

Особо следует отметить специальный тип данных serial.Он описывает поле типа integer, значения которого зада-ются автоматически создаваемой последовательностью(см. далее) и так же автоматически индексируются. То естьэто, по сути, аналог ограничения AUTO_INCREMENT вMySQL.

Будучи объектно-реляционной СУБД, PostgreSQL под-держивает и составные типы данных – массивы. Чтобыопределить поле как массив, его тип дополняется паройквадратных скобок (например, «char(10)[]»). Массив (какконстанта) записывается с помощью фигурных скобок:«’{1,2,3}’», «’{“один”, “два”, “три”, “четыре”}’». Обращениек элементу массива, как и в других языках программиро-вания, выполняется по индексу: arra[2].

Пример:

31№7(20), июль 2004

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

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

Теперь про обещанные ранее последовательности.Последовательность (sequence) представляет собой счет-чик, то есть автоматически увеличивающееся целое чис-ло. При вызове специальной функции nextval(‘seq_name’),где seq_name – имя последовательности, значение пос-ледовательности увеличивается на шаг, заданный при еесоздании (по умолчанию – 1), и возвращается получен-ное значение. Прочитать это значение еще раз без увели-чения последовательности можно с помощью функцииcurrval(‘seq_name’). Следующий листинг демонстрируетосновные принципы работы с последовательностью:

PostgreSQL имеет довольно развитые возможности ра-боты с индексами. Создаются они командой CREATE INDEX,синтаксис которой можно посмотреть в терминале коман-дой «\h create index». В ряде случаев индексы создаютсяавтоматически (например, для полей с ограничениемPRIMARY KEY). Созданные пользователем индексы мож-но просмотреть командой \di. Поддерживается три типаиндексов: B-tree (по умолчанию), R-tree и хэш. В большин-стве случаев следует использовать B-деревья, хотя иног-да (например, при операциях с геометрическими типамиданных) R-tree-индекс может показать лучшие результа-ты. В любом случае выбор остается за пользователем.

Модифицировать таблицы можно с помощью коман-ды ALTER TABLE. Однако нужно заметить, что она не по-зволяет удалять столбцы или менять их тип, что связано сособенностями организации базы данных. В большинствеслучаев достаточно переименовать ненужный столбец вочто-нибудь типа «deleted» и забыть про него. Если же оченьхочется удалить его физически, то воспользуйтесь коман-дой CREATE TABLE AS, которая создаст новую таблицуна базе существующей (или даже нескольких, посколькуисточником данных может быть любой запрос). Крометого, всегда можно воспользоваться «универсальным ал-горитмом»:! CREATE TABLE newtable .. – создаем новую таблицу с

нужной структурой;! INSERT INTO newtable SELECT .. FROM oldtable – встав-

ляем в новую таблицу нужные поля записей из старой;! DROP TABLE oldtable – удаляем старую таблицу;! ALTER TABLE newtable RENAME TO oldtable – переиме-

новываем новую.

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

32

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

чу: требуется БД для учета имеющихся на предприятиикомпьютеров (IP-адрес машины, место установки, опера-ционная система), при этом для серверов дополнительнотребуется указать работающие на них службы (WWW, FTP,DNS и т. д.). В классической реляционной СУБД это ре-шалось бы созданием отдельной таблицы для храненияинформации по службам и привязкой ее к таблице ма-шин по IP либо по дополнительному полю-идентификато-ру. Объектные возможности PostgreSQL позволяют ре-шить указанную задачу следующим образом:

Создаем родительскую таблицу (как обычно):

Добавляем в нее запись для рабочей станции (все опе-рации – обычные):

Создаем дочернюю таблицу (предложение inherits суказанием родительских таблиц):

Хотя таблица servers создавалась с одним полем, тридругих она унаследовала от родительской:

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

В дочерней – только те, которые заносились непосред-ственно в нее:

Ключевое слово ONLY позволяет выбрать записи изродительской таблицы без учета содержимого дочерней:

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

ко со всеми производными (указав ключевое словоCASCADE в команде DROP TABLE).

PostgreSQL позволяет создавать собственные функции,которые сохраняются в базе данных и могут быть исполь-зованы при модификации полей записи, в операциях вы-борки по условию, как триггеры, и т. д. Разработчику, по-мимо процедурного языка PL/pgSQL (являющегося ана-логом PL/SQL в СУБД Oracle), доступны PL/Perl, PL/Pythonи др. Для этого PostgreSQL должна собираться с соответ-ствующими опциями.

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

Следующая особенность СУБД – возможность созда-вать представления пользователя (view), которые пред-ставляют собой результаты выборки (запроса), доступныедля непосредственного обращения к ним в будущем безпересылки повторных запросов. Помимо упрощения ло-гики работы с БД (когда вместо сложных запросов к не-скольким таблицам можно отправить весьма простой зап-рос к представлению пользователя), эта возможность по-зволяет гибко управлять доступностью данных для раз-личных пользователей. Например, если в БД есть табли-ца, содержащая имена и пароли клиентов, но оператордолжен получить доступ только к именам, то достаточносоздать представление, в которое выбрать поле «Имя», идать оператору доступ к нему, а возможность чтения са-мой таблицы исключить.

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

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

33№7(20), июль 2004

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

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

Вопросы администрированияВ начале статьи упоминалось, что локальные пользовате-ли компьютера, на котором запущен сервер postmaster,могут подключаться к БД под именем любого пользова-теля без указания пароля. Связано это с тем, что хостlocalhost по умолчанию является доверенным. Изменитьэто можно в файле pg_hba.conf, находящемся в каталогеdata, инициированном командой initdb.

Синтаксис этого файла хорошо прокомментирован внем самом. Поле TYPE содержит тип записи, которыйможет быть одним из следующих: local (соединение, уста-навливаемое с того же компьютера, на котором работаетсервер СУБД; использует сокеты UNIX), host (соединениеTCP/IP) или hostssl (защищенное соединение TCP/IP сиспользованием протокола SSL).

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

роля;! reject – отклонить соединение;! password – требовать соответствия пароля (передает-

ся в открытом виде);! crypt – требовать соответствия пароля (пароль шиф-

руется);! krb4, krb5 – аутентификация Kerberos;! ident – аутентификация по карте соответствия имени

пользователя PostgreSQL системному имени пользо-вателя. Карты соответствия содержатся в файлеpg_ident.conf.

Назначение остальных полей файла pg_hba.conf пояс-нений, думаю, не требует. При запросе соединения про-верка условий выполняется с начала файла до обнаруже-ния соответствия, после чего выполняется действие, за-данное полем METHOD. Если соответствие не будет най-дено, соединение не будет установлено. Следует заме-тить, что после внесения изменений в этот файл требует-ся перезапустить процесс postmaster, послав ему сигналSIGHUP, либо перезагрузить сервер СУБД командой:

Чтобы сервер мог обслуживать подключения по прото-колу TCP/IP, процесс postmaster должен быть запущен сключом –i. Для SSL-соединений также требуется ключ –l,и, кроме того, СУБД должна быть собрана с поддержкойSSL (ключ --with-openssl).

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

Некоторого пояснения требуют команды назначения иотмены привилегий (GRANT и REVOKE). Команда GRANTпозволяет давать пользователю или группе следующиеправа (перечислены только основные):

Аналогично, команда REVOKE ограничивает соответ-ствующие права. В качестве объекта, для работы с кото-рым назначаются права, могут выступать таблицы, пред-ставления пользователя и последовательности. Посмот-реть назначенные привилегии доступа позволяет коман-да терминала \z.

При необходимости программного доступа к инфор-мации о пользователях и привилегиях весьма полезныслужебные таблицы pg_shadow (таблица пользователей)и pg_class (права доступа к объектам БД).

Для тех, кто клавиатуре предпочитает мышь, разрабо-тан пакет phpPgAdmin (аналог phpMyAdmin для MySQL),позволяющий работать с СУБД через веб-интерфейс. ДляFreeBSD найти его можно в коллекции портов: /usr/ports/databases/phppgadmin.

Также существует мультиплатформенная графическаяоболочка pgAdmin (www.pgadmin.org/pgadmin3), обеспечи-вающая доступ ко всем функциям администрирования иразработки.

ЗаключениеИтак, были рассмотрены основные особенности СУБДPostgreSQL. Описание получилось несколько расплывча-тым и отрывочным, но надеюсь, эта статья все же позво-лит вам оценить возможности этой системы управлениябазами данных и принять принципиальное решение о ееиспользовании (или неиспользовании) для решения сто-ящих перед вами задач.

Дополнительная информация:! Страницы справочного руководства man (см. каталог

/usr/local/pgsql/man/man1 (программы «обвязки») иman7 (справки по командам SQL));

! Встроенная справка интерактивного терминала (\h –справочник по SQL-командам, \? – справочник по ко-мандам терминала);

! Официальный сайт проекта – www.postgresql.org, одиниз русскоязычных сайтов – www.linuxshare.ru/docs/software/SQL/postgresql)

# pg_ctl reload

34

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

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

Webmin (http://www.webmin.com) представляет собойвеб-интерфейс для системного администрирования UNIX,использование которого существенно упрощает процессуправления системой. Кроме того, он будет полезен дляудаленного управления системой тем администраторам,

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

УПРОЩАЕМ СЕБЕ ЖИЗНЬ С WEBMIN

у которых нет в данный момент доступа к компьютеру сустановленной UNIX-подобной системой, а стандартныесетевые средства Windows не блещут особым выборомнеобходимых утилит. В этом случае, используя любой веб-браузер, поддерживающий таблицы и формы (и JAVA длянекоторых модулей), можно без затруднений в нагляднойформе с локального или удаленного компьютера настро-ить пользовательские аккаунты, установить/удалить про-граммы, настроить Web, mail, DNS-сервер, сервер печа-ти, управлять базами данных, организовать совместноеиспользование файлов, применяя Samba или NFS, настро-ить firewall, синхронизировать время, организовать совме-стный доступ в Интернет, мониторинг состояния серви-сов, осуществить резервное копирование, записать CD-диск, получить доступ к файлам на удаленном компьюте-ре, в том числе документации и прочие бесчисленные за-дачи администрирования, коих не счесть, но требующихопределенных умений. При этом Webmin избавит вас отсинтаксических ошибок и неточностей, как сможет пре-дупредит о потенциально опасных действиях. Но это, прав-

35№7(20), июль 2004

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

Еще один момент. Для возможности работы по защи-щенному каналу (а из внешней сети работать нужно толь-ко так, да и во внутренней не будет лишней подстраховка)требуется наличие модуля Net::SSLeay и OpenSSL (http://www.openssl.org/). Поэтому при появлении сообщения

загрузите модуль с CPAN и повторите установку, за до-полнительной информацией обращайтесь по адресу: http://www.webmin.com/ssl.html. Иначе в строке веб-браузеранабирайте http вместо https. Кстати, удалить Webmin так-же просто. Запускаем скрипт /etc/webmin/uninstall.sh, и егокак не бывало. Дальнейшую настройку можно произво-дить уже через Webmin. Но, например, если вы забылипароль, то локально его изменить можно при помощискрипта changepass.pl.

Также изменить некоторые настройки можно, напря-мую редактируя конфигурационные файлы miniserv.confи config, которые лежат в каталоге с Webmin. В них воз-можно изменить значение сетевого порта, включить/вык-лючить SSL (опция ssl=0/1), изменить месторасположениерабочих файлов, установить другой язык интерфейса (длярусского значение lang должно быть ru_RU (для кодиров-ки СР-1251) или ru_SU (koi8-r)). Если планируете часто за-ходить с компьютеров, где установлена ОС Windows, вы-берите лучше вариант с СР-1251, тогда будете реже пе-ренастраивать кодировку в браузере. После измененийперезапустите webmin.

Но все настройки, повторяю, теперь доступны через веб-браузер. Набираем в строке браузера https://hostname:10000,авторизируемся (рис. 1):

После чего попадаем в главное окно программы (рис. 2).

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

Написанный Джейми Камероном (Jamie Cameron) наязыке Perl, Webmin имеет модульную структуру, позво-ляющую свободно наращивать требуемую функциональ-ность или, наоборот, убрать все ненужное. В настоящеевремя доступно около 200 модулей как входящих в стан-дартную поставку, так и доступных для загрузки отдель-но. Дополнительно ко всему интерфейс переведен на 32языка, среди которых имеется и русский. На страницеhttp://www.webmin.com/support.html найдете список из 35UNIX-подобных операционных систем (в том числе иCygwin, Mac OS X), на которых Webmin без проблем бу-дет работать. Если вашего дистрибутива в нем нет, тоотчаиваться не стоит, скорее всего, Webmin удастся зас-тавить работать без трудностей. При этом одним из ос-новных преимуществ Webmin является то, что он факти-чески подстраивается, в том числе изменяя свой интер-фейс и поведение в соответствии с используемой ОС,т.е. фактически скрывает от конечного пользователя раз-личия между всеми вариантами UNIX. Еще одним преиму-ществом Webmin является возможность делегироватьчасть полномочий по настройке определенных сервисовдругим пользователям. Установить Webmin проще просто-го: скачиваем архив размером чуть меньше 7 Мб (доступ-ны и прекомпилированные пакеты), распаковываем его,заходим внутрь и даем команду ./setup с указанием ка-талога, в котором вы хотите видеть установленныйWebmin. По умолчанию установка будет произведена втекущий каталог. После чего необходимо будет ответитьна ряд вопросов о будущем размещении конфигураци-онных файлов, нахождении интерпретатора Perl, номе-ре порта, на котором Webmin будет ожидать соединения(по умолчанию 10000), логин и пароль для доступа, ав-томатический запуск при старте системы.

В большинстве случаев можно со всем соглашаться инажимать Enter. Если программа установки что-либо самане найдет, то тогда в другой консоли при помощи whereisсамостоятельно находим и прописываем путь вручную.После чего запустится свой мини-веб-сервер и будет вы-дана подсказка, по которой можно найти в сети webmin.

#/usr/local/webmin-1.140/changepass.pl /etc/webmin ↵↵↵↵↵ïîëüçîâàòåëü íîâûé_ïàðîëü

# /etc/webmin/stop && /etc/webmin/start

Ðèñóíîê 1

36

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

Как видите, вполне привычная большинству пользо-вателей рабочая обстановка.

Небольшое примечание: если Webmin уже был уста-новлен в системе, то для входа вместо admin придетсявоспользоватья root (нужного пользователя можно посмот-реть в файле webmin.acl, он идет первым, например,admin), но затем заведите лучше отдельного пользовате-ля для работы с Webmin. Также в некоторых дистрибути-вах может быть выставлен другой порт, используемыйWebmin, иногда при выборе его значения следует учиты-вать, что некоторые провайдеры не любят пропускать па-кеты на порты с адресами выше 1024, и, например, еслине используется защищенный веб-доступ, то вполне по-дойдет порт 443, также и проследите, чтобы нужный портбыл открыт firewall.

А так, зная особенности работы тех или иных серви-сов, настроить их с Webmin особого труда не составит,просто выбираете нужную категорию (рис. 3) и заполняе-те или выбираете параметры, к тому же по адресу http://www.swelltech.com/support/webminguide-1.0/index.html до-ступна неплохая книга по использованию, которая будетособенно полезна начинающим «The book of Webmin».

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

ляется родным языком админа, но, согласитесь, общать-ся на родном все же приятней. Заходим «WebminConfiguration →→→→→ Language» и выбираем из выпадающегосписка нужный язык, после чего подтверждаем свой вы-бор нажатием на «Change Language». И возвращаемсятеперь уже к пункту «Настройка Webmin». По умолча-нию Webmin будет принимать подключения со всех ад-ресов, что не всегда нужно и безопасно, используя пункт«Управление доступом по IP» (IP Access Control), можноограничить доступ, оставив его только для тех адресов,которым вы доверяете (например, внутренняя сеть), пол-ный доступ можно разрешить, только если вы, например,уезжаете в отпуск и хотите иметь возможность попастьна свой сервер. Здесь возможно задать в качестве па-раметра сразу сеть или подсеть, отдельные узлы по IP-адресу или доменному имени. В последнем случае дляподстраховки установите галочку в пункте «ОпределятьIP-адрес по имени при каждом запросе». Для быстротыэту операцию можно проделать и вручную, использовавв файле /etc/webmin/miniserv.conf параметры allow= илиdeny=. Первый содержит список узлов и компьютеров,перечисленных через пробел, которым позволено соеди-няться, второй, наоборот, попытки доступа с которыхбудут игнорироваться.

После установки при положительном ответе на воп-рос «Start Webmin at boot time» Webmin будет загружать-ся при старте системы, другим вариантом запуска бу-дет использование для этих целей xinetd. Для этого вфайл miniserv.conf добавляем строчку inetd=1 и убира-ем session=1. После этого пишем в файл /etc/xinetd.conf(в некоторых дистрибутивах вроде Slaskware его сна-чала создаем командой touch /etc/xinetd.conf):

После чего перезапускаем xinetd.Теперь самое время заняться пользователями. Для

начала используем модуль «Аутентификация», которыйпозволяет включить увеличение задержки между неудач-ными попытками ввода пароля для одного и того жепользователя и блокирование доступа после несколькихнеудачных попыток на определенное время, что затруд-нит попытки подбора пароля в лоб, все подобные дей-ствия можно также заносить в журнал. Для забывчивыхи ленивых пользователей можно активировать опцию, по-зволяющую автоматически отключать доступ после оп-ределенного интервала времени, и здесь же отключитьвозможность запоминания введенного пароля. Для улуч-шения защиты от перебора стоит также установить ути-литу logwatch http://www.logwatch.org/, с которой отличноладит Webmin.

Ðèñóíîê 2

Ðèñóíîê 3

service webmin{ user = root env = LANG= port = 10000 socket_type = stream protocol = tcp wait = no disable = no type = UNLISTED server = /usr/local/webmin-1.140/miniserv.pl server_args = /etc/webmin/miniserv.conf}

37№7(20), июль 2004

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

Следующий полезный модуль «Пользователи Webmin»(Webmin Users) позволит создать пользователя или груп-пу, наделенную определенными правами по работе с темиили иными сервисами.

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

Webmin может вести журнал событий в стандартномформате журнальных файлов CLF (combined log format),при этом имеет довольно гибкие возможности по регист-рации. Так, зайдя в меню «Настройка Webmin» →→→→→ «Жур-нал» можно указать, какие IP-адреса и имена узлов будутзаноситься в журнал, действия каких пользователей бу-дут регистрироваться, а также как часто журнал будеточищаться. Записи журнала будут заноситься в файл /var/webmin/miniserv.log.

Кроме того, при активации опции «Заносить измене-ния, произведенные в файлах при каждом действии» так-же будут вестись подробные записи действий пользова-телей в файл /var/webmin/webmin.log. Этот журнал можетбыть просмотрен и проанализирован с помощью модуля«Журнал действий Webmin» (Webmin Actions Log).

Если возможностей Webmin не хватает или соскучи-лись по командной строке, то во вкладке «Прочее» (Others)имеются несколько специальных пунктов. «Вход по SSH/Telnet» (SSH/Telnet Login), который по умолчанию пыта-ется подключиться к 23 порту сервиса telnet, чтобы из-менить поведение, нажимаем вкладку «Настройка моду-ля» и в строке «Тип соединения» выбираем Secure Shell,здесь же можно выставить количество строк, другой узелдля работы и использование отдельного окна. Так чтоWebmin может пригодиться для того, чтобы попасть насвои компьютеры, используя SSH в местах, где не такпросто найти необходимые приложения (даже из интер-нет-кафе), для этого достаточно запустить его на однойиз своих машин.

Далее во вкладке «Прочие» обнаруживается и интер-фейс к командному интерпретатору «Командная оболоч-ка (shell)» (Command Shell), позволяющий удаленно вы-полнять команды оболочки и поддерживающий историюкоманд.

Следующий пункт «Команды пользователя» (CustomCommands) позволяет неподготовленным пользователямвыполнять команды или скрипты нажатием одной кнопки.Админу достаточно создать команду, заполнив соответ-ствующие поля (прописать комманду, задать параметрыпользователя, от имени которого будет выполняться ко-манда, добавить описание и пр.).

Здесь же во вкладке «Прочее» найдете и менеджерфайлов (рис. 4) (требует подержки JAVA), который позво-лит получить доступ к файлам на удаленном компьютерев удобной графической оболочке.

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

ты. Некоторые модули доступны с главного сайта, большуюколлекцию модулей найдете по адресу http://www.thirdpartymodules.com/webmin. В первую очередь хотелось бы от-метить модуль Usermin (http://www.usermin.com), написан-ный также Джейми Камероном. В отличие от Webmin, на-целенного на администратора, Usermin ориентирован наконечного пользователя, позволяя читать почту, работатьс GPG, иметь удаленный доступ к своим файлам, управ-лять заданиями cron и пр.

Для установки достаточно зайти в раздел «Настрой-ка Usermin» (Usermin Configuration) и нажать на кнопку«Install Usermin tar.gz package». Для работы с модулями(обычно файл с расширением .wbm, хотя возможна ус-тановка и rpm-пакетов) заходим в «Модули Webmin»(Webmin Modules), где можно установить новый, указавего местонахождение на локальном диске или в Интер-нете, удалить модуль, выбрав его из списка, или копиро-вать модуль. Копирование модулей позволяет иметь одини тот же модуль с разными настройками, который можноположить в разные группы для быстрого доступа и раз-решить доступ разным пользователям.

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

Вот такой он, Webmin. Простой в установке и настрой-ке, полезный в работе, позволяющий администраторамбольше сосредоточиться на процессе настройки системыи дающий возможность безопасно работать и получатьинформацию из тех мест, где нет доступа нужным утили-там. Есть, конечно, и другие утилиты, имеющие аналогич-ные (почти) возможности, наиболее популярен здесьlinuxconf (http://www.solucorp.qc.ca/linuxconf), традиционновходящий в состав RedHat и умеющий работать как в кон-соли, так и в Х, и позволяющий подключаться через сеть.Но все-таки linuxconf, как мне кажется, менее удобен, осо-бенно для новичка, имеет меньше возможностей и ори-ентирован в первую очередь на локальное применение.

Ðèñóíîê 4

38

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

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

Сначала немного теории. Для передачи кадра (речь бу-дет идти об Ethernet) другому устройству сетевой адаптермашины должен знать его физический (MAC) адрес. Уда-ленное устройство будет принимать только кадры, содер-жащие в заголовке (поле Destination) его адрес, то естьадресованные именно ему. Ну еще широковещательныекадры, адресованные на специальный адрес ff:ff:ff:ff:ff:ff. Нопоскольку работа протоколов верхних уровней основана на

FreeBSD TIPS: ARP В «ЗАМОРОЗКЕ»

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

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

IP-адресах, то кто-то должен уметь сопоставлять IP-адрессетевого устройства с MAC-адресом его адаптера. Этим«кем-то» является протокол ARP (address resolution protocol).

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

39№7(20), июль 2004

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

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

Для адресов, которые не задействованы в подсети,можно создать статические записи с фиктивными физи-ческими адресами (например, 00:11:22:33:44:55). Это ис-ключит возможность использования кем-либо данных IP-адресов.

Далее очищаем ARP-таблицу и заполняем ее из сфор-мированного файла:

Естественно, имя и местоположение файла соответ-ствия может быть любым – удобным для вас. Теперь оста-лось занести указанные команды в сценарий автозапус-ка, например, с именем /usr/local/etc/rc.d/statarp.sh:

Осталось не забыть сделать данный файл исполняе-мым.

Итак, мы получили статическую таблицу соответствиямежду IP- и MAC-адресами. Теперь выход в Интернет че-рез FreeBSD-сервер с «чужого» IP-адреса станет невоз-можным, если, конечно, заодно не подменить и MAC-ад-рес (с последним явлением можно бороться разве чтоорганизационными методами).

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

# arp �an | awk �v OFS=�\t� �{print(substr($2, 2, ↵↵↵↵↵length($2)-2), $4)}� > ethers

# arp �d �a# arp �f /usr/local/etc/ethers

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

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

Управлять записями ARP-таблицы позволяет одно-именная утилита arp. Ее полный синтаксис доступен в manarp(8). Нам понадобятся следующие команды:! arp –a – выводит содержимое таблицы ARP.! arp <host> – выводит ARP-запись для заданного хоста.! arp –d <host> – удаляет запись, соответствующую хосту.! arp –d –a – удаляет все записи таблицы.! arp –s <host> <MAC-address> – добавляет запись.! arp –f <file> – добавляет записи из файла соответствия

<file>.

Таким образом, дальнейшие действия понятны – длявсех «критических» (а если сеть небольшая, то просто длявсех) IP-адресов можно создать статические записи в ARP-таблице, тем самым исключив их подмену. Для этого су-ществует два пути:! Использовать команду arp –s <host> <MAC-address>

для создания каждой записи;! Создать файл соответствия и выполнить команду arp –f

<file>.

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

Формат файла соответствия продемонстрирован наследующем примере:

То есть в каждой строке записывается IP-адрес хоста(либо его каноническое имя) и через пробелы или симво-лы табуляции – соответствующий ему MAC-адрес. Запол-нить его достаточно просто – включите все машины сег-мента и обратитесь с них к серверу (или с сервера к ним)любым способом, например, запустите на них браузер иливыполните обычный пинг. Это обновит ARP-таблицу, пос-ле чего достаточно будет сохранить в файле результат вы-полнения команды «arp –an» и немного его подправить,удалив все лишнее и добавив нужное. Сократить необхо-димые правки позволит следующая команда:

#!/bin/sh# Static ARP-table loadercase $1 in

start)arp -d -a > /dev/nullarp -f /usr/local/etc/ethers > /dev/nullecho 'Static ARP-table is loaded';;

stop)arp -d -a > /dev/nullecho 'Static ARP-table is unloaded';;

restart)arp -d -a > /dev/nullarp -f /usr/local/etc/ethers > /dev/nullecho 'Static ARP-table is reloaded';;

status)arp -an;;

*)echo "Usage: `basename $0` ↵↵↵↵↵

{start|stop|restart|status}" >&2;;

esacexit 0

40

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

Построенный на основе Debian испанский дистрибутивLuinux http://www.masilla.org/luinux/ предназначен как раздля использования в качестве интернет-шлюза (ПК, ви-деоконсоль, ТВ) в домашних сетях или для небольшихорганизаций. Построен по принципу «установил и исполь-зуй». Распознает большую часть Ethernet-адаптеров, кро-ме традиционного для Linux firewall, имеет в своем соста-ве и NIDS Snort, поддерживается возможность легкогосоздания бекапов в iso, поддержка QoS позволяет распо-ложить по приоритетам важный трафик, поддерживается

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

СТРОИМ ШЛЮЗ С LUINUX

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

прозрачное http-кэширование, для удаленной настройкииспользуется SSH, статистику о работе можно получитьпри помощи веб-интерфейса, возможность создания сво-его сервера для обмена мгновенными сообщениями, на-стройка совместного использования файлов, в том числеи NetBios, автоматическая установка времени при помо-щи NTP (Network Time Protocol).

Для работы Luinux требуется по нынешним временам да-леко не самый мощный компьютер: процессор 166 МГц+,ОЗУ 64 Mб+ (128 Mб рекомендуется) и жесткий диск не

41№7(20), июль 2004

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

менее 1 Гб (SCSI не поддерживаются). И два сетевых адап-тера: к первому eth0 подключается провайдер, ко второ-му eth1 – локальная сеть.

УстановкаУстановка особых проблем вызвать не должна. Загружа-ем ISO-образ размером 77 Мб, записываем и загружаем-ся с него. Если BIOS не поддерживает загрузку с CD-ROM,то используйте образ bootflop.img для загрузки с дискеты.Через некоторое время система, пожужжав, выдаст та-кое сообщение.

Все, как видите, просто. Для установки переходим вкаталог /etc/recovery и вводим ./install.sh, после чего скриптвсе проделает сам – и диск разобьет, и пакеты распакует.Для работы в режиме expert, когда вы хотите разбить дискпо своему усмотрению, запускаем fdisk /dev/hda и затемвводим ./clone-disk.sh. Для восcтановления старой фай-ловой системы может понадобиться ./restore-fs.sh. Систе-ма разбивает диск на четыре раздела hda1-4 (все данныепри этом будут потеряны), на которые будут примонтиро-ваны соответственно swap, корневой, /var и /home, после-дние три форматируются с файловой системой ext3. Пос-ле окончания процесса копирования систему можно пе-резагружать.

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

После чего рекомендую сменить клавиатурную рас-складку – установленная по умолчанию несколько неудоб-на для работы.

Введя в консоли tzconfig, изменяем значение времен-ного пояса.

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

настроен на адрес 192.168.1.1, рекомендую его так и ос-тавить, если не хотите потом перестраивать самостоятель-но все остальные сервисы. Проверяем, как поднята сеть.

Если утилита выдала информацию о двух сетевых ин-терфейсах с выставленными IP-адресами, значит можетесчитать себя счастливчиком и приступать к тестированиюсервисов. К сожалению, на сайте разработчика нет спис-ка поддерживаемых адаптеров, поэтому узнать, будет лиработать ваше сетевое оборудование, можно только экс-периментальным путем. Как вариант выхода из ситуацииможно скомпилировать необходимый модуль в Debian иподгрузить его самостоятельно при помощи insmod. Плюско всему можно воспользоваться утилитой apt-get для того,чтобы обновить или доустановить приложения, которыепосчитаете нужными. Для того чтобы выставить другуюконфигурацию сетевых интерфейсов, которая будет ра-ботать и после перезагрузки системы, изменяем значе-ния параметров в файле /etc/network/interfaces, взяв запример конфигурацию eth1.

И заносим в файл имена серверов DNS.

И в файле /etc/hostname можно выставить новое имякомпьютера, но теперь придется и перенастроить другиесервисы, например, чтобы получать почту (в качестве МТАиспользуется Exim). Для того чтобы найти все примене-ния имени, используемого по умолчанию, – servidor, по-пробуйте команду: grep -r servidor /etc /var /usr.

После чего выполняем:

И вводим в действие новые настройки:

После чего еще раз сверяемся при помощи ifconfig. Пос-ле этого достаточно указать на пользовательских компью-терах IP-адрес в диапазоне с 192.168.1.2 до 192.168.1.254,сетевую маску 255.255.255.0, адрес шлюза 192.168.1.1 ив качестве DNS указанные выше в /etc/resolv.conf адреса(по обещанию разработчика в следующей версии 1.1 бу-дет свой кэширующий DNS-сервер) и можно тестироватьработу шлюза и установленных сервисов.

Теперь попробуйте погулять по Интернету, Luinux будеткэшировать посещенные странички, затем зайдите в ftp-

# cp /usr/share/keymaps/i386/qwerty/ru4.kmap.gz ↵↵↵↵↵/etc/console/boottime.kmap.gz

#/etc/init.d/keymap.sh reload

#ifconfig

#mcedit /etc/network/interfacesauto loiface lo inet loopback#òåïåðü äëÿ eth0 óêàçûâàåì íóæíûé ñòàòè÷åñêèé IP-àäðåñauto eth0iface eth0 inet staticadress 190.2.34.100netmask 255.255.255.0

#mcedit /etc/resolv.confsearchnameserver ip_adress_your_provider_primary_dnsnameserver ip_adress_your_provider_secondary_dns

#/etc/init.d/hostname.sh

#/etc/init.d/networking restart

42

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

архивы, отправьте почту, зайдите на сервер по протоколуSSH. У меня здесь проблем не было, что даже подозри-тельно. После чего зайдите по адресу: http://192.168.1.1/stats/ для просмотра статистики работы сервера (рис. 1).

Для сбора статистики в Luinux используется приложениеHotSaNIC – «HTML overview to System and Network InformationCenter» (домашняя страница http://hotsanic.sourceforge.net).Представляющее собой набор скриптов, написанных на Perlи использующих для работы rrdtool http://ee-staff.ethz.ch/~oetiker/webtools/rrdtool/. Эти скрипты, основываясь на дан-ных, выдаваемых системными утилитами каждые 10 се-кунд, просматривают статистику проходящего через интер-фейсы трафика, загрузку процессора, памяти, пользова-тели, данные, полученные о работе жесткого диска, и в ре-зультате через 15 минут генерируют графики, по которымможно просмотреть статистику работы системы и нагрузкуна отдельные компоненты за последний час, неделю, ме-сяц и год. К сожалению, HotSaNIC не выводит статистикуотдельно по каждому клиентскому IP-адресу, но, очевид-но, исходя из задач дистрибутива, это и не требовалось, акому понадобится – на сайте есть документация, расска-зывающая, как создать к нему свой модуль. Следующийна очереди проверки – сервис Mldonkey, представляющийсобой мультиплатформенный мультисетевой peer-to-peerклиент, распространяемый под лицензией GNU.

В данный момент работает с сетями: eDonkey, Overnet,

Bittorrent, Gnutella (Bearshare, Limewire и др.), Gnutella2(Shareaza), Fasttrack (Kazaa, Imesh, Grobster), Soulseek(beta), Direct-Connect (alpha) и Opennap (alpha). На Luinuxзапускается демон, для настройки и проверки работы ко-торого набираем в строке браузера http://192.168.1.1:4080/(рис. 2).

Для тестирования общедоступного каталога на серве-ре используем пользователя – edonkey с паролем edonkey.Вся документация по работе и настройке Mldonkey нахо-дится в /var/opt/mldonkey/, ограничить максимальную ско-рость upload/download можно, изменив значения перемен-ных в файле start. Если Mldonkey не нужен, то отключитеего.

И еще одна утилита mkCDrec (http://mkcdrec.ota.be/)позволяет создать загрузочный iso-образ с копией систе-мы, которую в случае неприятностей можно легко восста-новить. Поддерживаются файловые системы ext2 , ext3,minix, xfs , jfs, reiserfs, LVM и software RAID и примонтир-ванные разделы с ФС msdos, fat, vfat и ntfs, сжатие припомощи gzip, bzip2, lzop и других утилит. Создать такойобраз легко, только процедура создания потребует нали-чия 3 Гб свободного места на жестком диске.

И затем копируем с другого компьютера.

Записываем образ на болванку.

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

Изменив значения параметров UP и DOWN в файле/etc/init.d/packetfilter, можно изменить значения полосыupload/download для интерфейса eth0, т.е. Интернета. Пос-ле чего не забудьте перезапустить сервис.

Для работы Samba-сервера отредактируйте файл /etc/samba/smb.conf под свои нужды (как это сделать, описанов моей статье «Что такое Samba», журнал «Системныйадминистратор», октябрь 2002 г.). После чего сервер Luinuxможно использовать еще и в качестве файл-сервера.

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

Ðèñóíîê 1

Ðèñóíîê 2

#update-rc.d mldonkey remove

#cd /var/opt/mkcdrec/#make clean#make CD-ROM

#scp [email protected]:/tmp/CDrec.iso

#cdrecord -v speed=4 dev=0,0 CDrec.iso

#/etc/init.d/packetfilter stop#/etc/init.d/packetfilter start

43№7(20), июль 2004

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

Слово «кластер» означает «подмножество объектов с оп-ределенными наборами признаков».

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

Существует четыре основных преимущества исполь-зования кластерных систем:! высокая доступность (High Availability);! масштабируемость;! гибкость;! простота управления.

Кластер – это также возможность использовать вычис-лительные ресурсы системы так, что полученная системапревосходит по своим возможностям суммарные возмож-ности ее частей.

«СТАЛЬНОЙ ГЛАЗ НА СТРАЖЕ ЖИЗНИ»HA-кластер LifeKeeper компании SteelEye

АНТОН БОРИСОВКластеры имеют свою специализацию, но тем не ме-

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

Из компьютерного словаря:Cluster (кластер) – группа терминалов или рабочих

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

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

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

44

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

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

Когда говорят о кластерах хранения информации, под-разумевают системы, разработанные фирмой Sistina(GFS – Global FileSystem) и проектом OpenGFS. Кластерысостоят из узлов, которые обеспечивают параллельный и вы-соконадежный доступ к данным единой файловой системы.

Кластер баз данных – это Oracle Parallel Server (OPS;сейчас известный как Oracle 9I RAC), состоит из узлов,которые обеспечивают параллельное, согласованное ивысоконадежное соединение с базой данных.

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

Сегодня мы рассмотрим последний тип кластеров, аименно HA-кластеры, т.е. из семейства отказоустойчивых.

Остановим свое внимание на продукте LifeKeeper фир-мы SteelEye.

Согласно техническим характеристикам поддержива-ется до 32 узлов в кластере. Узлы могут быть построеныкак на базе Linux (в первую очередь это Red Hat и совме-стимые с ней системы), так и на базе Windows 2000 ивыше. Хотя я подозреваю, что есть и решения для узловна базе Sun Solaris, впрочем, это не афишируется, но лю-бознательные читатели всё равно посмотрят установоч-ные и сервисные скрипты.

Как сервера узнают о нормальном функционированиидруг друга? Очень просто – с помощью heartbeat-меха-низма, т.е. с помощью обмена информацией по выделен-ным каналам. Под термином heartbeat подразумеваетсясердцебиение. В нашем случае «сердцебиение» узлов кла-стера. Если один из серверов перестает отвечать друго-му, значит произошел отказ/сбой и предпринимаются ава-рийные меры. В нашем случае проверки происходят с по-мощью запросов, отправленных на порты 81, 82. Если уда-ленная машина не формирует правильный ответ по дан-ным портам, то очевидно, что на узле не запущено клас-терное ПО или же узел «упал». В этом случае происходитперемещение функций на другой узел. Выделенными ка-налами могут выступать как отдельное, дополнительноеethernet-соединение, так и соединение по RS-232 прото-колу. В первом случае ethernet-соединение может исполь-зоваться серверами как дополнительный канал для об-мена информацией по TCP/IP-протоколу. Рекомендуютделать не один канал для heartbeat-целей, а два и более.Подразумевается, что даже в случае отказа коммуника-

без использования разделяемой физической памяти. Сейфакт, а также то, что на отдельно взятом узле запущенаоперационная система, отличает наш кластер от класте-ров на платформе NUMA (Non-Uniform Memory Architecture)и SMP (Symmetric Multi-Processor). Более подробно смот-рите в «вопросах и ответах» [8]. Однако никто не мешаетпостроить кластер на основе и этих платформ. Кстати, всписке top 500 [9], содержащем самые быстродействующиекластеры планеты, есть несколько штук, собранных на PC-платформе. Их, в частности, можно определить по строч-кам self-made (самособранные). Все остальное работает наоснове специального оборудования. С точки зрения тепло-выделения, потреблямых энергоресурсов и занимаемогопространства персоналки явно не лучший материал длясоздания сколько-нибудь быстродействующих кластеров.

Задача кластера заключается в обеспечении согласо-ванной работы всех узлов для достижения поставленнойцели. Целью может быть высокая устойчивость (HA – HighAvailability), высокая вычислительная способность (HP – HighPerformance), параллельное вычисление, параллельное об-служивание запросов. Наконец, кластер отличается от кли-ент-серверных распределенных вычислений тем, что клас-терное взаимодействие – это все-таки равноценное взаи-модействие каждого узла друг с другом, по принципу пи-ринговых сетей (peer-to-peer), когда каждый узел, в своюочередь, является членом более крупной системы. Услов-но в кластере выбирается мастер-узел, а другие являются«подшефными» узлами. В случае отказа мастер-узла вы-бирается по заранее выбранному алгоритму новый мастер-узел, который и курирует в дальнейшем весь кластер.

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

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

Кластеры проекта LVS (Linux Virtual Server) и класте-ры типа Piranha (RedHat Linux) считаются кластерами спараллельным обслуживанием запросов. Они в чем-то по-хожи на Mosix-кластеры, так как также занимаются рас-пределением нагрузки, правда, в несколько другом клю-че. Приходящие веб-запросы распределяются системоймежду набором стандартных веб-серверов. Данный типкластера больше напоминает ферму, нежели кластер, таккак узлы с веб-службами обычно не подозревают друг о

45№7(20), июль 2004

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

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

В случае, когда у нас кластер состоит из двух узлов,применяется соединение, представленное на рисунке.

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

Как я уже отмечал выше, поддерживается в первуюочередь Red Hat Linux. С выпуском LifeKeeper версии 4.4.3кластер можно развернуть на следующих релизах:

Попытка установки «в лоб» кластера, например, наSlackware Linux, к сожалению, пока не удалась. Поэтомупришлось обратиться к дистрибутиву ASP Linux 9.2. За-роботало все достаточно быстро и беспроблемно. Кста-ти, запрос в компанию Nordicmind, а именно она осуще-ствляет техническую поддержку для стран Европы, Бал-тии и СНГ, подтвердил, что на данный момент последнимсертифицированным ядром является 2.4.21, т.е. работа-ющие под 2.6.x. ядрами остаются пока не у дел, к сожале-нию.

Итак, начинаем установку пакетов на ASP Linux-систе-ме. Кластерное ПО можно взять по адресу [7], предвари-тельно зарегистрировавшись. Там же получить ключи наиспытательный срок в 30 дней. Маленькое отступление.Вашим идентификатором, на основе которого компания-разработчик сформирует вам ключи, является именноMAC-адрес сетевой карты. Что ж, время передать браздыправления root.

Убедимся, что у вас присутствуют те же пакеты, что иу меня.

По словам представителя службы технической поддер-жки из Nordicmind, подверсия ядра (т.е. -14, -19, -24) прин-ципиальной разницы не играет. Поэтому ставим пакетHADR.

Аналогично поставим пакеты:

# rpm -ih HADR-RedHat-2.4.18-14-4.4.2-3.i386.rpm

46

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

! HANFS-RedHat-2.4.18-14-4.4.2-3.i386.rpm – для NFSслужб;

! steeleye-lkRedHat70-4.2.0-13.i386.rpm – ядро LifeKeeperпод RedHat-платформу;

! steeleye-lkLIC-4.2.0-13.i386.rpm – пакет для управлениялицензиями;

! jre-1.3.1.i386.rpm – Java для GUI-интерфейса управле-ния кластером.

Из директории licensing установим пакет управления ли-цензиями.

И наконец устанавливаем основные пакеты для клас-тера:

В ходе установки этих пакетов вы получите информа-ционные сообщения, последнее из которых сообщает отом, что для чтения man-документации следует добавитьстрочку в файл .profile или .bash_profile в вашей домаш-ней директории.

В итоге программное обеспечение поставлено в дирек-торию /opt/LifeKeeper, параметры управления кластеромлежат в директории /etc/default/LifeKeeper.

Не забудьте записать ключи, полученные вами от ком-пании steeleye или её представителя, в директорию /var/LifeKeeper/license.

Затем запускаем кластер – /opt/LifeKeeper/bin/lkstart. В/etc/inittab пропишутся необходимые для работы сервисы.Также следует прописать в файл /etc/default/LifeKeeperстроку NOBCASTPING=1, т.к. тестировать кластер мы бу-дем, вероятно, в отдельной сетке, где нет дополнитель-ных машин. Она означает, что кластерное ПО будет игно-рировать пакеты бродкастов. При переносе в дикую сре-ду не забудьте раскомментировать её.

Следует обратить внимание, что в /etc/hosts (или в DNS-сервер) следует прописать как названия машин с их IP-адресами, так и информацию о тех ресурсах, которые бу-дут считаться разделяемыми.

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

где pc-box1, pc-box2 – названия узлов; bb-box1, bb-box2 –названия plip-интерфейсов, которые будут использовать-ся как heartbeat-каналы; triton – собственно разделяемыйресурс.

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

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

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

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

Этим мы сейчас и займемся. Начало процесса приве-дено на lk-step2.png. Начинаем настройку с узла pc-box1.Локальный IP-адрес выбираем такой же, что и в /etc/hosts,

[root@pc-box1 java]# rpm -ih jre-1.3.1.i386.rpm

# cd licensing/# rpm -ih steeleye-lkLIC-4.4.2-3.i386.rpm

steeleye-lk-4.4.2-2.i386.rpmsteeleye-lkIP-4.4.2-2.i386.rpmsteeleye-lkAPA-4.4.0-1.i386.rpmsteeleye-lkMAN-4.4.2-2.i386.rpmsteeleye-lkGUI-4.4.2-2.i386.rpmsteeleye-lkRAW-4.4.2-2.i386.rpmsteeleye-lkHLP-4.4.2-2.i386.rpm[root@pc-box1]# rpm -ih steeleye-lk*

10.0.0.100 pc-box1

[root@pc-box1]# /opt/LifeKeeper/bin/lkGUIapp

10.0.0.101 bb-box110.0.0.200 pc-box210.0.0.201 bb-box210.0.0.150 triton

47№7(20), июль 2004

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

а именно 10.0.0.100. Собственно говоря, LifeKeeper отту-да все и берет. Но помним, что 10.0.0.101 зарезервиро-ван в качестве backbone-канала (или в данном случае какheartbeat-соединение).

Далее заполняем необходимые значения для второгоузла.

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

Дальнейшая наша задача – создать ресурс, которыйбудет отказоустойчивым. В данном случае это IP-адрес скодовым названием «triton». Он-то и является ключевойфигурой нашего повествования. Ведь именно он находитсяв иерархии отказоустойчивых ресурсов, которыми мы се-годня занимаемся.

Создание ресурса comm/ip напоминает наши предыду-щие действия по созданию коммуникационного канала.Отмечу, что ресурс я создал под названием «ip-triton-tag».Можно назвать его по-другому, на ваше усмотрение.

Теперь «расширяем» ресурс на второй узел.

Проверяем доступен ли новый IP-адрес. Да, он откли-кается, причем с каждого из узлов. Достигается это сле-дующим образом. На устройство eth0 добавляется алиасв виде eth0:1 с новым IP-адресом. При переезде с одногоузла на другой алиас с первого узла удаляется и создает-ся на новом.

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

Укажем, где находится бинарный файл от Apache, ирасположение файлов конфигурации.

Видим, что на первом узле создался новый ресурс.

[anthony@pc-box1 anthony]$ /sbin/ifconfig

48

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

Теперь предстоит «расширить» настройки на второйузел и завершить на этом настройку ресурсов.

Убедимся, что на двух узлах у нас стоят одинаковыеверсии.

При обновлении следите также за тем, чтобы ключиот кластера не затерлись в /var/LifeKeeper/license.

Установку кластера можно считать законченной. Не-сколько слов о конфигурации apache. В файле httpd.confкоманду Listen следует применять по отношению к наше-му «устойчивому» ресурсу triton. У меня она выглядит наобоих узлах как Listen 10.0.0.150:80. Остальные опции неизменялись. Маленький нюанс: при падении одного изузлов также упадет и вся статистика от веб-сервера, т.к.в этой статье мы не рассматривали создание отказоус-тойчивого ресурса для файловой системы. Очевидно, чтоконфигурация на каждом из узлов должна совпадать.

Условимся, что первый узел является основным, а вто-рой – резервным. Тогда при остановке основного узларесурсы «переедут» на второй. Что мы и можем видетьна приведенном рисунке.

Чтобы переключить узел с активного состояния на пас-сивное или же перевести ресурсы с одного узла на дру-гой, надо выбрать пункт In Service/Out of Service на вклад-ке конкретного узла. Это производится через GUI-прило-жение. Вполне возможно произвести эту операцию черезкомандную строку:

Как видите, я произвожу переключение кластера совторого узла, на который переедут ресурсы.

Несколько слов о том, как перенести файлы с одногоузла на другой средствами ПО самого кластера. Для этихцелей существует утилита lcdrcp. Я нахожусь на втором узлев директории /var/www/html, и требуется перенести файл

[root@pc-box2]# /opt/LifeKeeper/bin/perform_action ↵↵↵↵↵-a restore -t ip-triton-tag

[anthony@pc-box1 anthony]$ nmap -v triton

49№7(20), июль 2004

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

index.html на первый узел. Запускаем следующим образом:

Уточняем, куда именно следует положить файл – вдиректорию /var/www/html, но уже на первом узле.

В первом примере мы переводили ресурс ip-triton-tagс узла на узел, но тогда в иерархии он не был связан сресурсом apache-tag. Сейчас же давайте посмотрим, какпройдет процесс переезда двух ресурсов. Уже скопиро-вали индексный файл для apache и хотим посмотреть, какзапустятся ресурсы на первом узле.

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

Управлять кластером можно не только посредствомGUI-приложения, но из-командной строки, а также окош-ка браузера. Впрочем, последнее не слишком сильно от-личается от GUI-управления. Приведу несколько команди их назначение.

Для старта и остановки кластера LifeKeeper, GUI-при-ложения:

Мониторинг кластера:

Запуск ресурса на выполнение/остановку:

Команды для создания настроек коммуникационныхпутей:

Пример:

Команды по управлению приложениями:

Пример:

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

Спасибо за поддержку сотрудникам Esko Wessman иMarko Lehtimaki из компании NordicMind, а также за тех-ническую помощь сотрудникам Denise Hodges и Randy Hinzкомпании SteelEye.

Ссылки:1. http://www.openmosix.org.ru/docs/openMosix-HOWTO-

multi/ch02.html2. http://www.cio-world.ru/techniques/effect/29933/3. http://parallel.ru/parallel/russia/russian_clusters.html4. http://distributed.org.ru/?main&newsday=24-Mar-20045. http://www.steeleye.com/6. http://licensing.steeleye.com/support/download_get.php/

configclusters.pdf?dir=0&file=configclusters.pdf7. http://licensing.steeleye.com/download/8. http://lse.sf.net/numa/faq/index.html9. http://www.top500.org//lists/2003/11/

[root@pc-box2 html]# /opt/LifeKeeper/bin/lcdrcp index.htmlpc-box1:/var/www/html

[root@pc-box1 bin]# ./perform_action -a restore -t apache-tag

net_create -d pc-box1 -s pc-box2 -D MyPath -n TCP ↵↵↵↵↵-r 10.0.0.200 -l 10.0.0.100 -p 1

crelcm pc-box1 pc-box2 TCP 10.0.0.100 10.0.0.200 10

app_create -d pc-box1 -a apache-tagapp_list -d pc-box1

50

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

Обеспечение бесперебойной работы и сохранности дан-ных – головная боль для системного администратора, при-чем независимо от размеров обслуживаемой им сети. Од-нако при обсуждении проблем отказоустойчивости в ос-новном рассматриваются либо конструктивные особенно-сти достаточно дорогих моделей серверов, либо различ-ные кластерные конфигурации или построение сетей хра-нения данных, что, на мой взгляд, может представлять ин-терес лишь для крупных и/или достаточно богатых компа-ний. И очень мало информации по решениям, пригоднымдля использования в небольших фирмах, которых суще-ственно больше, чем близких к нефтяным или финансо-вым потокам. Поэтому когда в рамках одного из проектовзаказчик попросил включить в него предложения по обес-печению отказоустойчивости для сети из нескольких ПКи сервера под управлением ОС Windows 2000, на кото-ром размещен внутренний веб-сайт и хранятся совмест-но используемые файлы, в первый момент возникло не-которое замешательство. Готового рецепта не было. На-чался поиск во всевозможных источниках, результат ко-торого материализовался в виде CD-диска с программ-ным продуктом SurviveIT 2000 фирмы Computer Associates.

Для чего же предназначен SurviveIT? В документациинаписано следующее: «Это высоконадежное решение дляплатформы Windows NT/2000, обеспечивающее бесперебой-ный доступ к вашим приложениям и данным даже в случаеотказа сервера». Выглядит это следующим образом. В ло-кальной сети устанавливается дополнительный компьютер,называемый вторичным, который берет на себя выполне-ние всех функций, включая имя и IP-адрес основного (пер-вичного) сервера в случае выхода последнего из строя. Воз-

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

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

ВЕЖЛИВЫЙ ОТКАЗ– Капитан, барометр упал.

– Сильно?– Вдребезги!

АЛЕКСАНДР ШИБЕНКО

клиентские ПК

коммутатор ЛВС

выделенный сегмент

первичные (основные)сервера

вторичный (резервный)сервер

коммутатор

Ðèñóíîê 1.

51№7(20), июль 2004

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

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

На момент тестирования под рукой не было двух оди-наковых компьютеров, но оказалось, что тип процессора,сетевого адаптера и контроллера дисков первичных и вто-ричного серверов, а также объем установленной в них па-мяти могут отличаться. И действительно, ПК с процессо-ром Pentium III 500 МГц и 20-ти Гб IDE-диском без проблемзаработал в качестве вторичного для старенького серверас обычным Pentium 200 и SCSI-диском на 8 Гб. Но преждечем это произошло, естественно, необходимо было уста-новить SurviveIT на оба компьютера.

Процесс установки не вызвал никаких проблем, доста-точно было следовать инструкциям инсталлятора и в концеперезагрузиться. Сложнее оказалось получить ключ акти-вации. У меня был демо-диск с ограниченной лицензией, нодаже ее необходимо было зарегистрировать. Я попыталсясделать это в режиме «on-line», но все попытки заполнитьсоответствующую форму системой регистрации отверга-лись. Точно не знаю, какое па из исполняемых шаманскихтанцев возымело действие, но ключ получить удалось. Воз-можно, проще было бы сделать все это по электронной по-чте. И еще одну особенность регистрации хочется отметить.Похоже, ключ привязывается к IP-адресу сервера, и в слу-чае смены адреса он может оказаться недействительным.

После установки пакета на оба сервера с помощью кон-соли управления можно приступать к конфигурированию.Сначала необходимо задать серверам соответствующиероли: первичный или вторичный. Первичному серверу мож-но указать, какое имя и IP-адрес он должен будет получить,после того как снова перейдет в рабочее состояние послеаварии. Это может оказаться нужным, ведь под его исход-ным именем и адресом в сети будет присутствовать дуб-лер. Затем на вторичном сервере создается задание на реп-ликацию. Для обеспечения дополнительной гибкости каж-дое задание может содержать несколько работ, в рамкахкоторых предлагается выбрать, какие каталоги на дискахпервичных серверов необходимо реплицировать и куда, атакже какие каталоги вторичного сервера сделать доступ-ными для сетевых клиентов в случае отказа основного сер-вера. Даже если сбой произошел во время репликации,SurviveIT гарантирует целостность данных и исключает по-вреждения файлов, записывая на диск только завершен-ные транзакции. После завершения синхронизации целос-тность поддерживается путем передачи по сети толькофактических изменений, а не за счет копирования файловцеликом. Поэтому защищаемые и резервный сервера мо-гут включаться непосредственно в локальную сеть или дажесоединяться низкоскоростным каналом. Однако если пред-полагается реплицировать большие объемы данных, воз-можно, окажется целесообразным установить в каждыйсервер по дополнительному сетевому адаптеру и органи-зовать выделенный сегмент, изолированный от ЛВС, к ко-торой подключены клиентские рабочие места.

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

что и на первичном. Затем в свойствах задания на репли-кацию указывается, какие сценарии будут выполняться насерверах в случае отказа. В состав пакета входят сцена-рии для следующих приложений:! Unicenter TNG! Lotus Notes Server! Microsoft Exchange Server! Microsoft SQL Server! Microsoft Internet Information Server! Jasmine II! Microsoft Proxy Server! Netscape SuiteSpot! Oracle Enterprise Server! Sybase Adaptive Server! Ingres II

Можно создавать и собственные сценарии. Для этого всостав пакета включен соответствующий шаблон. Скачатьего можно на сайте журнала (www.samag.ru/source).

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

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

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

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

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

52

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

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

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

Эта статья посвящена автоматизации администрирова-ния файловых серверов с помощью стандартных средствMicrosoft Windows. Решением поставленной задачи явля-ется инструмент, созданный на основе VBScript1, позво-

УПРАВЛЕНИЕ ФАЙЛОВЫМИ СЕРВЕРАМИ

ИВАН КОРОБКО

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

ляющий абстрагироваться от файловой системы и авто-матизировать администрирование файловых серверов.

Выбор вариантаСоздание сервера является нетривиальной задачей, со-стоящей из нескольких основных этапов.

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

53№7(20), июль 2004

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

работка структуры каталогов при загрузке страницы за-нимает много времени, поэтому загрузка html-страницыбудет длиться десятки минут. Для увеличения скоростиработы приложения его разделяют на 2 части.

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

Вторая часть представляет собой сайт (см. рис. 1а, 1б),созданный на основе ASP-страниц (для функционирова-ния ASP-страниц требуется установка Internet InformationServer (IIS). IIS является приложением, входящим в комп-лект поставки Microsoft Windows). С помощью ASP осу-ществляется отображение информации, поиск по различ-ным критериям.

VBScript: работа с массивамиПри создании данного комплекса активно использовалисьмассивы. О некоторых особенностях работы с массиваминеобходимо рассказать отдельно, чтобы впоследствии неотвлекаться на подобные разъяснения.

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

Ðèñóíîê 1à

вер, на котором хранятся дистрибутивы программ, раз-лична. Исходя из нагрузки на сервер будут определеныего аппаратные характеристики. Вторым фактором, вли-яющим на аппаратные характеристики сервера, являетсяязык программирования, на основе которого создан ин-струмент. В качестве такового выбран VBScript по следу-ющим критериям:! Язык программирования VBScript входит в поставку

Microsoft Windows, поэтому перенос инструмента с одно-го Windows-сервера на другой не представляет труда.

! Синтаксис языка достаточно прост.! VBScript является объектно-базированным языком и

имеет встроенную поддержку объектов.

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

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

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

ка программного обеспечения: по названию продукта, поназванию фирмы-производителя приложения (Microsoft,Adobe, Symantec и др), по назначению приложения (пап-ка, содержащая архиваторы, такие как Zip, Rar, назы-вается Arc; программы для тестирования аппаратныхсредств – SysInfo и т. д.) или предпочесть смешанныйвариант. Каждый системный администратор решаетсамостоятельно, какой из вариантов сортировки ресур-сов ему удобнее использовать.

! Как осуществлять сортировку ресурсов по языковомупризнаку (имеется в виду язык интерфейса)?

! Какое место в файловой структуре займет разделдрайверов, документации и т. д.

! По какому принципу будет осуществляться сортиров-ка драйверов – по названию фирмы-производителя(HP, Canon, Intel, Asus, Maxtor) или по назначению уст-ройств (Video, Audio, Chipset, Printer)?

! Как будут учитываться версия операционной системы,для которой создан драйвер устройства?

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

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

Поскольку объем файлового сервера огромен, то об-

Ðèñóíîê 1á

54

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

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

Объявление массивовРассмотрим общий случай – многомерный массив. Мас-сивы объявляются с помощью оператора Dim. После име-ни многомерного массива в круглых скобках через запя-тую указывают границы каждого измерения массива.

Особенности объявления массивов:! индексация элементов массивов начинается с нуля;! в многомерном массиве может быть до 60 измерений;! динамические одномерные и многомерные массивы

объявляются одинаково.

Приведем пример объявления многомерного и одно-мерного массивов. Одномерный массив является частнымслучаем многомерного (см. таблицу 1).

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

! Preserve – переопределяет размер, сохраняя существу-ющие данные в массиве, если параметр не указан, товсе ячейки массива обнуляются;

! Array_name – название массива;! Subscripts – количество элементов в массиве.

При изменении размера многомерного массива кор-ректировке поддается только размер последнего измере-ния.

Определение границ массиваОпределение размера выделенной памяти для массиваосуществляется с помощью команд lbound(array_name) иubound(array_name), где array_name – название массива,границы которого необходимо определить. С помощьюкоманды lbound определяется нижняя граница массива, спомощью ubound – верхняя граница.

Данный прием часто используется для чтения всех эле-ментов динамического массива:

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

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

Первая часть: создание кэш-файлаСоздание кэш-файла осуществляется с помощью сценария,написанного на VBScript, который запускается через задан-ные промежутки времени стандартным планировщиком за-дач Microsoft Windows. По ходу выполнения сценария осу-ществляется чтение структуры подкаталогов в указанномродительском каталоге. Анализируется содержимое подка-талогов. Если в подкаталоге обнаружена метка – файл!meta.txt, – путь к этой папке записывается в массив.

Файл !meta.txt является идентификационно-парамет-рическим. Для удобства файл будем называть файломпараметров, или параметрическим. Он содержит в себетри параметра, по одному в каждой строке.

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

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

VBScript-сценарий состоит из нескольких частей:! чтение исходных параметров из конфигурационного

файла;! чтение структуры подкаталогов;! обработка считанной структуры подкаталогов;! формирование кэш-файла.

Чтение исходных параметровиз конфигурационного файлаВсе исходные параметры для скрипта содержатся в от-дельном конфигурационном файле, например, cache.ini.Он представляет собой текстовый файл и содержит сле-дующие параметры:! Имя и путь создаваемого кэш-файла, например, cache.dat.

Òàáëèöà 1

ReDim [Preserve] array_name(subscripts) [, varname(subscripts)] ...

Ïðèìåð1:For i=Lbound(Array_) to Ubound(Array_)Msgbox Array_(i)Next

Ïðèìåð 2:Dim Array(100)��������For j=0 to 100For i=0 to 100

If StrComp(Array_sort(i),Array_sort(i+1),0)=1 Thentemp=Array(i)Array (i)=Array(i+1)Array(i+1)=temp

End ifNextNext

55№7(20), июль 2004

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

! Путь к корневому каталогу, структура подкаталогов ко-торого подлежит обработке, например \\server\software.

! Определение флага, по которому определяется необ-ходимая парапка. Флагом является имя параметричес-кого файла, например, meta.txt.

! Метка предназначеная для разделения параметров приформировании кэш-файла.

Рассмотрим структуры файла cache.ini. Файл содер-жит следующие поля и соответствующие им характерис-тики:

Чтение данных из параметрического файла осуществ-ляется с помощью Windows Scripting Host (WSH)2, поддер-живаемого VBScript.

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

После того как сформирован массив, содержащийстроки параметрического файла, осуществляется анализего элементов и распознавание значений параметров последующему алгоритму:! Чтение элементов массива.! Поиск в строке символа «=» с помощью функции instr()3.! Сравнение строк до знака равенства с названиями па-

раметров, перечисленных в таблице 1.! В случае совпадения названия параметра и части стро-

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

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

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

Как уже говорилось, данный фрагмент считывает всеподкаталоги в заданном каталоге. Для чтения всей струк-туры подкаталогов необходимо этот механизм поместитьв функцию, а ее сделать рекурсивной4. Функция будетиметь два параметра – путь к абсолютному подкаталогу(PATH) и уровень вложенности подкаталогов (IDX).

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

Òàáëèöà 2

Ïðèìåð 3:Text=""i=0Dim Array()FileName="cache.ini"Set fso = CreateObject("Scripting.FileSystemObject")If fso.FileExists(filename) Then

Set Fline = fso.OpenTextFile(FileName)Do While Not (Fline.atEndOfStream)redim preserve array(i)Array(i)= Fline.ReadLinei=i+1

LoopElseText="File Not Found"End IfFor i=lbound(array) to ubound(array)Text=Text+cstr(array(i))+vbCrLf � vbCrLf=chr(13)+chr(10)=ENTERNextMsgBox Text

Ïðèìåð 4:For i=lbound(array) to ubound(array)len1=instr(cstr(array(i)),"=")msgbox "len1: "&len1if len(cstr(array(i)))<>0 then

Ïðèìåð 5:Path=�C:\RootFolder�Temp=��Set fso=Wscript.CreateObject("Scripting.FileSystemObject")Set oFolder=fso.GetFolder(path)Set oFolders=oFolder.SubFolders

For Each oF In oFoldersTemp=Temp+cstr(oF.Path)+chr(13)+chr(10)

NextMsgBox Temp

value=left(cstr(array(i)), len1-1)msgbox "value: "& value Select Case valueCase "Symbol" path1=right(cstr(array(i)), ↵↵↵↵↵

len(cstr(array(i)))-len1)Case "Path_To_Root" path2=right(cstr(array(i)), ↵↵↵↵↵

len(cstr(array(i)))-len1)Case "Label_FileName" path3=right(cstr(array(i)), ↵↵↵↵↵

len(cstr(array(i)))-len1)Case "Cache_FileName" path4=right(cstr(array(i)), ↵↵↵↵↵

len(cstr(array(i)))-len1) End SelectEnd ifNextMsgBox path1+chr(13)+ path2+chr(13)+ path3+chr(13)+ path4+chr(13)

Ïðèìåð 6:Path=�C:\RootFolder�i=0Dim Array() 'Îáúÿâëåíèå äèíàìè÷åñêîãî ìàññèâàSet fso=Wscript.CreateObject("Scripting.FileSystemObject")Set oFolder=fso.GetFolder(path)Set oFolders=oFolder.SubFolders' Èçìåíåíèå ðàçìåðà äèíàìè÷åñêîãî ìàññèâàRedim Preserve Array(oFolders.count)

For Each of In oFoldersArray(i)=cstr(oF.Path) ' Çàïèñü ýëåìåíòîâ â ìàññèâi=i+1

Next'×òåíèå ýëåìåíòîâ ìàññèâàTemp=��For i=Lbound(Array) to Ubound(Array)Temp=Temp+cstr(Array(i))+chr(13)+chr(10)NextMsgBox Temp

56

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

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

Пример упорядочивания одномерного массива – см.пример 2; многомерных массивов см. в приложении, лис-тинги файлов service.vbs и soft.asp.

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

Параметры в файле разделены спецсимволом, в ка-честве которого рекомендуется один из символов табли-цы ASCII-II (см. рис. 2),выбор которого обусловлен тем,что ни один из них не может быть использован в описаниипараметров файла !meta.txt.

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

Пример файла cache.dat см. в приложении.В случае необходимости нагрузка по считыванию и

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

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

Подключение к файловому серверу необходимо осуще-ствлять с помощью сетевого диска, например, диска S (см.приложение файл cache.ini). Подключение к сетевому дискув данном примере осуществляется при помощи команды:

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

Данная команда запускает сценарий Service.vbs каждыйдень в 8 часов вечера на сервере под именем «Server».

Обработка кэш-файла

Файловая структура проекта на основе ASPИнструмент представляет сайт, точкой входа в которыйявляется страница на языке HTML. Сайт создан на осно-ве окон (Frame): файл default.htm делит окно браузера надва столбца.

Ðèñóíîê 2

Ïðèìåð 8: text= �____________� set fso = CreateObject("Scripting.FileSystemObject") set MyFile = fso.CreateTextFile(strFileName, True, TRUE) �  òåêñòîâûé ôàéë çàïèñûâàåòñÿ çíà÷åíèå ïåðåìåííîé «text» MyFile.WriteLine(text) MyFile.Close

net use s: \\server\software

AT \\Server 20:00 /interactive /every:M,T,W,Th,F,S,Su ↵↵↵↵↵C:\InetPub\Soft\Data\Service.vbs

Ïðèìåð 9: Ëèñòèíã ôàéëà default.htm<html><head><title>Ïðîãðàììíîå îáåñïå÷åíèå </title><meta http-equiv="Content-Type" content="text/html; ↵↵↵↵↵

charset=windows-1251">

Ïðèìåð 7: Øàáëîí ðåêóðñèâíîé ôóíêöèè���..' Âûçîâ ôóíêöèè RecFolder â òåëå ñöåíàðèÿRecFolder index, path���..Function Recfolder (idx, path)���..���..���..Call Recfolder (idx+1, path)���..End Function

57№7(20), июль 2004

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

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

Таблица стилей и выбор исходнойкодировки документаОбе ASP-страницы используют таблицу стилей. Тексто-вая информация изначально выводится в кодировке WIN-1251. Стили описываются в подключаемом файле style.css(см. приложение).

Файл стилей описывается в разделе <LINK>, необхо-димая кодировка – в разделе <META> (HTML):

Значение параметра CHARSET определяет исходнуюкодировку документа. Клиент, загрузив страницу, можетконвертировать ее для наилучшего отображения в любуюдругую удобную для него кодировку.

Остальные страницы, отображающиеся в 2 фреймах,см. рис. 1, взаимосвязаны друг с другом и являются ре-курсивными. Обе страницы создаются с помощью скрип-тов ASP.

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

Прямой метод: в исходной странице создается фор-ма, содержащая поля для ввода информации, кнопку дляотправки информации:

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

Подразделом, который обязательно присутствует в раз-деле <FORM>, является INPUT. INPUT имеет следующиепараметры: TYPE, NAME, VALUE. Параметр TYPE опреде-

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

Запрос, который формируется с помощью метода GET,в общем виде выглядит следующим образом: http://имя_страница.asp(htm)?П1=З1&П2=З2&...Пn=Зn.

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

Прямой метод используется для осуществления поиска.Косвенный метод: также используется для передачи

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

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

В качестве критерия может быть выбран один из пара-метров: «Везде», «Фирма», «Название». По умолчаниюпринято значение «Везде». Выбор значения по умолча-нию осуществляется меткой CHECKED в соответствую-щем разделе INPUT. Форма на странице-отправителе выг-лядит следующим образом (HTML):

Вторая часть поисковой системы – «приемник» инфор-мации находится в ASP-файле.

Считывание значений параметров осуществляетсяследующим образом:

Ïðèìåð 10:<HEAD><LINK HREF="style.css" TYPE=text/css REL=stylesheet><META HTTP-EQUIV ="Content-Type" CONTENT="text/html; ↵↵↵↵↵

CHARSET=windows-1251"></HEAD>

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

set search_t= Request.QueryString(«Search_Text»)

<FONT FACE="Arial" size="3"></FONT></head><!-- Ëåâûé ñòîëáåö ñîñòàâëÿåò 20% îò øèðèíû âñåãî îêíà.Ëåâîå îêíî èìååò èäåíòèôèêàòîð «SortSearch», âòîðîå «Product». --><frameset cols="25%,*" FRAMEBORDER="5" BORDER="yes" ↵↵↵↵↵

FRAMESPACING="5" ><frame src="sortsearch.asp" name="sortsearch" scrolling="yes" ↵↵↵↵↵

ÌÀRGINHEIGHT=1 ><frame src="soft.asp?Search_Text=&radGrp=1" name="product"></frameset></html>

Ïðèìåð 12:<% <A HREF="http://èìÿ_ñòðàíèöà.asp(htm)?Ï1=Ç1&Ï2=Ç2&...Ïn=Çn"target=" & chr(34) &"var"& chr(34) & " > ↵↵↵↵↵

<IMG SRC =images\pr1.jpg BORDER=0> </A> %>

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

<INPUT CHECKED TYPE="radio" VALUE="1" NAME="radGrp">Íàçâàíèå< INPUT TYPE="radio" VALUE="2" NAME="radGrp">Îïèñàíèå< INPUT TYPE ="radio" VALUE="3" NAME="radGrp">Ðàçìåùåíèå

</FORM>

Ïðèìåð 14:set radio_=Request.QueryString("radGrp")set search_= Request.QueryString("Search_Text")

58

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

после того как считаны параметры, указывающие, где ис-кать (radio_) и что искать (Search_), выполняется проце-дура поиска:

Отображение результатов: файл soft.aspФайл soft.asp является по своей сути сердцем проекта.Все остальные файлы являются вспомогательными. Фун-кция рождения страницы, содержащей всю необходимуюинформацию, возложена на сценарий, содержащийся вэтом файле. Рассмотрим алгоритм работы данного сце-нария.

На первом этапе осуществляется чтение информации,переданной прямым методом из HTML-файла. Из конфи-гурационного файла soft.ini считываются параметры, оп-ределяющие символ «разделить» и местоположение кэш-файла. На этом подготовительный этап завершен.

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

Затем каждая строка временного массива делится напараметры, разграниченные спецсимволом. Полученныеданные заносятся в многомерный массив.

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

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

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

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

рых следует осуществлять поиск. Затем выполняется про-цедура поиска и запись в переменную. Результат выво-дится на экран.

Внедрение визуальной частиВ качестве месторасположения инструмента можно выб-рать любой из серверов, на котором должен быть уста-новлен IIS. При установке IIS будет создана стандартнаяпапка C:\InetPub, в которой предлагается сделать подпап-ку Soft. В ней расположить файлы – defalt.htm, style.css,softsearch.asp, soft.asp.

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

1 Visual Basic Script Edition (VBScript) является интерпре-тируемым языком. Представляет собой сокращеннуюверсию VB. Имеет встроенную поддержку объектов.Сценарии могут быть не только встроенными в код веб-страницы, но и могут быть автономными файлами срасширением VBS.

2 В 1998 году Microsoft предложила в качестве инстру-мента разработки и выполнения сценариев для опера-ционной системы Microsoft Windows сервер сценариевWindows Scripting Host (WSH). В комплект поставкиMicrosoft Windows 98 входит WSH версии 1.0, в MicrosoftWindows 2000 – WSH 2.0; Сценарии WSH поддержива-ет два встроенных в Microsoft Windows языка програм-мирования – Microsoft Visual Basic Script Edition(VBScript) и Miscrosoft Java Script Edition(Jscript). WSHпредъявляет минимальные требования к объему ОП,является удобным инструментом для создания сцена-риев и автоматизации повседневных задач. Возмож-ности WSH-сценариев: выводить информацию в видедиалоговых сообщений; cчитывать информацию изпотока данных; управлять процессами MicrosoftWindows; подключать сетевые диски и принтеры; ра-ботать со специальными папками; с системным реест-ром; управлять OLE-объектами и т. д.

3 InStr([start, ]string1, string2[, compare]) – функция опре-деляет наличие подстроки в строке. Ее возвращаемымзначением является номер символа, начиная с которо-го подстрока совпадает со строкой. start – начальнаяпозиция, с которой начинается поиск. Является обяза-тельным параметром в случае использования парамет-ра тип сравнения; string1 – строка, в которой ищетсяподстрока, указанная в параметре string2; compare –числовой параметр, определяющий тип поиска строкив подстроке. Параметр compare может принимать сле-дующие значения:

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

5 Приложение со всеми листингами смотрите на сайтежурнала: http://www.samag.ru/source.

Ïðèìåð 15:Select case radio_Case "1"If instr(ucase(cstr(array_(i,0))), ucase(search_)) then

T=T+cstr(array_data(i,0)))+�End If

Case "2"If instr(ucase(cstr(array_data(i,1))), ucase(search_)) then

T=T+cstr(array_data(i,0)))+�End If��End Select

59№7(20), июль 2004

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

Недавно, подготавливая загрузочную антивируснуюдискету, у меня возникли трудности в ограничении по раз-меру – необходимые файлы не удавалось упаковать в объём3,5-дюймовой дискеты, несмотря на все ухищрения. Тог-да я решил поискать версию DOS с поддержкой FAT32, нос меньшим объёмом загрузочных файлов, чем у MS-DOSиз комплекта Windows. Оказалось, что у FreeDOS уже име-ются нужные возможности и при этом сохранился малень-кий объём загрузочного файла. Сравним размер ядра MS-DOS из состава Windows 98 Second Edition RUS и ядра издистрибутива FreeDOS Beta9RC5:

Разница почти в 5 раз! Так что для запуска с дискетыпредпочтительно использовать именно FreeDOS.

К сожалению, при работе с FreeDOS выяснился одиннеприятный момент – FreeDOS не поддерживает сменуинформации о кодовых страницах. Команда COUNTRY вфайле CONFIG.SYS обрабатывается только частично, ис-пользуется первый параметр (код страны) для установкинациональных форматов даты, времени, валюты и разде-

Разработка системы FreeDOS началась более 10 лет на-зад – файл HISTORY.TXT в исходных текстах ядра начи-нает отсчёт с 25 мая 1993 года. Несмотря на столь солид-ную историю, пригодной для практического использова-ния в современных условиях система стала недавно – под-держка файловой системы FAT32 начала разрабатывать-ся в 2001 году. Конечно, не все применения DOS требуютподдержки большой файловой системы. Задолго до по-явления FAT32 FreeDOS использовалась как встроеннаяоперационная система в условиях малого дискового про-странства и небольших объемов оперативной памяти, атакже входила в состав дистрибутива программыDOSEMU – среды эмуляции DOS для Linux. Однако дляменя DOS – это прежде всего система, которую можнозагрузить с дискеты и использовать для восстановленияработоспособности операционной системы на жесткомдиске, среда для запуска утилит аварийного восстанов-ления данных и антивирусных программ. После появле-ния версий Microsoft Windows с поддержкой файловойсистемы FAT32 использовать для аварийно-восстанови-тельных работ DOS без поддержки этой файловой систе-мы было проблематично. Поэтому достаточно длительноевремя FreeDOS меня не интересовала.

ВАДИМ ДРУЖИН

РУСИФИКАЦИЯ FreeDOS

60

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

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

Для сборки ядра FreeDOS нам понадобится компиля-тор языка C. Выполнять компиляцию можно при помощиTurbo C 2.01, Turbo C++ 1.01, Turbo C 3.0, Borland C 4.51 и5.01, по утверждению авторов, можно использовать другиекомпиляторы Borland, Microsoft C и (Open)Watcom C. Хотянекоторые версии компиляторов Borland сейчас доступныв Интернете для свободного скачивания, я (как и разработ-чики FreeDOS) рекомендую использовать OpenWatcom C.Я пробовал использовать для сборки компилятор Turbo C2.01. Процесс прошёл успешно, но получившееся ядро несмогло нормально загрузиться. А после сборки компиля-тором OpenWatcom C 1.2 получился полностью рабочийисполняемый файл.

Компилятор OpenWatcom можно свободно загрузитьиз Интернета по адресу: http://openwatcom.mirrors.pair.com/watcom/open-watcom-win32-1.2.exe – это полный инсталя-тор для среды Win32, включая компиляторы C и Fortran77(размер файла 63.1 Mб).

Если вы не хотите качать весь файл, можно получитьнабор только необходимых для компиляции компонентов поадресу: http://openwatcom.mirrors.pair.com/watcom/zips-1.2.

Компиляцию можно выполнять как из-под Windows, таки из-под DOS. Версию компилятора для DOS можно ис-пользовать, например, в среде DOSEMU под Linux. В за-висимости от ОС, под которой будет проходить компиля-ция, нужно скачать соответствующий набор ZIP-архивов.

Все скачанные архивы нужно распаковать в какой-нибудькаталог, пусть для определенности это будет C:\WATCOM.Распаковывать архивы нужно с сохранением структурыкаталогов.

Кроме компилятора C для сборки понадобится такжеассемблер NASM версии не ниже 0.98.36. Я использовалверсию 0.98.38 (DOS 32-bit). Загрузить NASM можно поадресу: http://nasm.sourceforge.net. Будем считать, чтоNASM распакован в каталог C:\NASM.

Маленький размер ядра FreeDOS достигается при по-мощи использования динамической упаковки. После ком-пиляции файл дополнительно обрабатывается упаковщи-ком UPX, и при загрузке происходит его автоматическаяраспаковка в оперативную память. Похожую технологиюиспользует ядро Linux, там для упаковки используетсяалгоритм GZIP или BZIP2. Скачать UPX можно по адресу:http://upx.sourceforge.net. Я пользовался UPX 1.24d (32-bitDOS version). По аналогии с NASM пусть UPX располага-ется в каталоге C:\UPX.

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

Вы можете скачать с сайта http://www.freedos.org/ дис-трибутив FreeDOS в виде образа загрузочного компакт-диска (ISO), в который входят исходные тексты, скомпи-лированные версии всех файлов и интерактивный инстал-лятор, либо скачать с того же адреса по отдельности не-обходимые утилиты (команды и драйверы DOS) и по ад-ресу http://sourceforge.net/projects/freedos/ исходные текстыядра.

Если скачивать утилиты по отдельности, вы получитесамые последние версии, программы, входящие в устано-вочный образ, могут быть устаревшими. Я использовал длясборки исходные тексты ядра версии 2.0.34 из дистрибути-ва FreeDOS Beta9RC5, они находятся в файле FREEDOS\PACKAGES\SRC_BASE\DISK04\KERNELS.ZIP на компакт-диске. После распаковки архива с сохранением структу-ры каталогов в корне диска C мы получим каталогC:\SOURCE\KE2034, в котором и располагаются исходныетексты, документация на английском языке (в подкатало-ге DOCS) и командные файлы, выполняющие сборку.Сборка производится с помощью командного файлаBUILD.BAT или утилиты make. При запуске make без па-раметров выполняется вызов того же самого BUILD.BAT,так что разницы фактически никакой.

Перед началом компиляции нужно задать парамет-ры, такие как тип и место нахождения используемогокомпилятора, архитектура процессора, для которогопредназначено ядро (16 или 32 бита), и необходимостьподдержки файловой системы FAT32. Задаются эти па-раметры в файле CONFIG.BAT. Чтобы получить исход-ный вариант файла (с настройками по умолчанию), нуж-но скопировать с этим именем файл CONFIG.B (copyCONFIG.B CONFIG.BAT). Теперь вносим в файлCONFIG.BAT необходимые изменения.

Следующие строки нужно закомментировать:

set COMPILER=TC2set TC2_BASE=c:\tc201set XCPU=86set XFAT=16

61№7(20), июль 2004

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

А взамен раскомментировать (убрать символы «:- » вначале строки):

Следующие строки изменить:

Если вы используете версию компилятора Watcom Cдля среды Win32, то в строку

нужно добавить путь к каталогу binnt:

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

Минимально необходимая модификация ядра, кото-рая позволяет без проблем обрабатывать файлы с рус-скими символами в именах, – это задание правильнойтаблицы преобразования строчных/заглавных букв. Ин-формация о кодовой странице (частью которой являет-ся таблица преобразования) хранится в файле KERNEL\NLS_HC.ASM. Этот файл является копией одного из ис-ходных файлов, находящихся в каталоге KERNEL\NLS.В стандартном ядре это KERNEL\NLS\001-437.HC.

Насколько я понял из комментариев, для созданияHC-файлов должна использоваться некая утилита, ко-торая преобразует файл формата UNF (Universal NLSdata Format) в ассемблерный листинг (HC). Никаких сле-дов этой утилиты мне обнаружить не удалось, поэтомуя решил взять в качестве исходного ассемблерный кодфайла NLS_HC.ASM и поменять таблицу непосредствен-но в нём. Структура файла вполне очевидна. Хотя, кро-ме заголовка, комментарии в файле отсутствуют, име-ющиеся имена меток достаточно информативны. Таб-лица преобразования регистра символов имеет метку_nlsUpcaseHardcoded. Кроме этой таблицы, я также ис-правил таблицу порядка сортировки, которая помеченакак _nlsCollHardcoded.

Порядок сортировки в изменённом варианте исполь-зуется не алфавитный, а по возрастанию расширенныхASCII-кодов символов.

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

Мой вариант файла NLS_HC.ASM можно скачать поссылке http://vdruzhin.chat.ru/freedos/007-866.hc. Послескачивания файл нужно переименовать и скопироватьвместо оригинального NLS_HC.ASM.

Теперь вернемся в каталог KE2034 и, собравшись с ду-хом, запустим команду BUILD.BAT. После окончания ком-пиляции в каталоге BIN мы получим файл KERNEL.SYS –наше новое ядро FreeDOS. Кроме него, в каталоге BINнаходятся дополнительные файлы и утилиты:! AUTOEXEC.BAT – пример конфигурационного коман-

дного файла;! CONFIG.SYS – пример конфигурационного файла DOS;! INSTALL.BAT – командный файл для создания загру-

зочной дискеты с собранным ядром;! KWC38632.map – карта памяти ядра (отладочная ин-

формация);! KWC38632.sys – копия ядра, в имени файла которого

указаны использованные опции сборки – тип компиля-тора, тип процессора, тип файловой системы;

! SYS.COM – команда для копирования системных фай-лов и записи на диск загрузочного сектора.

Я не разбирался, привязана ли жёстко командаSYS.COM к версии ядра, скорее всего нет, но на всякийслучай я использую оба файла, собранные совместно.

Чтобы проверить работоспособность скомпилирован-ных файлов, можно использовать командный файлINSTALL.BAT. Вставьте в дисковод A: чистую дискету и,находясь в каталоге KE2034\BIN, выполните командуINSTALL. На дискету будет скопировано ядро, конфигура-ционные файлы и командный интерпретатор.

Только при копировании файла COMMAND.COM воз-никает небольшая проблема. Дело в том, что команда SYSищет этот файл в трёх местах – в исходном каталоге, вкорневом каталоге исходного диска и в переменной сре-ды «COMSPEC», при этом она не проверяет, принадле-жит ли найденный файл именно FreeDOS. Так как в ката-логе KE2034\BIN после завершения сборки никакогоCOMMAND.COM нет, найден и скопирован на дискету бу-дет командный интерпретатор той операционной систе-мы, под которой выполнялась компиляция. Не самое пло-хое решение, однако если окажется, что текущая опера-ционная система – это не FreeDOS, а MS-DOS (или MSWindows), то загрузочная дискета будет неработоспособ-ной, так как COMMAND.COM от Microsoft работает тольков «своей» версии DOS. Чтобы исправить эту ситуацию,можно либо заранее скопировать в каталог KE2034\BINкомандный интерпретатор от FreeDOS, либо после созда-ния дискеты скопировать файл на неё, заменив вариант,записанный командой SYS. На инсталяционном компакт-диске FreeDOS COMMAND.COM можно найти в каталогеisolinux\buildcd.

Теперь осталось перезагрузить компьютер (не забывв настройках BIOS Setup разрешить загрузку с дискеты)и убедиться в работоспособности скомпилированногоядра.

Ссылки:1. FreeDOS – http://www.freedos.org2. OpenWatcom – http://www.openwatcom.org3. NASM (Netwide Assembler)- http://nasm.sourceforge.net4. UPX (Ultimate Packer for eXecutables) – http://upx.source-

forge.net

:- set COMPILER=WATCOM:- if not \%WATCOM% == \ goto watcom_defined:- set WATCOM=c:\watcom:- set PATH=%PATH%;%WATCOM%\binw:- set XCPU=386:- set XFAT=32

set XNASM=c:\bin\nasm16 →→→→→ set XNASM=c:\nasm\nasmset XUPX=upx --8086 �best →→→→→ set XUPX=c:\upx\upx --8086 --best

set PATH=%PATH%;%WATCOM%\binw

set PATH=%PATH%;%WATCOM%\binw;%WATCOM%\binnt

62

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

Механизмы внедрения в PE-файлы весьма разнообраз-ны, но довольно поверхностно описаны в доступной лите-ратуре. Имеющиеся источники либо катастрофически не-полны, либо откровенно неточны, да к тому же рассеянныпо сотням различных FAQ и tutorial. Приходится, выража-ясь словами Маяковского, перелопачивать тонны словес-ной руды, прежде чем обнаружится нечто полезное. Дан-ная работа представляет собой попытку систематизациии классификации всех известных способов внедрения.

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

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

ТЕХНИКА ВНЕДРЕНИЯ КОДАВ РЕ-ФАЙЛЫ И МЕТОДЫЕГО УДАЛЕНИЯ

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

Настоящая статья – попытка систематизировать и классифицировать существующие алгоритмывнедрения в PE32/PE64-файлы, способы визуальной идентификации потенциально опасного кодаи методы его удаления. Публикация рассчитана на широкий круг читателей, знакомых с языком Сии имеющих опыт системного программирования на операционных системах семейства Windows 9xи Windows NT.

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

Для экономии места в статье используется ряд обще-принятых сокращений, перечисленных ниже:! FA: File Alignment – физическое выравнивание секций;! SA, OA: Section Alignment или Object Alignment – вир-

туальное выравнивание секций;! RVA: Relative Virtual Address – относительный виртуаль-

ный адрес;! FS: First Section – первая секция файла;! LS: Last Section – последняя секция файла;! CS: Current Section – текущая секция файла;! NS: Next Section – следующая секция файла;! v_a: Virtual Address – виртуальный адрес;! v_sz: Virtual Size – виртуальный размер;! r_off: raw offset – физический адрес начала секции;! f_sz: raw size – физический размер секции;! DDIR: DATA DIRECTORY – нет адекватного перевода;! EP: Entry Point – точка входа.

63№7(20), июль 2004

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

Под Windows NT, если не оговорено обратное, подра-зумевается вся линейка NT-подобных операционных сис-тем: Windows NT 4.0/Windows 2000/Windows XP, а подWindows 9x – Windows 95, Windows 98 и Windows Me.

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

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

Цели и задачи Х-кодаПеред X-кодом стоят по меньшей мере три задачи:! разместить свое тело внутри подопытного файла;! перехватить управление до начала выполнения основ-

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

собственного функционирования.

Методология перехвата управления и определения ад-ресов API-функций уже рассматривалась нами ранее в[1, 2, 3], поэтому здесь не описывается. Ограничимся тем,что напомним читателю основные моменты.

Перехват управления обычно осуществляется следу-ющими путями:! переустановкой точки входа на тело X-кода;! внедрением в окрестности оригинальной точки входа

команды перехода на X-код (естественно, перед пере-дачей управления X-код должен удалить команду, вос-становив исходное содержимое EP);

! переустановкой произвольно взятой команды JMP/CALL на тело X-кода с последующей передачей управ-ления по оригинальному адресу (этот прием не гаран-тирует, что X-коду вообще удастся заполучить управ-ление, но зато обеспечивает ему феноменальнуюскрытность и максимальную защищенность от анти-вирусов);

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

Определение адресов API-функций обычно осуществ-ляется следующими путями:

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

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

! Прямым вызовом API-функций по их абсолютным ад-ресам, жестко прописанным внутри X-кода (адресафункций KERNEL32.DLL/NTDLL.DLL меняются от од-ной версии системы к другой, а адреса USER32.DLL ивсех остальных пользовательских библиотек непосто-янны даже в рамках одной конкретной системы и ва-рьируются в зависимости от Image Base остальных заг-ружаемых библиотек, поэтому при всей популярностиданного способа пользоваться им допустимо только вобразовательно-познавательных целях).

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

! Непосредственным поиском функций LoadLibrary/GetProcAddress в памяти, поскольку KERNEL32.DLL проеци-руется на адресное пространство всех процессов, а еебазовый адрес всегда выровнен на границу в 64 Кб, отнас всего лишь требуется просканировать первую по-ловину адресного пространства процесса на предметпоиска сигнатуры «MZ». Если таковая найдена – убеж-даемся в наличии сигнатуры «PE», расположенной посмещению e_lfanew от начала базового адреса загруз-ки. Если она действительно присутствует, анализируемDATA DIRECTORY и определяем адрес таблицы экспор-та, в которой требуется найти LoadLibraryA и GetProcAddress. Если же хотя бы одно из этих условий не со-впадает, уменьшаем указатель на 64 Кб и повторяемвсю процедуру заново. Пара соображений в подмогу:прежде чем что-то читать из памяти, вызовите функ-цию IsBad ReadPtr, убедившись, что вы вправе это де-лать; помните, что Windows 2000 Advanced Server иDatacenter Server поддерживают загрузочный параметр/3GB, предоставляющий в распоряжение процесса 3 Гбоперативной памяти и сдвигающий границу сканирова-ния на 1 Гб вверх; для упрощения отождествленияKERNEL32.DLL можно использовать поле Name RVA, со-держащееся в Export Directory Table и указывающее наимя динамической библиотеки, однако оно может бытьи подложным (системный загрузчик его игнорирует).

! Определением адреса функции KERNEL32!_except_handler3, на которую указывает обработчик структур-ных исключений по умолчанию. Эта функция не экс-портируется ядром, однако присутствует в отладочнойтаблице символов, которую можно скачать со следую-щего сервера http://msdl.microsoft.com/download/symbols.(Внимание! Сервер не поддерживает просмотр браузе-ром, и с ним работают только последние версии MicrosoftKernel Debugger и NuMega Soft-Ice). Это делается так:

Ðèñóíîê 1. Óñëîâíûå ãðàôè÷åñêèå îáîçíà÷åíèÿ, ïðèíÿòûå â ñòàòüå

64

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

После выполнения кода регистр EAX содержит адрес,лежащий где-то в глубине KERNEL32. Выравниваемего по границе 64 Кб и ищем MZ/PE-сигнатуры, как по-казано в предыдущем пункте (это наиболее коррек-тный и надежный способ поиска).

! Определением базового адреса загрузки KERNEL32.DLLчерез PEB:

Базовый код возвращается в регистре EBX (это оченьпростой, хотя и ненадежный прием, т.к. структура PEBв любой момент может измениться, и за все время су-ществования Windows она уже менялась по меньшеймере три раза, к тому же PEB есть только в NT);

! Использованием native API операционной системы, вза-имодействие с которым осуществляется либо черезпрерывание INT 2Fh (Windows 3.x, Windows 9x), либо че-рез прерывание INT 2Eh (Windows NT, Windows 2000),либо через машинную команду syscall (Windows XP).Краткий перечень основных функций можно найти вInterrupt List Ральфа Брауна: http://www.pobox.com/~ralf/files.html (это наиболее трудоемкий и наименее надеж-ный способ из всех, мало того, что native API-функ-ции не только недокументированы и подвержены по-стоянным изменениям, так они еще и до безобразияпримитивны, т.е. реализуют простейшие низкоуров-невые функции, непригодные к непосредственномуиспользованию).

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

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

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

(так же называемое затиранием);! размещение X-кода в свободном месте программы

(интеграция);! дописывание X-кода в начало, середину или конец

файла с сохранением оригинального содержимого;! размещение X-кода вне основного тела файла-носи-

теля (например, в динамической библиотеке или NTFS-потоке), загружаемого «головой» X-кода, внедреннойв файл одним из предыдущих способов.

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

Требования, предъявляемые к X-кодуВо-первых, X-код должен быть полностью перемещаем,т.е. сохранять свою работоспособность независимо отбазового адреса загрузки. Это достигается использова-нием относительной адресации: определив свое текущеерасположение вызовом команды:

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

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

В третьих, X-код должен быть предельно компактным,поскольку объем пространства, пригодного для внедре-ния, подчас очень даже ограничен. Имеет смыл разбитьX-код на две части: крошечный загрузчик и протяжныйхвост. Загрузчик лучше всего разместить в PE-заголовкеили регулярной последовательности внутри файла, а хвостсбросить в оверлей или NTFS-поток, комбинируя тем са-мым различные методы внедрения.

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

ВнедрениеПеред внедрением в файл необходимо убедиться, что онне является драйвером, не содержит нестандартных таб-лиц в DATA DIRECTORY и доступен для модификации.Присутствие оверлеев крайне нежелательно, и без осо-бой необходимости в оверлейный файл лучше ничего невнедрять, а если и внедрять, то придерживаться наибо-лее безболезненной стратегии внедрения – стратегии А(см. раздел «Классификация механизмов внедрения»).

Ниже все эти требования разобраны подробнее:! если файл расположен на носителе, защищенном от

записи, или у нас недостаточно прав для его записи/чтения (например, файл заблокирован другим процес-сом), отказываемся от внедрения;

mov esi, fs:[0]/lodsd/lodsd

mov eax, fs:[30h]/mov eax, [eax + 0Ch]/mov esi, ↵↵↵↵↵[eax + 1Ch]/lodsd/mov ebx, [eax + 08h]

  CALL $+5/POP EBP

65№7(20), июль 2004

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

! если файл имеет атрибут, запрещающий модифика-цию, либо снимаем этот атрибут, либо отказываемсяот внедрения;

! если поле Subsystem > 2h или Subsystem < 3h, отказы-ваемся от внедрения;

! если FA < 200h или SA < 1000h – это, вероятнее всего,драйвер, и в него лучше ничего не внедрять;

! если файл импортирует одну или несколько функцийиз hal.dll и/или ntoskrnl.exe, отказываемся от внедре-ния;

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

! если DATA DIRECTORY содержит ссылки на таблицы,использующие физическую адресацию, либо отказы-ваемся от внедрения, либо принимаем на себя обяза-тельства корректно «распотрошить» всю иерархиюструктур данных и скорректировать физические адре-са;

! если ALIGN_UP(LS.r_off + LS.r_sz, A) > SizeOfFile, файлскорее всего содержит оверлей, и внедряться в негоможно только по методу А;

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

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

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

Еще несколько соображений общего типа. В последнеевремя все чаще и чаще приходится сталкиваться с испол-няемыми файлами чудовищного объема, неуклонно при-ближающегося к отметке в несколько гигабайт. Обрабаты-вать таких монстров по кускам нудно и сложно. Загружатьвесь файл целиком – слишком медленно, да и позволит лиWindows выделить такое количество памяти! Поэтому име-ет смысл воспользоваться файлами, проецируемыми в па-мять (Memory Mapped File), управляемыми функциямиCreateFileMapping и MapViewOfFile/UnmapView OfFile. Этоне только увеличивает производительность, упрощает про-граммирование, но и ликвидирует все ограничения на пре-дельно допустимый объем, который теперь может дости-гать 18 экзобайтов, что соответствует 1 152 921 504 606846 976 байтам. Как вариант можно ограничить размеробрабатываемых файлов несколькими мегабайтами, лег-ко копируемыми в оперативный буфер и сводящими коли-чество «обвязочного» кода к минимуму (кто работал с фай-лами от 4 Гб и выше, тот поймет).

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

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

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

Родственные X-коды всегда могут «договориться» другс другом, отмечая свое присутствие уникальной сигнату-рой. Например, если файл содержит строку «x-codeZANZIBAR here», отказываемся от внедрения на том ос-новании, что здесь уже есть «свои». К сожалению, этоттрюк очень ненадежен, и при обработке файла любым упа-ковщиком/протектором сигнатура неизбежно теряется. Нуразве что внедрить сигнатуру в ту часть секции ресурсов,которую упаковщики/протекторы предпочитают не трогать(иконка, информация о файле и т. д.). Еще надежнее вне-дрять сигнатуру в дату/время последней модификациифайла (например, в десятые доли секунды). Упаковщики/протекторы ее обычно восстанавливают, однако короткаядлина сигнатуры вызывает большое количество ложныхсрабатываний, что тоже нехорошо.

66

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

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

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

Классификация механизмов внедренияМеханизмы внедрения можно классифицировать по-раз-ному: по месту (начало, конец, середина), по «геополити-ке» (затирание исходных данных, внедрение в свободноепространство, переселение исходных данных на новоеместо обитания), по надежности (предельно корректное,вполне корректное и крайне некорректное внедрение), порентабельности (рентабельное или нерентабельное) и т. д.Мы же будем отталкиваться от характера воздействия нафизический и виртуальный образ подопытной програм-мы, разделив все существующие механизмы внедренияна четыре категории, обозначенные латинскими буквамиA, B, C и Z.! К категории А относятся механизмы, не вызывающие

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

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

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

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

Категория A наименее конфликтна и приводит к от-казу лишь тогда, когда файл контролирует свою целост-ность. Сфера применений категорий B и C гораздо бо-лее ограничена, в частности, она неспособна обрабаты-вать файлы с отладочной информацией, поскольку от-ладочная информация практически всегда содержитбольшое количество ссылок на абсолютные адреса. Ееформат не документирован, и к тому же различные ком-пиляторы используют различные форматы отладочнойинформации, поэтому скорректировать ссылки на новыеадреса нереально. Помимо отладочной информации ещесуществуют сертификаты безопасности и прочие струк-туры данных, нуждающиеся в неприкосновенности сво-их смещений. К сожалению, механизмы внедрения кате-гории А налагают достаточно жесткие ограничения напредельно допустимый объем X-кода, определяемыйколичеством свободного пространства, имеющегося впрограмме, и достаточно часто здесь не находится мес-та даже для крохотного загрузчика, поэтому приходитсяидти на вынужденный риск, используя другие категориивнедрения.

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

Категория A: внедрение в пустое место файла

Внедрение в PE-заголовокТипичный PE-заголовок вместе с MS-DOS-заголовком изаглушкой занимает порядка 300h байт, а минимальнаякратность выравнивания секций составляет 200h. Такимобразом, между концом заголовка и началом первой сек-ции практически всегда имеется 100h бесхозных байт,которые можно использовать для «производственных це-лей», размещая здесь либо всю внедряемую программуцеликом, либо только загрузчик X-кода, считывающийсвое продолжение из дискового файла или реестра.

67№7(20), июль 2004

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

Внедрение. Перед внедрением в заголовок X-код дол-жен убедиться, что хвостовая часть заголовка (ласково на-зываемая «предхвостием») действительно свободна, т.е.SizeOfHeadres < FS.r_off. Если же SizeOfHeadres == FS.r_offвовсе не факт, что свободного места в конце заголовканет. «Подтягивать» хвост заголовка к началу первой сек-ции – обычная практика большинства линкеров, усматри-вающих в этом гармонию высшего смысла. Сканирова-ние таких заголовков обычно выявляет длинную цепочкунулей, расположенных в его хвосте и, очевидно, никак иникем не используемых. Может ли X-код записать в нихсвое тело? Да, может, но только с предосторожностями.Необходимо отсчитать по меньшей мере 10h байт от пос-леднего ненулевого символа, оставляя этот участок не-тронутым (в конце некоторых структур присутствует до 10hнулей, искажение которых ни к чему хорошему не приве-дет).

Некоторые программисты пытаются проникнуть в MS-DOS-заголовок и заглушку. Действительно, загрузчикWindows NT реально использует всего лишь шесть байт:сигнатуру «MZ» и указатель e_lfanew. Остальные же егоникак не интересует и могут быть использованы X-кодом.Разумеется, о последствиях запуска такого файла в го-лой MS-DOS лучше не говорить, но… MS-DOS уже давнотруп. Правда, некоторые вполне современные PE-загруз-чики дотошно проверяют все поля MS-DOS-заголовка (вособенности это касается win32-эмуляторов), поэтому безособой нужды лучше в них не лезть, а вот использоватьдля своих нужд MS-DOS-заглушку можно, пускай и не безограничений. Многие системные загрузчики неспособнытранслировать виртуальные адреса, лежащие к западу отPE-заголовка, что препятствует размещению в MS-DOS-заголовке/заглушке служебных структур PE-файла. Дажеи не пытайтесь внедрять сюда таблицу импорта или таб-лицу перемещаемых элементов! А вот тело X-кода вне-дрять можно.

Кстати говоря, при обработке файла популярным упа-ковщиком UPX X-код, внедренный в PE-заголовок, не вы-живает, поскольку UPX полностью перестраивает заголо-вок, выбрасывая оттуда все «ненужное» (MS-DOS-заглуш-ку он, к счастью, не трогает). Упаковщики ASPack и tElockведут себя более корректно, сохраняя и MS-DOS-заглуш-ку, и оригинальный PE-заголовок, однако X-код долженисходить из худшего варианта развития событий.

В общем случае внедрение в заголовок осуществля-ется так:! считываем PE-заголовок и приступаем к его анализу;! если SizeOfHeaders < FS.r_off и (SizeOfHeaders + sizeof(X-

code))< FS.r_off, то:! увеличиваем SizeOfHeaders на sizeof(X-code) или же

просто подтягиваем его к raw offset первой секции;! записываем X-код на образовавшееся место;

! иначе:! сканируем PE-заголовок на предмет поиска непре-

рывной цепочки нулей и, если таковая будет дей-ствительно найдена, внедряем свое тело, начиная с10h байта от ее начала;

! внедряем X-код в MS-DOS-заглушку, не сохраняя еестарого содержимого;

! если внедрение прошло успешно, перехватываем уп-равление на X-код.

Идентификация пораженных объектов. Внедрениев PE-заголовок в большинстве случаев можно распоз-нать и визуально. Рассмотрим, как выглядит в hex-ре-дакторе типичный исполняемый файл (см. рис. 3): вследза концом MS-DOS-заголовка, обычно содержащим всебе строку «This program cannot be run in DOS mode»(или что-то подобное), расположена «PE»-сигнатура, закоторой следует немного мусора, щедро разбавленногонулями и плавно перетекающего в таблицу секций, со-держащую легко узнаваемые имена .text, .rsrc и .data(если файл упакован, названия секций скорее всего бу-дут другими).

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

Восстановление пораженных объектов. Не все ди-зассемблеры позволяют дизассемблировать PE-заголо-вок. IDA PRO относится к числу тех, что позволяют, ноделает это только в случаях крайней необходимости, ког-да точка входа указывает внутрь заголовка. Заставить жеее отобразить заголовок вручную, судя по всему, невоз-можно. HIEW в этом отношении более покладист, но RVA-адреса и переходы внутри заголовка он не транслирует иих приходится вычислять самостоятельно. Дизассембли-ровав X-код и определив характер и стратегию перехватауправления, восстановите пораженный файл в исходныйвид или потрассируйте X-код в отладчике, позволив емусделать это самостоятельно, а в момент передачи управ-ления оригинальной программе сбросьте дамп (разуме-ется, прогон активного X-кода под отладчиком всегда таитв себе угрозу и отлаживаемая программа в любой моментможет вырваться из-под контроля, поэтому если вы хотябы чуточку не уверены в себе, пользуйтесь дизассембле-ром, так будет безопаснее).

Если X-код оказался утрачен, например, вследствиеупаковки UPX, распакуйте файл и постарайтесь иденти-фицировать стартовый код оригинальной программы (вэтом вам поможет IDA PRO), переустановив на него точ-ку входа. Возможно, вам придется реконструировать ок-рестности точки входа, разрушенные командой перехо-да на X-код. Если исходный стартовый код начинался спролога (а в большинстве случаев это так), то на ремонтфайла уйдет совсем немного времени (первые 5 байтпролога стандартны и легко предсказуемы, обычно это55 8B EC 83 EC, 55 8B EC 83 C4, 55 8B EC 81 EC или

Ðèñóíîê 2. Âíåäðåíèå X-êîäà â ñâîáîäíîå ïðîñòðàíñòâî õâîñòàPE-çàãîëîâêà

68

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

55 8B EC 81 C4, правильный вариант определяется поправдоподобности размера стекового фрейма, отводи-мого под локальные переменные). При более серьезныхразрушениях алгоритм восстановления становится нео-днозначен, и вам, возможно, придется перебрать боль-шое количество вариантов. Попробуйте отождествитькомпилятор и изучить поставляемый вместе с ним стар-товый код – это существенно упрощает задачу. Хуже,если X-код внедрился в произвольное место программы,предварительно сохранив оригинальное содержимое взаголовке (которого теперь с нами нет). Возвратить ис-порченный файл из небытия скорее всего будет невоз-можно, во всяком случае, никаких универсальных рецеп-тов его реанимации не существует.

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

которая, к сожалению, неверна. Как уже говорилось выше,любой компилятор/линкер вправе использовать всеSizeOfHeaders байт заголовка.

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

Ðèñóíîê 3. Òàê âûãëÿäèò òèïè÷íûé PE-çàãîëîâîê íåçàðàæåííîãî ôàéëà

e_lfanew + SizeOfOptionalHeader + 14h + NumberOfSections*40

69№7(20), июль 2004

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

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

Для приличия (чтобы не ругались антивирусы) можноудалить неактивный X-код из файла, установив SizeOfHeaders на последний байт таблицы секций (или таблицыдиапазонного импорта, если она есть) и вплоть до FS.r_off,заполнив остальные байты нулями, символом «*» илилюбым другим символом по своему вкусу. Например, «по-сторонним вирусам вход воспрещен!».

Внедрение в хвост секцииОперационная система Windows 9x требует, чтобы физи-ческие адреса секций были выровнены по меньшей мерена 200h байт (Windows NT – на 002h), поэтому между сек-циями практически всегда есть некоторое количество сво-бодного пространства, в котором легко затеряться.

Рассмотрим структуру файла notepad.exe из поставкиWindows 2000 (см. листинг 2). Физический размер секции.text превышает виртуальный на 6600h – 65CAh == 36h байт,а .rsec – аж на C00h! Вполне достаточный объем простран-ства для внедрения, не правда ли? Разумеется, такое ве-зение выпадает далеко не всегда, но пару десятков сво-бодных байт можно найти практически в любом файле.

Ðèñóíîê 4. Òàê âûãëÿäèò çàãîëîâîê ôàéëà ïîñëå âíåäðåíèÿ X-êîäà

Ëèñòèíã 1. Äèçàññåìáëåðíûé  ôðàãìåíò  X-êîäà,  âíåäðåííîãîâ çàãîëîâîê (âñå êîììåíòàðèè ïðèíàäëåæàò Èäå)HEADER:01000300 ; The code at 01000000-01000600 is hidden

; from normal disassemblyHEADER:01000300 ; and was loaded because the user ordered

; to load it explicitlyHEADER:01000300 ;HEADER:01000300 ; <<<< IT MAY CONTAIN TROJAN HORSES,

; VIRUSES, AND DO HARMFUL THINGS >>>HEADER:01000300 ;HEADER:01000300 public startHEADER:01000300  start:HEADER:01000300 call $+5HEADER:01000305 pop ebpHEADER:01000306 mov esi, fs:0HEADER:0100030C lodsdHEADER:0100030D push ebpHEADER:0100030E lodsdHEADER:0100030F push eax

Ëèñòèíã 2. Òàê âûãëÿäèò òàáëèöà ñåêöèé ôàéëà notepad.exeNumber Name v_size  RVA   r_size  r_offst flag  1 .text 00065CA 0001000 0006600 0000600 60000020  2 .data 0001944 0008000 0000600 0006C00 C0000040  3 .rsrc 0006000 000A000 0005400 0007200 40000040

Ðèñóíîê 5. Âíåäðåíèå X-êîäà â õâîñò ñåêöèè, îñòàâøèéñÿîò  âûðàâíèâàíèÿ

70

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

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

Правда тут есть одно «но», почему-то не учитывае-мое подавляющим большинством разработчиков: есливиртуальный размер секции меньше физического, заг-рузчик игнорирует физический размер (хотя и не обязанэто делать) и он может быть любым, в том числе и заве-домо бессмысленным! Если виртуальный размер равеннулю, загрузчик использует в качестве него физический,округляя его на величину Section Alignment. Поэтому,если r_off + r_sz некоторой секции превышает r_off сле-дующей секции, следует либо отказаться от обработкитакого файла, либо самостоятельно вычислить физичес-кий размер на основе разницы raw offset двух соседнихсекций.

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

Большинство разработчиков X-кода, проявляя преступ-ную небрежность, пренебрегают проверкой атрибутовсекции, что приводит к критических ошибкам и прочимсерьезным проблемам. Внедряемая секция должна быть,во-первых, доступной (флаг IMAGE_SCN_MEM_READ ус-тановлен) и, во-вторых, невыгружаемой (флаг IMAGE_SCN_MEM_DISCARDABLE сброшен). Желательно, но нео-бязательно, чтобы по крайней мере один из флаговIMAGE_SCN_CNT_CODE, IMAGE_SCN_CNT_INITIALIZED_DATA был установлен. Если же эти условия не соблюда-ются и других подходящих секций нет, допустимо моди-фицировать флаги одной или нескольких секций вручную,однако работоспособность подопытного приложения вэтом случае уже не гарантирована. Если флаги IMAGE_SCN_MEM_SHARED и IMAGE_SCN_MEM_WRITE установ-лены, в такую секцию может писать кто угодно и что угод-но, а во-вторых, адрес ее загрузки может очень сильноотличаться от v_a, поскольку та же Windows 9x позволяетвыделять разделяемую память только во второй полови-не адресного пространства.

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

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

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

Обобщенный алгоритм внедрения выглядит приблизи-тельно так:! считываем PE-заголовок;! анализируем Section Table, сравнивая физическую

длину секций с виртуальной;! ищем секции, у которых r_sz > v_sz, и записываем их

в кандидаты на внедрение, предварительно убедив-шись, что в хвосте секции содержатся одни нули;

! если r_sz – v_sz >= FA, не трогаем такую секцию, т.к.скорее всего она содержит оверлей;

! если кворума набрать не удалось, ищем секции, у ко-торых r_sz <= v_sz, и пытаемся найти непрерывную це-почку нулей в их конце;

! из всех кандидатов отбираем секции с наибольшим ко-личеством свободного места;

! находим секцию, атрибуты которой располагают к вне-дрению (IMAGE_SCN_MEM_SHARED, IMAGE_SCN_MEM_DISCARDABLE cброшены, IMAGE_SCN_MEM_READ илиIMAGE_SCN_MEM_EXECUTE установлены, IMAGE_SCN_CNT_CODE или IMAGE_SCN_CNT_INITIALIZED_DATAустановлены), а если таких среди оставшихся канди-датов нет, либо корректируем атрибуты самостоятель-но, либо отказываемся от внедрения;

! если v_sz != 0 и v_sz < r_sz, увеличиваем v_sz наsizeof(X-code) или подтягиваем к v_a следующей сек-ции.

Идентификация пораженных объектов. Распознатьвнедрения этого типа достаточно проблематично, осо-бенно если X-код полностью помещается в первой кодо-вой секции файла, которой, как правило, является сек-ция .text.

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

Внедрение во все служебные секции (например, сек-цию ресурсов или fixup) распознается по наличию в нихчужеродных элементов, которые не принадлежат никакойподструктуре данных (см. рис. 6).

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

71№7(20), июль 2004

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

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

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

Внедрение в регулярную последовательность байтЦепочки нулей необязательно искать в хвостах секций.Дался нам этот хвост, когда остальные части файла ни-чуть не хуже, а зачастую даже лучше конца! Скажембольше, необязательно искать именно нули – для вне-дрения подходит любая регулярная последовательность(например, цепочка FF FF FF… или даже FF 00 FF 00…),которую мы сможем восстановить в исходный вид пе-ред передачей управления. Если внедряемых цепочекбольше одной, X-коду придется как бы «размазаться»по телу файла (а скорее всего так и будет). Соответ-ственно стартовые адреса и длины этих цепочек при-

дется где-то хранить, иначе как потом прикажете их вос-станавливать?

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

Правда, некоторые программисты исподтишка внедря-ются в таблицу перемещаемых элементов, необратимо за-тирая ее содержимое, поскольку, по их мнению, исполняе-мым файлам она не нужна. Варвары! Хоть бы удостовери-лись сначала, что 01.00.00.00h >= Image Base >= 40.00.00h,в противном случае таблица перемещаемых элементовреально нужна файлу! К тому же не все файлы с расши-рением EXE исполняемые. Под их личиной вполне можетпрятаться и динамическая библиотека, а динамическим

Ðèñóíîê 6. Îñìûñëåííûé ìàøèííûé êîä â õâîñòå ñåêöèè äàííûõ � ïðèçíàê âíåäðåíèÿ

72

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

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

Автор знаком с парой лабораторных вирусов, умелоинтегрирующих X-код в оригинальную программу и ак-тивно использующих строительный материал, найденныйв теле файла-хозяина. Основной интерес представляютбиблиотечные функции, распознанные по их сигнатуре(например, sprintf, rand), а если таковых не обнаружива-ется, X-код либо ограничивает свою функциональность,либо реализует их самостоятельно. В дело идут и оди-ночные машинные команды, такие как CALL EBX илиJMP EAX. Смысл этого трюка заключается в том, что по-добное перемешивание команд X-кода с командами ос-новной программы не позволяет антивирусам делить X-код от файла. Однако данная техника еще не доведенадо ума и все еще находится в стадии разработки…

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

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

! убеждаемся, что никакая часть цепочки не принадле-жит ни одной из подструктур, перечисленных в DATADIRECTORY (именно подструктур, а не структур, по-скольку таблицы экспорта/импорта, ресурсов, переме-щаемых элементов образуют многоуровневые древо-видные иерархии, произвольным образом рассеянныепо файлу, ограничиться одной лишь проверкой к при-надлежности IMAGE_DATA_DIRECTORY.VirtualAddressи IMAGE_DATA_DIRECTORY.Size категорически недо-статочно);

! проверяем атрибуты секции, которым принадлежит це-почка (IMAGE_SCN_MEM_SHARED, IMAGE_SCN_MEM_DISCARDABLE cброшены, IMAGE_SCN_MEM_READили IMAGE_SCN_MEM_EXECUTE установлены, IMAGE_SCN_CNT_CODE или IMAGE_SCN_CNT_INITIALIZED_DATA установлены);

! «нарезаем» X-код на дольки, добавляя в конец каж-дой из них команду перехода на начало следующей,не забывая о том, что тот jmp, который соответствуетмашинному коду EBh, работает с относительными ад-ресами, и это те самые адреса, которые образуются

после загрузки программы в память. С «сырыми» сме-щениями внутри файла они вправе не совпадать. Какправильно вычислить относительный адрес перехода?Определяем смещение команды перехода от физичес-кого начала секции, добавляем к нему пять байт (дли-на команды вместе с операндом). Полученную вели-чину складываем с виртуальным адресом секции икладем полученный результат в переменную a1. За-тем определяем смещение следующей цепочки, отсчи-тываемое от начала той секции, к которой она принад-лежит, и складываем его с виртуальным адресом, за-писывая полученный результат в переменную a2. Раз-ность a2 и a1 и представляет собой операнд инструк-ции jmp;

! запоминаем начальные адреса, длины и исходное со-держимое всех цепочек в импровизированном храни-лище, сооруженном либо внутри PE-заголовка, либовнутри одной из цепочек. Если этого не сделать, тог-да X-код не сможет извлечь свое тело из файла-хо-зяина для внедрения во все последующие. Некото-рые разработчики вместо команды jmp используютcall, забрасывающий на вершину стека адрес возвра-та. Как нетрудно сообразить, совокупность адресоввозврата представляет собой локализацию «хвостов»всех используемых цепочек, а адреса «голов» хранят-ся в операнде команды call! Извлекаем очереднойадрес возврата, уменьшаем его на четыре и относи-тельный стартовый адрес следующей цепочки переднами!

Идентификация пораженных объектов. Внедрениев регулярную последовательность достаточно легко рас-познать по длинной цепочке jmp или call, протянувшихсячерез одну или несколько секций файла и зачастуюрасполагающихся в совсем несвойственных исполняемо-му коду местах, например, секции данных (см. листинг 3).А если X-код внедрится внутрь иконки, она начинает ха-рактерно «шуметь» (см. рис. 8). Хуже, если одна регуляр-ная цепочка, расположенная в кодовой секции, вмещаетв себя весь X-код целиком – тогда для выявления внедрен-ного кода приходится прибегать к его дизассемблирова-нию и прочим хитроумным трюкам. К счастью, такие ре-гулярные цепочки в живой природе практически не встре-чаются. Во всяком случае, просканировав содержимоепапок WINNT и Program Files, я обнаружил лишь один та-кой файл, да и то деинсталлятор.

Ðèñóíîê 7. Âíåäðåíèå X-êîäà â ðåãóëÿðíûå öåïî÷êè

Ëèñòèíã 3. Âíåäðåíèå X-êîäà â ðåãóëÿðíûå öåïî÷êè.0100A708: 9C pushfd.0100A709: 60 pushad.0100A70A:  E80B000000 call .00100A71A   --- (1).0100A70F:  64678B260000 mov esp,fs:[00000].0100A715:  6467FF360000 push d,fs:[00000].0100A71B:  646789260000 mov fs:[00000],esp.0100A721:  E800000000 call .00100A726   --- (2).0100A726: 5D pop ebp.0100A727:  83ED23 sub ebp,023 ;"#".0100A72A:  EB2B jmps .00100A757   -------- (3)�.0100A757:  EB0E jmps .00100A767   -------- (1)�

73№7(20), июль 2004

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

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

Восстановление иконок и bitmap не представляетбольшой проблемы и осуществляется тривиальной прав-кой ресурсов в любом приличном редакторе (например,в Visual Studio). Задачу существенно упрощает тот факт,что все иконки обычно хранятся в нескольких экземпля-рах, выполненных с различной цветовой палитрой и раз-решением. К тому же из всех регулярных последователь-ностей программисты обычно выбирают для внедрениянули, соответствующие прозрачному цвету в иконках ичерному в bitmap. Сама картинка остается неповрежден-ной, но окруженной мусором, который легко удаляетсяластиком. Если после удаления X-кода файл отказыва-ется запускаться, просто смените редактор ресурсовлибо воспользуйтесь hiew, при минимальных навыкахработы с которым иконки можно править и в hex-режиме(считайте, что идете по стопам героев «Матрицы», рас-сматривающих окружающий мир через призму шестнад-цатеричных кодов).

Отдельный случай представляет восстановление таб-лицы перемещаемых элементов, необратимо разрушен-ных внедренным X-кодом. Если Image Base < 40.00.00h, та-кой файл не может быть загружен под Windows 9x, если внем нет перемещаемых элементов. Причем поле IMAGE_DIRECTORY_ENTRY_BASERELOC имеет приоритет надфлагом IMAGE_FILE_RELOCS_STRIPPED, и если IMAGE_DIRECTORY_ENTRY_BASERELOC != 0, а таблица переме-щаемых элементов содержит мусор, то попытка переме-щения файла приведет к непредсказуемым последстви-ям – от зависания до отказа в загрузке. Если это возмож-но, перенесите поврежденный файл на Windows NT, ми-нимальный базовый адрес загрузки которой составляет1.00.00h, что позволяет ей обходиться без перемещенийдаже там, где Windows 9x уже не справляется.

X-код, не проверяющий флага IMAGE_FILE_DLL, мо-жет внедриться и в динамические библиотеки, имеющиерасширение EXE. Вот это действительно проблема! В от-личие от исполняемого файла, всегда загружающегосяпервым, динамическая библиотека вынуждена подстраи-ваться под конкретную среду самостоятельно, и без пере-мещаемых элементов ей приходится очень туго, посколь-ку на один и тот же адрес могут претендовать множествобиблиотек. Если разрешить конфликт тасованием библио-тек в памяти не удастся (это можно сделать утилитойEDITBIN из SDK, запущенной с ключом /REBASE), придет-ся восстанавливать перемещаемые элементы вручную.Для быстрого отождествления всех абсолютных адресовможно использовать следующий алгоритм: проецируемфайл в память, извлекаем двойное слово, присваиваемее переменной X. Нет, X не годится, возьмем Y. ЕслиY >= Image Base и Y <= (Image Base + Image Size), объяв-ляем текущий адрес кандидатом в перемещаемые эле-менты. Смещаемся на байт, извлекаем следующее двой-ное слово и продолжаем действовать в том же духе, покане достигнем конца образа. Теперь загружаем исследуе-мый файл в ИДУ и анализируем каждого кандидата на«правдоподобность» – он должен представлять собойсмещение, а не константу (отличие констант от смещенийподробно рассматривалось в «Фундаментальных основаххакерства» Криса Касперски). Остается лишь сформиро-вать таблицу перемещаемых элементов и записать ее вфайл. К сожалению, предлагаемый алгоритм чрезвычай-но трудоемок и не слишком надежен, т.к. смещение легкоспутать с константой. Но других путей, увы, не существу-ет. Останется надеяться лишь на то, что X-код окажетсямал и затрет не всю таблицу, а только ее часть.

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

Ðèñóíîê 8. Âíåäðåíèå X-êîäà â ãëàâíóþ èêîíêó ôàéëà

.0100A767:  8BC5 mov eax,ebp

.0100A769:  EB2C jmps .00100A797   -------- (1)�.0100A797:  EB5E jmps .00100A7F7   -------- (1)�.0100A7F7:  EB5E jmps .00100A857   -------- (1)�.0100A857:  EB3E jmps .00100A897   -------- (1)�.0100A897:  EB3D jmps .00100A8D6   -------- (1)�.0100A8D6:  EB0D jmps .00100A8E5   -------- (1)�.0100A8E5:  2D00200000 sub eax,000002000 ;"    ".0100A8EA:  89857E070000 mov [ebp][00000077E],eax.0100A8F0: 50 push eax.0100A8F1:  0500100000 add eax,000001000 ;"   ".0100A8F6:  89857E070000 mov [ebp][00000077E],eax.0100A8FC: 50 push eax.0100A8FD:  0500100000 add eax,000001000 ;"   ".0100A902:  EB31 jmps .00100A935   -------- (1)

74

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

луатации! Исключение составляют, пожалуй, одни лишьупакованные файлы, которые уже не ужмешь, хотя…много ли X-коду нужно пространства? А секция кодаупакованного файла по-любому должна содержать упа-ковщик, хорошо поддающийся сжатию. Собственно го-воря, разрабатывать свой компрессор совершенно нео-бязательно, т.к. соответствующий функционал реали-зован и в самой ОС (популярная библиотека lz32.dll длянаших целей непригодна, поскольку работает исключи-тельно на распаковку, однако в распоряжении X-кодаимеются и другие упаковщики: аудио-/видео-кодеки,экспортеры графических форматов, сетевые функциисжатия и т. д.).

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

Возникают проблемы и при распаковке. Она должнаосуществляться на предельной скорости, иначе время заг-рузки файла значительно возрастет и пользователь тутже почует что-то неладное. Поэтому обычно сжимают невсю секцию целиком, а только ее часть, выбрав места снаибольшей степенью сжатия. Страницы кодовой секцииот записи защищены, и попытка их непосредственной мо-дификации вызывает исключение. Можно, конечно, привнедрении X-кода присвоить кодовой секции атрибутIMAGE_SCN_MEM_WRITE, но красивым это решение ни-как не назовешь: оно демаскирует X-код и снижает на-дежность программы. Это все равно что сорвать с котлааварийный клапан – так и до взрыва недалеко. Лучше (иправильнее!) динамически присвоить атрибут PAGE_READWRITE вызовом VirtualProtect, а после завершенияраспаковки возвратить атрибуты на место.

Внедрение. Обобщенный алгоритм внедрения выгля-дит так:! открываем файл, считываем PE-заголовок;! находим в таблице секций секцию с атрибутом IMAGE_

SCN_CNT_CODE (как правило, это первая секция фай-ла);

! убеждаемся, что эта секция пригодна для внедрения(она сжимается, не содержит в себе никаких служеб-ных таблиц, используемых загрузчиком, и не имеетатрибута IMAGE_SCN_MEM_DISCARDABLE);

! сжимаем секцию и размещаем X-код либо в началесекции, либо в ее конце;

! анализируем таблицу перемещаемых элементов и от-бираем оттуда все элементы, относящиеся к сжатой ча-сти секции, и размещаем их внутри X-кода, а на осво-бодившиеся места записываем IMAGE_REL_BASED_ABSOLUTE – своеобразный аналог команды NOP дляперемещаемых элементов.

Идентификация пораженных объектов. Распознатьфакт внедрения в файл путем сжатия части секции труд-но, но все-таки возможно. Дизассемблирование сжатойсекции обнаруживает некоторое количество бессмыслен-ного мусора, настораживающего опытного исследовате-ля, но зачастую ускользающего от новичка. Разумеется,речь не идет о внедрении в секцию данных – присутствиепостороннего кода в которой не заметит только слепой(однако если X-код перехватывает управление косвен-ным образом, он не будет дизассемблированной ИДОЙи может прикинуться овечкой невинного массива дан-ных).

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

Восстановление пораженных объектов. Типичнаяошибка большинства разработчиков – отсутствие про-верки на принадлежность сжимаемой секции служебнымструктурам (или некорректно выполненная проверка). Вбольшинстве случаев ситуация обратима, достаточно об-нулив все поля DATA DIRECTORY загрузить файл в ди-зассемблер, реконструировать алгоритм распаковщикаи написать свой собственный, реализованный на любомсимпатичном вам языке (например, ИДА-Си, тогда длявосстановления файла даже не придется выходить изИДЫ).

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

Категория A: создание нового NTFS-потокавнутри файлаФайловая система NTFS поддерживает множество по-токов в рамках одного файла, иначе называемых рас-ширенными атрибутами (Extended Attributes) или имено-ванными разделами. Безымянный атрибут соответству-ет основному телу файла, атрибут $DATE – времени со-здания файла и т. д. Вы также можете создавать и своиатрибуты практически неограниченной длины (точнее, до64 Кб), размещая в них всякую всячину (например, X-код). Аналогичную технику использует и Mac OS, толькотам потоки именуются труднопереводимым словом forks.

Ðèñóíîê 9. Âíåäðåíèå X-êîäà ïóòåì ñæàòèÿ ñåêöèè

75№7(20), июль 2004

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

Подробнее об этом можно прочитать в «Основах WindowsNT и NTFS» Хелен Кастер, «Недокументированных воз-можностях Windows NT» А.В.Коберниченко и «WindowsNT File System Internals» Rajeev Nagar.

Сильной стороной этого алгоритма является высочай-шая степень его скрытности, т.к. видимый объем файлапри этом не увеличивается (под размером файла систе-ма понимает отнюдь не занимаемое им пространство, аразмер основного потока), однако список достоинств наэтом и заканчивается. Теперь поговорим о недостатках.При перемещении файла на не NTFS-раздел (например,дискету, zip или CD-R/RW) все рукотворные потоки бес-следно исчезают. То же самое происходит при копиро-вании файла из оболочки наподобие Total Commander (вдевичестве Windows Commander) или обработке архива-тором. К тому же полноценная поддержка NTFS естьтолько в Windows NT.

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

Функции работы с потоками недокументированы и до-ступны только через Native-API. Это NtCreateFile, NtQueryEaFile и NtSetEaFile, описание которых можно найти, вчастности, в книге «The Undocumented Functions MicrosoftWindows NT/2000» Tomasz Nowak, электронная копия ко-торой может быть бесплатно скачана с сервера NTinterl-nals.net.

Создание нового потока осуществляется вызовом фун-кции NtCreateFile, среди прочих аргументов принимающийуказатель на структуру FILE_FULL_EA_INFORMATION, пе-редаваемый через EaBuffer. Вот она-то нам и нужна! Каквариант можно воспользоваться функцией NtSetEaFile, пе-редав ей дескриптор, возвращенный NtCreateFile, откры-вающей файл обычным образом. Перечислением (и чте-нием) всех имеющихся потоков занимается функцияNtQueryEaFile. Прототипы всех функций и определенияструктур содержатся в файле NTDDK.H, в котором при-сутствует достаточное количество комментариев, чтобысо всем этим хозяйством разобраться, однако до тех пор,пока Windows 9x не будет полностью вытеснена с рынка,подобная техника внедрения, судя по всему, останется не-востребованной.

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

Другой, не менее красноречивый признак внедрения, –обращение к функциям NtQueryEaFile/NtSetEaFile, кото-

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

а в Windows XP еще и машинной командой syscall. Воз-можен также вызов по прямым адресам NTDLL.DLL илидинамический поиск экспортируемых функций в памяти.

Восстановление пораженных объектов. Если пос-ле обработки упаковщиком/архиватором или иных внеш-не безобидных действий файл неожиданно отказал в ра-боте, одним из возможных объяснений является гибельрасширенных атрибутов. При условии, что потоки не ис-пользовались для хранения оригинального содержимо-го файла, у нас неплохие шансы на восстановление.Просто загрузите файл в дизассемблер и, проанализи-ровав работу X-кода, примите необходимые меры про-тиводействия. Более точной рекомендации дать, увы, неполучается, поскольку такая тактика внедрения суще-ствует лишь теоретически и своего боевого крещенияеще не получила.

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

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

Когда пространства, имеющегося в PE-заголовке (иликакой-либо другой части файла) оказывается недостаточ-но для размещения всего X-кода целиком, мы можем по-пробовать растянуть заголовок на величину, выбраннуюпо своему усмотрению. До тех пор, пока SizeOf Headersне превышает физического смещения первой секции, та-кая операция осуществляется элементарно (см. «Внедре-ние в PE-заголовок»), но вот дальше начинаются пробле-мы, для решения которых приходится кардинально пере-страивать структуру подопытного файла. Как минимум не-обходимо увеличить raw offset всех секций на величину,кратную принятой степени выравнивания, прописанной вполе File Alignment, и физически переместить хвост фай-ла, записав X-код на освободившееся место.

Максимальный размер заголовка равен виртуально-му адресу первой секции, что и неудивительно, т.к. заго-ловок не может перекрываться с содержимым странич-ного имиджа. Учитывая, что минимальный виртуальныйадрес составляет 1000h, а типичный размер заголовка –300h, мы получаем в свое распоряжение порядка 3 Кбсвободного пространства, достаточного для размещенияпрактически любого X-кода.

В крайнем случае можно поместить оставшуюся частьв оверлей. Хитрость заключается в том, что системныйзагрузчик загружает лишь первые SizeOfHeaders байтзаголовка, а остальные (при условии, что они есть) остав-ляет в оверлее. Мы можем сдвинуть raw offset всех сек-ций хоть на мегабайт, внедрив мегабайт X-кода в заголо-вок, но в память будет загружено только SizeOf Headersбайт, а о загрузке остальных X-код должен позаботитьсясамостоятельно.

INT 2Eh.EAX=067h/INT 2Eh.EAX = 9Ch

76

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

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

Внедрение. Типичный алгоритм внедрения выглядит так:! считываем PE-заголовок;! проверяем DATA DIRECTORY на предмет присутствия

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

! если SizeOfHeaders = FS.v_a, отказываемся от внедре-ния, т.к. внедряться уже некуда;

! если SizeOfHeaders != FS.r_off первой секции, подопыт-ный файл содержит оверлей и после внедрения можетоказаться неработоспособным, однако, если от SizeOfHeders до raw offset содержатся одни нули, внедрять-ся сюда все-таки можно;

! если sizeof(X-code) <= FS.r_off, переходим к главе «вне-дрение в PE-заголовок»;

! если sizeof(X-code) <= FS.v_a, то:! вставляем между концом заголовка и началом стра-

ничного имиджа ALIGN_UP((sizeof(X-code) + SizeOfHeaders – FS.r_off), FA) байт, физически переме-щая хвост файла; при загрузке файла весь X-кодбудет спроецирован в память;

! увеличиваем поле SizeOfHeaders на заданную ве-личину;

! иначе:! вставляем между концом заголовка и началом стра-

ничного имиджа ALIGN_UP((sizeof(X-code) + SizeOfHeaders – FS.r_off), FA) байт, физически перемещаяхвост файла; при загрузке файла системный загруз-чик спроецирует только первые FS.v_a – SizeOfHeaders байт X-кода, а все последующие ему при-дется считывать самостоятельно;

! SizeOfHeaders := FS.v_a;! увеличиваем raw offset всех секций на величину физи-

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

ческим смещениям внутри файла, перечисленные вDATA DIRECTORY.

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

Восстановление пораженных объектов. При растяжкезаголовка с последующим перемещением физического со-держимого всех секций и оверлеев вероятность нарушенияработоспособности файла весьма велика, а причины ее сле-дующие: неверная коррекция raw offset и привязка к физи-ческим адресам. Ну против неверной коррекции, вызваннойгрубыми алгоритмическими ошибками, не пойдешь, и с ис-порченным файлом скорее всего придется расстаться (новсе-таки попытайтесь, отталкиваясь от виртуальных разме-ров/адресов секций, определить их физические адреса илиидентифицируйте границы секций визуальными методами,благо они достаточно характерны), а вот преодолеть при-вязку к физическим адресам можно! Проще всего это сде-лать, вернув содержимое секций/оверлеев на старое место.Последовательно сокращая размер заголовка на величинуFile Alignment и физически подтягивая секции на освободив-шиеся место, добейтесь его работоспособности. Ну а еслине получится, значит, причина в чем-то еще.

Категория B: сброс части секции в оверлейВместо того чтобы полностью или частично сжимать сек-цию, можно ограничиться переносом ее содержимого воверлей, расположенный в конце, середине или началефайла. Дописаться в конец файла проще всего. Ника-кие поля PE-заголовка при этом корректировать ненадо – просто копируем sizeof(X-code) байт любой частисекции в конец файла, а на освободившееся место вне-дряем X-код, который перед передачей управления про-грамме-носителю считывает его с диска, возвращая наисходное место.

Сложнее разместить оверлей в середине файла, на-пример, расположив его между секциями кода и данных,что обеспечит ему высокую степень скрытности. Для это-го будет необходимо увеличить raw offset всех последу-ющих секций на величину ALIGN_UP(sizeof(X-code), FA),физически сдвинув секции внутри файла. Аналогичнымобразом осуществляется и создание оверлея в заголов-

Ðèñóíîê 10. Ïîäîïûòíûé ôàéë è åãî ïðîåêöèÿ â ïàìÿòüäî è ïîñëå âíåäðåíèÿ X-êîäà ïóòåì ðàçäâèæêè çàãîëîâêà

77№7(20), июль 2004

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

ке, о котором мы уже говорили (см. «раздвижка заго-ловка»).

При обработке файла упаковщиков оверлеи (особенносерединные) обычно гибнут, но даже если и выживают, тооказываются расположенными совершенно по другим фи-зическим смещениям, поэтому X-код при поиске оверлеяни в коем случае не должен жестко привязываться к егоадресам, вычисляя их на основе физического адреса сле-дующей секции. Пусть длина оверлея составляет OX байт,тогда его смещение будет равно: NS.r_off – OX, а для пос-леднего оверлея файла: SizeOfFile – OX. Оверлеи в заго-ловках намного более выносливы, но при упаковке UPXгибнут и они.

Внедрение. Обобщенный алгоритм внедрения выгля-дит так:! считываем PE-заголовок и приступаем к его анализу;! если DATA DIRECTORY содержит ссылку на структу-

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

! если LS.r_off + LS.r_sz > SizeOfFile, файл скорее всегосодержит оверлей, и лучше отказаться от внедрения;

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

! выбираем секцию, подходящую для внедрения(IMAGE_SCN_MEM_SHARED, IMAGE_SCN_MEM_DISCARDABLE cброшены, IMAGE_SCN_MEM_READ илиIMAGE_SCN_MEM_EXECUTE установлены, IMAGE_SCN_CNT_CODE или IMAGE_SCN_CNT_INITIALIZED_DATAустановлены); которой, как правило, является перваясекция файла;

! физическое смещение начала секции в файле равноее raw offset (это надежное поле, и ему можно верить);

! физическое смещение конца секции в файле вычис-ляется более сложным образом: min(CS.raw offset +ALIGN_DOWN(CS.r_sz, FA), NS.raw_off);

! находим часть секции, не содержащую подструктурслужебных таблиц PE-файла, таких, например, как таб-лицы импорта/экспорта;

! в выбранной части (частях) секции находим один илинесколько регионов, свободных от перемещаемых эле-ментов, а если это невозможно, выбираем эти элемен-ты из fixup table для последующей обработки X-кодомвручную;

! при желании находим первый пролог и последний эпи-лог внутри выбранных частей секции, чтобы линия «от-реза» не разорвала функцию напополам (это не нару-шит работоспособности файла, но сделает факт вне-дрения более заметным);

! если мы хотим создать оверлей внутри файла, то:! увеличиваем raw offset всех последующих секций на

величину ALIGN_UP(sizeof(X-code), FA);! физически сдвигаем все последующие секции в

файле на эту же величину;! перемещаем выбранные части секции в оверлей, за-

писывая их в произвольном формате, но так, чтобысами потом смогли разобраться;

! иначе:! дописываем выбранные части секции в конец фай-

ла, записывая их в произвольном формате, но так,чтобы сами потом смогли разобраться;

! на освободившееся место записываем X-код.

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

Ничего другого не остается, как анализировать весьX-код целиком, и если манипуляции с восстановлениемсекции будут обнаружены – факт внедрения окажется ра-зоблачен. X-код выдает себя вызовом функций VirtualProtect (присвоение атрибута записи) и GetCommandLine,GetModuleBaseName, GetModuleFullName или GetModuleFullNameEx (определение имени файла-носителя). Убеди-тесь также, что кодовая секция доступна только лишь начтение, в противном случае шансы на присутствие X-кодасущественно возрастут (и ему уже будет не нужно выз-вать VirtualProtect).

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

Реже встречаются ошибки определения длины сбра-сываемой секции: если CS.v_sz < CS.r_sz и CS.r_off +CS.raw_sz > NS.raw_off, то системный загрузчик загружа-ет лишь CS.v_sz байт секции, а внедряемый код сбрасы-вает CS.r_sz байт секции, захватывая кусочек следующей

Ðèñóíîê 11. Âíåäðåíèå X-êîäà â ôàéë ïóòåì ñáðîñà ÷àñòè ñåêöèèâ îâåðëåé

78

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

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

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

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

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

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

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

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

Восстановление пораженных объектов. Если X-кодспроектирован корректно, для его удаления достаточноубить оверлей (например, упаковав программу ASPack сосброшенной галочкой «сохранять оверлеи»). Методикаудаления загрузчика, внедренного по категории А, ужебыла описана выше, так что не будем повторяться.

Категория C: расширение последнейсекции файлаИдея расширения последней секции файла не нова и сво-ими корнями уходит глубоко в историю, возвращая нас вовремена господства операционной системы MS-DOS ифайлов типа OLD-EXE (помните историю с фальшивымимонетами, на которых было отчеканено 2000 г. до н. э.?Древние не знали, что они живут до нашей эры! OLD-EXEтогда еще не были OLD).

Это наиболее очевидный и наиболее популярный ал-горитм из всех алгоритмов внедрения вообще (часто даже

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

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

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

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

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

Ðèñóíîê 12. Âíåäðåíèå X-êîäà â ôàéë ïóòåì ðàñøèðåíèÿïîñëåäíåé  ñåêöèè

79№7(20), июль 2004

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

С атрибутами секций дела обстоят еще хуже. Секциинеинициализированных данных вообще не обязаны заг-ружаться с диска (хотя 9x/NT их все-таки загружают), аслужебные секции (например, секция перемещаемыхэлементов) реально востребованы системой лишь наэтапе загрузки PE-файла, активны только на стадии заг-рузки, а дальнейшее их пребывание в памяти негаран-тированно, и X-код запросто может схлопотать исключе-ние еще до того, как успеет передать управление основ-ной программе. Конечно, X-код может скорректироватьатрибуты последней секции по своему усмотрению, ноэто ухудшит производительность системы, и будет слиш-ком заметно. Если физический размер последней сек-ции равен нулю, что характерно для секций неинициали-зированных данных, лучше ее пропустить, внедрившисьв предпоследнюю секцию.

Типичный алгоритм внедрения выглядит так:! загружаем PE-заголовок и анализируем атрибуты пос-

ледней секции;! если флаг IMAGE_SCN_MEM_SHARED установлен, от-

казываемся от внедрения;! если флаг IMAGE_SCN_MEM_DISCARDABLE установ-

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

! если флаг IMAGE_SCN_CNT_UNINITIALIZED_DATA ус-тановлен, лучше всего отказаться от внедрения;

! если ALIGN_UP(LS.r_sz, FA) + LS.r_a > SizeOfFile, файлсодержит оверлей, лучше отказаться от внедрения;

! если LS.v_sz > LS.r_rz, хвост секции содержит данныеинициализированные нулями, и следует либо отказать-ся от внедрения, либо перед передачей управленияподчистить все за собой;

! дописываем X-код к концу файла;! устанавливаем LS.r_sz на SizeOfFile – LS.r_off;! если LS.v_sz >= (LS.r_a + LS.r_sz + (SizeOfFile – (LS.r_a +

ALIGN_UP(LS.r_sz, FA))), оставляем LS.v_sz без изме-нений; иначе LS.v_sz := 0;

! если LS.v_sz != 0 пересчитываем Image Size;! при необходимости корректируем атрибуты внедряе-

мой секции: сбрасываем атрибут IMAGE_SCN_MEM_DISCARDABLE, и присваиваем атрибут IMAGE_SCN_MEM_READ;

! пересчитываем Image Size.

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

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

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

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

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

Начнем с того, что LS.r_off + LS.r_sz не всегда совпа-дает с концом файла, и если файл содержит оверлей, онбудет безжалостно уничтожен. Если LS.v_sz < LS.r_sz, тоr_sz может беспрепятственно вылетать за пределы фай-ла, и разработчик X-кода должен это учитывать, в про-тивном случае в конце последней секции образуется каша.

Очень часто встречается и такая ошибка: вместо тогочтобы подтянуть LS.r_sz к концу X-кода, программист уве-личивает LS.r_sz на размер X-кода, и, если конец после-дней секции не совпадал с концом оригинального файла,X-код неожиданно для себя окажется в оверлее! К счас-тью, этой беде легко помочь – просто скорректируйте полеLS.r_sz, установив его на действительный конец файла.

Нередко приходится сталкиваться и с ошибками кор-рекции виртуальных размеров. Как уже говорилось, уве-личивать LS.v_sz на размер X-кода нужно лишь тогда, ког-да LS.v_sz <= LS.r_sz, в противном случае виртуальныйобраз уже содержит часть кода или даже весь X-код це-ликом. Если LS.v_sz != 0, такая ошибка практически ни-как не проявляет себя, всего лишь увеличивая количествопамяти, выделенной процессору, но если LS.v_sz == 0,после внедрения он окажется равным… размеру X-кода,который много меньше размера всей секции, в результа-те чего ее продолжение не будет загружено, и файл отка-жет в работе. Для возращения его в строй просто обнули-те поле LS.v_sz или вычислите его истинное значение.

После изменения виртуальных размеров секции тре-буется пересчитать Image Size, что многие программистыделают неправильно, либо просто суммируя виртуальныеразмеры всех секций, либо увеличивая его на размер вне-дряемого кода, либо забывая округлить полученный ре-зультат на границу 64 Кб, либо допуская другие ошибки.Правильный алгоритм вычисления Image Size выглядиттак: LS.v_a + ALIGN_UP((LS.v_s)? LS.v_s:LS.r_sz, OA).

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

Для удаления X-кода из файла просто отберите у негоуправление, отрежьте sizeof(X-code) байт от конца после-дней секции и пересчитайте значения полей: Image Base,LS.r_sz и LS.r_off.

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

80

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

Внедрение. Обобщенный алгоритм выглядит так:! загружаем PE-заголовок и смотрим, что расположено

за таблицей секций;! если здесь не нули, отказываемся от внедрения;! если (e_lfanew + SizeOfOptionalHeader + 14h + (Number

OfSections + 1)*40) > SizeOfHeaders, раздвигаем заголо-вок, как показано в разделе «Внедрение в PE-заголовок»,а если это невозможно, отказываемся от заражения;

! дописываем X-код к концу файла;! увеличиваем NumberOfSections на единицу;! выравниваем LS.r_sz на величину FA;! дописываем к таблице секций еще один элемент, за-

полняя поля следующим образом:! имя: не имеет значения;! v_a: LS.v_a + ALIGN_UP( (LS.v_sz)? LS.v_sz: LS.r_sz),

Section Alignment);! r_offset: SizeOfFile;! v_sz: sizeof(X-code) или 0x0;! r_sz: sizeof(X-code);! Charic.: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_

EXECUTE;! остальные: 0x0;

! пересчитываем Image Size.

Идентификация пораженных объектов. Внедренияэтого типа легко распознаются по наличию кодовой сек-ции в конце файла (стандартно кодовая секция всегда идетпервой).

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

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

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

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

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

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

Собственно говоря, вся проблема в том, что подавля-ющее большинство кодовых секций начинается с адреса1000h, – минимально допустимого адреса, диктуемоговыбранной кратностью выравнивания OA, так что отсту-пать уже некуда – заголовок за нами. Здесь можно посту-пить двояко: либо уменьшить базовый адрес загрузки навеличину, кратную 64 Кб, и скорректировать все ссылкина RVA-адреса (что утомительно, да и базовый адрес заг-рузки подавляющего большинства файлов – это мини-мальный адрес, поддерживаемый Windows 9x), либо от-ключить выравнивание в файле, отодвинув границу налюбое количество байт, кратное двум (но тогда файл небудет запускаться под Windows 9x).

Типовой алгоритм внедрения путем уменьшения базо-вого адреса загрузки выглядит так:! считываем PE-заголовок;! если Image Base < 1.00.00h и перемещаемых элемен-

тов нет, отказываемся от внедрения;! если Image Base <= 40.00.00h и перемещаемых эле-

ментов нет, лучше отказаться от внедрения, т.к. файлне сможет запускаться в Windows 9x;

! внедряем 1.00.00h байт в заголовок по методу, опи-санному в разделе «Раздвижка заголовка», оформляявсе 1.00.00h байта как оверлей (т.е. оставляя SizeOfHeaders неизменным), а если это невозможно, отка-зываемся от внедрения;

! уменьшаем FS.v_a и FS.r_off на 1.00.00h;! увеличиваем FS.r_sz на 1.00.00h;! если FS.v_sz не равен нулю, увеличиваем его на 1.00.00h;! увеличиваем виртуальные адреса всех секций, кроме

первой, на 1.00.00h;! анализируем все служебные структуры, перечислен-

ные в DATA DIRECTORY (таблицы экспорта, импорта,перемещаемых элементов и т. д.), увеличивая все RVA-ссылки на 1.00.00h;

Ðèñóíîê 13. Âíåäðåíèå X-êîäà â ôàéë ïóòåì ñîçäàíèÿñîáñòâåííîé  ñåêöèè

81№7(20), июль 2004

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

! внедряем X-код в начало кодовой секции от FS.r_offдо FS.r_off + 1.00.00;

! пересчитываем Image Size.

Типовой алгоритм внедрения путем переноса запад-ной границы первой секции, выглядит так:! считываем PE-заголовок;! если OA < 2000h лучше отказаться от внедрения, т.к.

файл будет неработоспособен на Windows 9x, но еслимы все-таки хотим внедриться, то:! устанавливаем FA и OA равными 20h;! для каждой секции: если NS.v_a – CS.v_a – CS.v_sz >

20h, подтягиваем CS.v_sz к NS.v_a – CS.v_a;! для каждой секции: если v_sz > r_sz, увеличиваем дли-

ну секции на v_sz – r_sz байт, перемещая все осталь-ные в физическом образе и страничном имидже;

! для каждой секции: если v_sz < r_sz, подтягиваемv_sz к NS.v_a – CS.v_a, добиваясь равенства физи-ческих и виртуальных размеров;

! внедряем в заголовок ALIGN_UP(sizeof(X-code), OA)байт, оформляя их как оверлей;

! уменьшаем FS.v_a и FS.r_off на ALIGN_UP(sizeof(X-code), OA);

! внедряем X-код в начало первой секции файла;! пересчитываем Image Size.

Внедрение в конец. Чтобы внедриться в конец кодо-вой секции, необходимо раздвинуть нестраничный имидж,заново пересчитав ссылки на все адреса, т.к. старых дан-ных на прежнем месте уже не будет. Задача кажется не-выполнимой (встраивать в X-код полноценный дизассем-блер с интеллектом ИДЫ не предлагать), но решение ле-жит буквально на поверхности. В подавляющем большин-стве случаев для ссылок между секциями кода и данныхиспользуются не относительные, а абсолютные адреса,перечисленные в таблице перемещаемых элементов (приусловии, что она есть). В крайнем случае абсолютныессылки можно распознать эвристическими приемами:если (Image Base + Image Size) >= Z >= Image Size, то Z –эффективный адрес, требующий коррекции (разумеется,предложенный прием не слишком надежен, но все же онработает).

Типовой алгоритм внедрения выглядит так:! считываем PE-заголовок;! если нет перемещаемых элементов, лучше отказать-

ся от внедрения, т.к. файл может потерять работоспо-собность;

! находим кодовую секцию файла;! если CS.v_sz ==0 или CS.v_sz >= CS.r_sz, увеличива-

ем r_sz кодовой секции файла;! если CS.v_sz < CS.r_sz, CS.r_sz := NS.r_off +

ALIGN_UP(sizeof(X-code), FA);! если CS.v_sz < CS.r_sz, CS.v_sz := CS.r_sz;! физически сдвигаем все последующие секции на

ALIGN_UP(sizeof(X-code), FA) байт, увеличивая их r_offна ту же самую величину;

! сдвигаем все последующие секции в страничном имид-же, увеличивая их v_a на ALIGN_UP(sizeof(X-code), OA)байт;

! если таблица перемещаемых элементов присутству-ет, увеличиваем все абсолютные ссылки на переме-щенные секции на ALIGN_UP(sizeof(X-code), OA) байт,если же таблицы перемещаемых элементов нет, ис-пользуем различные эвристические алгоритмы;

! пересчитываем ImageSize.

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

Восстановление пораженных объектов. Ни одногопораженного объекта пока не зафиксировано.

Категория Z: внедрение черезавтозагружаемые DLLВнедриться в файл можно, даже не прикасаясь к нему. Неверите? А зря! Windows NT поддерживает специальныйключ реестра, в котором перечислены DLL, автоматичес-ки загружающиеся при каждом создании нового процес-са. Если Entry Point динамической библиотеки не равнанулю, она получит управление еще до того, как начнетсявыполнение процесса, что позволяет ей контролироватьвсе происходящие в системе события (такие, например,как запуск антивирусных программ). Естественно, борь-ба с вирусами под их руководством ни к чему хорошемуне приводит, и система должна быть обеззаражена. Убе-дитесь, что в HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs перечислены тольколегальные динамические библиотеки и нет ничего лиш-него!

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

Дополнительная литература:1. Касперски К. Борьба с вирусами: опыт контртеррорис-

тических операций, журнал «Системый администра-тор», №10(11), октябрь, 2003 г. – 68-76 с.

2. Касперски К. Вирусы в UNIX, или Гибель Титаника II,журнал «Системый администратор», №1(14), январь,2004 г. – 6-23 с.

3. Касперски К. Ошибки переполнения буфера извне иизнутри как обобщенный опыт реальных атак, журнал«Системый администратор», №3(16), март, 2004 г. –64-72 с.

1 Как вариант, X-код может внедриться в хвост класте-ра, оккупируя один или несколько незанятых секторов(если они там есть), однако, здесь этот вариант не рас-сматривается, т.к. никакого отношения к PE-файловон имеет.

82

на правах рекламы

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

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

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

Схем организации стека по сути две:! Звезда – схема, в основе которой находится мастер-

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

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

Другие возможные варианты сводятся к описаннымвыше. Обе схемы имеют свои достоинства и недостатки,но общим узким местом является длина стекирующего ка-беля. Для преодоления этого ограничения разработчикивнедряют технологии стекирования на основе стандарт-ных базовых портов. Примером могут служить коммута-торы D-Link серии DES-3500 и DES-6500, поддерживаю-щие технологию Single IP Management.

Single IP Management (SIM) – это концепция стекиро-вания коммутаторов друг с другом посредством стандар-тных Ethernet-портов вместо использования специальныхпортов или модулей. Устройства, поддерживающие этутехнологию, формируют стек, предоставляя порты 10/100/1000 Мбит/с и возможность организации гигабитного под-ключения к магистрали. Вот несколько достоинств, реа-лизованных в этой технологии:! SIM уменьшает количество IP-адресов, использующих-

ся в сети.! Для объединения в стек SIM позволяет обойтись без

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

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

! SIM – это дополнительная функция коммутатора. Онаможет быть включена через управляющий интерфейси не влияет на его базовые функции.

В коммутаторах с поддержкой Single IP Management(SIM) термин «стек» равнозначен термину «SIM-группа».(SIM-группа – это группа коммутаторов, которая управля-ется, как единое устройство.)

Их общие характеристики выглядят так:! Коммутаторы, входящие в стек, могут выполнять одну

из трех функций:! Commander Swith (CS) – мастер-коммутатор в груп-

пе. Ему присваивается IP-адрес. Один CS не можетвходить в разные SIM-группы.

! Member Swith (MS) – коммутатор, который распоз-нается CS, как член SIM-группы. Один MS может вхо-дить только в одну SIM-группу.

! Candidate Switch (CaS) – коммутатор, подключенныйфизически к SIM-группе, но не определенный CS какее член. Любой коммутатор в режиме CaS можносконфигурировать на ручное или автоматическоеподключение к SIM-группе.

! В SIM-группу может входить только один CommanderSwith.

! Все коммутаторы SIM-группы должны входить в одиншироковещательный домен.

! В SIM-группу может входить до 32 коммутаторов (от 0до 31), включая Commander Switch (под номером 0).

! Нет ограничений на количество SIM-групп в одном ши-роковещательном домене, однако один коммутатор мо-жет входить только в одну группу.

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

С помощью встроенного веб-менеджера можно полу-чить информацию, представленную в виде дерева (TreeView) о членах стека и топологии сети, с указанием мес-торасположения устройств стека и связей между ними.Это простое и достаточно эффективное веб-управлениеисключает необходимость установки дорогого ПО дляSNMP-управления.

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

ПЕРЕДОВАЯ ТЕХНОЛОГИЯ СТЕКИРОВАНИЯКОММУТАТОРОВ – SINGLE IP MANAGEMENT

ЯКОВ ЮНИЦКИЙЗАО «ТАЙЛЕ»

84

сети

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

Несмотря на то что технология Ethernet (низкоскорост-ные сети 10Base) используются только для объединенияпериферийных пользователей, базовые принципы все рав-но наследуются более современными последователямиэтого популярного стандарта. Поэтому автор позволитсебе обратиться к истории.

Изначально Ethernet работал как единая шина и толь-ко один электрический сигнал мог распространяться посети в каждый момент времени. Если же случалось, что всеть было послано несколько сигналов, то они наклады-вались друг на друга и переставали быть распознавае-мыми. Неудивительно, что был разработан способ пере-дачи данных, учитывающий эту неприятную особенность –в противном случае пользы от таких сетей не было бы вов-се. Алгоритм, известный как CSMA/CD (множественныйдоступ с контролем несущей и с определением столкно-вений), определял порядок доступа к среде передачи.

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

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

Базовую модель сети можно представить как объеди-нение пользовательского оборудования (CE – CustomerEquipment). Для данной процедуры используются сетевыеинтерфейсы пользователя (UNI – User Network Interface)и непосредственно Metro Ethernet Network (MEN).

Причем в роли UNI используются стандартные полу-чившие широчайшее распространение во всем мире пла-ты Ethernet (10 Мб/с, 100 Мб/с, 1 Гб/с, 10 Гб/с).

Учитывая пространственную разнесенность абонентови потенциальное отсутствие непосредственных связеймежду ними, вводится такое понятие, как Ethernet VirtualConnection – EVC (виртуальное соединение Ethernet). Приэтом разделяют три типа виртуальных соединений:! Point to point (точка-точка),! Point to multipoint (точка-многоточка),! Multipoint to multipoint (многоточка-многоточка).

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

Ethernet. История стандартаРеализация концепции MetroEthernet базируется на техно-логии Ethernet, которая известна уже более двадцати лет,но наиболее бурное развитие получила в поледние 8 лет.

METRO ETHERNETMETRO ETHERNET

ДЕНИС ЕЛАНСКИЙ

Ðèñóíîê 1. Áàçîâàÿ ìîäåëü MEN Ðèñóíîê 2. Àíàëîãèÿ MEN è Frame Relayà) Âèðòóàëüíûå ñîåäèíåíèÿ Frame Relayá) Âèðòóàëüíûå ÷àñòíûå ëèíèè íà áàçå ñåðâèñà E-Line

85№7(20), июль 2004

сети

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

! Если сеть свободна, отправитель начинает передачу.! Во время процесса передачи отправитель продолжает

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

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

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

дится пересылать повторно. Это приводит к росту за-держек в сети.

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

Часть этих проблем решается применением коммута-торов, а именно:! Не происходит коллизий, а соответственно нет необ-

ходимости в повторной трансляции утерянных по этойпричине кадров.

! Сетевые устройства не тратят времени на ожиданиеосвобождения среды передачи.

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

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

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

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

Благодаря этим позитивным тенденциям технологияEthernet перестает быть технологией построения ЛВС, втор-гаясь на рынок сетей масштаба города (Metropolitan AreaNetworks).

Привлекательность MetroEthernetТак что же дает концепция Metro Ethernet провайдерам?Почему все большее число производителей оборудова-ния начинает поддерживать эту концепцию? Почему спе-циалисты прогнозируют бурный рост сетей Metro Ethernet?

По мнению экспертов компании In-Start/MDR, рост при-быльности сетей Metro Ethernet составит колоссаль-ные значения и к 2008 году данная технология сравняетсяпо распространенности с SDH-сетями.

Подобные оценки основаны на том, что пропускная спо-собность каналов Ethernet постоянно растет (достигая наданном этапе величины в 10 Гб/с), вместе с этим улучша-ются надежностные показатели технологии, ее управляе-мость и масштабируемость. При этом с распространени-ем новых сред передачи (например, оптического волок-на) возросли перекрываемые дистанции.

Помимо этого, технология Ethernet не просто домини-рует на рынке ЛВС, а осталась практически единствен-ной, сохранившейся до настоящего времени (более 90 %рынка ЛВС приходится на сети Ethernet).

Все это лежит в основе перспективности технологии MetroEthernet как для провайдеров, так и для абонентов. Что по-лучают провайдеры от сетей Metro Ethernet? Высокоскоро-стную опорную сеть, сегменты которой могут достигать 100км, а пропускная способность одного канала может дости-гать 10 Гб/с. Чем же привлекательна эта технология для

Ðèñóíîê 3. Ðîñò äîõîäîâ îò óñëóã ãîðîäñêèõ ñåòåé Ethernet â ÑØÀ

Ðèñóíîê 4. Ãèáêîñòü ðîñòà ïðîïóñêíîé ñïîñîáíîñòè â ñåòÿõ Ethernet

86

сети

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

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

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

После введения такого строгого фильтра в рассмотре-нии останется не так уж много фирм, не больше десятка. Кним смело можно отнести таких гигантов, как:! Cisco Systems (www.cisco.com)! Extreme Networks (www.extremenetworks.com)! Nortel Networks (www.nortelnetworks.com)! Riverstone Networks (www.riverstonenet.com)

Cisco SystemsЯвляясь одним из признанных лидеров на рынке телеком-муникаций, Cisco Systems предлагает для магистральныхEthernet-сетей два класса устройств. Это в первую очередьмагистральные маршрутизаторы (такие как Cisco 7600OSR,10000 и 12600) и высокопроизводительные коммутаторыуровня ядра (семейство Cisco Catalyst 6500). Оборудова-ние обоих классов может использоваться в любом из уз-лов сети (даже в таких требовательных системах, как опор-ные сети операторов) с той лишь разницей, что каждоешасси поддерживает различные типы плат расширения.

Характерными особенностями оборудования Cisco явля-ются следующие черты: поддержка технологии MPLS, про-токолов маршрутизации (RIP, OSPF, BGP, IGRP, EIGRP, IS-IS), высокая масштабируемость, поддержка высокопроизво-дительных протоколов резервирования каналов передачиданных (протокол STP и его многочисленные модификации),наиболее высокая (до недавнего времени) плотность пор-тов, единая операционная система IOS, высокая производи-тельность и надежность. Все это, а также агрессивная мар-

кетинговая политика плюс неудачи конкурентов сделалиCisco законодателем мод в сфере систем передачи данных.

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

Extreme NetworksСозданная в 1995 году компания Extreme Networks с пер-вых дней своего существования задумывалась как конку-рент Cisco Systems в области магистральных решений.Стоит отметить, что за восемь лет своего существованияинженеры и менеджеры компании справились с этой зада-чей, и получилось это у них весьма неплохо.

Об этом говорит тот факт, что на традиционно сильномамериканском рынке, дающем большую часть дохода, по-зиции основных конкурентов были значительно ослабле-ны, и около 15% поставляемого в настоящее время обору-дования производится Extreme Networks. Такое развитиесобытий имеет под собой две основные причины.

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

Дополнительным бонусом этой системы является интег-рация с HP-OpenView. В продуктовой линейке Extreme внастоящее время представлены три семейства оборудова-ния: Summit, Alpine и Black Diamond. Такое разделение по-зволяет обеспечить весь спектр решений как для конечно-го пользователя, так и для крупного регионального опера-тора связи. При этом капиталовложения будут соответство-вать решаемой задаче. Как говорилось ранее, основнойприоритет Extreme – высокопроизводительные магистраль-ные сети, построенные на базе стандарта Ethernet. Для этойтехнологии было создано оборудование, являющееся насегодняшний день наиболее производительным (с точкизрения битовой коммутации) и оптимально расширяемым(одно шасси поддерживает до 48/480/2304 физических пор-тов 10 Гб/с, 1 Гб/с, 100 Мб/с соответственно, а при исполь-зовании технологии CWDM число логических портов мо-жет превышать число физических портов в 8 раз).

Помимо высокоскоростных портов Ethernet оборудова-ние Extreme имеет возможность для интеграции с опорны-ми сетями SDH. В наличии имеются интерфейсы STM-1,STM-4, а также интерфейс АТМ 3,2 Гб/с. Наличие SDH-ин-терфейсов позволят использовать устройства BlackDiamond как для сопряжения с сетями SDH, так и для пре-доставления сервисов IPoSDH и SDHoIP.

Помимо распространенных протоколов обмена цифро-вой информацией коммутаторы Extreme позволяют стро-ить «пакетные кольца».

Òàáëèöà 1. Ñòàòèñòè÷åñêèå ïîêàçàòåëè Cisco

87№7(20), июль 2004

сети

В отличие от тех случаев, когда резервирование обес-печивается средствами протоколов из семейства STP (STP,RSTP, STP+), время восстановления маршрута для техно-логии «paket ring» не превышает 50 мс. Это позволяет го-ворить о гарантированном качестве, сравнимом с каче-ством в сетях SDH.

Nortel NetworksКомпания Nortel, уже давно известная в мире как один изосновных производителей оборудования телефонии, пос-ле слияния с Bay Networks стала активно осваивать новыйдля себя сегмент рынка. Наибольшим вниманием у NortelNetworks пользуется направление Metro Ethernet. В рамкахразвития этой концепции было создано новое семействомагистральных коммутаторов OPTERA Metro. По техноло-гичности производимого оборудования Nortel во многом пре-восходит своих конкурентов, однако несмотря на это суще-ствует ряд объективных факторов, снижающих популярностьи распространенность оборудования OPTERA у операторов.

Как и все крупные производители, Nortel обеспечиваетсвоих потенциальных заказчиков всем необходимым. Обо-рудование этого производителя предоставляет инструмен-ты для интеграции в высокоскоростные Ethernet-магистра-ли (1 Гб/с и 10 Гб/с), а также для сопряжения с магистраля-ми SDH, равно как и для подключения абонентов. Поддер-живается широчайший спектр существующих протоколовобмена, реализованы «proprietary»-протоколы, примеромкоторых может служить протокол «пакетного кольца», ана-логичный реализованному в оборудовании Extreme и обес-печивающий восстановление канала в пределах 50 мс.Создана единая операционная система, конфигурируемаякак в консольном, так и в графических режимах.

Оборудование добротно и перспективно. Но каждый па-раметр, по которому его можно оценить, имеет одно «но».Унификация оборудования произведена, однако заставитьработать его в связке с оборудованием стороннего произ-водителя не всегда просто.

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

Riverstone NetworksРуководство Riverstone позиционирует свое оборудованиекак капиталосберегающее решение для перехода от сетей,чувствительных к задержкам (приложения VoIP), к сетям,требующим сверхвысокой пропускной способности (прило-жения CRM и ERP). При этом компания не отказывается отподдержки приложений реального времени. Для воплоще-ния этой стратегии было создано семейство магистральныхкоммутаторов XGS. В общих чертах коммутаторы XGS –это модульное оборудование, расширяемое по мере необ-ходимости и оптимизированное для работы с потоками ин-

формации 10 Гб/с. Программное обеспечение коммутато-ров обеспечивает как потоковую коммутацию (line-rateswitching), так и маршрутизацию трафика. Естественно,поддерживаются протоколы Q-in-Q и MPLS.

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

К недостаткам оборудования Riverstone нельзя не отне-сти следующее: высокопроизводительная серия толькоанонсирована – даже на официальном сайте нет подроб-ного описания данного оборудования. А маршрутизаторысерии RS значительно уступают (по некоторым показате-лям на порядок) оборудованию других производителей. Так,например, битовая коммутация происходит на скоростивсего лишь 170 Гб/с, в то время как Black Diamond 10800(Extreme Networks) выполняет аналогичную процедуру наскорости 1600 Гб/с. Помимо этого, маршрутизаторы серииRS поддерживают стандарт SDH только до 16-го уровня,что не позволяет встраивать их в кольца магистралей STM-64. Кроме этого, анонсированное семейство XGS вообщеосталось без модулей SDH.

Возможно, по мере развития спроса и популярностиRiverstone пойдет на расширение своего модельного рядаоборудованием для интеграции с сетями SDH. На сегод-няшний же день доступное оборудование серии RS не мо-жет в полной мере считаться аппаратурой операторскогокласса. Для формирования центров обработки данных та-кие коммутаторы подойдут практически идеально (при вы-сокой надежности, достаточной производительности и мас-штабируемости они имеют относительно низкую стоимость)либо для построения узлов доступа к сетям MAN/MEN, нодля использования в качестве магистрального это обору-дование еще не готово.

Сравнение производителейЛюбое оборудование, любая компания, его производящая,имеют свои преимущества и недостатки. Если в разделе«Производители и оборудование» я постарался рассказатьоб оборудовании вообще, то в этой главе акценты будут по-ставлены несколько иначе. А именно: в чем преимуществане оборудования (здесь не может быть однозначного мне-ния), а производителей, где их сильные и слабые стороны?

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

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

88

сети

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

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

Но не только плюсами обладает Cisco. К недостаткамкомпании нельзя не отнести высокие (а порой и сверхвы-сокие) цены на оборудование. Это превышение колеблет-ся в среднем от 15 до 50 % и распространяется как на обо-рудование, так и на сервис. В условиях партнерских согла-шений цены естественно снижаются, но стоимость владе-ния по-прежнему остается на очень высоком уровне.

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

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

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

Extreme Networks. За и противExtreme Networks, основанная в 1995 году уступает по мас-штабам и именитости трем остальным компаниям. Одна-ко в последние годы наметился бурный рост качества, авместе с ним и распространенности оборудования этогопроизводителя. В пользу компании говорит уже тот факт,что за 9 лет существования ее продукция отвоевала у ми-ровых гигантов 9 % рынка, доведя этот показатель по не-которым отраслям до 18 %. Характерен и тот факт, чтооборудование Extreme Networks (а именно магистральныекоммутаторы семейства Black Diamond) было использо-вано при построении вычислительной сети министерстваобороны США.

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

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

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

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

Еще одним положительным моментом является нали-чие мощного графического средства управления сетью.Этот инструмент весьма универсален (во всяком случаесравним по эффективности с Cisco Works), при этом значи-тельно менее ресурсоемок.

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

Помимо отсутствия развитой структуры представи-тельств и партнерских отношений настораживает сравни-тельная молодость производства вообще и продукции в ча-стности. Если фирмы, созданные 20, 30 лет назад, уже оп-ределили концепцию развития и обкатали стратегию со-вершенствования аппаратно-программного обеспечения, тоотносительно молодые производства еще не до конца от-ладили программную компоненту своей продукции, след-ствием чего является необходимость частого обновленияпрограммного обеспечения. Хотя в случае с ExtremeNetworks эта закономерность прослеживается не оченьярко: обновления ПО выходят только при появлении ново-го аппаратного обеспечения.

Nortel Networks. Альтернативный выборУнаследовав всю мощь этого гиганта, Nortel стал однимиз лидеров в сфере производства и разработки системпередачи данных.

Касательно оборудования Nortel можно констатироватьследующее: у него нет ярко выраженных недостатков, нои с преимуществами тоже не все очевидно. Если бы этобыли автомобили, можно было бы сказать – «добротныйавтомобиль». Это оборудование имеет весь необходимыйперечень функций, которые могут понадобиться. Nortel ве-дет собственные разработки, реализует сторонние дос-тижения, но не более того. Что касается архитектуры шас-си, то и здесь отношение к производителю можно опре-делить как «не хуже, чем у других». Но и не лучше. Этоиллюстрируется ситуацией с плотностью и качеством пор-тов: при производстве задействованы самые современ-ные технологии, управление отдельными узлами совер-шенно, но плотность портов из расчета на шасси хоть ивелика, но уступает показателям Extreme и Cisco, а с точ-ки зрения управляемости композиция добротных элемен-

89№7(20), июль 2004

сети

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

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

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

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

Исходя из официальных материалов, предлагаемых насайте производителя, можно понять, что Riverstone нахо-дится на расстоянии трех лет (что по меркам сверхбыст-ро развивающегося производства очень большой срок)от конкурентов. Это предположение может быть обосно-вано хотя бы тем, что серия маршрутизаторов Cisco 12000была заявлена еще в 2001 году, а в дальнейшем происхо-дило только ее совершенствование, в то время как появ-ление конкурентоспособной серии XGS от Riverstone анон-сировано только сейчас. При этом стоит помнить, что ли-дирует по техническим показателям Black Diamond 10800(Extreme Networks) – магистральный коммутатор, которо-му уже больше полугода.

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

Практически не существует программы сертификацииинженеров.

Партнерские программы развиты слабо: большая частьстратегических партнеров Riverstone – американские ком-пании.

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

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

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

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

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

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

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

Условные оценки выставляются по пятибалльной шка-ле, если не оговорено иного.

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

Òàáëèöà 2. Îáîáù¸ííàÿ òàáëèöà õàðàêòåðèñòèê îáîðóäîâàíèÿ MEN

91№7(20), июль 2004

образование

ВТОРОЕ НАЧАЛО ТЕРМОДИНАМИКИ –ГАРАНТ УСПЕХА СИСТЕМС ОТКРЫТЫМ ИСХОДНЫМ КОДОМ

АЛЕКСЕЙ МИЧУРИН

Мы вышли на развилку, нам некуда вперёд;Идти назад нам не позволит наша честь.

Непонятно, что такие, как мы,До сих пор делаем в таком отсталом месте, как здесь.

Борис Гребенщиков

Мы живём в очень интересное время.Информационные технологии настолько прочновошли в жизнь человечества, что без них уженевозможно представить не только развитие,но и существование нашей цивилизации.Жизненная необходимость разработкии совершенствования ПО уже не вызываетникаких сомнений, и нет оснований полагать,что ситуация изменится в ближайшее время.Поэтому особую остроту моменту придаёт то,что человечество фактически стоит на распутье.Стало очевидно, что есть две принципиальноразные доктрины разработки и распространенияПО – с открытым исходным кодом и с закрытымкодом, оба убедительно демонстрируют своюуспешность. Единого мнения, какое ПО успешней,нет. Множество людей ведут горячие спорыо преимуществах и недостатках того или иногопути. Ситуация стремительно меняется.Человечество пытается принять решение.

92

образование

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

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

Давайте сперва разберёмся, что такое энтропия, какприменить это понятие к нашему вопросу и почему онавозрастает.

Энтропия – мера возможностейВсе знают магические слова: «энтропия – мера беспо-рядка», но мало кто задумывается о том, что за беспо-рядок имеется в виду.

Строго говоря (по определению), энтропия данногомакросостояния системы – величина, пропорциональнаялогарифму числа микросостояний, которыми реализует-ся данное макросостояние. Понятнее не стало? Давайтеразбираться.

Простой пример: у нас есть два спичечных коробка ичетыре спички. С нашей макроскопической точки зренияспички неразличимы, одна ничем не хуже другой. Для насважно только, сколько в каком коробке находится спичек.Это макроописание системы. Однако, на микроуровне (науровне спичек) они (спички) различимы и их можно, на-пример, пронумеровать и раскладывать в коробки разны-ми способами, получая одну и ту же макроконфигурацию.Сколькими способами мы можем реализовать макросос-тояние: в первой коробке – одна спичка, во второй – три(обозначим это состояние 1 + 3)? Или иначе, сколькимиспособами мы можем разложить четыре неодинаковыеспички по двум коробкам, получая заданное макрососто-яние 1 + 3? Очевидно, таких способов четыре (см. рису-нок). А сколькими способами можно реализовать состоя-ние 2 + 2? Шестью (тот же рисунок). Энтропия последнегосостояния больше. Энтропия же состояния 0 + 4 равнанулю, так как это состояние реализуется только однимспособом (логарифм единицы – ноль).

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

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

Если рассмотреть больше коробков, то драматизм си-туации ещё более возрастает. Например, для четырёхкоробков и восьми спичек конфигурация 1 + 1 + 1 + 5реализуется 336 способами, а ситуация 2 + 2 + 2 + 2 мо-жет реализоваться 2520 способами. Энтропия последне-го состояния, как вы понимаете, гораздо больше. Дажеминимальное отклонение от этого состояния в состоя-ние типа 2 + 2 + 3 + 1 уменьшит количество возможныхреализаций на треть (до значения 1680 шт.).

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

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

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

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

93№7(20), июль 2004

образование

нящих его с живыми существами. Это видно даже из тер-минологии, достаточно вспомнить термин «virus» или опе-ратор «die» (язык Perl), или команду «kill» (ОС UNIX). Во-вторых, любая эволюция подчиняется одним и тем же гло-бальным законам, но эволюция Живого гораздо старшеэволюции ПО и может преподать много поучительныхуроков.

Что же демонстрирует эволюция Живого? Она крас-норечиво свидетельствует, что Живое всё время стре-мится к разнообразию. ДНК – основной носитель на-следственной информации – наращивается3 в ходе эво-люции (эквивалентно увеличению числа коробков в на-ших захватывающих опытах со спичками). Таким обра-зом, увеличивается число возможностей реализоватьЖизнь. То есть Природа остаётся верна себе, постоян-но увеличивая энтропию. При этом увеличивается небеспорядок в бытовом смысле, а скорее информацион-ная ёмкость. Возвращаясь к нашему определению энт-ропии: возрастает количество микросостояний, доступ-ных системе.

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

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

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

Но мы уже рискуем увлечься, вернёмся теперь в мирПО.

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

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

Представьте себе Интернет, на всех серверах кото-рого стоит один набор программ, скомпилированных од-ним компилятором с одним набором параметров ком-пиляции, установленных с одного диска одним касани-ем клавиши Enter... Клоны, клоны, клоны... ни чем неотличающиеся друг от друга. В конце концов, появитсявирус, который воспользуется общей уязвимостью иразрушит весь этот мир. Если же ядро ОС каждого сер-вера и программное обеспечение хотя бы просто пере-компилированы, то атаки, направленные, скажем, на пе-реполнение буферов (наверное, наиболее опасные иэффективные атаки4), затронут только тот soft, которыйимеет строго определённый двоичный код. Остальнойsoft будет неуязвим. Это простой пример, только одиниз многих.

Тут читатели меня спросят: «Как же всё произойдёт?Что будет переломным моментом? Когда ждать предска-зываемой мною победы OpenSource?»

К сожалению (или к счастью?), я не могу ответить наэти вопросы, как не могу ответить, почему именно этамолекула воздуха оказалась именно здесь и когда здесьокажется другая.

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

Дополнение 1:Несколько слов об изолированностисистемыЯ уже слышу возмущённые голоса читателей: «Уважа-емый автор совершенно верно сказал, что второе на-чало ТД справедливо только для изолированных сис-тем, а сам применяет его к чему попало! Ведь всем ясно,что наша планета не является термодинамически изо-лированной системой, получая тепло от Солнца. Темболее не являются изолированными подсистемы, упо-мянутые автором: компьютеры подключены в сеть элек-тропитания, программисты потребляют еду и напитки...Как же можно применять второе начало ТД ко всем этимсистемам?».

94

образование

Читатель абсолютно прав. Упомянутые системы неизолированы в термодинамическом смысле, но это недолжно нас смущать, ведь и энтропию мы рассматрива-ем не в термодинамическом смысле. Мы не рассматри-ваем атомы и молекулы, как это делает термодинамика,мы выбрали другие микро- и макроуровни рассмотрения.

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

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

Однако все законы продолжают выполняться и в на-шем случае. Так, чтобы уменьшить энтропию, необхо-димо совершить работу. В нашем случае со спичками –продумать, как их разместить, и выполнить необходи-мые перестановки, переведя систему, скажем, из со-стояния 2+2 в состояние 0+4. Это сродни той работе,которую вы затрачиваете на уборку, складывая равно-мерно разбросанные вещи (два карандаша на столе,два – под столом) в одно место (все четыре – на столе,ноль – под столом). Причём я имею в виду не простомеханическую работу (тем более не теплоту в термоди-намическом смысле), а усилия в самом общем смысле:сюда включены и поиски карандашей, и подбор наибо-лее подходящего для них места... Опять же, неизоли-рованность вашего стола и карандашей в термодина-мическом смысле (их возможность обмениваться теп-лом с другими телами) нисколько не повлияет на ходвашей уборки, потому что ваши усилия иные, нежелитеплообмен с системой.

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

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

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

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

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

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

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

2 Так и хочется закричать: «Как вообще можно гово-рить о беспорядке в Природе или в физике! Бога по-бойтесь!»

3 Биологи, ознакомившись с черновиком этой статьи,очень не одобрили это «дилетантское» слово, про-шу меня извинить, если кого-то оно заденет.

4 Детальному рассмотрению этого вопроса посвяще-ны, в частности, статьи Криса Касперского, опубли-кованные в недавних номерах «Системного админи-стратора».

5 Кстати, с накоплением таких ошибок и сбоев связани процесс старения. И это ещё одно отличие, про-грамма не стареет (устаревает, но не стареет физи-чески).

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

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

87836по каталогуагентства«Пресса России»

Российская Федерация! Подписной индекс: 81655

Каталог агентства «Роспечать»! Подписной индекс: 87836

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

! Альтернативные подписные агентства:Агентство «Интер-Почта» (095) 500-00-60, курьерскаядоставка по МосквеАгентство «Вся Пресса» (095) 787-34-47Агентство «Курьер-Прессервис»

! Подписка On-linehttp://www.arzy.ruhttp://www.gazety.ruhttp://www.presscafe.ru

СНГВ странах СНГ подписка принимается в почтовых отделе-ниях по национальным каталогам или по списку номенк-латуры АРЗИ:! Казахстан – по каталогу «Российская Пресса» через

ОАО «Казпочта» и ЗАО «Евразия пресс»! Беларусь – по каталогу изданий стран СНГ через РГО

«Белпочта» (220050, г.Минск, пр-т Ф.Скорины, 10)

! Узбекистан – по каталогу «Davriy nashrlar» российскиеиздания через агентство по распространению печати«Davriy nashrlar» (7000029, Ташкент, пл.Мустакиллик,5/3, офис 33)

! Азербайджан – по объединенному каталогу российс-ких изданий через предприятие по распространениюпечати «Гасид» (370102, г. Баку, ул. Джавадхана, 21)

! Армения – по списку номенклатуры «АРЗИ» черезГЗАО «Армпечать» (375005, г.Ереван, пл.Сасунци Да-вида, д.2) и ЗАО «Контакт-Мамул» (375002, г. Ереван,ул.Сарьяна, 22)

! Грузия – по списку номенклатуры «АРЗИ» через АО«Сакпресса» ( 380019, г.Тбилиси, ул.Хошараульская,29 ) и АО «Мацне» (380060, г.Тбилиси, пр-т Гамсахур-дия, 42)

! Молдавия – по каталогу через ГП «Пошта Молдавей»(МД-2012, г.Кишинев, бул.Штефан чел Маре, 134)по списку через ГУП «Почта Приднестровья» (МD-3300,г.Тирасполь, ул.Ленина, 17)по прайслисту через ООО Агентство «Editil Periodice»(2012, г.Кишинев, бул. Штефан чел Маре, 134)

! Подписка для Украины:Киевский главпочтампПодписное агентство «KSS»Телефон/факс (044)464-0220

95№7(20), июль 2004

подписка на II полугодие 2004

96

СИСТЕМНЫЙ АДМИНИСТРАТОР№7(20), Июль, 2004 год

РЕДАКЦИЯИсполнительный директорВладимир ПоложевецОтветственный секретарьНаталья Хвостова[email protected]Технический редакторВладимир ЛукинРедакторАндрей Бешков

РЕКЛАМНАЯ СЛУЖБАтел./факс: (095) 928-8253Константин Меделянreс[email protected]

Верстка и оформление[email protected][email protected]Дизайн обложкиНиколай Петрочук

103045, г. Москва,Ананьевский переулок, дом 4/2 стр. 1тел./факс: (095) 928-8253Е-mail: [email protected]: www.samag.ru

РУКОВОДИТЕЛЬ ПРОЕКТАПетр Положевец

УЧРЕДИТЕЛИВладимир ПоложевецАлександр Михалев

ИЗДАТЕЛЬЗАО «Издательский дом«Учительская газета»

Отпечатано типографиейГП «Московская Типография №13»Тираж 7000 экз.

Журнал зарегистрированв Министерстве РФ по делам печати,телерадиовещания и средств мас-совых коммуникаций (свидетельствоПИ № 77-12542 от 24 апреля 2002г.)

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

ЧИТАЙТЕВ СЛЕДУЮЩЕМНОМЕРЕ:

В яблочко!Данная статья – краткий обзор ОСDarwin 7.0 на платформе x86 (она жеJaguar, она же Mac OS X 10.3).

Не прошло и полгода, как взоры ав-тора вернулись к упомянутому в заго-ловке продукту. Что же может при-влечь помимо легендарного названияфирмы Apple Computer? Наверное, са-мое главное – ориентирование даннойоперационной системы на открытость.Правда, можно долго дискутироватьотносительно открытости продуктовсамой фирмы Apple, а нас в первуюочередь должно волновать несколькомоментов: списки совместимости с обо-рудованием (так называемые hardwarecompatibility list [1]); знание структуры*BSD-систем; потребность в использо-вании данной ОС в обучающем про-цессе/на производстве.

Запуск в VMWare гостевойоси, установленнойна физическом дискеВ этой статье будет описана возмож-ность запуска гостевой системы, уста-новленной на компьютере при помощиVMWare самым обычным способом.Для более рационального использова-ния времени и ресурсов необходимоодну из этих систем (в данном случаеWindows) запускать либо на виртуаль-ной машине, либо на реальном компь-ютере, чтобы при этом сохранялись всеизменения, сделанные в системе вовремя работы. Это необходимо на слу-чай отсутствия администратора на ра-боте. Про установку и запуск этой про-граммы можно прочитать на http://www.onix.opennet.ru, где выложены ста-тьи Андрея Бешкова. Но там не описанвопрос запуска уже установленной си-стемы, находящийся на физическомдиске, который мы сегодня рассмотрим.

отметить относительное спокойствие. Авот Windows XP действительно смогпривлечь пользователя, этот момент истоит считать началом действительно-го интереса разработчиков к проблеме.Многие (да почти все) производителивключили поддержку NTFS в ядрах сво-их дистрибутивов. Проблем с доступомк разделам NTFS не обнаружат пользо-ватели Mandrake, SUSE, ALTLinux,ASPLinux, Slackware, Debian и прочихпопулярных дистрибутивов. Только ком-пания RedHat, очевидно руководству-ясь лицензионной чистотой своего ди-стрибутива, не включила поддержкуданной ФС. Поэтому пользователиRedHat и Fedora увидят при попыткемонтирования раздела сообщение, вы-веденное в заголовок.

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

Linux и NTFSДо недавнего времени острой необхо-димости в доступе к разделам с фай-ловой системой NTFS во общем-то и небыло. Ругать разработчиков ядра Linuxне за что, необходимые работы ведут-ся уже давно и отнюдь не безуспешно.Уже в 1995 году для ядер серии 2.0 былдоступен патч для работы с этой фай-ловой системой, а с версии 2.2 (еслибыть точнее 2.1.74) подержка NTFS вядро была включенна стандартно. Новсе равно разработки велись несколь-ко вяло. Причин несколько. Семействопользовательских операционных сис-тем Windows до Me включительно под-держивают только FAT, а NTFS исполь-зовалась на ОС корпоративно-сервер-ного уровня, где вряд ли кто-то доду-мается поставить одновременно двеоперационные системы на одном ком-пьютере. Появление же Windows 2000практически ничего не изменило, надомашних компьютерах ее устанавли-вали довольно неохотно, и если посмот-реть на форумах тех времен, то можно