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

№2(27) февраль 2005

подписной индекс 81655


www.samag.ru

Системная интеграция – общие концепции


Автоматическая установка
операционной системы
и программного обеспечения
SOCKS – универсальный прокси-сервер
Строим виртуальную сеть с TINC
Создание релиза FreeBSD
IP-роуминг: вводный курс
Почтовый сервер на базе Postfix
Режем спам. Дополнительные методы
Техника оптимизации под Linux
№2(27) февраль 2005

Считаем трафик на FreeBSD:


ng_ipacct + Perl+ MySQL
оглавление

ТЕНДЕНЦИИ 2 FreeBSD tips: NAT по старинке


Сергей Супрунов
СОБЫТИЯ 3 amsand@rambler.ru 44
Всегда на связи,
РЕПОРТАЖ 4 или IP-роуминг: вводный курс
Сергей Яремчук
АДМИНИСТРИРОВАНИЕ grinder@ua.fm 46
Сага о биллинге,
Системная интеграция – или Считаем трафик на FreeBSD
комплексный подход (ng_ipacct + perl+ MySQL)
к самостоятельному Часть 1
решению проблемы
Владимир Чижиков
Роман Марков skif@owe.com.ua 50
stepan-razin@newmail.ru 6
Автоматическая установка ОС
Кто купил Corel Linux? и сопутствующего программного
Обзор возможностей настольного дистрибутива Xandros. обеспечения
Валентин Синицын Иван Коробко
val@linuxcenter.ru 12 ikorobko@prosv.ru 60
Создание релиза FreeBSD ПРОГРАММИРОВАНИЕ
Андрей Елсуков
bu7cher@yandex.ru 16 Техника оптимизации под Linux
Конструктивный Dialog Крис Касперски
kk@sendmail.ru 68
Сергей Супрунов
amsand@rambler.ru 20 Zend Studio 4.0 – новая версия,
новые возможности
Почтовый сервер на базе Postfix
Защита от вирусов и нежелательной почты минимальными Евгений Воякин
средствами. evgy@mail.ru 75
Геннадий Дмитриев HARDWARE
stranger03@mail.ru 26
Режем спам. Дополнительные методы Запись дисков CD-R/RW в Linux
Часть 4
Денис Назаров
pheonix@sysattack.com 30 Владимир Мешков
ubob@mail.ru 80
Универсальный прокси-сервер
ОБРАЗОВАНИЕ
Валентин Синицын
val@linuxcenter.ru 34
Unformat для NTFS
Строим виртуальную сеть с TINC
Крис Касперски
Сергей Яремчук kk@sendmail.ru 88
grinder@ua.fm 39
BUGTRAQ 11, 15

№2, февраль 2005 1


тенденции
Пополнение серверной линейки HP Сага о патентах на ПО в Европе
Пресс-конференция компании HP, посвященная представ- Продолжается затянувшаяся история с принятием законо-
лению новых серверных продуктов HP ProLiant на базе про- проекта о патентах на программное обеспечение в Европе.
цессоров AMD Opteron, прошла 21 февраля в Москве в оте- На OSDL Linux Summit в очередной раз эту проблему под-
ле «Балчуг». нимают видные деятели Open Source (среди них Торвальдс,
Специалистами компании была анонсирована обновлен- Белендорф и Капор), открыто критикуя инициативу ЕС. И
ная линейка процессоров AMD Opteron x52, презентованы уже 2 февраля выясняется, что директива CIID (о компью-
новые модели 2-х и 4-х процессорных серверов HP ProLiant терных разработках) будет переписана – таковы итоги за-
DL385 и DL585 на процессорах AMD, и также новые сер- седания юридического комитета Европарламента (JURI).
верные модули на базе процессоров AMD в форм-факторе Несмотря на этот успех, Мартин Финк, Linux-специалист из
блейд-серверов BL25p и BL35p. Hewlett-Packard, предостерегает всех противников патен-
Новые процессоры AMD Opteron, изготовленные по про- тов на ПО, советуя им смириться с тем, что данного шага
цессу 90 нм, модели 152, 252 и 852, были представлены Сер- все равно не избежать, и к этому надо привыкать. В сере-
геем Мелеховым, ведущим инженером по внедрению про- дине месяца при поддержке FFII в Брюсселе проходит ак-
дукции AMD. Набор привычных технологических новшеств ция протеста против принятия закона о патентах на ПО, в
в стиле «дальше, выше и быстрее», которые характеризуют которой принимает участие около 300 представителей раз-
продукцию AMD, возглавляют технологии Direct Connect, личных европейских стран. Позже Хартмут Пилч, возглав-
HiperTransport и AMD PowerNow!. Старшие модели этого ряда ляющий FFII, высказывает сомнение в том, что Европейс-
специально ориентированы на использование в многопро- кая комиссия воспользуется возможностью подготовить ка-
цессорных системах. Наиболее интересными представля- чественную замену отвергнутому законопроекту.
ются результаты применения AMD PowerNow!, которые по-
зволяют процессорам AMD существенно превосходить кон- Новости «огненного лиса»
курентные аналоги по энергосбережению. Разработчик Firefox Бен Гуджер сообщает о планах по бу-
Но, бесспорно, самое важное свойство новых изделий – дущим релизам браузера. Firefox 1.1 Alpha появится в мар-
это так называемая совместимость с двуядерными процес- те, Beta – через месяц, а выпуск финальной версии 1.1, из-
сорами (Dual-Core), выпуск которых намечен на середину начально ожидавшийся к началу весны, перенесен на июнь.
2005 года. Использование этих процессоров в новых сер- Ориентировочным временем выхода Firefox 2 остается де-
верах HP ряда DL и BL, о которых рассказали менеджеры кабрь 2005 года. Поисковая система Yahoo решила после-
соответствующих направлений компании HP Игорь Слеп- довать примеру Amazon.com и выпустила свою панель для
цов и Сергей Члек, делает эти модели очень привлекатель- Firefox, с помощью которой пользователи могут искать в
ными, поскольку позволит без аппаратных переделок про- сети, не заходя на сайт. Компания Ask Jeeves проявила за-
извести апгрейд на двуядерные процессоры AMD Opteron интересованность в возможном создании собственного бра-
и практически удвоить тем самым вычислительные мощ- узера на базе Mozilla Firefox, а также выразила готовность
ности. открыть свои технологии поиска из Ask Jeeves Desktop
Новые серверы HP ProLiant DL385 и DL585, соответствен- Search. 16 февраля Mozilla Foundation публикует анонс о
но 2U/2P и 4U/4P (для новичков: размер по вертикали/число том, что Firefox скачали уже более 25 миллионов раз, а 24
процессоров) являются очередными отлично выполненными числа сообщается о выходе Firefox 1.0.1 с исправлениями
изделиями компьютерного hi-end и вполне могут повторить (в частности, в безопасности браузера).
успех предыдущей серверной пары на процессорах Intel
(DL380 в настоящее время лидер продаж). Производителем Linux-активность Novell
гарантируется полная совместимость с широким рядом опе- Novell не перестает вести активную политику по отноше-
рационных систем и прикладных программ. нию к Linux. В начале месяца компания анонсирует бета-
Серверы BL25p и BL35p, оба двухпроцессорные, выпол- версию Novell Client для Linux, затем совместно с IBM объяв-
нены в форм-факторе «блейд». Серверы такого типа сей- ляет о намерении продвигать свой корпоративный дистри-
час фавориты внимания. Стратегия их внедрения, так на- бутив SLES на платформе Power, а позже представляет
зываемые «экосистемы», очень спорна. Но именно в этом решение на базе SUSE Linux для обеспечения сетевой бе-
классе серверов, в силу высокой интеграции, максимально зопасности – Security Manager. Но не останавливается и на
выгодно могут быть использованы свойства процессоров этом: Novell открывает 200 тысяч строк кода проекта NetMail,
AMD Opteron, пониженное тепловыделение и в недалеком на которых базируется новое серверное Open Source ПО
будущем двуядерные процессоры. И уже сейчас эти блейд- компании для работы с электронной почтой, календарями
серверы вместе с моделями DL показывают максимальную и контактами, получившее название Hula. Linux-инициати-
производительность в своем классе. вы Novell добрались и до азиатских регионов: на Тайване
Хотя, что тут удивительного! Если в Cray на основе AMD открыто два центра для сертификации дистрибутива SUSE
Opteron создают суперкомпьютеры, то применение этих про- Linux, а в Корее подписан договор с KT, по которому мест-
цессоров в серверах стандартной архитектуры вместе с вы- ный оператор сотовой связи будет заниматься продажами
сокими технологиями HP позволяет добиваться замечатель- SLES.
ных результатов.
Составил Дмитрий Шурупов
Алексей Барабанов по материалам www.nixp.ru

2
события
Форум по открытому коду в России «Open Source Forum Russia» и возможность внеконкурсного
27-29 апреля 2005 г. показа своих разработок в демозоне OpenSourceLive.
В конце апреля впервые состоится Open Source Forum Заявки на участие в конкурсе принимаются до 15 марта
Russia – крупнейшее на сегодняшний день мероприятие, 2005 года по адресу http://www.opennet.ru/konkurs. С 15 мар-
целиком посвященное технологиям разработки программ- та по 10 апреля будет проходить голосование, а уже 11 ап-
ного обеспечения с открытым исходным кодом. реля будут подведены итоги и опубликованы результаты ра-
Форум, включающий в себя конференцию и выставку, боты.
пройдет 27-29 апреля 2005 года в Москве, в гостинице «Рэ- В качестве претендентов могут выступать специалис-
диссон САС Славянская». Организаторы – ассоциация РУС- ты, участвующие в разработке программ, распространяе-
СОФТ, агентство Форт-Росс и компания Линукс Инк. мых с открытыми исходными текстами; авторы статей и пе-
Чем особенно интересно данное мероприятие? реводов документации; энтузиасты, поддерживающие па-
! Многие широко известные в мире гуру открытого кода кеты программ; эксперты, предоставляющие консультации
и главы компаний, занимающихся открытым кодом, уже в веб-форумах, новостных конференциях и почтовых рас-
подтвердили свои выступления в программе. Это Jon сылках.
maddog (Linux International), Richard Seibt (Novell), David Кроме бесплатного участия в московском форуме, по-
Axmark (MySQL), Larry Wall (Perl), Alex Pinchev (RedHat) бедители конкурса ОpenNet.ru получат комплект призов от
и другие. компании LinuxCenter. От редакции журнала «Системный
! Во время форума будет постоянно работать выставка, администратор» обладатели призовых мест получат в по-
два раздела которой будут посвящены демонстрации дарок бесплатную подписку на издание на 2005 год. Для
наиболее интересных решений (в разделе Linux City – одного из участников, не вошедшего в тройку лидеров, на
как различные предприятия и организации полностью основании решения администрации OpenNet.ru будет пре-
функционируют на Linux, и в разделе OpenSourceLive – доставлен сертификат на покупку книг на сумму 3000 руб.
лучшие приложения и решения на открытом коде, ото- Планируется, что проводимое в рамках OpenNet.ru ме-
бранные к демонстрации на конкурсной основе). роприятие получит продолжение в серии конкурсов, направ-
! Форум поддержан Министерством ИТ и связи и Мини- ленных на поддержание и стимулирование русскоязычных
стерством экономического развития и торговли. Вопро- разработчиков открытых программ.
сам использования открытого кода в государственных
структурах будет посвящен один из дней конференции. Международная специализированная
выставка-конференция
Программный комитет включает представителей все- Infosecurity Russia
мирно известных вендоров, лидеров разработки программ- 7-9 сентября 2005 г.
ного обеспечения, представителей ведущих отраслевых Выставочное объединение «Рестэк» совместно с компани-
министерств и крупнейших ИТ-ассоциаций как РУССОФТ ей Reed Exhibitions объявляют о проведении международной
и ITAA. Форум по открытому коду в России получил под- специализированной выставки-конференции Infosecurity
держку Всемирного Альянса ИТ-ассоциаций (WITSA). Russia.
Программный комитет отбирает темы и выступления для Выставка пройдет 7-9 сентября 2005 года на одной пло-
широкого обсуждения и профессиональных дискуссий: щадке с LinuxWorld Russia и StorageExpo в выставочном ком-
! управление проектами при разработке ПО с открытым плексе «Гостиный двор» (Москва, ул. Ильинка, д. 4).
кодом; В рамках выставки Infosecurity 2005 предусмотрена на-
! безопасность программных продуктов и технологий на сыщенная деловая программа, которая включает в себя кон-
базе ПО с открытым кодом; ференцию, «круглые столы», семинары и презентации для
! обучение персонала ведению разработок в среде ПО с специалистов отрасли.
открытым кодом; На выставке Infosecurity 2005 будут представлены про-
! особенности разработки и оказания коммерческих ус- дукты и решения мировых лидеров отрасли информаци-
луг по разработке ПО с открытым кодом; онной безопасности, таких как Cisco Systems, CPS, Hewlett-
! сравнение характеристик ПО с открытым кодом и зак- Packard, McAfee (Associates), Nortel, PatchLink Corporation,
рытого ПО. RedHat, SafeBoot, Sun Microsystems, Symantec, Veritas, а
также ведущих российских фирм, таких как АМТ Груп, Ди-
Подробную информацию об участии в выставке и кон- алогНаука, Информзащита, Инфосистемы Джет, Корпо-
ференции вы можете найти на сайте по адресу: http:// рация ЮНИ, Компьюлинк, Лаборатория Касперского, ЛА-
www.opensource-forum.ru. Ждем вашей регистрации на сай- НИТ, ЛанКрипто, МОО «АЗИ», Элвис Плюс, Aladdin, Digital
те или по электронной почте: info@fort-ross.ru. Security, InfoWatch, Positive Technologies, Protection
Technologies, Rainbow Technologies, SecurIT и других.
Конкурс Посетить экспозицию выставки Infosecurity 2005, а также
Стартовал первый конкурс разработчиков открытого про- послушать любой из докладов экспертов абсолютно бесплат-
граммного обеспечения, проводимый проектом OpenNet.ru но может каждый специалист по информационной безопас-
совместно с ассоциацией РУССОФТ, компанией LinuxCenter ности, предварительно зарегистрировавшийся на официаль-
и журналом «Системный администратор». Трех победителей ном веб-сайте выставки www.infosecuritymoscow.com с мар-
ждет бесплатное участие в специализированном форуме та 2005 года. Следите за обновлениями на сайте!

№2, февраль 2005 3


репортаж
Школа-cеминар
«Информационные технологии в образовании: Технологии Linux»
C 26 по 28 января на базе Московского Государственного использовать среду KDE, создавать текстовые документы,
Педагогического Университета (МПГУ) прошла школа-се- электронные таблицы, презентации и даже векторные ди-
минар «Информационные технологии в образовании: Тех- аграммы в открытом офисном пакете OpenOffice.org и ре-
нологии Linux». Организаторами мероприятия выступили дактировать растровые изображения в The GIMP.
Всемирный Распределенный Университет – World Distributed
University (WDU) и Центр компетенции Linux корпорации IBM.
Журнал «Системный администратор» выступил информа-
ционным спонсором этого события.
В работе школы приняли участие более 100 преподава-
телей информатики, студентов старших курсов, аспиран-
тов и IT-специалистов, прибывших в МПГУ со всех уголков
России и даже бывших союзных республик: Азербайджана
и Украины.

По окончании работы школы слушатели, успешно усво-


ившие программу практических занятий и подтвердившие
свои знания в ходе квалификационного экзамена, получи-
ли профессиональный сертификат «Пользователь Linux»,
удостоверенный печатью WDU. Кроме этого, участники се-
минара получили самозагружаемые компакт-диски (LiveCD)
со специализированной версией дистрибутива Knoppix RE,
содержащие тезисы наиболее интересных докладов, и дру-
Рабочий день семинара традиционно делился на две ча- гие полезные материалы.
сти. В первой половине дня проходили пленарные заседа-
ния и «круглые столы», затрагивающие актуальные темы:
«Технологии Linux», «Специальность ИТО», «Защита ин-
формации и информационная безопасность». С доклада-
ми на этих секциях выступали специалисты-практики, а
также приглашенные эксперты из министерств РФ.

Семинар «Технологии Linux» – первое и пока что един-


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

Живым интересом со стороны слушателей-педагогов


пользовались «истории успеха» – сообщения о примене-
нии Linux в образовательном процессе в высшей школе, а
также вопросы совместного использования Windows и Linux.
Вторая половина дня отводилась для практических за-
нятий. Вниманию участников школы были предложены две
программы, разработанные Мельниковым В.В. (Академия
наук Крыма) и Синицыным В.Е. (LinuxCenter.ru) и рассчи-
танные на разный уровень начальной подготовки. В ходе
этих занятий слушатели приобрели базовые навыки, необ- Валентин Синицын
ходимые для повседневной работы в Linux. Они научились Фото Павла Заклякова

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

СИСТЕМНАЯ ИНТЕГРАЦИЯ – КОМПЛЕКСНЫЙ


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

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

6
администрирование
С чего начать? реть «лишнюю пару» – дополнительный провод (или не-
Попробуем описать общие концепции такого проекта, а так- сколько – все зависит от задач), который не будет исполь-
же типичные ошибки и трудности, с которыми придется зоваться сразу, однако при необходимости легко вводится
столкнуться на различных этапах работы. Автор статьи яв- в общую схему коммутации. Это поможет в будущем избе-
ляется руководителем отдела системной интеграции IT-ком- жать проблем с потерей скорости при резком увеличении
пании и принимает прямое участие в таких проектах. Опи- количества рабочих мест в соседних зданиях/помещениях.
санные ситуации основаны на реальных событиях, проис- Телефонная сеть вообще является камнем преткновения
ходящих в процессе взаимодействия с участниками проек- при расширении компании. В случае с масштабированием
та. Как было сказано выше, «системная интеграция» – гло- компьютерной сети всегда можно выйти из положения (пусть
бальный процесс, поэтому участниками проекта в той или и ценой потери скорости передачи данных) установкой до-
иной мере являются все сотрудники фирмы. В связи с этим полнительного сетевого коммутатора в помещение, где
и появляется необходимость в создании административных сгруппировались новые рабочие места. К сожалению, со
правил для всех подразделений предприятия. Впрочем, обо стандартной телефонией такой фокус не проходит и при
всем по порядку. Опишем порядок как административных, необходимости увеличить количество телефонов в опреде-
так и технических мер. ленном помещении приходится тянуть туда новые прово-
Существуют два варианта развития проекта: да. В этом случае и можно будет использовать «лишний
! Вы хотите построить на своем предприятии всю IT-струк- провод», который был заблаговременно оставлен при пер-
туру «с нуля» и «под ключ». вичной прокладке сети. Причем задействовать витую пару,
! У вас уже есть функционирующая сетевая инфраструк- которая была запланирована под локальную сеть с некото-
тура, которую необходимо упорядочить. рой избыточностью, оказывается гораздо удобнее, так как
по стандартной витой паре можно прокинуть сразу несколь-
Как правило, первый вариант всегда проще, хотя и в ко телефонных линий.
этом случае обязательна разработка плана и концепций. В Постарайтесь при начальном монтаже максимально об-
противном случае в итоге вы получите вариант №2 и нача- легчить себе дальнейшую жизнь. Справедливость поговор-
ло новой попытки системной интеграции. Рассмотрим пер- ки «Два переезда равны одному пожару» много раз прове-
вый вариант как основу построения корпоративных систем, рена на практике, поэтому попробуйте приложить все уси-
а затем на его базе проанализируем возможные пути мо- лия, чтобы спланировать это еще на этапе проектирования
дификации уже существующей инфраструктуры. кабельных систем. Помимо этого, не стоит забывать об уже
прочно держащих позиции технологиях беспроводных се-
Кабельная система – все «с нуля» тей. В последние годы оборудование для построения бес-
Как «театр начинается с вешалки», так и любая IT-система проводных сетей наконец-то стало удовлетворять тем тре-
начинается с физических коммуникаций. Проще говоря, с бованиям, которые возникают при работе пользователей с
проводов (или беспроводных коммуникаций). Именно гра- современными сетевыми приложениями, так что их приме-
мотное проектирование с учетом дальнейшего роста ком- нение в помещениях с прямой видимостью (или с незначи-
пании, а также качественная разводка кабельных систем и тельными перекрытиями) является прекрасной альтерна-
определяет дальнейшие возможности масштабирования су- тивой проводным системам. Однако следует помнить, что
ществующей сети. стремиться построить полностью беспроводную сеть не
Старайтесь сразу строить предварительные расчеты и стоит – соединения между помещениями/этажами лучше
планы таким образом, чтобы свести все коммуникации (ло- сделать на кабельной основе.
кальная сеть и телефония) в единый центр коммутации. Как
правило, это коммутационный шкаф-стойка для установки Оборудование
в нем патч-панелей и оборудования. Именно здесь рекомен- После того, как все кабельные системы спроектированы и
дуется сконцентрировать все проводные коммуникации для построены, можно приступать к закупке нового оборудова-
их дальнейшей коммутации и распределения. Кажущиеся из- ния и модификации устаревшего. Тут следует руководство-
лишними трудозатраты по организации описанной схемы с ваться многократно описанными принципами соответствия
лихвой оправдаются дальнейшей экономией времени при ре- поставленных задач и необходимой для этого техники.
организации фирмы (переезды отделов в другие помеще- Прежде всего необходимо напомнить основную мысль, ко-
ния, добавление рабочих мест и т. п.). Статистика показыва- торую, к сожалению, очень часто игнорируют: не экономь-
ет, что в средних и крупных компаниях примерно 30% слу- те на узлах, которые являются критичными по отношению
жащих раз в год меняют свое рабочее место в связи с опи- к работоспособности всей системы. Практика показывает,
санными выше событиями. И именно по этой причине все- что возможность сэкономить хотя бы сотню долларов час-
гда необходимо планировать кабельную сеть таким образом, то приводит к тому, что закрываются глаза на обратную
чтобы количество розеток было большим, чем нужно для сторону медали – итоговую надежность системы. Как пра-
удовлетворения сегодняшнего спроса. При масштабирова- вило, руководители, принимающие решения в области фи-
нии сети такой избыток дает возможность пользователям и нансирования, не в состоянии оперировать техническими
гостям беспроблемно мигрировать внутри офиса. понятиями. Зато они прекрасно знают и понимают значи-
Всегда необходимо помнить, что и в глобальных комму- мость таких терминов, как «убытки в результате простоя
никациях (это могут быть как соединения между помеще- предприятия», «цейтнот при формировании результатов»,
ниями, так и между зданиями) рекомендуется предусмот- «налоговая и финансово-экономическая отчетность». И в

№2, февраль 2005 7


администрирование
техническом обосновании приобретения надежной техни- Ну и последнее замечание, касаемо физического пост-
ки должны бросаться в глаза не «гигагерцы и гигабайты», роения сетей. Документируйте свои действия, маркируйте
а аргументы, понятные именно этим людям. Например, коммуникации. Даже если вы не владеете профессиональ-
фраза о том, что «скорость формирования товарного отче- ными программами для проектирования и документирова-
та увеличится в 6-10 раз, а скорость формирования склад- ния информационных сетей – программу Microsoft Visio ник-
ских документов повысится в 4 раза» гораздо эффектив- то не отменял. Она представляет собой довольно неплохой
нее, нежели «время реакции дисковой системы при опера- инструмент для инженерного планирования начального
циях чтения-записи улучшается в 5 раз». Всегда помните – уровня. Маркировка кабелей и кабель-каналов – вообще
для руководства важны итоговые результаты, а не техни- обязательное действие. Помимо этого необходимо марки-
ческие подробности. Научитесь формулировать свои мыс- ровать и серверы в стойках. Когда в стойке смонтировано
ли и идеи так, чтобы они были понятны людям, принимаю- несколько серверов от одного производителя, вряд ли уда-
щим решения о финансировании проекта. Тогда вы полу- стся навскидку сказать, какой из них за что отвечает. Кре-
чите большие возможности для реализации задуманного. пите на них таблички с DNS-именем и IP-адресом.
Также немаловажным является приведение расчетов, по-
казывающих экономическую эффективность модерниза- Если что-то уже есть…
ции. Спрогнозировав возможные перемещения рабочих Если вы модернизируете уже существующую информаци-
мест сотрудников, увеличение их численности, появление онную систему, то все советы, приведенные выше, остают-
новых задач, рост рабочих информационных баз, вы смо- ся в силе. Помимо этого, при наличии старых коммуника-
жете заранее просчитать будущие затраты на необходимую ций необходимо проверить их на целостность и качество
модернизацию ресурсов, и сравнив их с возможностью сра- передачи.
зу приобрести необходимую технику, вывести экономичес- Простейший способ – посмотреть статистику передачи
кую выгоду. по сетевым интерфейсам после проведения множествен-
В частности, попытка сэкономить на серверных систе- ных операций передачи/приема данных. Если скорость пе-
мах обычно приводит либо к необходимости новой моди- редачи недостаточна, а в статистике появляются потерян-
фикации уже через полгода, либо вообще к падению опе- ные пакеты – стоит задуматься о смене кабельной систе-
рационной системы, потере рабочих данных и, соответ- мы или отдельных ее частей. Однако такой способ провер-
ственно, незапланированным простоям – от невозможнос- ки является довольно спорным и отражает действитель-
ти работы одного отдела до остановки работы всего пред- ность только при грамотной настройке приемника/передат-
приятия. чика. В противном случае, например, плохо настроенное
Если рассматривать требования к таким системам, то оче- антивирусное ПО, может отрицательно повлиять на упомя-
видна необходимость применения в серверах надежных дис- нутые характеристики, хотя сама кабельная система ока-
ковых систем в случае больших вычислительных нагрузок – жется идеальной. Гораздо лучше применять тестирование
многопроцессорных ресурсов, резервных систем электропи- кабельной системы на физическом уровне при помощи
тания и защиты от перегрузок в электрических сетях. Не стоит приборов, измеряющих такие характеристики, как сигнал/
пользоваться принципом: «система может и на IDE-диске шум, сопротивление изоляции и др. Это дорогостоящее
стоять – там никаких нагрузок нет». Сэкономив 50-100 у.е. оборудование, однако вовсе необязательно его приобре-
сейчас, ваша фирма получит неработоспособную систему тать. Для тестирования в сомнительных случаях можно об-
через год. Причем произойдет это как всегда «в самый не- ратиться к организациям, оказывающим подобные услуги.
подходящий момент». Запомните – не бывает «подходящих В любом случае при сложной кабельной разводке такое
моментов» для выхода из строя информационной системы. исследование обойдется дешевле смены всей кабельной
И именно вы несете за это ответственность. Если при об- системы. Точно так же необходимо подвергнуть тестирова-
суждении расходов вы натыкаетесь на стену непонимания и нию и ресурсы серверов, и при необходимости – рабочих
экономить на критически важных узлах принуждают люди, станций. Недостаточно просто переустановить операцион-
принимающие решения о финансировании, – не забывайте ную систему на сервере. Необходимо убедиться в том, что
принять меры для того, чтобы не оказаться крайним. В дан- нет дефектов в оборудовании – дисковой системы, памяти
ном случае рекомендуется написать на имя руководителя и т. д.
служебную записку примерно следующего содержания:
Информационная среда
Äèðåêòîðó ÎÎÎ «Ðîãà è êîïûòà» Убедившись в исправности физических коммуникаций и
Ïóïêèíó Âàñèëèþ Äîðìèäîíòîâè÷ó
îò ñèñòåìíîãî àäìèíèñòðàòîðà оборудования, следует переходить к следующему этапу –
Ôåäüêèíà Ïåòðà Èâàíîâè÷à внедрению информационной среды. На этом этапе необхо-
Ñëóæåáíàÿ çàïèñêà димо будет установить операционные системы на серверы
и рабочие станции, организовать их взаимодействие, на-
Äîâîæó äî Âàøåãî ñâåäåíèÿ, ÷òî èñïîëüçîâàíèå â ïðèîáðåòà-
åìûõ ñåðâåðàõ æåñòêèõ äèñêîâ òèïà IDE, à òàêæå îòñóòñòâèå строить программное обеспечение под конкретных пользо-
èñòî÷íèêîâ áåñïåðåáîéíîãî ïèòàíèÿ ìîùíîñòüþ íå ìåíåå 1000 вателей. Разумеется, что выбор операционных систем и
VA ìîãóò ïðèâåñòè ê íåïîëàäêàì â ðàáîòå èíôîðìàöèîííîé ñèñ-
òåìû âïëîòü äî ïîëíîãî âûõîäà èç ñòðîÿ è ïîòåðå õðàíèìûõ распределение задач должны происходить еще до того, как
äàííûõ. будет закуплено оборудование. Тут все стандартно – под-
Ïîäïèñü бор соответствующего оборудования происходит исходя из
Îçíàêîìëåí: <ïîäïèñü äèðåêòîðà> поставленных задач.

8
администрирование
Перейдем к принципам настройки серверного программ- вилам, должны отбрасываться. Причем чаще всего реко-
ного обеспечения, вопросам защиты от вторжений, а так- мендуется применять для защиты «режим молчания». Зап-
же настройке рабочих станций для взаимодействия с сер- рещающие правила систем маршрутизации при поступле-
верами и между собой. Акцентируем ваше внимание, что в нии соответствующего пакета отправляют ответ о том, что
статье не приводится инструкций по настройке конкретно- запрошенный ресурс запрещает подключение к нему. При
го программного обеспечения или оборудования, а даются соблюдении режима молчания такой пакет игнорируется,
общие рекомендации, следуя которым вы получите макси- имитируя выключенное или несуществующее устройство.
мально защищенную IT-структуру. Также не указывается Для настройки таких систем необходим специалист, хоро-
никаких предпочтений при выборе операционных систем шо представляющий работу стека протокола IP. Для боль-
для реализации проекта. Автор ни в коей мере не претен- шей надежности рекомендуется использовать аппаратные
дует на непогрешимость указанных методов, а всего лишь маршрутизаторы/межсетевые экраны. Абсолютным лиде-
делится своим опытом реализации подобных проектов. ром в этой области является компания Cisco Systems. Од-
Практика показала, что после сдачи таких сетей у заказчи- нако их продукты отличаются очень высокой стоимостью
ков не возникает необходимости полной реорганизации, а (проверенная надежность не бывает дешевой). В последнее
масштабируемость позволяет легко вводить в эксплуата- время на рынок вышли многочисленные компании, пред-
цию новые сервера, рабочие места и программное обеспе- лагающие недорогую альтернативу подобным продуктам.
чение. Практически все производители сетевого оборудования
Прежде всего необходима логическая структура, кото- имеют в ассортименте решения для построения защитных
рая будет объединять все учетные записи для пользовате- систем эконом-класса (маршрутизаторы со встроенными
лей, компьютеров и серверов в одно целое. Это «домен». пакетными фильтрами, VPN-маршрутизаторы). Наиболее
Обращаем внимание, что понятие «домен» вовсе не под- надежным окажется решение с использованием каскадно-
разумевает обязательное использование продуктов го комплекса защиты. Например, последовательного ис-
Microsoft, как многие ошибочно считают. «Домен» в пере- пользования аппаратного маршрутизатора и шлюзового
воде означает «область», «район». То есть в нашем случае сервера с работающими на нем средствами маршрутиза-
домен – это логическое объединение для централизован- ции и протоколирования.
ного управления. Домен отличается от рабочей группы тем, Следующие шаги также неразрывно связаны с досту-
что данные о всех структурных единицах, в него входящих, пом во внешний мир. Это использование антивирусных
хранятся в единой центральной базе данных, что сильно мониторов и сканеров корпоративного уровня, а также обя-
упрощает администрирование системы в целом. зательное создание внутреннего почтового сервера, отве-
Внутри домена необходимо спланировать разделение чающего за перенаправление всей электронной почты ком-
упомянутых структурных единиц на группы. Это упростит пании. Акцентируем внимание на словосочетании «корпо-
дальнейшее делегирование прав на пользование ресурса- ративный уровень». Помните, что в системе IT-безопасно-
ми. Помните, что основой построения защищенной среды сти компании не должно быть звеньев, хоть каким-то обра-
является принцип «что не разрешено, то запрещено» и ни зом зависящих от решения пользователя. Понятие «корпо-
в коем случае не наоборот! Действительно, по умолчанию ративный антивирусный монитор и сканер» означает, что
при начальном вводе систему в эксплуатацию никто (кро- это программное обеспечение настраивается и устанавли-
ме администратора, разумеется) не должен иметь доступа вается администратором системы, автоматически прове-
никуда. Абсолютно! После этого можно делегировать груп- ряет наличие обновлений, распространяется на всю сеть, а
пам и структурным единицам определенные права. Упомя- пользователь не в состоянии ни отключить, ни удалить про-
нутый и кажущийся очень простым принцип на самом деле дукт со своей рабочей станции. Такой антивирусный про-
подразумевает под собой систему глобальной безопаснос- дукт при грамотной настройке не будет спрашивать пользо-
ти. Просто необходимо научиться корректно его реализо- вателя о необходимости обновить свои базы, не станет уточ-
вывать. нять, что делать с зараженным файлом, не позволит вме-
шаться в свою работу.
Связь с внешним миром При этом корпоративная почтовая система просканиру-
и безопасность ет всю входящую и исходящую корреспонденцию еще до
Построив систему в виде локальной сети и проверив ее того, как пользователь получит возможность принять ее,
работоспособность (взаимодействие клиент-сервер, кли- отбросит зараженные письма, заблокирует подозрительные
ент-клиент, действие запретов и разрешений), приступаем и явно запрещенные вложения, проверит легитимность от-
к организации связи с внешним миром. Проще говоря, под- правителя и отсутствие его в международных черных спис-
ключаемся к сети Интернет и другим филиалам компании. ках. И только после этого доставит письмо пользователю.
Тут действует тот же универсальный принцип, о котором Как правило, на почтовые системы устанавливают антиви-
мы уже писали. Поэтому перед тем, как подключить кабель рус другого производителя, нежели используется в режи-
от внешнего мира к вашей локальной сети, необходимо убе- ме монитора внутри локальной сети. Таким образом дости-
диться в том, что на устройстве маршрутизации запрещен гается страховка от несвоевременного выхода обновлений
проход любого трафика во всех направлениях. Только пос- какого-либо из них. Неопознанное на почтовом сервере
ле этого можно аккуратно добавлять настройки, которые зараженное письмо будет поймано монитором на локаль-
будут частично разрешать прохождение необходимого тра- ной машине пользователя и наоборот. Для еще большей
фика. Любые запросы, не отвечающие разрешающим пра- надежности можно применять третий способ защиты – ска-

№2, февраль 2005 9


администрирование
нирование межсетевого трафика на промежуточном шлю- технологиями. Если к этому присовокупить то, что часто
зе. Однако стоит помнить, что нельзя использовать одно- такие люди занимают одни из ведущих или необходимых
временно несколько таких средств в едином логическом постов в компании и к их словам бездумно прислушивают-
пространстве (например, сервере или рабочей станции). ся руководители, не желая при этом проанализировать си-
Так, одновременная установка двух антивирусных монито- туацию, – процесс может быть крайне затруднен. На прак-
ров разных производителей на один компьютер когда-то тике встречались разные случаи. Например, в одной круп-
породила известную в IT-мире байку про дуэль антивиру- ной строительной фирме бухгалтер со скандалом врыва-
сов. Проверка может быть только последовательной. лась к директору и жаловалась на то, что системный адми-
Не стоит также забывать о контроле активности пользо- нистратор умышленно мешает ей работать. На самом деле
вателей в сети Интернет, ведении статистики посещаемо- администратор после внедрения домена Windows 2000 хо-
сти и отчетов по трафику интернет-ресурсов. Так, перио- тел добиться работы в единой операционной среде на всем
дически просматривая указанную статистику, можно обна- предприятии и заменить технически устаревшую операци-
ружить «нездоровую» активность в определенном направ- онную систему Windows 98 на Windows 2000, тем более что
лении и предотвратить утечку информации или распрост- ресурсы компьютера это позволяли. А бухгалтер заявила,
ранение вредоносных программ. Помните, что «вы не мо- что не будет работать в другой системе. В итоге техничес-
жете управлять тем, что не можете подсчитать». Как пра- кому специалисту было в приказном порядке запрещено
вило, при грамотной настройке дальнейшая работа адми- что-либо менять на компьютере бухгалтера. Помимо этого
нистратора сети заключается в постоянном контроле. Все- претензия заключалась в том, что «не надо мне никаких
го и вся. Осознание того, что полностью контролируешь нортонов, пусть стоит касперский». В другой организации
процесс, приносит уверенность в дальнейшей работе. И бухгалтера постоянно провоцировали сбои и ошибки в ра-
напротив – даже малое непонимание происходящего в ито- боте системы учета, так как не хотели принимать решение
ге приведет к полному падению системы. Контролируйте руководства о переходе на новую информационную систе-
свою систему и спите спокойно. И тогда бытующее мнение му бухгалтерского учета взамен старой, которая уже не
о том, что системные специалисты работают круглосуточ- соответствовала изменениям в законодательстве. Сгово-
но и не спят ночами, канет наконец-то в лету. В таком дер- рившись, они умышленно искажали результаты работы про-
ганом режиме работают те, кто не спланировал работу за- граммы. К счастью руководство оказалось более лояльным
ранее. по отношению к техническим специалистам и, уволив из
бухгалтерии двух человек, издало приказ о «содействии
Проблемы при модернизации сотрудников техническому персоналу для перехода на но-
существующих систем вую систему учета».
Перестроение уже работающей структуры также отвечает Эти случаи далеко не единичны и многим знакомы не
описанным требованиям. Однако при таком развитии со- понаслышке. К сожалению, тут два выхода: либо убедить
бытий появляются некоторые трудности. Во-первых, необ- руководство в необходимости модернизации и создания
ходимо составить подробный план перехода и проанализи- административных приказов и инструкций, либо отказать-
ровать, с какими именно трудностями можно столкнуться ся от проекта. В противном случае можно получить «час-
при реализации каждого этапа. Во-вторых, осуществить тично работающую систему», что не является приемлемым
внедрение в исключительно короткие сроки. Это, пожалуй, в любых случаях.
самое трудновыполнимое условие, однако поверьте, что при
наличии необходимых профессиональных навыков и опы- Подводя итоги
та оно осуществимо. В противном случае стоит задуматься В заключение можно сказать, что компании, решившиеся
о возможности привлечения дополнительных специалистов на реализацию проекта системной интеграции своими си-
на время проекта. Чтобы не быть голословными, скажем, лами, должны быть уверены в том, что опыт сотрудников
что полная реорганизация информационной сети компании собственного IT-отдела позволит осуществить внедрение
(замена всех кабельных систем, располагающихся в 2 зда- от начала и до конца. То есть не прекратить его, а именно
ниях, со 100 рабочими станциями и 3 серверами, довольно завершить. В противном случае может оказаться, что из-
большое количество сетевых приложений, включая уста- за отсутствия навыков в некоторых областях весь проект
ревшие DOS-программы) заняла у нас 3.5 дня. Выпавшие может претерпеть неудачу. Как следствие придется прибе-
на эти дни государственные праздники оказались как гать к помощи компании-системного интегратора, которая,
нельзя кстати, и уже в начале второй половины рабочего скорее всего, заново будет просчитывать весь процесс и
дня сотрудники приступили к своим обязанностям. В пос- потребует сменить не соответствующее требованиям обо-
ледующие 2 дня специалисты выслушивали пожелания со- рудование. Что, разумеется, приведет к дополнительным
трудников и исправляли незначительные неточности. (и часто немалым) расходам. Поэтому именно на руково-
Хотелось бы сказать еще об одной довольно серьезной дителя IT-структуры ложится основная ответственность по
проблеме, часто препятствующей успешной реализации выбору пути системной интеграции. И глобальное понима-
проекта. Это человеческий фактор. А точнее – нежелание ние этим человеком всей структуры и бизнес-процессов
определенных индивидуумов оказывать содействие специ- предприятия, а также профессионального потенциала сво-
алистам, а иногда и саботаж с их стороны. За этим стоят их подчиненных поможет в итоге принять правильное ре-
разные причины, одной из которых может быть нежелание шение, сделав процесс максимально эффективным, раци-
обучаться работе с новыми программными продуктами и ональным, а значит, и экономически выгодным.

10
bugtraq

Отказ в обслуживании при обработке Обход встроенных механизмов защиты


BGP-пакетов в Cisco IOS от переполнения буфера в куче
Программа: Cisco IOS все версии. и технологии DEP в Windows XP SP2
Опасность: Высокая. Программа: Windows XP.
Описание: Уязвимость существует во всех версиях Cisco OIS Опасность: Высокая.
при использовании Border Gateway Protocol (BGP) и устрой- Описание: Positive Technologies сообщает о возможности
ствах с включенным bgp log-neighbor-changes. Удаленный обхода встроенных механизмов защиты от переполнения
пользователь может послать устройству специально сфор- кучи и выполнения кода в области данных в Windows XP
мированный BGP-пакет, что вызовет перезагрузку систе- Service Pack 2.
мы. Большое количество таких пакетов приведет к отказу в Несколько уязвимостей обнаружено в механизме про-
обслуживании. верки маркера («cookie»), введенного для определения це-
URL производителя: http://www.cisco.com. лостности заголовка блока памяти.
Решение: Установите обновления с сайта производителя Проверочный маркер проверяется только тогда, когда
для соответствующей версии IOS. выделяется свободный блок, однако такая проверка не
выполняется при его освобождении. В результате возмож-
Отказ в обслуживании при обработке но изменить размер блока и поместить его в произвольный
IPv6-пакетов в Cisco IOS freelist.
Программа: Cisco IOS с включенным IPv6 (все версии). При работе с lookaside-списками не реализовано ника-
Опасность: Высокая. ких проверок целостности заголовка – нет даже проверки
Описание: Уязвимость обнаружена при обработке IPv6 во достоверности значения проверочного маркера. В резуль-
всех версиях Cisco IOS. Злонамеренный пользователь мо- тате этого, теоретически, появляется возможность переза-
жет с помощью специально сформированного IPv6-пакета писать до 1016 байт в любой области памяти.
вызвать перезагрузку системы. Большое количество таких Подробнее об уязвимости и практических примерах ее
пакетов приведет к отказу в обслуживании устройства. эксплуатации можно прочитать тут: http://www.securitylab.ru/
URL производителя: http://www.cisco.com. 52238.html.
Решение: Установите обновления с сайта производителя URL производителя: www.microsoft.com.
для соответствующей версии IOS или запретите использо- Решение: Способов устранения обнаруженной уязвимос-
вание IPv6-протокола. ти не существует в настоящее время. В качестве времен-
ного решения, компания Positive Technologies выпустила
Отказ в обслуживании при обработке бесплатную утилиту, которая для определенных приложе-
MPLS-пакетов в Cisco IOS ний устанавливает глобальный флаг, который будет зап-
Программа: Cisco IOS 12.1T, 12.2, 12.2T, 12.3 и 12.3T. рещать использование ассоциативных списков. Скачать
Опасность: Высокая. программу можно отсюда: http://www.ptsecurity.ru/
Описание: Уязвимость существует при обработке Multi ptmshorp.asp.
Protocol Label Switching (MPLS)-пакетов во всех версиях
Cisco IOS, которые поддерживают MPLS, даже если MPLS Множественные уязвимости
запрещено на интерфейсе. Удаленный пользователь может в PostgreSQL
послать специально сформированный пакет и вызвать пе- Программа: PostgreSQL 7.x, 8.x.
резагрузку системы. Большое количество таких пакетов Опасность: Высокая.
приведет к отказу в обслуживании. Описание: Ошибка в опции LOAD позволяет непривилеги-
URL производителя: http://www.cisco.com. рованному пользователю загрузить произвольные библио-
Решение: Установите обновления с сайта производителя теки. Удачная эксплуатация этой уязвимости может позво-
для соответствующей версии IOS. лить выполнить произвольный код с повышенными приви-
легиями. Выполнение такого кода возможно лишь на
Отказ в обслуживании в Squid Windows и UNIX ELF-системах (Linux).
при обработке WCCP-сообщений Злоумышленник может обойти ограничения на выпол-
Программа: Squid 2.5.STABLE7 и более ранние версии. нение функций и выполнить произвольные функции на си-
Опасность: Высокая. стеме.
Описание: Уязвимость существует при обработке WCCP- Неизвестная уязвимость в contrib/intagg.
сообщений. Удаленный пользователь может создать спе- Переполнение буфера при выполнении plpgsql с боль-
циально сформированное длинное WCCP-сообщение и выз- шим количеством параметров.
вать переполнение буфера в функции recvfrom(), что при- URL производителя: http://postgresql.org
ведет к аварийному завершению работы прокси-сервера. Решение: Установите обновление: http://www.master.
URL производителя: http://www.squid-cache.org. postgresql.org/download/mirrors-ftp.
Решение: Установите обновление от производителя: http://
w w w . s q u i d - c a c h e . o r g / Ve r s i o n s / v 2 / 2 . 5 / b u g s / s q u i d - Составил Александр Антипов
2.5.STABLE7-wccp_buffer_overflow.patch.

№2, февраль 2005 11


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

КТО КУПИЛ COREL LINUX?


ОБЗОР ВОЗМОЖНОСТЕЙ НАСТОЛЬНОГО ДИСТРИБУТИВА XANDROS
ВАЛЕНТИН СИНИЦЫН
Историческая справка нальную плату. Иными словами, с точки зрения домашнего
Компания Xandros была основана в мае 2001 года в Кана- пользователя, Xandros OCE оказался ничем не хуже Fedora
де с целью создания и продвижения на рынок недорогой, Core или (не побоюсь этого высказывания) оригинального
дружественной пользователю настольной операционной си- Debian, поскольку вносить изменения в код системы или за-
стемы на базе Linux, которая составила бы конкуренцию рабатывать с ее помощью деньги многие из них и не помыш-
Microsoft Windows – «Complete Linux Desktop Solution». В ляли. Удачно составленная лицензия на продукт не могла не
августе того же года компания приобрела Corel Linux OS, привлечь внимание дистрибьютеров, в частности Линукс-
некогда популярную и весьма удачную систему, оставшую- Центра (www.linuxcenter.ru), благодаря усилиям которых при-
ся в результате известных событий в истории Corel «не у обрести Xandros OCE в России стало не сложнее, чем обыч-
дел». Именно она легла в основу выпущенного некоторое ный свободный дистрибутив. Впрочем, граждане с тонким
время спустя Xandros Desktop 1.0. Будучи наследником Corel кошельком и толстым каналом всегда могут загрузить ISO-
Linux, Xandros Desktop OS ведет свою родословную от про- образ системы через сети BitTorrent.
екта Debian, разработки которого и используются по сей В момент написания данной статьи последней версией
день для поддержания кодовой базы. Таким образом, Xandros является третья, отличающаяся от своих предше-
Xandros, по сути, является коммерческой разновидностью ственниц встроенной функцией записи DVD и персональным
Debian, подобной Libranet GNU/Linux и Linspire (с последней брандмауэром. Однако в связи с ее недоступностью для боль-
системой Xandros некоторое время «жил под одной кры- шей части читателей мы решили сфокусировать свое вни-
шей» и развивался параллельно, в память о чем сохранил- мание на второй версии дистрибутива, распространяющей-
ся имущественный иск, предъявленный Linspire к Xandros ся в форме редакции OCE. О планах выпуска Open Circualtion
около года назад), а значит, он совместим с пакетами DEB, Edition для Xandros 3 компания ничего не сообщает, однако
репозитариями apt и прочими «прелестями цивилизации». можно предположить, что это все же случится, ведь свора-
В настоящий момент модельный ряд Xandros насчиты- чивать данную инициативу пока никто не собирается.
вает несколько продуктов. Это Xandros Desktop 3 Standard/
Deluxe Edition, ориентированный на домашенго пользова- Установка
теля, корпоративный рабочий стол Xandros Business Desktop Программа-инсталлятор системы является предметом гор-
OS Version 2.5 Business Edition и его разновидность Xandros дости компании Xandros, и не без оснований. Как утверж-
Desktop OS PowerTerm Edition, а также серверный дистри- дает реклама, дистрибутив можно установить в пять щелч-
бутив – Xandros Desktop Management Server. С возможнос- ков мышью. Это вполне соответствует действительности:
тями каждого из них можно ознакомиться по адресу: http:// процедура установки проходит в пять этапов. После стан-
www.xandros.com/products/products.html. дартного приветствия и ознакомления с лицензией пользо-
В том что касается бесплатных и оценочных версий, кор- вателю предлагается сделать выбор между автоматичес-
порация Xandros придерживается несколько запутанной стра- ким (Express Install) и ручным (Custom Install) режимом ус-
тегии. Долгое время они попросту отсутствовали. Однако тановки. Предпочитающие делать все «дешево и быстро»
аккурат 1 апреля 2004 года компания переменила свое мне- могут выбрать первый вариант, создать пару учетных за-
ние, неожиданно предоставив для свободной загрузки са- писей и приступить непосредственно к копированию фай-
мый дорогой (на тот момент) из своих продуктов – Xandros лов, как это обычно и происходит в других настольных дис-
Business Desktop OS Version 2.5. Было это розыгрышем или трибутивах. Однако Xandros предоставляет более богатые
нет, но спустя несколько дней Xandros, не объяснив мотивов возможности для настройки в ручном режиме. Во-первых,
своих действий, прекратила распространение ISO-образа. это менеджер разделов, вещь сама по себе не удивительная
Однако уже в середине лета компания анонсировала еще и распространенная повсеместно: от Red Hat до Slackware.
одну community-инициативу, получившую название Xandros Однако его разновидность, входящая в состав Xandros, об-
Desktop OS Version 2 Open Circulation Edition – OCE (http:// ладает рядом особенностей. Это в первую очередь встро-
www.xandros.com/products/home/desktopoc/dsk_oc_intro.html). енный навигатор по файловой системе в стиле Konqueror,
Суть ее сводилась к следующему. Из состава дистрибутива поддерживающий ext2, ext3, ReiserFS и даже NTFS. Если в
удалили коммерческие приложения, в первую очередь – эму- других случаях вам приходилось «играть в русскую рулет-
лятор CrossOver Office и офисный пакет StarOffice 7, ограни- ку», вспоминая, какой из разделов жесткого диска подле-
чили скорость записи компакт-дисков во встроенном фай- жит сносу, а какой – содержит бесценные данные, то сей-
ловом менеджере (об этом далее), лишили поддержки про- час достаточно просто нажать на кнопку и посмотреть его
фессиональных консультантов и... отпустили в свободное содержимое. Как правило, структура каталогов и имена на-
плавание. Систему было разрешено использовать в неком- ходящихся в них файлов говорят простому пользователю
мерческих целях и даже распространять, беря за это номи- (да, впрочем, и не очень простому пользователю тоже) куда

12
администрирование
больше, чем аббревиатуры типа «hda3» или словосочета- сия LILO наотрез отказалась дружить с моим ноутбуком,
ния вроде «третий основной раздел». Для уже созданных намертво зависая при загрузке. Пожалуй, этой проблемы
разделов можно назначить точку монтирования, которая вы- можно было бы избежать, если знать о ней заранее: я бы
бирается из выпадающего списка (в соответствии с нау- просто попросил программу не устанавливать свой загруз-
кой, содержащаяся на разделе файловая система – ext2, чик в MBR или вообще никуда – Xandros предоставляет и
ext3 или ReiserFS – может быть смонтирована в /, /usr/local, такую возможность.
/var или /opt). Если вы пожелаете установить Xandros на После всех описанных выше манипуляций программа
непустой раздел, инсталлятор предложит вам сохранить откроет окно «Summary». Проверьте и, если вас устраива-
имеющиеся на нем каталоги /root и /home. Естественно, это ют все введенные параметры, нажмите кнопку Finish, что-
произойдет лишь в том случае, если раздел ранее принад- бы начать копирование файлов. Инсталлятор будет держать
лежал какой-либо UNIX-системе. Среди элементов управ- вас в курсе происходящего, постоянно сообщая о своих те-
ления в окне менеджера разделов присутствует и кнопка кущих занятиях («устанавливаю базовую систему», «на-
«Add», которая, по логике вещей, должна создавать новые страиваю Samba» ) в строке статуса.
партиции, однако по не очень понятным мне причинам она
перманентно отключена. Первый запуск
Другая уникальная в разрезе рассмотренных ранее на- После того как инсталлятор закончит работу, вам будет
стольных дистрибутивов возможность Xandros – это функ- предложено перезагрузить компьютер (в вопросах подоб-
ция выбора пакетов. Начинающий администратор может ус- ного рода Xandros не скупится – соответствующие пригла-
тановить одну из заранее определенных конфигураций: шения выводятся на экран шрифтом такого размера, что
«Minimal Desktop» (минимальный набор, всего 655 Мб), разрешения 1024x768 едва хватает на 3-4 строчки текста).
«Standard Desktop» (стандартный набор – 980 Мб), Выбрав нужный пункт в загрузочном меню и подождав не-
«Complete Desktop» (полный набор, 1156 Мб) и «Custom которое время (как и все настольные дистрибутивы, Xandros
Desktop» (установка по выбору пользователя). Все доступ- тяжеловат на подъем), вы увидите менеджер входа в сис-
ные пакеты сгруппированы по категориям, а их выбор осу- тему, выглядящий на фоне своих аналогов из Linspire или
ществляется путем выставления «галочки» возле имени. Lycoris Desktop/LX несколько аскетично: выпадающее меню
Отрадно, что в этом списке присутствуют и средства раз- с именем учетной записи, поле для ввода пароля и пара
работки. Как правило, производители настольных дистри- кнопок. Как видите, ничего лишнего. После авторизации
бутивов по ряду причин предпочитают не включать столь появляется стандартный стартовый экран KDE, а затем –
мощный инструмент в базовый комплект поставки. мастер первого запуска («First Run Wizard»). Выбрав тип
Разобравшись с программным обеспечением, можно пе- мыши («левая» или «правая»), пользователь попадает на
реходить к вводу параметров сети (Static IP/DHCP, шлюз, поистине интересную вкладку: «Regional Settings» («Регио-
DNS). Здесь все вполне стандартно. Далее инсталлятор нальные настройки»). Здесь можно указать системную ло-
предложит ввести пароль администратора (Administrator), каль, язык рабочего стола, кодировку и раскладку клавиа-
он же – root. При этом в нижней части окна будут располо- туры для текущего пользователя. Для каждого из этих па-
жены две «галочки», одна из которых – «Enforce strong раметров (кроме, к сожалению, языка рабочего стола) дос-
passwords» («Требовать сильные пароли») – сейчас пред- тупны «русифицированные» варианты ответа. Лично я ос-
ставляет для нас особый интерес. Если она находится во тановился на следующем наборе: локаль – ru_RU, кодиров-
включенном состоянии, то отделаться паролем «123456», ка – KOI8-R, раскладка – Russian. После этого Xandros сра-
который, не пикнув, проглатывали Linare, Linspire и Lycoris зу же заговорил по-русски, весьма неплохо, хотя и с «ак-
Desktop/LX, уже не удастся. Второй флажок – «Make user центом». Шрифты, используемые системой для отображе-
home folders private» («Сделать домашние каталоги пользо- ния кириллицы, выглядят ничуть не хуже латинских, благо
вателей личными») – просто запрещает автоматический до- в стандартную поставку Xandros (в том числе, Xandros OCE)
ступ к домашним каталогам пользователей по сети. Завер- входит некоторое число коммерческих фонтов от Bitstream.
шив эти манипуляции, можно приступать к созданию не- Правда, моноширинный кириллический шрифт, использу-
привилегированных учетных записей. Рекомендуется сде- емый в эмуляторе терминала, почему-то странно двоится,
лать хотя бы одну из них, и использовать ее для повседнев- однако этот огрех можно считать мелочью на фоне того,
ных надобностей. При включенной опции «Enforce strong что творится с поддержкой русского языка в иных конкури-
passwords» к паролям простых пользователей предъявля- рующих продуктах (любознательного читателя мы отсыла-
ются те же требования, что и к паролю администратора. ем за подробностями к более ранним статьям данного цик-
Однако пустой пароль инсталлятор вполне устраивает. ла [1, 2, 3]). Для нормальной работы с системой следует до-
В вопросах установки дискового загрузчика Xandros так- установить язык US. English. Это можно сделать с помощью
же проявил неординарную проницательность и учтивость. контекстного меню стандартного переключателя раскладок
Инсталлятор корректно определил уже установленные на KDE, «обитающего» в системном лотке. Несмотря на несом-
компьютере операционные системы: Mandrakelinux и ненные достижения в области «лингвистики», Xandros был
Windows 2000 и добавил их в свое меню, сохранив, таким и остается иностранцем, поэтому пользоваться родным язы-
образом, время, которое я традиционно тратил на восста- ком в нем приходится с некоторой долей осторожности. Не-
новление содержимого MBR после деятельности менее которые подводные камни мы обсудим чуть позже.
аккуратных «собратьев». Правда, «покопаться с паяльни- Вслед за региональными настройками вам будет пред-
ком» все же пришлось: включенная в состав Xandros вер- ложено выбрать часовой пояс и установить принтеры (под-

№2, февраль 2005 13


администрирование
держиваются как локальные, так и сетевые, например, уп- Xandros File Manager
равляемые компьютерами на базе Windows или подключен- Файловый менеджер является еще одним козырем в колоде
ные напрямую через HP JetDirect). После ненавязчивой Xandros. Так или иначе о нем упоминают все рекламные
просьбы о регистрации Мастер первого запуска попроща- проспекты, а встроенная возможность записи CD (в версии
ется с вами, сказав напоследок, где его можно будет най- 3.0 – еще и DVD) выставляется как едва ли не главное пре-
ти, если он вдруг понадобится. Принимая во внимание час- имущество этой ОС над конкурентами. В общем, данный
тые мучения пользователей, вспоминающих, «где же было продукт вполне заслуживает пристального рассмотрения.
такое вот окошко», эта информация кажется весьма и весь-
ма нелишней.
Закрыв мастер, можно начинать знакомиться с рабочим
окружением (рис. 1). По умолчанию на каждого непривиле-
гированного пользователя автоматически заводится два
виртуальных рабочих стола: «синий» и «зеленый». В про-
цессе повседневной работы их число легко можно увели-
чить, щелкнув правой кнопкой мыши по апплету «Virtual
Desktop» в панели и выбрав пункт меню «Configure Virtual
Desktops». Простой эксперимент показывает, что столы с
номерами три и четыре имеют соответственно желтый и
фиолетовый цвета, а в дальнейшем эта закономерность
портится, и все становится одинаково темно-синим.

Ðèñóíîê 2. Îêíî Xandros File Manager ñ ìåíåäæåðîì ïðîåê-


òîâ. Ïóíêò «Removable Disc» â ñàìîì íèçó äåðåâà ñîîòâåòñòâó-
åò ïîäêëþ÷åííîìó USB-íîñèòåëþ
В основе Xandros File Manager (XFM) лежит Konqueror,
что весьма логично – это обеспечивает высокую степень
интеграции с KDE. В левой части окна XFM находится дере-
во My Linux (рис. 2), того самого аналога «Моего компьюте-
ра», который почему-то забыли поместить на рабочий стол.
Первой среди его ветвей является My Home (домашний ка-
талог), за нею следуют принтеры, сетевые ресурсы Microsoft
(компьютеры с Xandros добавляются сюда автоматически) и
NFS, разделы Windows, которые имеют привычные имена:
C,D,..., а также менеджер проектов записи CD (CD Writer) и
подключенные съемные носители. Легко заметить, что дос-
Ðèñóíîê 1. Ðàáî÷èé ñòîë íåïðèâèëåãèðîâàííîãî ïîëüçîâàòåëÿ тупа к корневой файловой системе и «посторонним» разде-
Xandros лам Linux дерево не предоставляет, однако для этого можно
В свою очередь рабочий стол администратора имеет воспользоваться адресной строкой. Введя в ней что-нибудь
красный цвет, так что разобраться, какими полномочиями вроде «/», вы увидите соответствующее запросу дерево ка-
вы обладаете в системе, не составляет труда – достаточно талогов, а в My Linux появится новый, скрытый доселе пункт:
беглого взгляда на экран. Кнопка «Пуск» в Xandros назы- «All File Systems». Видимо, разработчики не без оснований
вается «Launch», рядом с ней располагается панель быст- полагают, что рядовому пользователю шастать за предела-
рого запуска, на которой находятся пиктограммы эмулято- ми своего домашнего каталога не стоит, вот и решили пре-
ра терминала (только для root), веб-браузера, файлового достеречься от излишне любопытных. Кстати, если вы все
менеджера, встроенной справки и очистки рабочего стола. же решите полазить по дереву каталогов в одиночку, без
Крайняя правая кнопка возле системного лотка (tray) слу- помощи KDE, имейте в виду, что все «чужие» файловые си-
жит для смены пользователя («Switch user»). При ее нажа- стемы (в том числе разделы Windows и съемные носители:
тии открывается диалог, предлагающий заблокировать те- CD-ROM, USB Flash и т. д.) Xandros подключает не в /mnt,
кущую сессию и запустить X-сервер на новой консоли. Пе- как можно было бы того ожидать, а в /disks.
реключение между ними осуществляется как стандартным Как уже вскользь упоминалось выше, XFM обладает
способом (<Ctrl>+<Alt>+<Fn>, где n = 7, 8, 9), так и при по- собственными функциями для записи CD, причем, на мой
мощи все того же диалогового окна. Однако первое, что взгляд, реализует их удачнее, чем Microsoft Windows XP. В
бросается в глаза при обзоре рабочего стола, – это отсут- основе этой возможности лежит понятие проекта – т.е. на-
ствие пиктограммы «Мой компьютер», столь привычной бора файлов, предназначенных для записи на CD. Суще-
пользователям Windows. Как мы увидим ниже, сама кон- ствующие проекты хранятся в «папке» CD Writer в My Linux.
цепция «My Computer» в Xandros живет и здравствует, а Там же находятся инструменты, позволяющие создать но-
почему разработчики решили не помещать средство дос- вый проект и начать запись.
тупа к ней в привычное место – остается только догады- Чтобы добавить к проекту файл(ы) или целые катало-
ваться. ги, можно воспользоваться пунктом контекстного меню «Add

14
администрирование
to CD Prject», ссылкой «Add all to CD Project...» в окне с со- Попробуем подвести итог вышесказанному. Xandros,
держимым каталога или простым перетаскиванием (drag- несомненно, один из самых мощных игроков на рынке на-
n-drop). Опыт работы показывает, что для файлов или про- стольного Linux, а неплохая поддержка русского языка и
ектов с русскими именами применим только последний наличие бесплатной версии делает его привлекательным
метод. Очевидно, что подобным образом можно добавлять и для отечественных пользователей. Неопределенность
файлы, находящиеся в различных каталогах или даже на относительно будущего Open Circualtion Edition несколько
различных носителях. Сведения о текущем состоянии про- настораживает, однако если вы твердо решили установить
екта можно получить, щелкнув по его имени в ветви «CD Linux на своем рабочем столе, я бы посоветовал вам иметь
Writer» (рис. 2). В нижней части появившегося окна распо- Xandros в виду. При своей доступности и легкости внедре-
ложена линейка, хорошо знакомая пользователям Ahead ния он может составить достойную конкуренцию распрост-
Nero и отражающая текущий процент заполнения диска. раненным некоммерческим дистрибутивам Linux.
XFM умеет работать с rewritable-носителями (т.е. очищать В заключение цикла статей о настольном Linux я хочу
их) и может создавать аудио-CD. К сожалению, разработ- привести небольшую сводную таблицу рассмотренных нами
чики не предусмотрели поддержку мультисессионных дис- дистрибутивов, чтобы вам было легче сравнивать их меж-
ков, т.е. «записать» на диск получится, а вот «дописать» – ду собой. Предварительно необходимо сделать несколько
уже нет. замечаний. В графе «Стоимость» указан диапазон цен для
В заключение отметим, что в бесплатном Xandros OCE различных моделей продуктовой линейки. Наличие средств
максимальная скорость записи в XFM ограничена 4x (600 разработки и запуска Windows-приложений определялось
Кб/сек). по принципу: «хотя бы в одной редакции продукта в стан-
дартной комплектации». Это означает, что доступность со-
Впечатления от работы ответствующих пакетов в сетях поддержки (например, CNR
В стандартную поставку Xandros входит весьма неплохой Warehouse) в расчет не принималась. Качество поддержки
комплект программ, способный удовлетворить все нужды русского языка оценивалось по пятибалльной шкале, где 1
среднестатистического офисного служащего. Немного соответствует некоему абстрактному дистрибутиву, в прин-
удивляет отстуствие полноценного графического редакто- ципе не способному отображать ничего, кроме латиницы, а
ра, например, GIMP, однако для простых рисунков неплохо 5 – полностью русифицированной системе (ввод и вывод
подойдет и KPaint. В качестве браузера по умолчанию ис- кириллицы на экран и на печать, переведенные системные
пользуется Opera 7.5 (в версии OCE – adware), ее же пред- сообщения, интерфейс программ и т. д.).
полагается применять для работы с электронной почтой.
Ни Mozilla, ни Firefox, ни тем более Evolution в состав
Xandros, как ни странно, не входят. Вообще у разработчи-
ков наблюдается странная неприязнь к приложениям на
базе GTK. Они практически отсутствуют – за исключени-
ем, пожалуй, MP3-проигрывателя XMMS, который искусно
замаскирован под общий стиль оформления (Plastik) при
помощи соответствующей «шкурки». Архитектурно такой
подход оправдан – рабочий стол получается более интег-
рированным, однако, как ловко подметил кто-то из экспер-
тов: «И в мире GTK, и в мире Qt есть приложения, не имею-
щие аналогов». Вряд ли ориентированность на другую ин- Пока верстался номер, 14 февраля в Сети появились све-
терфейсную библиотеку стала причиной нелюбви к GIMP – дения о том, что компания Xandros выпустила в свет третью
вероятнее всего, он просто не влез на диск. Для исправле- версию Open Circulation Edition, восстановив таким образом
ния сложившейся ситуации можно использовать Xandros соответствие между бесплатной и платной версиями. В со-
Networks (http://www.xandros.com/products/home/xn/ став продукта вошли веб-браузер Mozilla Firefox, клиент элек-
xn_intro.html) – продуманную систему для установки и об- тронной почты Mozilla Thunderbird и интернет-телефон Skype.
новления пакетов, бесплатно доступную всем зарегистри- Как и его предшественник, Xandros Desktop 3 Open Circulation
рованным пользователям. Edition будет доступен для свободной загрузки через
Xandros Networks может работать как с собственным BitTorrent. Вероятно, к выходу этого номера из печати, дист-
программным репозитарием, так и с банком программ рибутив можно будет приобрести и в российских интернет-
Debian, компакт-дисками и любыми другими хранилищами, магазинах.
совместимыми с apt. Если автоматическое разрешение за-
висимостей для вас не играет принципиальной роли, с по- Литература:
мощью Xandros Networks можно установить или удалить 1. Синицын В. Заметки о Linare. – журнал «Системный
любой пакет в формате DEB и RPM. Помимо свежего ПО администратор», №11, ноябрь 2004 г.
через сеть Xandros Networks распространяются новости, 2. Синицын В. Linspire одним глазком. – журнал «Систем-
уведомления и патчи. Таким образом, эта программа пред- ный администратор», №12, декабрь 2004 г.
ставляет собой мощный инструмент для сопровождения и 3. Синицын В. Linux из Редмонда: обзор Lycoris Desktop/
управления системой, но, к сожалению, ее детальное рас- LX. – журнал «Системный администратор», №1, январь
смотрение выходит за рамки данной статьи. 2005 г.

№2, февраль 2005 15


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

СОЗДАНИЕ РЕЛИЗА FreeBSD

АНДРЕЙ ЕЛСУКОВ
В этой статье я хочу обобщить свой опыт по сборке релиза не существует, то следующие компоненты для вас не важ-
операционной системы FreeBSD. Создание релиза – не та- ны, если же нет, то идём по пунктам.
кая уж сложная задача, но достаточно длительная и при
некоторых обстоятельствах может продолжаться дольше, CVS-репозитарий
чем ей необходимо. Да и к тому же описание этого процес- Эта «свалка файлов» в архиве на данный момент у меня
са на русском языке мне найти не удалось. Надеюсь, что занимает порядка 500 Мб. Чтобы получить репозитарий –
статья поможет желающим собрать свой релиз и обойти те проще всего воспользоваться CVSup. У меня по крону раз
проблемы, с которыми столкнулся когда-то я. в сутки запускается следующая команда для обновления
репозитария:
Для чего это нужно?
Я вижу несколько причин, для чего может понадобиться со- # cvsup –g –L 2 /mnt/cvs/cvs-supfile
здать релиз ОС FreeBSD в «домашних» условиях:
! не всегда есть время, средства, возможность покупать где конфигурационный файл CVSup выглядит так:
свежий релиз системы, чтобы иметь его на CD для бо-
лее быстрой установки «свежей» системы; *default host=cvsup2.FreeBSD.org
*default base=/var/db
! хочется иметь под рукой загрузочный инсталляционный *default prefix=/mnt/cvs/ncvs
диск системы со специфическими настройками: устано- *default release=cvs
*default delete use-rel-suffix
вочный диск STABLE-ветки; диск с обновленными драй- *default compress
верами, например для RAID-контроллеров; с определен-
src-all
ным набором скомпилированных пакетов; с архивами ports-all
исходных файлов некоторых программ для компиляции doc-all
cvsroot-all
из «портов»;
! хочется всё знать и уметь. Лучше всего, если вы достанете архив репозитария, пусть
даже старый у своего знакомого или ещё где-то – сэконо-
Кто-то, возможно, предложит свои причины, для меня мите кучу времени и трафика. Поддержание репозитария
достаточно и этих. в «свежем» состоянии уже не так накладно, так что, сде-
лав один раз, использую и сейчас.
Что нам необходимо для начала?
Как это ни банально, нужна машина под управлением ОС Архивы исходных файлов для сборки портов
FreeBSD. Причём желательно, чтобы версия системы была Не пугайтесь, дистрибутивы для всех портов нам не понадо-
из той же ветки, что и версия будущего релиза (почему «же- бятся. Но и перечислять каждый порт довольно утомитель-
лательно» – расскажу позднее). Если ваша машина под- ное занятие, да и от релиза к релизу этот список может раз-
ключена к Интернету и проблемы с ценой трафика для вас личаться, поэтому я немного обобщу:

16
администрирование
! для сборки проекта документации понадобятся исход- которых может фатально сказаться на дальнейшей сборке
ные файлы для портов, список которых можно посмот- релиза, например Perl. Так что, если не хотите терять вре-
реть в файле src/release/Makefile.inc.docports; мя, лучше на первый раз закомментировать все опции в
! для создания ISO-образов дисков нужен порт ports/sys make.conf или переименовать этот файл. Возможно, наобо-
utils/cdrtools; рот, вы хотите использовать какие-то специфические оп-
! для создания полноценного miniinst-диска нужны исход- ции, например дополнительную оптимизацию, – дело ваше.
ные файлы Perl и X.org, либо XFree (в зависимости от
версии системы). Переменные окружения
Часть переменных окружения описана в мануале release(7).
В общем-то, вот и всё. Недостающие компоненты мож- Часть можно найти в make-скриптах, используемых при
но будет скачать во время сборки (если есть доступ к Инте- сборке (в папке src/release). Хочу обратить внимание на не-
ренету, то они скачаются автоматически). которые из них:
! DOC_LANG – в ней можно перечислить через пробел
Как это происходит? языки, для которых вы хотите собрать документацию,
Весь процесс сборки я условно разделил на несколько эта- например, DOC_LANG=”en_US.ISO8859-1 ru_RU.KOI8-
пов. Отчасти моя классификация перекрывает ту, что опи- R”. Если вы не укажете языки, то будут собираться все
сана в мануале release(7). Итак, по порядку. возможные, а это довольно долго.
! NOPORTREADMES – при включении в дистрибутив де-
Подготовка к сборке рева портов не будут генерироваться README.html с
Кроме вышеперечисленного я отнёс сюда следующие дей- описанием портов, что существенно ускорит процесс
ствия: сборки релиза.
! получение исходных файлов системы для будущего ре- ! RELEASENOUPDATE – если при сборке у вас возникнет
лиза; ошибка, эта переменная совместно с целью make
! выбор раздела, на котором достаточно свободного ме- rerelease освободит вас от повторного обновления ис-
ста. ходных файлов системы из CVS-репозитария.
! BUILDNAME – имя релиза. Если не зададите, то получи-
К слову сказать, для сборки релиза может понадобить- те в результате что-то подобное FreeBSD-4.11-20050131-
ся от двух до четырёх с небольшим гигабайт свободного STABLE. Ещё рекомендую задавать имя в стандартном
места. виде, как это делается в оригинальных дистрибутивах,
например 5.3-STABLE. Не нужно называть релиз своим
Сборка мира именем, если не хотите в дальнейшем иметь пробле-
Собственно, сборка мира точно такая же, как и при обнов- мы, например, при установке или обновлении портов.
лении системы, подробности – в handbook. ! MAKE_ISOS – если задать, то при завершении всех эта-
пов сборки автоматически будут созданы ISO-образы
Создание chroot-окружения дисков дистрибутива. Советую не спешить с указанием
Весь процесс сборки релиза, сразу после компиляции мира, этой переменной, создать образы никогда не поздно.
происходит в chroot-окружении. Сначала туда инсталлиру- ! hostname – это не переменная окружения, но я отнёс её
ется собранный мир, затем там происходит дальнейшая сюда. Когда вы соберёте релиз, при его установке, в
компиляция системных библиотек, ядер, портов, проекта выводе команды uname, будет фигурировать имя хос-
документации и т. п. та, на котором происходила сборка. Из эстетических
соображений на время сборки можно сменить имя хос-
Создание дистрибутива та командой hostname.
Это заключительная стадия, включает в себя компиляцию
указанных ядер, создание структуры каталогов дистрибути- «distfiles» для портов
ва, размещение архивов бинарных файлов и установочных Как я уже говорил, для сборки релиза понадобятся дистри-
скриптов, создание каталога для инсталляции с FTP, созда- бутивы некоторых портов. Если у вас уже есть скачанные
ние ISO-образов дисков. дистрибутивы, вы можете указать скриптам их местополо-
жение, и они не будут скачиваться снова. Для этого исполь-
На что следует обратить внимание? зуется переменная окружения RELEASEDISTFILES. Если вы
Рекомендую прочитать Makefile в каталоге src/release. Из него пользуетесь системой портов и в вашем дереве есть ката-
можно почерпнуть довольно много полезной информации. лог ports/distfiles, то переменную можно не определять, этот
Так же обязательно прочитать мануал release(7) и желательно каталог будет скопирован в chroot-окружение (наверное,
просмотреть все файлы, на которые он ссылается. стоит задуматься о том, сколько места он занимает).

make.conf Когда что-то пошло не так


При сборке мира используются установки из /etc/make.conf Если с машины, где происходит сборка релиза, нет прямо-
текущей системы. Рекомендую просмотреть их и подумать – го доступа к Интернету, то есть большая вероятность того,
нужны ли они вам. К примеру, некоторые настройки могут что на каком-нибудь этапе сборка прервётся с ошибкой.
запрещать сборку отдельных частей системы, отсутствие Хотя практика показывает, что они могут возникать и при

№2, февраль 2005 17


администрирование
наличии доступа в Интернет. Ошибки, препятствующие ! Какой-то определённый порт не собирается, даже если
сборке релиза, могут быть разными. Начиная от простых – выполнить предыдущие рекомендации. Некоторые пор-
нехватки каких-нибудь дистрибутивов для сборки из пор- ты во время сборки определяют версию системы и в за-
тов и заканчивая различными ошибками при компиляции. висимости от неё выбирают соответствующие парамет-
ры сборки приложения, либо по версии системы выби-
Не нужно начинать всё сначала рается, какие зависимости имеет порт. Система портов
Чтобы не начинать всё заново, расскажу, как с «минималь- определяет версию через переменные ядра. Поэтому,
ными потерями» продолжить сборку релиза. Итак, предпо- хоть сборка порта и происходит в chroot-окружении, где
ложим, что процесс сборки прервался по какой-то причине. все бинарные файлы и исходные коды от нужной вер-
Решив проблему, вы хотите продолжить сборку. Для этого сии ОС, для системы портов версия ОС будет той, в ко-
нужно указать утилите make цель «rerelease». И если нет не- торой вы собираете релиз. Это следует помнить, так как
обходимости в обновлении исходных файлов системы из ре- версия системы влияет и на выбор индексного файла, и
позитария, желательно определить переменную RELEASE на то, какой файл будет скачиваться при выполнении
NOUPDATE. make fetchindex, и какой файл будет генерироваться при
Теперь, предположим, что вы хотите повторить какой-то выполнении make index. Это ограничение можно обой-
этап сборки, например пересобрать ISO-образы системы. ти, если определить переменные OSVERSION и OSREL.
Предыдущая схема здесь не сработает. Если ISO-образы уже Формат OSVERSION можно посмотреть в переменной
были созданы, то повторного создания таким методом не ядра kern.osreldate, OSREL определяется по первым
добиться, даже если предварительно их удалить. По той про- цифрам вывода «uname -r». Подробнее всё это можно
стой причине, что при завершении этапов сборки (они опи- узнать, просмотрев скрипты в каталоге ports/Mk. Эти
саны в мануале release(7)) скриптами сохраняются «помет- переменные можно поместить в ${CHROOTDIR}/etc/
ки» об их завершении. Пометки – это обычные файлы, со- make.conf, тогда они будут использоваться при каждом
зданные командой touch. Имена файлов соответствуют на- запуске make в chroot-окружении.
званию завершившегося этапа. Файлы находятся в катало-
ге ${CHROOTDIR}/usr/obj/usr/src/release. Для того чтобы вновь Прочие ошибки
пересобрать ISO-образы, нужно удалить файл «iso.1» и уже Искать способы исправления других ошибок вам придётся,
тогда запускать make rerelease. видимо, самим. Можно попытаться обратиться в один из
списков рассылки или форум, посвящённый FreeBSD. Рас-
Не хватает дистрибутивов для установки порта скажу только об одной ошибке, не относящейся к предыду-
Если есть доступ в Интернет, то возникновение такой ошиб- щим пунктам. Я столкнулся с ней, когда попытался собрать
ки маловероятно. Если же доступа нет, то можно вручную релиз 4-й ветки, находясь в 5-й. Ошибка возникает, когда
скачать дистрибутив для установки порта с машины, где система пытается создать загрузочную область и образы
есть доступ, и поместить его в папку ${CHROOTDIR}/usr/ загрузочных дискет. В 5-й версии было убрано псевдоуст-
ports/distfiles, конечно, нужно не забывать, что некоторые ройство vn(4) и утилита vnconfig(8), их функционал перене-
дистрибутивы могут располагаться в отдельных каталогах. сён в драйвер md(4) и mdconfig(8). Да, и ещё в 5-й версии
Чтобы узнать, должен ли дистрибутив порта располагаться используется devfs.
в отдельном каталоге, нужно выполнить в каталоге порта Итак, как решить проблему по созданию релиза 4-й вер-
команду grep DIST_SUBDIR Makefile. После этого можно сии FreeBSD в окружении 5-й? Не скажу, что способ пра-
продолжить сборку, как это описано выше. вильный, но он рабочий, по пунктам:
! Нужно определить в make.conf переменные OSVERSION
Ошибки компиляции и OSREL в значение, которое они должны иметь в со-
Однозначный ответ на вопрос: что делать при ошибках ком- здаваемом релизе.
пиляции? – пожалуй, дать довольно сложно. Опять же, могу ! Собираем мир, устанавливаем его и после завершения
направить к чтению handbook, в котором есть несколько этапа release.2 прерываем сборку. Добавляем аналогич-
советов на эту тему. Приведу несколько примеров ошибок ные опции в ${CHROOTDIR}/etc/make.conf. Это необхо-
и возможных путей их решения: димо для корректной сборки портов. Продолжаем сбор-
! При сборке порта выводится ошибка о нехватке какой- ку релиза.
либо библиотеки, вместо установки её как зависимости. ! После завершения этапа release.7 сборка должна пре-
Возможно, у вас отсутствует индексный файл портов – рваться с ошибкой в скрипте doFS.sh. Теперь нужно ста-
ports/INDEX или ports/INDEX-5 (для 5-й ветки FreeBSD), тически собрать утилиту mdconfig, чтобы исключить все
ports/INDEX-6 (для 6-й ветки FreeBSD). Можно скачать ин- зависимости от разделяемых библиотек. Для этого по-
дексный файл с сайта – http://www.freebsd.org/ports/ надобятся исходные файлы текущей системы (той, в ко-
INDEX.bz2, INDEX-5.bz2 или INDEX-6.bz2. Или просто пе- торой происходит сборка релиза), переходим в каталог
рейти в ${CHROOTDIR} и собрать требуемый порт рука- src/sbin/mdconfig и запускаем команду «make -DNO
ми, устанавливая каждую зависимость, а затем продол- SHARED depend all». В каталоге obj/usr/src/sbin/mdconfig
жить сборку. Переходить в ${CHROOTDIR} нужно с по- будет статически скомпилированная утилита mdconfig.
мощью команды chroot, чтобы порты устанавливались и Копируем её в ${CHROOTDIR}/sbin/. Монтируем файло-
регистрировались в окружении той системы, релиз кото- вую систему devfs – «mount_devfs devfs ${CHROOTDIR}/
рой вы собираете. dev». Теперь можно продолжить сборку релиза.

18
администрирование
Я не проверял, будет ли этот способ работать при сбор- Перед сборкой ISO-образов в 5-й версии FreeBSD не-
ке релиза 5-й версии FreeBSD, находясь в окружении 4-й, обходимо создать пакеты xorg и perl5. Если делать всё «по
но не вижу причин, по которым сборка может не удастся. правилам», то для создания пакетов должен использовать-
Различие только в том, что собирать нужно будет не ся отдельный сервер, так как других лишних серверов у
mdconfig, а vnconfig и вместо монтирования devfs создавать меня в наличии нет, я использую этот же.
файлы устройств с помощью скрипта /dev/MAKEDEV. Технология такая:
! Создаётся каталог ${CHROOTDIR}/usr/ports/packages.
Приступим к сборке ! В chroot-окружении создаются необходимые пакеты вме-
Процесс сборки релиза опишу именно так, как делаю его я. сте со всеми зависимостями при помощи make package-
Начальные данные: recursive.
! Рабочий сервер, у которого есть доступ в Интернет, на ! По имеющимся пакетам создаётся файл INDEX.
нём находятся CVS-репозитарий и каталог distfiles с ди- ! Каталог packages копируется в ${CHROOTDIR}/R/cdrom/
стрибутивами для сборки портов. disc1/.
! Ещё один сервер, на котором я ставлю эксперименты,
он находится внутри локальной сети без доступа в Ин- По первым двум пунктам вроде бы вопросов быть не дол-
тернет. жно, а вот о создании файла INDEX расскажу подробнее.
! Доступ к CVS-репозитарию осуществляется по NFS. Я использовал для его создания свой скрипт, поэтому
! Собирать буду FreeBSD 5.3-STABLE, т.е. с CVS-тэгом не заметил, как в версии 5.3 появился скрипт src/release/
RELENG_5. scripts/mkpkgindex.sh.
Мой скрипт выглядит так:
Подготовка
#!/usr/local/bin/perl
# cd /usr/home
# mkdir release foreach(`ls All/`) {
chop;
# mount_nfs –o rdonly server:/usr/home/cvs /mnt s/\.t.z$//;
# cvs –Rd /mnt/ncvs co –Pr RELENG_5 src
# cd src/ `grep -E "^$_" ../INDEX-5 >> INDEX`;
}
# mv /etc/make.conf /etc/make.conf.old
# make –j8 buildworld
# cd release/
# vim start.sh Итак, для минимального дистрибутива нужны пакеты
perl и xorg, создаём их и копируем на «будущий» диск:
После сборки мира я создаю скрипт примерно со сле-
дующим содержанием: # mkdir /usr/home/release/usr/ports/packages
# cp mkindex.pl /usr/ports/packages
# chroot /usr/home/release
make –j8 CHROOTDIR=/usr/home/release BUILDNAME=5.3-STABLE ↵ # cd /usr/ports/lang/perl5.8 && make package-recursive
CVSROOT=/mnt/ncvs RELEASETAG=RELENG_5 ↵ # cd /usr/ports/x11/xorg && make package-recursive
DOC_LANG=”en_US.ISO8859-1 ru_RU.KOI8-R” ↵ # cd /usr/ports/x11/xorg-manpages && make package-recursive
NOPORTREADMES=yes RELEASENOUPDATE=yes release # cd /usr/ports/packages
# ./mkindex.pl
# rm mkindex.pl
-j8 –максимальное количество make-процессов, которое мо- # cp –PRv /usr/ports/packages /R/cdrom/disc1/
# exit
жет работать параллельно (сервер у меня двухпроцессор-
ный, со SCSI RAID-5); RELEASENOUPDATE – это на буду- Теперь можно создавать ISO-образы, исправляем файл
щее (чтобы не забыть), для цели «release» эта переменная start.sh, добавив переменную MAKE_ISOS=yes, и запуска-
не используется. ем start.sh. Установится порт cdrtools и создадутся два об-
NFS-каталог server:/usr/ports/distfiles можно примонтиро- раза диска.
вать сейчас в /usr/ports/distfiles или позже. На этом всё.

Сборка релиза Заключение


Теперь запускаем сборку релиза: sh start.sh. После получе- В завершение хотелось бы упомянуть о возможностях со-
ния исходных файлов системы и дерева портов из CVS здания нестандартного дистрибутива, имеющихся в сбороч-
можно прервать сборку и примонтировать distfiles: ных скриптах релиза системы.
В первую очередь это настройка sysinstall при помощи
# mount_nfs –o rdonly server:/usr/ports/distfiles ↵ конфигурационного файла install.cfg. На эту тему в Интер-
/usr/home/release/usr/ports/distfiles
# vim start.sh нете можно найти множество статей, ну и конечно же не
надо забывать про мануал sysinstall(8).
В файле start.sh исправляем цель release на rerelease и Также есть возможность применения сторонних патчей
запускаем sh start.sh. Теперь можно заняться своими дела- к исходным файлам системы во время создания релиза.
ми, но переодически посматривать за процессом сборки. Обратите внимание на переменные LOCAL_PATCHES,
Если каких-то портов не будет хватать, я запускаю на сер- PATCH_FLAGS и LOCAL_SCRIPT в мануале release(7).
вере make fetch-recursive для нужного порта и после завер- Ну и если вам необходимо что-то действительно нео-
шения снова запускаю start.sh. Когда процесс закончится, бычное, обратите внимание на сборочные скрипты таких
вы увидите надпись «make rerelease for i386 finished …». проектов, как Frenzy, FreeSBIE, LiveBSD.

№2, февраль 2005 19


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

КОНСТРУКТИВНЫЙ DIALOG

СЕРГЕЙ СУПРУНОВ
Думаю, вам приходилось сталкиваться с работой утилиты Нужно заметить, что версии этой утилиты для Linux и
dialog, входящей в состав большинства UNIX-систем (вклю- для FreeBSD несколько отличаются. Данная статья будет
чая FreeBSD и практически все дистрибутивы Linux). Для посвящена версии, входящей в состав FreeBSD по умолча-
Linux она часто используется в конфигурационных сцена- нию (конкретно – FreeBSD 5.3), а в завершение я скажу не-
риях, во FreeBSD ее можно встретить при установке неко- сколько слов об особенностях dialog в Linux.
торых приложений из коллекции портов (например, oops, Если в командной строке набрать «dialog» без парамет-
php). Она позволяет создавать простейшие диалоговые ров, то будет выведена справка по использованию утили-
окна для взаимодействия с пользователем, используя псев- ты. Нужно заметить, что богатством функций она не бле-
дографику (как в sysinstall). Конечно, для «ортодоксально- щет. Так, с ее помощью можно задать пользователю воп-
го» системного администратора любое отступление от ко- рос, требующий ответа «Да» или «Нет», отобразить содер-
мандной строки – кощунство, однако интерактивность в жимое файла или результат работы какой-нибудь коман-
ряде случаев может быть весьма полезной. ды, запросить ввод строки, предложить выбрать одну или

20
администрирование
несколько альтернатив из списка, создать меню, отобразить strerr (имеющий дескриптор 2) в файл с помощью такой кон-
список некоторых значений в виде дерева. Dialog не позво- струкции: 2> apctl.tmp. В дальнейшем сохраняем содержи-
ляет комбинировать несколько элементов в одном окне (на- мое этого файла в переменной $COMMAND и дополняем
пример, группу полей ввода), то есть если вы решите ис- полным именем утилиты apachectl. Таким образом, в пере-
пользовать его для разработки сценария настройки сете- менной $COMMAND оказывается команда, которую нужно
вых интерфейсов, то такие параметры, как IP-адрес, мас- исполнить. Теперь уточним у пользователя, действительно
ка, шлюз по умолчанию, придется запрашивать поочеред- ли он хочет выполнить эту команду, для чего используем
но в отдельных окнах. Тем не менее на базе этой утилиты еще один диалог типа «Да/Нет». Результат взаимодействия
можно строить достаточно «продвинутые» сценарии. с пользователем в данном случае можно получить из пере-
Синтаксис команды, с вашего позволения, дублировать менной $?, хранящей код возврата последней команды.
не буду. Для разминки сразу напишем сценарий, позволяю- Если была выбрана кнопка «Yes», код возврата будет 0 (ус-
щий управлять сервером Apache – запускать его, останав- пешное завершение).
ливать, выполнять «мягкий» и «жесткий» перезапуск (graceful
и restart соответственно). Обычно для этого используется
утилита apachectl, однако если Apache работает достаточно
стабильно, то ее ключи начинают забываться. Следующий
пример демонстрирует решение поставленной задачи:

Ïðèìåð 1: apctl.sh - Ñöåíàðèé óïðàâëåíèÿ ñåðâåðîì Apache

#!/bin/sh
# apctl.sh

dialog --title "Apachectl interface" \


--menu "
Äàííûé ñöåíàðèé óïðàâëÿåò ñåðâåðîì Apache.
Âûáåðèòå äåéñòâèå èç ïðåäëîæåííûõ íèæå:" 17 50 8 \
start "Çàïóñê ñåðâåðà Apache" \
stop "Îñòàíîâ ñåðâåðà Apache" \ Ðèñóíîê 1
restart "'Æåñòêèé' ïåðåçàïóñê" \
graceful "'Ìÿãêèé' ïåðåçàïóñê" \ Ну и прежде чем завершить работу, сценарий apctl.sh
status "Ñòàòóñ ñåðâåðà" \
fullstatus "Ïîäðîáíûé ñòàòóñ" \ должен удалить созданный им временный файл apctl.tmp.
configtest "Òåñò êîíôèãóðàöèîííîãî ôàéëà" \ Учитывая, что этот файл создается в том же каталоге, из
help "Âûâîä ñïðàâêè" 2> apctl.tmp
которого был вызван сценарий, вероятность, что несколь-
COMMAND=`cat apctl.tmp` ко пользователей запустят его одновременно в одной и той
COMMAND="/usr/local/sbin/apachectl $COMMAND"
же папке, достаточно низка. Тем не менее если она все же
dialog --title "Apachectl interface" \ существует, то имеет смысл имя временного файла фор-
--yesno "
ÂÍÈÌÀÍÈÅ! Áóäåò âûïîëíåíà ñëåäóþùàÿ êîìàíäà: мировать динамически, как будет показано ниже.
Перейдем к более серьезному примеру: напишем сцена-
$COMMAND
рий, позволяющий формировать файл .htaccess для управ-
Ïðîäîëæèòü?" 10 50 ления поведением сервера Apache в конкретных каталогах.
if [ $? = 0 ]; then Как вы сейчас увидите, работа эта неблагодарная, и создать
$COMMAND файл тонкой настройки вручную намного проще. Тем не ме-
fi
нее если вы выделяете своим пользователям место под до-
rm apctl.tmp машнюю страничку и предоставляете им терминальный до-
ступ к домашнему каталогу, то подобным сценарием можно
Рассмотрим подробнее, что происходит. Основная ра- несколько упростить жизнь не только хозяевам странички,
бота выполняется утилитой dialog, которой передаются па- но и службе технической поддержки. К тому же в данном
раметры для построения в данном случае диалога «Меню», примере мы встретимся почти со всеми типами диалоговых
позволяющего выбрать один из вариантов среди предло- окон, что очень хорошо для усвоения материала.
женных. Синтаксис достаточно прост. Ключ --title задает за- Чтобы не завязнуть в возможностях .htaccess и не уйти
головок окна, далее ключ --menu указывает тип диалога и от основной темы статьи, ограничимся двумя простейши-
требует следующих параметров: ми опциями: обработкой ошибки 404 «Файл не найден» (оп-
! Сопроводительный текст. ция ErrorDocument 404) и включением SSI-обработки для
! Высота окна (в символах). файлов с определенными расширениями (опция AddHandler
! Ширина окна (в символах). server-parsed).
! Количество пунктов меню. Опция ErrorDocument может принимать в качестве вто-
! Пары «Ключ» – «Пояснение» для каждого пункта меню. рого параметра (первый в нашем случае равен «404» – но-
мер обрабатываемой ошибки) либо просто текстовую стро-
В результате мы получим окно, изображенное на рис. 1. ку, которая будет использоваться в стандартной странице
Ключ выбранного пункта меню выводится в стандарт- ошибки, либо URL файла, возвращаемого пользователю
ный поток сообщений об ошибках (stderr), и, чтобы можно при запросе несуществующей страницы. Причем файл мо-
было его в дальнейшем использовать, мы перенаправляем жет располагаться как локально на этом же сервере, так и

№2, февраль 2005 21


администрирование
на другой, удаленной машине. В первом случае указывает- OFF \
ся относительный или абсолютный (от корня веб-сервера) REDIR "Ïåðåíàïðàâëåíèå íà óäàëåííûé ↵
ðåñóðñ" OFF 2> $TF
путь к файлу, во втором – полный URL ресурса, включая
протокол: ERR_MSG=`grep "MSG" $TF`
ERR_FILE=`grep "FILE" $TF`
ERR_REDIR=`grep "REDIR" $TF`
ErrorDocument 404 “Çàïðîøåííàÿ ñòðàíèöà íå ñóùåñòâóåò
ErrorDocument 404 /_srv_/error404.html QUOT=""
ErrorDocument 404 http://my.server.ru/errors/error404.htm if [ "$ERR_MSG" != "" ]; then
QUOT="\""
TEXT="
С опцией AddHandler все еще проще – она первым па- Ââåäèòå òåêñò ñîîáùåíèÿ îá îøèáêå 404:"
раметром принимает тип обработчика (в нашем случае это fi
server-parsed, говорящий, что будет обрабатываться SSI), if [ "$ERR_FILE" != "" ]; then
а далее – список расширений файлов, которые должны под- TEXT="
Ââåäèòå àáñîëþòíîå èìÿ ôàéëà (îò êîðíÿ âåá-ñåðâåðà)
падать под действие этого обработчика: èëè èìÿ îòíîñèòåëüíî òåêóùåãî êàòàëîãà:
Ïðèìåð: /errors/err404.html"
fi
AddHandler server-parsed .shtml .shtm
if [ "$ERR_REDIR" != "" ]; then
TEXT="
Как обычно, сначала приведу весь сценарий полностью: Ââåäèòå ïîëíûé URL ðåñóðñà (âêëþ÷àÿ íàèìåíîâàíèå ïðîòîêîëà):
Ïðèìåð: http://my.server.ru/errors/err404.html"
fi
Ïðèìåð 2: mkhtac.sh – Ñöåíàðèé äëÿ ñîçäàíèÿ .htaccess
#==[Dialog 3b]==
#!/bin/sh dialog --title "Make .htaccess: ErrorDocument" \
# mkhtac.sh --inputbox "$TEXT" 10 70 2> $TF
# Ñîçäàíèå âñïîìîãàòåëüíûõ ôàéëîâ ERRMSG=`cat $TF`
TF=`mktemp –t dlg` ERR2HT="ErrorDocument 404 $QUOT$ERRMSG"
TF_TREE=`mktemp –t tree` echo $ERR2HT
fi
# Çàïèñü â ôàéë äåðåâà êàòàëîãîâ
find www -type d > $TF_TREE if [ "$SSI" != "" ]; then
#==[Dialog 4a]==
# Ðåãèñòðàöèÿ îáðàáîò÷èêà ñèãíàëîâ dialog --title "Make .htaccess: SSI parse" \
trap "rm -f $TF $TF_TREE" 0 2 9 15 --checklist "
Îòìåòüòå, êàêèå ôàéëû äîëæíû
#==[Dialog 0]== îáðàáàòûâàòüñÿ ïàðñåðîì SSI:" 15 40 4 \
dialog --title "Make .htaccess: Confirmation" \ ".shtml" "ôàéëû shtml" ON \
--yesno " ".shtm" "ôàéëû shtm" ON \
Äàííûé ñöåíàðèé ïîìîæåò âàì ".html" "ôàéëû html" OFF \
ñîçäàòü ôàéë .htaccess. ".htm" "ôàéëû htm" OFF 2> $TF
Ïðîäîëæèòü?" 10 40 EXTLST=`cat $TF | tr "\"" "\0"`
SSI2HT="AddHandler server-parsed $EXTLST"
if [ $? != 0 ]; then echo $SSI2HT
exit fi
fi
# Çàïèñü ðåçóëüòàòîâ â ôàéë .htaccess
#==[Dialog 1]== HTFILE=$HTDIR/.htaccess
dialog --title "Make .htaccess: Select dir" \ touch $HTFILE
--ftree $TF_TREE "/" " [ "$ERR2HT" != "" ] && echo $ERR2HT >> $HTFILE
Óêàæèòå êàòàëîã, â êîòîðîì äîëæåí [ "$SSI2HT" != "" ] && echo $SSI2HT >> $HTFILE
áûòü ñîçäàí ôàéë .htaccess:" 19 40 10 2> $TF
#==========================[Dialog 5]==
if [ $? != 0 ]; then dialog --title "Make .htaccess: Finish" \
exit --msgbox "
fi Ðàáîòà çàâåðøåíà. Ñåé÷àñ ñîçäàííûé ôàéë
áóäåò âûâåäåí íà ýêðàí, ÷òîáû âû ìîãëè
HTDIR=`cat $TF` îçíàêîìèòüñÿ ñ ðåçóëüòàòîì.
#==[Dialog 2]== Äàëüíåéøèå èçìåíåíèÿ â ñîçäàííûé ôàéë
dialog --title "Make .htaccess: Select options" \ ìîæíî áóäåò âûïîëíèòü âðó÷íóþ." 15 50
--checklist "
Óêàæèòå îïöèè, êîòîðûå ñëåäóåò äîáàâèòü #==[Dialog 6]==
â ôîðìèðóåìûé .htaccess:" 15 50 2 \ dialog --title "Make .htaccess: Result" \
ErrorDocument "Îáðàáîòêà îøèáêè 404" OFF \ --textbox $HTFILE 15 50
AddHandler "Âêëþ÷åíèå SSI" OFF 2> $TF

if [ $? != 0 ]; then В первых строках сценарий подготавливает два времен-


exit ных файла. Они создаются утилитой mktemp с префиксами
fi
dlg и tree соответственно и по умолчанию будут размеще-
ERROR=`grep "ErrorDocument" $TF` ны в каталоге /tmp.
SSI=`grep "AddHandler" $TF`
Первый из них ($TF) служит для перехвата вывода ути-
if [ "$ERROR" != "" ]; then литы dialog, во второй ($TF_TREE) заносится результат ра-
#==[Dialog 3a]==
dialog --title "Make .htaccess: ErrorDocument" \ боты команды find, которая возвращает имена всех ката-
--radiolist " логов, найденных в папке www. Благодаря тому, что mktemp
Âûáåðèòå îäèí èç ñïîñîáîâ îáðàáîòêè îøèáêè 404:" 15 60 3 \
MSG "Òåêñòîâîå ñîîáùåíèå îá îøèáêå" ON \ создает файлы со случайными именами, можно не беспо-
FILE "Ïåðåíàïðàâëåíèå íà ëîêàëüíûé ôàéë" ↵ коиться о том, что скрипт, запущенный одним пользовате-

22
администрирование
лем, удалит временные файлы, с которыми в этот же мо- нейшем используется в следующем диалоге ([Dialog 3b]),
мент времени работает другой экземпляр сценария. поясняя пользователю, что же он должен ввести.
Командой trap регистрируем обработчик для сигналов
0 (нормальное завершение), 2 (SIGINT – прерывание, на-
пример, по Ctrl-C), 9 (SIGKILL – безусловное завершение) и
15 (SIGTERM – программное прерывание). При поступле-
нии одного из этих сигналов будет выполнена команда rm,
удаляющая созданные сценарием временные файлы.
Фрагмент сценария, помеченный как [Dialog 0], выво-
дит окно типа «Да/Нет» с вопросом о продолжении, и при
ответе «Нет» работа сценария завершается.
[Dialog 1] выводит дерево каталогов, корнем которого
является в нашем случае папка www, и пользователь мо-
жет выбрать в нем каталог, в котором следует создать файл
.htaccess. Результат представлен на рис. 2, выбор пользо-
вателя заносится в переменную $HTDIR. Ðèñóíîê 4
Значение, введенное в [Dialog 3b] (рис. 5), заносится в
переменную $ERRMSG, и вместе с именем самой опции в
переменной $ERR2HT формируется строка, которая в даль-
нейшем будет записана в файл.

Ðèñóíîê 2
[Dialog 2] (см. рис. 3) выводит список флажков (checklist),
предлагая пользователю отметить те опции, которые он
желает иметь в создаваемом файле .htaccess. Результат
выбора раскладывается по переменным $ERROR и $SSI с Ðèñóíîê 5
помощью утилиты grep. Если та или иная опция не упоми- Следующий диалог ([Dialog 4a]) предлагает пользова-
нается во временном файле, то соответствующая перемен- телю отметить типы файлов, которые будут обрабатывать-
ная останется пустой, что и используется при определении ся SSI-парсером (рис. 6). Поскольку отмеченные пункты при
последующих действий. выводе в stderr (перенаправляемый в файл) заключаются
в кавычки, то при их извлечении кавычки нужно удалить,
для чего используется утилита tr.

Ðèñóíîê 3
Так, если была выбрана опция ErrorDocument, то на эк-
ране появится диалоговое окно, изображенное на рис. 4. Ðèñóíîê 6
За его формирование отвечает вызов dialog, помеченный, После всех этих мучений наконец-то создается файл
как [Dialog 3a]. Здесь реализуется список зависимых кно- .htaccess, и в него записываются сформированные строки
пок (radiolist), позволяющий выбрать один из предложен- (если они не пустые). [Dialog 5] поздравляет пользователя
ных вариантов. В зависимости от выбора пользователя в с этим знаменательным моментом (рис. 7), а [Dialog 6] вы-
переменную $TEXT заносится сообщение, которое в даль- водит на экран полученный результат, демонстрируя рабо-

№2, февраль 2005 23


администрирование
ту диалога типа «textbox», который выводит содержимое Linux работать не будет, и придется запрашивать папку для
указанного в качестве параметра файла. создания .htaccess другим способом (например, с помощью
поля ввода).

Ðèñóíîê 7
Вернемся к свойствам утилиты dialog. Цветовую гамму Ðèñóíîê 9
окон и некоторые другие параметры (например, отображе- Ряд параметров (цвет элементов окна, наличие тени
ние тени) можно изменить. Для этого используется конфи- и т. д.) в Linux-версии можно изменить не только в конфи-
гурационный файл, шаблон которого можно создать такой гурационном файле, но и в командной строке с помощью
командой: соответствующих ключей.
Кстати говоря, Linux-версию утилиты dialog можно ус-
$ dialog --create-rc <file> тановить и на FreeBSD. Она доступна в коллекции портов
под именем cdialog (/usr/ports/devel/cdialog).
В результате в файл <file> будет записана конфигура- Помимо консольной версии существует Xdialog, выпол-
ция по умолчанию. Полученный файл следует либо пере- няющий аналогичные функции в графической среде. В том
именовать в .dialogrc и поместить в домашнюю папку же Knoppix его работу можно наблюдать, например, при
пользователя (в результате он будет распространяться на вызове сценария настройки сети (рис. 10). А на рис. 11 еще
все диалоги, запущенные этим пользователем), либо ука- раз показан «Календарь», но уже в исполнении Xdialog.
зать к нему путь в переменной окружения DIALOGRC. Ре-
дактирование конфигурационного файла сложностей выз-
вать не должно, поскольку каждая строчка в нем достаточ-
но хорошо прокомментирована.

Ðèñóíîê 10

Ðèñóíîê 8
Ну и как было обещано – несколько слов об особеннос-
тях dialog в Linux. Так как «стационарного» Linux у меня под
рукой нет, я воспользовался LiveCD-дистрибутивом Knoppix. Ðèñóíîê 11
В отличие от FreeBSD-версии в Linux dialog имеет ряд допол- В завершение статьи отмечу также, что библиотеку,
нительных опций и возможностей. Так, с его помощью мож- лежащую в основе утилиты dialog, можно использовать и
но реализовать диалоги выбора даты (--calendar, рис. 8), непосредственно в своих программах на C/C++. Существу-
выбора файла (--fselect, рис. 9), вывести индикатор выполне- ют также интерфейсы к данной библиотеке для Perl, Python
ния процесса, именуемый в народе «термометром» (--gauge), и Ruby (их можно установить из коллекции портов: devel/
запросить ввод пароля (элемент --passwordbox), можно до- p5-Dialog, devel/py24-dialog и devel/ruby-dialogs соответствен-
бавлять в диалоговые окна дополнительные кнопки и т. д. но). Дополнительную информацию, как обычно, можно по-
Зато в нем нет «деревьев» (элементы --tree и --ftree в лучить на страницах справочного руководства man dialog(1)
FreeBSD-версии), так что рассмотренный нами пример 2 на и dialog(3).

24
bugtraq

Множественные уязвимости в AWStats Переполнение буфера в fd_set-структуре


Программа: AWStats 6.3 final и более ранние версии. во многих приложениях
Опасность: Высокая. Программа: gnugk 2.2.0, jabber 1.4.1, bnc 2.8.4, socks5 1.0r1,
Описание: Уязвимость позволяет удаленному пользовате- citadel 6.27, dante 1.1, rinetd 0.62, bld 0.3, 3proxy 0.4.
лю выполнить некоторые perl-директивы, вызвать отказ в Опасность: Высокая.
обслуживании и получить доступ к важной информации Описание: Структура fd_set на всех POSIX-совместимых
пользователей. платформах определяется как bitmask-массив с номером
Уязвимость обнаружена в плагине rawlog при обработ- сокета в качестве индекса массива. Структура fd_set ис-
ке переменных loadplugin и pluginmode. Удаленный пользо- пользуется в функции select() и нескольких специальных
ватель может выполнить произвольный perl-сценарий с при- макросах (FD_SET, FD_CLR, FD_ISSET, FD_CLEAR) для
вилегиями веб-сервера или вызвать отказ в обслуживании. работы с дескрипторами ввода/вывода. Ни FD_SET ни фун-
Пример: кция select() не контролируют, чтобы номер сокета был боль-

http://www.lan.server/cgi-bin/awstats-6.4/awstats.pl?↵ ше значения FD_SETSIZE. Удаленный пользователь может
&PluginMode=:print+getpwent перезаписать память за fd_set-структурой и выполнить про-
Удаленный пользователь может выполнить произволь- извольный код или вызвать отказ в обслуживании.
ный плагин. Уязвимость существует из-за недостаточной Решение: Установите обновления от производителей.
проверки данных перед вызовом функции require(). Пример: Источник: http://www.security.nnov.ru/advisiories/sockets.asp.
http://server/cgi-bin/awstats-6.4/awstats.pl? ↵
&loadplugin=../../../../usr/libdata/perl/5.00503/blib Php-инклудинг и XSS в SquirrelMail
Удаленный пользователь может получить доступ к важ- Программа: SquirrelMail версии до 1.4.4.
ной информации, вызвав один из отладочных сценариев. Опасность: Высокая.
Пример: Описание: Некоторые переменные в сценарии src/web
http://www.lan.server/cgi-bin/awstats-6.4/awstats.pl?debug=1 mail.php позволяют удаленному пользователю с помощью
http://www.lan.server/cgi-bin/awstats-6.4/awstats.pl?debug=2 специально сформированных параметров произвести php-
URL производителя: http://awstats.sourceforge.net. инклудинг и выполнить произвольные команды на системе
Решение: Установите обновление с сайта производителя. с привилегиями веб-сервера.
Удаленный пользователь может с помощью специаль-
Выполнение произвольного кода но сформированного URL произвести XSS-нападение и по-
в Symantec Norton Anti-Virus лучить доступ к важным данным пользователей. Уязвимость
Программа: Norton AntiVirus для Microsoft Exchange 2.1, вер- существует в сценарии src/webmail.php.
сии до build 2.18.85; Symantec Norton Antivirus 2004 для Отсутствие инициализации переменных в файле functions/
Windows и Macintosh; Symantec Norton Antivirus 9.0 для prefs.php позволяет удаленному пользователю инклудинг и
Macintosh. выполнение произвольных php-сценариев при включенной
Опасность: Высокая. опции register_globals в конфигурационном файле php.ini.
Описание: Уязвимость обнаружена в DEC2EXE при обра- URL производителя: http://www.squirrelmail.org.
ботке UPX-файлов. Удаленный пользователь может создать Решение: Установите обновление: http://www.squirrel
специальным образом UPX-файл, вызвать переполнение mail.org/download.php
буфера и выполнить произвольный код на уязвимой систе-
ме. Удаленное выполнение произвольного
URL производителя: http://www.symantec.com. кода в BrightStor ARCserve Backup
Решение: Установите обновление: http://www.symantec.com/ Программа: BrightStor ARCserve Backup версии до 11.1.
techsupp. Опасность: Высокая.
Описание: BrightStor ARCserve посылает пробные UDP-со-
Уязвимость форматной строки в ngIRCd общения на широковещательный адрес для выявления дру-
Программа: ngIRCd 0.8.2 и более ранние версии. гих BrightStor-серверов в сети. Служба Discovery слушает
Опасность: Высокая. на 41524 UDP-порту пробные запросы. Переполнение бу-
Описание: Обнаружена уязвимость форматной строки, ко- фера существует в функции recvfrom() при обработке проб-
торая позволяет удаленному пользователю выполнить про- ных UDP-пакетов. Функция получает 4096 байт, которые ко-
извольный код на уязвимой системе. пируются в буфер меньшего размера. UDP-сообщение, раз-
Уязвимость обнаружена в функции Log_Resolver() фай- мером более 1000 байт, вызовет переполнение буфера и
ла log.c. Если ngIRCd был скомпилирован с поддержкой Ident, даст возможность удаленному пользователю выполнить
syslog и DEBUG, удаленный пользователь может послать произвольный код на уязвимой системе с привилегиями
строку специально сформированных данных ident в ответ на Local SYSTEM.
ident-запрос и выполнить произвольный код на системе. URL производителя: http://supportconnectw.ca.com/public/
URL производителя: http://arthur.ath.cx/~alex/ngircd. enews/BrightStor/brigcurrent.asp.
Решение: Способов устранения уязвимости не существу- Решение: Установите обновления от производителя.
ет в настоящее время.
Составил Александр Антипов

№2, февраль 2005 25


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

ПОЧТОВЫЙ СЕРВЕР НА БАЗЕ POSTFIX


ЗАЩИТА ОТ ВИРУСОВ И НЕЖЕЛАТЕЛЬНОЙ ПОЧТЫ
МИНИМАЛЬНЫМИ СРЕДСТВАМИ

ГЕННАДИЙ ДМИТРИЕВ
В январском номере журнала за прошлый год вышла моя чтобы она выполняла функции фильтрации почты как на
статья [1], посвященная настройке почтовых фильтров на вирусы, так и на нежелательную корреспонденцию. В этой
базе MTA Sendmail. Тогда я не предполагал, что она может статье я не буду подробно описывать всю систему цели-
вызвать такой широкий интерес и привести к целому ряду ком, материалов на похожие темы предостаточно. Я лишь
публикаций на совершенно разные темы. Очень большое укажу на некоторые интересные моменты в данной связке
количество откликов со стороны читателей натолкнуло меня и покажу, какими минимальными средствами можно полу-
на мысль поделиться своими новыми изысканиями в обла- чить вполне рабочую систему. Итак, начнем.
сти системного администрирования.
Kaspersky
Немного теории Со времен выхода первой статьи [1], где я рассказывал о
Среди многочисленных систем передачи информации в связке Sendmail и Kaspersky Antivirus for FreeBSD, ничего не
глобальной сети Интернет немаловажную роль играет сис- изменилось. Однако для привязки Kaspersky Antivirus в RHEL
тема передачи электронных сообщений от одного респон- 3.0 нужно будет использовать отдельную утилиту, обеспечи-
дента к другому. Она включает в себя клиентов доставки, вающую шлюз для обмена данными между Postfix и антиви-
протоколы передачи данных и процедуры согласования русной программой. Но все по порядку.
между агентами. Один из основных агентов, отвечающий Первое, с чего мы начнем – это создадим отдельную
за доставку сообщения от одного клиента к другому, полу- группу и пользователей, от имени которых будут работать
чил название MTA (Mail Transfer Agent). На сегодняшний наши демоны. Они пригодятся нам в дальнейшем, когда
день этих агентов насчитывается уже более десяти. В дан- мы будем устанавливать и настраивать спам-фильтры.
ной статье речь пойдет об MTA Postfix.
Некоторое время назад я сменил работу, перейдя в одну # groupadd filter –g 551
# mkdir /var/spool/filter /var/spool/filter/spamd
из лучших фирм Петербурга на должность ведущего инже- # useradd -u 542 -g 551 -d /var/spool/filter/spamd ↵
нера. Системный администратор, занимавшийся управлени- -s /sbin/nologin avpclient
# useradd -u 543 -g 551 -d /nonexistent ↵
ем сетевой инфраструктурой фирмы, был очень занят серь- -s /nonexistent avpdaemon
езным проектом и меня попросили помочь в решении не- # chown avpclient:filter /var/spool/filter/spamd
# cd /var/spool/filter/avp
большой проблемы, связанной с постоянным падением по- # mkdir Bases ctl dev etc proc tmp tst usr var var/log
чтового сервера. Таким образом я получил в свои руки # chown –R avpdaemon:filter Bases ctl tmp tst var
# cd dev
связку из Red Hat Enterprise Linux (RHEL) 3.0 и как-то на- # mknod console c 0 0
строенного Postfix. При всем моем скептическом отноше- # mknod null c 2 2
нии к Linux меня в данной ситуации подогревал жуткий ин-
терес, какими минимальными средствами можно заставить Последние две команды необходимы, так как антиви-
корректно работать данную систему. При этом требовалось, русный демон будет запускаться в chroot-окружении.

26
администрирование
Покончив с деревом каталогов, берем дистрибутив BackupInfected=No
Kaspersky Antivirus for Linux Server (kavwslinux-4.0.3.1.tgz), IfDisinfImpossible=1
распаковываем: [Report]
# Òðåáóåì âåñòè ôàéë æóðíàëà
Report=Yes
# tar xzvf kavwslinux-4.0.3.1.tgz UseSysLog=No
# cd kavwslinux # Ïðîïèñûâàåì ïóòü ê ôàéëó æóðíàëà
ReportFileName=/var/log/kavscan.log
Из всего списка получившихся файлов нам понадобит- # Îòêëþ÷àåì ðàñøèðåííûå ôîðìû çàïèñè â æóðíàëå
ся: AvpUnix.ini, kavdaemon, kavscanner, kavupdater, а также ExtReport=No
RepForEachDisk=No
файл /etc/defUnix.prf. LongStrings=Yes
Перейдем к установке и настройке антивируса. Скопи- # Îòêëþ÷àåì ïîëüçîâàòåëüñêèé ôàéë æóðíàëà
UserReport=No
руем в каталог /var/spool/filter/avp перечисленные выше фай-
лы. В результате должно получиться следующее (обратите # Óñòàíàâëèâàåì ðåàêöèþ íà îáíàðóæåíèå âèðóñà: íå äåëàòü
# êîïèè ïèñåì
внимание на имя владельца подкаталогов): [ActionWithInfected]
InfectedCopy=No
# ls –all # Óñòàíàâëèâàåì ïîðÿäîê äåéñòâèé ïðè ïîäîçðåíèè íà âèðóñ:
# íå äåëàòü êîïèè ïèñåì
drwxr-xr-x 17 root wheel 4096 Фев 14 19:36 .
[ActionWithSuspicion]
drwxr-xr-x 4 root wheel 4096 Янв 15 15:17 .. SuspiciousCopy=No
-rwxr-xr-x 1 root wheel 21713 Янв 14 19:44 avcheck
-rw-r--r-- 1 root wheel 170 Янв 17 11:54 AvpUnix.ini # Óñòàíàâëèâàåì ïîðÿäîê äåéñòâèé â ñëó÷àå, åñëè íå óäàëîñü
drwxr-xr-x 2 avpdaemon filter 4096 Янв 27 13:31 Bases # ðàñïàêîâàòü ôàéë (ñ÷èòàåì åãî ïîâðåæäåííûì): íå äåëàòü
drwxr-xr-x 2 avpdaemon filter 4096 Фев 14 18:15 ctl # êîïèè ïèñåì
-rw-r--r-- 1 root wheel 1865 Янв 15 14:44 defUnix.prf [ActionWithCorrupted]
drwxr-xr-x 2 root wheel 4096 Янв 15 14:31 dev CorruptedCopy=No
drwxr-xr-x 2 root wheel 4096 Янв 15 14:44 etc
-rwxr-xr-x 1 avpdaemon filter 830742 Янв 24 2003 kavdaemon [TempFiles]
-rwxr-xr-x 1 root wheel 803771 Янв 24 2003 kavscanner # Óñòàíàâëèâàåì ïðåäåëüíûé ðàçìåð ñêàíèðóåìûõ ôàéëîâ
-rwxr-xr-x 1 root wheel 647648 Янв 24 2003 kavupdater # è îïðåäåëÿåì êàòàëîã äëÿ âðåìåííûõ ôàéëîâ
drwxr-xr-x 2 root wheel 4096 Янв 15 14:30 proc
UseMemoryFiles=Yes
LimitForMemFiles=6000
drwxr-xr-x 2 avpdaemon filter 4096 Фев 10 14:49 tmp
MemFilesMaxSize=20000
drwxr-xr-x 2 avpclient filter 4096 Фев 15 10:57 tst TempPath=/tmp
drwxr-xr-x 2 root wheel 4096 Янв 15 14:30 usr
drwxr--r-- 3 avpdaemon filter 4096 Янв 15 14:55 var [Customize]
# Îòêëþ÷àåì ïðîâåðêó íåîáõîäèìîñòè îáíîâëåíèÿ âèðóñíûõ áàç.
Перейдем к конфигурационным файлам. Ниже будут # Äàííàÿ îïöèÿ íåîáõîäèìà äëÿ ðàáîòû àíòèâèðóñíîé ïðîãðàììû
приведены лишь параметры, значения которых отличают- # áåç âìåøàòåëüñòâà àäìèíèñòðàòîðà.  ïðîòèâíîì ñëó÷àå
# îíà áóäåò ïðîñèòü îáíîâèòü áàçû êàæäûé ðàç ïðè çàãðóçêå
ся от принятых по умолчанию. UpdateCheck=No
# Îòêëþ÷àåì âñå ëèøíèå ïðåäóïðåæäåíèÿ íà êîíñîëè ñåðâåðà
OtherMessages=No
AvpUnix.ini RedundantMessage=No
DeleteAllMessage=No
[AVP32]
# Ìåíÿåì ïóòü ê îñíîâíîìó êîíôèãóðàöèîííîìó ôàéëó Основная идея состоит в том, чтобы максимально упрос-
DefaultProfile=defUnix.prf
тить ведение файлов журнала, и хранить в них только самое
[Configuration] главное: проверен такой-то файл, инфицирован или нет. К
KeysPath=.
# Ïðîïèñûâàåì ïóòü ê âèðóñíûì áàçàì îò êîðíåâîãî êàòàëîãà тем параметрам, которые я менял в этом файле, написаны
BasePath=/Bases комментарии. Остальные параметры не менялись. Как мож-
но заметить, все каталоги прописаны от корневого, в кото-
Конфигурационный файл defUnix.prf описывает дей- ром, собственно, и находится антивирусная программа. Все
ствия антивирусного сканера при обнаружении вирусов в дело в том, что дальше мы будем запускать антивирус в
теле сканируемого файла. chroot-окружении (зачем это нужно, будет объяснено чуть
позже). Приведу сценарий для запуска процедуры обнов-
defUnix.prf ления вирусных баз. Он достаточно маленький и состоит
# same section with parameters for objects из двух строчек. Этот скрипт следует прописать в crontab
[Object] для ежедневного выполнения, скажем, в час ночи.
# Óêàçûâàåì êàòàëîã, â êîòîðîì áóäåì ïðîâîäèòü ñêàíèðîâàíèå
# ôàéëà íà âèðóñû
Names=*/tst updater.sh
# Îòêëþ÷àåì ñêàíèðîâàíèå ïàìÿòè è ñåêòîðîâ ëîãè÷åñêèõ òîìîâ
Memory=No #!/bin/sh
Sectors=No /var/spool/filter/avp/kavupdater -y -kb ↵
# Óêàçûâàåì ïàðàìåòðû ñêàíèðîâàíèÿ óïàêîâàííûõ ôàéëîâ, -ui=http://downloads2.kaspersky-labs.com/updates/ ↵
# àðõèâîâ, ñàìîðàçâîðà÷èâàþùèõñÿ àðõèâîâ è òàê äàëåå -b=/var/spool/filter/avp/Bases
Packed=Yes /etc/init.d/kavd restart
Archives=Yes
SelfExtArchives=Yes
MailBases=Yes Сценарий для запуска/остановки демона антивирусной
MailPlain=Yes
Embedded=Yes программы (/etc/init.d/kavd) также необходимо несколько
# Óñòàíàâëèâàåì ðåàêöèþ íà îáíàðóæåíèå âèðóñà â òåëå ïèñüìà модифицировать. Здесь приведены лишь его части, под-
# «3» îçíà÷àåò óäàëåíèå òåëà âèðóñà áåç ïîïûòîê åãî ëå÷åíèÿ
InfectedAction=3 вергшиеся изменению. Остальное можно найти в дистри-
# Òðåáóåì íå àðõèâèðîâàòü ïèñüìî â ñëó÷àå îáíàðóæåíèÿ âèðóñà бутиве AVP.

№2, февраль 2005 27


администрирование
/etc/init.d/kavd # ñîîáùåíèé îòïðàâèòåëþ è ïîëó÷àòåëþ âèðóñíîãî ñîîáùåíèÿ
VIRUS_ALERT=
# Óêàçûâàåì êàòàëîã, â êîòîðûé óñòàíîâëåí àíòèâèðóñíûé ôèëüòð # Îòêëþ÷àåì èíôîðìàòèâíûå ñîîáùåíèÿ îòïðàâèòåëþ è ïîëó÷àòåëþ
INSTPATH=/var/spool/filter/avp INFORM_SENDER=n # no send alert
# Óêàçûâàåì êàòàëîã, â êîòîðîì áóäåì òåñòèðîâàòü ôàéëû INFORM_RCPT=n # send alert to recipients
AVPDIR="/tst"
# Óêàçûâàåì êàòàëîã äëÿ õðàíåíèÿ ñîêåòà # Óäàëÿåì ôóíêöèè attach_message() è attach_message_headers()
AVPPIPE="/ctl"
# Óêàçûâàåì ïàðàìåòðû çàïóñêà äåìîíà # Â ñåêöèè ãåíåðàöèè ïðåäóïðåæäåíèÿ àäìèíèñòðàòîðó óáèðàåì
DPARMS="-Y -MP -f=$AVPPIPE -dl -MD -I0 -o{$AVPDIR} $AVPDIR" # âûçîâ ôóíêöèè attach_message(). Òàêæå â ñëó÷àå, åñëè ìû
# íå èñïîëüçóåì èíôîðìàòèâíûå ñîîáùåíèÿ îòïðàâèòåëþ
# Ñòðîêè, ïðîâåðÿþùèå íàëè÷èå êîíôèãóðàöèîííûõ è êëþ÷åâûõ # è ïîëó÷àòåëþ âèðóñíîãî ïèñüìà, ìîæíî óäàëèòü ñåêöèè
# ôàéëîâ, ìîæíî èñêëþ÷èòü.  ñëó÷àå êîððåêòíîé íàñòðîéêè # «send alert to sender»
# ñèñòåìû îíè íå íóæíû. Äàëåå â ñåêöèè çàïóñêà äåìîíà # «alert to recipients»
# óáèðàåì ïðîâåðêó äåìîíñòðàöèîííîé âåðñèè, íàëè÷èÿ âèðóñíûõ
# áàç è êîððåêòèðóåì ñòðîêó çàïóñêà ñàìîãî äåìîíà. Ïî÷åìó С настройкой антивирусного демона закончили. Перей-
# îíà âûãëÿäèò èìåííî òàê, áóäåò îáúÿñíåíî ÷óòü ïîçæå дем к установке SpamAssassin.
start ()
{ SpamAssassin
if [ -r "$PIDFILE" ]; then
echo "$NAME is running" С фильтром на нежелательную почту все немного проще.
exit 1 Находим дистрибутив, скачиваем, распаковываем, устанав-
fi
cd $INSTPATH ливаем:
echo -n "Starting $DESC: "
daemon "/bin/env - HOME=/ /bin/nice ↵
/var/spool/filter/avp/uchroot ↵ # tar xzvf Mail-SpamAssassin-3.0.2.tar.gz
-u avpdaemon $INSTPATH /kavdaemon $DPARMS" # cd Mail-SpamAssassin-3.0.2
RETVAL=$? # make
echo # make install
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$NAME
cd $WD
} Инсталляцию можно произвести и из RPM-пакета, если
таковой имеется у вас под рукой. Обратите внимание, в 3-й
Обратите внимание на строку запуска антивирусного версии SpamAssassin некоторые параметры конфигураци-
демона: онных файлов сильно отличаются. Ниже будут приведены
тексты именно для 3-й версии и выше. Файл конфигурации
daemon "/bin/env - HOME=/ /bin/nice ↵ SpamAssassin, приведенный целиком и созданный мною
/var/spool/filter/avp/uchroot -u avpdaemon ↵
$INSTPATH /kavdaemon $DPARMS" практически с нуля, а также стартовый сценарий (/etc/init.d/
spamd), который пришлось слегка модифицировать для
Как легко видеть, мы пытаемся запустить демона в запуска демона от имени другого пользователя.
chroot-окружение с использованием неких утилит. Дело в Все необходимые каталоги были созданы нами ранее.
том, что входящий в комплект AVP шлюз kavkeeper, обес- Конфигурационный файл SpamAssassin:
печивающий связь между почтовым сервером и антивирус-
ным демоном, корректно работает лишь в случае, когда в local.cf
качестве фильтров используется только антивирус. При по- # don't use agent
пытке привязать к системе дополнительные фильтры вро- use_razor2 0
use_dcc 0
де Spamassassin образовывается некая внутренняя петля, use_pyzor 0
и почтовое сообщение постоянно крутится по кругу внутри
# check rbl
почтового сервера. Переписка с технической поддержкой skip_rbl_checks 0
лаборатории Касперского по этому поводу, к сожалению,
# autowhitelist
ничего не дала. Поэтому вместо kavkeeper мы будем ис- use_auto_whitelist 1
пользовать avcheck (http://www.corpit.ru/avcheck), написан- auto_whitelist_path /var/spool/filter/spamd/auto_whitelist
ный Михаилом Токаревым. # bayes
use_bayes 1
# cd /home/gennadiy bayes_auto_learn 0
# tar xzvf avcheck-0.8.tar.gz bayes_path /var/spool/filter/spamd/bayes
bayes_expiry_max_db_size 1500000
# cd avcheck-0.8 bayes_auto_learn_threshold_nonspam 0.1
# make
# cp avcheck /var/spool/filter/avp/ bayes_auto_learn_threshold_spam 10.0
bayes_min_ham_num 100
# cp uchroot /var/spool/filter/avp/ bayes_min_spam_num 200
# mkdir /var/spool/filter/avp/infected
# cp infected.ex2.ru /var/spool/filter/avp/infected auto_learn 0
ok_languages en ru
Вот вроде бы и все. Единственный момент связан с тем, ok_locales en ru
что я откорректировал конфигурационный файл infected.
# Spam header rewriting – clear_headers
ex2.ru таким образом, чтобы в случае обнаружения вируса rewrite_header subject ****SPAM (_SCORE_)****
администратору высылалось лишь предупреждение без required_hits 3.5
оригинального вложения. # user rules
allow_user_rules 0
infected.ex2.ru
# report options
always_add_report 1
# Îñòàâëÿåì äàííóþ ñòðî÷êó ïóñòîé, ÷òîáû íå ïîñûëàòü ëèøíèõ

28
администрирование
report_safe 0 Последние штрихи
report_charset koi8-r Кажется, все хорошо. Почта работает, вирусы отлавливает,
# dns testing спам идентифицируется. Но, как всегда, хочется большего.
dns_available no В связке Sendmail + SpamAssassin в milter (это программа,
# score options предоставляющая транспорт между MTA и почтовым фильт-
score FROM_ILLEGAL_CHARS 1.5 ром) можно было указать, на какой адрес пересылать всю
score HEAD_ILLEGAL_CHARS 1.5
score SUBJ_ILLEGAL_CHARS 1.5 нежелательную корреспонденцию. В Postfix мы воспользу-
score SUBJ_HAS_SPACES 2.5 емся стандартными средствами фильтрации по заголовкам
score NO_REAL_NAME 1.0
score PENIS_ENLARGE 3.5 письма. Однако прежде чем это делать, нам необходимо
score PENIS_ENLARGE2 3.5 проверить, чтобы наш MTA был не ниже версии 2.1. Ранние
score FROM_HAS_MIXED_NUMS 1.0
score FORGED_IMS_TAGS 0.5 версии не поддерживают инструкцию REDIRECT. Находим
score FORGED_MUA_OUTLOOK 0.5 дистрибутив для RHEL 3.0, устанавливаем:
score FORGED_OUTLOOK_TAGS 0.5
score BAYES_80 3.5 # rpm –Uvh postfix-2.1.5-4.rhel3.i386.rpm
score BAYES_90 4.0
score BAYES_99 10.0
# network whitelist
В файле main.cf добавляем строки, осуществляющие
whitelist_from localhost поиск в заголовках письма по регулярному выражению,
сохраненному в /etc/postfix/header.regexp:
В скрипте запуска демона SpamAssassin меняем одну
строку, относящуюся к стартовым параметрам демона. main.cf

header_checks=regexp:/etc/postfix/header.regexp
/etc/init.d/spamd

# Set default spamd configuration. Затем создаем файл /etc/postfix/header.regexp следую-


SPAMDOPTIONS="-d -m 5 -u avpclient -x ↵ щего содержания:
-r /var/run/spamd/spamd.pid"

Особых изменений по сравнению с настройками для header.regexp


FreeBSD здесь не наблюдается (см. [1]), поэтому подробно /^X-Spam-Flag: YES/ REDIRECT spam@company.ru
останавливаться на данном вопросе мы не будем.
Нам осталось лишь настроить фильтры на нашем по- т.е. требуем, чтобы все письма, в заголовке которых стоит
чтовом сервере. флаг «X-Spam-Flag», перенаправлялись по адресу spam@
company.ru.
Postfix Соответственно стоит позаботиться, чтобы у нас в сис-
Каких-то особых хитростей в конфигурации данного почто- теме присутствовал пользователь с именем «spam» или на
вого сервера я описывать не буду. Статей на эти темы пре- существующего пользователя была сделана ссылка (alias).
достаточно и в журнале, и в глобальной Сети. Нам инте- Таким образом, весь почтовый трафик, идентифицирован-
ресны лишь моменты, связанные с использованием настро- ный как потенциальный спам, будет перенаправлен на оп-
енных нами почтовых фильтров. ределенный адрес. Вот вроде бы и все.
Для этого в файле main.cf необходимо включить фильтр
avcheck: Итоги
В этой статье я попытался поделиться секретами настрой-
main.cf ки почтовых фильтров на базе MTA Postfix. Статей на по-
content_filter=avcheck добные темы достаточно, однако некоторые из них слиш-
ком громоздки и используют очень большое количество
И добавить фильтры в файл master.cf: связок. Другие же слишком неполны. Я попытался обой-
тись минимальными средствами, чтобы получить макси-
master.cf мальный уровень защиты. Ведь чем проще система, тем
# check mail with spamd and kaspersky легче за ней следить. Тексты конфигурационных файлов
avcheck unix - n n - 5 pipe будут опубликованы на сайте журнала и на техническом
flags=q user=avpclient argv=/usr/bin/spamc ↵
-u avpclient -e /var/spool/filter/avp/avcheck форуме «Тринити».
-i /var/spool/filter/avp/infected/infected.ex2.ru -h Ok Хочется выразить огромную благодарность Сергею Та-
-d /var/spool/filter/avp/./tst -s AVP:/var/spool/ ↵
filter/avp/ctl/AvpCtl -f ${sender} раненко, системному администратору фирмы «Тринити»,
-S :1025 -- ${recipient} за интеллектуальную поддержку.
localhost:1025 inet n - n - - smtpd -o content_filter=
Ссылки и литература:
Теперь следует перезапустить Postfix и проверить ра- 1. Дмитриев Г. Почтовый сервер с защитой от спама и
ботоспособность почтового сервера. Если он не функцио- вирусов на основе FreeBSD. – журнал «Системный ад-
нирует, проверьте права доступа к каталогам, скрипты за- министратор», №1, январь 2005 г. – 68-73 с.
пуска, конфигурационные файлы. Приведенные мною при- 2. Большое количество полезной информации вы найде-
меры взяты с реального сервера. те на форуме http://www.3nity.ru.

№2, февраль 2005 29


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

РЕЖЕМ СПАМ
ДОПОЛНИТЕЛЬНЫЕ МЕТОДЫ
Идет бабулька по подворотням, видит два парня
третьего пинают, она cпрашивает:
– За что это вы его так, сынки?
– Бабка, да это спамер!
– А ну тогда по почкам его! По почкам!

ДЕНИС НАЗАРОВ
Знакомый анекдот? А в реальной жизни вы пробовали под- ников они не набирали. Пришлось разбираться дальше.
считать количество «спама», проходящего через ваш по- Проанализировав протоколы за месяц, я пришел к выводу,
чтовый сервер? Недавний аудит одной финансовой компа- что 20 из этих 22 Гб были просто «спамом». Решено было
нии показал, что через почтовый сервер прошло больше избавлять компанию от этой назойливой почты...
22 Гб почтового трафика в месяц. Я информировал об этом
начальство и со спокойной душой решил, что аудит окон- Итак, мы имеем в наличии
чен, но я ошибся, руководство компании уверяло меня в ! OpenBSD 3.6.
том, что это просто невозможно, т.к. раньше у них был го- ! Postfix 2.1.5 (считаю этот МТА одним из лучших благо-
раздо меньший объем почтового трафика, а новых сотруд- даря гибкости настройки и возможностям).

30
администрирование
! DrWeb 4.32 (отличный антивирус, никогда не подводил, /etc/rc.conf
идеально работает с OpenBSD). spamd_flags="" # for normal use: "" and see spamd-setup(8)
spamd_grey=YES # use spamd greylisting if YES
! Пользователи: примерно 500 человек.
Влючаем spamd и указываем на то, что мы хотим ис-
Задача: Обеспечить максимальную защиту от спама и пользовать Grey Listing.
вирусов, которые вам стремятся подсунуть по электронной
почте. Crontab
0 * * * * /usr/libexec/spamd-setup

Система В crontab для root прописываем запуск утилиты spamd-


Настройка системы начинается с файла /etc/rc.conf. С вер- setup таким образом, чтобы она выполнялась в начале каж-
сии 3.3 OpenBSD имеет встроенный механизм защиты от дого часа. Данная утилита скачивает из Интернета списки
спама, называемый spamd. Именно о настройке данного с IP-адресами спамерских релеев и автоматически зано-
компонента системы мы и поговорим. Что есть spamd? Это сит их в ваш «черный список».
демон, который пропускает через себя весь почтовый по-
ток и принимает решения – отдать ли письмо на обработку /etc/spamd.conf
all:\
«реальному» МТА или же отбросить, как «спам». :spamhaus:spews1:spews2:china:korea:whitelist:blacklist:
Как работает spamd? В его распоряжении имеются 2 или
# Mirrored from
3 списка (в зависимости от того, что вы выберете в конфигу- # http://spfilter.openrbl.org/data/sbl/SBL.cidr.bz2
рационном файле) – «черный список», «белый список», «се- spamhaus:\
:black:\
рый список». Последний («серый список») может быть от- :msg="SPAM. Your address %A is in the Spamhaus Block ↵
ключен, если вам нужен более жесткий контроль над спаме- List\n\
See http://www.spamhaus.org/sbl and\
рами. Демон spamd при запуске начинает слушать порт 8025 http://www.abuse.net/sbl.phtml?IP=%A for more details":\
на интерфейсе 127.0.0.1 (переопределить порт можно, отре- :method=http:\
:file=www.openbsd.org/spamd/SBL.cidr.gz
дактировав файл /etc/services). Затем при помощи PF
(OpenBSD Packet Filter) мы перенаправляем весь трафик с # Mirrored from http://www.spews.org/spews_list_level1.txt
spews1:\
25-го порта на порт 8025. И видим следующую картину: :black:\
:msg="SPAM. Your address %A is in the spews level 1 ↵
Trying 127.0.0.1... database\n\
Connected to localhost. See http://www.spews.org/ask.cgi?x=%A for more details":\
Escape character is '^]'. :method=http:\
220 bastion ESMTP spamd IP-based SPAM blocker;Tue Feb 15 12:57:50 2005 :file=www.openbsd.org/spamd/spews_list_level1.txt.gz

С виду похоже на приветствие обычного МТА, если не # Mirrored from http://www.spews.org/spews_list_level2.txt


spews2:\
считать строчку: IP-based SPAM blocker. :black:\
Вот теперь начинается самое интересное. Возвращяем- :msg="SPAM. Your address %A is in the spews level 2 ↵
database\n\
ся к спискам. See http://www.spews.org/ask.cgi?x=%A for more details":\
! «Черный список» – думаю все понятно. IP-адреса, пе- :method=http:\
:file=www.openbsd.org/spamd/spews_list_level2.txt.gz
речисленные тут, будут вежливо отвергнуты.
! «Белый список» – IP-адреса из этого списка будут иметь # Mirrored from http://www.okean.com/chinacidr.txt
china:\
доступ к «реальному» МТА напрямую, без прохождения :black:\
спам-фильтра. Подразумевается, что в этот список вы :msg="SPAM. Your address %A appears to be from China\n\
See http://www.okean.com/asianspamblocks.html ↵
вносите те IP-адреса, в которых уверены на 99,97%. for more details":\
! Grey List – динамический список. Приходящее письмо с :method=http:\
:file=www.openbsd.org/spamd/chinacidr.txt.gz
IP-адресом, не входящее ни в «черный список», ни в «бе-
лый список», будет помечено как «grey», и отвергнуто с # Mirrored from http://www.okean.com/koreacidr.txt
korea:\
ошибкой: «450. Temporary failure. Try again later.» Полу- :black:\
чая данный ответ, удаленный хост, отправивший вам :msg="SPAM. Your address %A appears to be from Korea\n\
See http://www.okean.com/asianspamblocks.html ↵
сообщение, должен будет снова попытаться переслать for more details":\
сообщение через некоторое время. Обычно интервал :method=http:\
:file=www.openbsd.org/spamd/koreacidr.txt.gz
ожидания может быть от 10 до 30 минут. Spamd следит
за этим и, получая письмо второй раз, передает его по-
# Whitelists are done like this, and must be added
чтовой системе, занося отправителя в «белый список». # to «all» after each blacklist from which you want
Зачем все это нужно? Получив в ответ ошибку, спамер # the addresses in the whitelist removed
whitelist:\
будет настойчиво пытаться впихнуть нам свое сообще- :white:\
ние. Возможно, даже выполняя множество попыток в :file=/var/mail/whitelist.txt
течение одной минуты. Spamd считает такие попытки. blacklist:\
При превышении определенного количества хост тут же :black:\
:msg="SPAM! Go fsck anyone else!":\
попадает в «черный список». :file=/var/mail/blacklist.txt
relaydb-black:\
Чтобы окончательно понять, как это работает, присту- :black:\
пим к конфигурированию. :msg="SPAM. Your address %A is in my relaydb list.":\

№2, февраль 2005 31


администрирование
:method=exec:\ ные файлы в /var/db, а также «привязывает» себя к пакет-
:file=relaydb -4lb: ному фильтру.
relaydb-white:\
:white:\ # ps ax | grep -i spa
:method=exec:\
:file=relaydb -4lw: 3123 ?? Is 3:52.08 spamd: (pf <spamd-white> update) (spamd)
17434 ?? I 17:44.88 /usr/libexec/spamd -g
Данный файл отвечает за обработку этих самых «чер- 11229 ?? I 0:01.86 spamd: (/var/db/spamd update) (spamd)
26245 ?? Is 0:00.00 /usr/libexec/spamlogd
ных», «белых» и «серых» списков. Я перечислил основные 23886 p0 I+ 0:00.00 grep -i spa
самые крупные «черные списки» для спамеров, вы можете
их смело использовать. Отлично. Спам-фильтр, основанный на проверке IP-ад-
Переходим к настройке ваших «черных» и «белых» спис- ресов, это, конечно, хорошо и будет работать в связке с
ков. любым МТА, но мы сделаем еще лучше.
Идем дальше.
blacklist:\
:black:\
:msg="SPAM! Go fsck anyone else!":\ Postfix
:file=/var/mail/blacklist.txt Я не буду рассказывать, почему Postfix такой замечатель-
ный и гибкий, и быстрый, и мощный – просто сразу начнем
Директива msg отвечает за то сообщение, которое мы его настраивать.
будем отправлять во время сессии, в том случае если хост
находится в «черном списке». Директива file определяет /etc/postfix/main.cf
#
путь для файла со списком IP-адресов, которые автоматом # Our stuff for coniguring Postfix goes here
при загрузке попадают в «черный список». #

# cat /var/mail/blacklist.txt Запрещаем использование команды VRFY для провер-


81.213.107.93 ки наличия пользователя в системе.
212.112.102.194
81.195.250.132 disable_vrfy_command = yes
212.19.145.86

Конфигурационный файл похож и для «белого списка», Обязываем удаленный хост здороваться с нами, а не
за исключением директивы msg – она отсутствует. сразу начинать нас забрасывать почтой. Софт, разработан-
ный для рассылки спама, зачастую не умеет работать с
# cat /var/mail/whitelist.txt smtp-командой helo.
192.168.0.0/24
smtpd_helo_required = yes
Важно.
Проверяем наличие «верного» имени хоста для отпра-
all:\ вителей. Иначе отказываем отправителю.
:spamhaus:spews1:spews2:china:korea:whitelist:blacklist:

Решение принимается на основе последнего совпаде- smtpd_helo_restictions = permit_mynetworks,


reject_invalid_hostname,
ния IP-адреса и записи в списках. reject_unknown_hostname,
Все. Основная конфигурация для spamd закончена. Так reject_non_fqdn_hostname
как мы перенаправляем письма в spamd при помощи PF
(Packet Filter), то конфигурируем сам фильтр: Проверяем наличе «верного» домена у отправителя,
иначе отказываем.
/etc/pf.conf
table <spamd> persist smtpd_sender_restrictions = reject_unknown_sender_domain,
table <spamd-white> persist check_sender_access hash:/etc/postfix/reject
rdr pass inet proto tcp from <spamd> to any port ↵
smtp -> 127.0.0.1 port 8025
rdr pass inet proto tcp from !<spamd-white> to any port ↵ Если же намеренно хотим отказать отправителю – за-
smtp -> 127.0.0.1 port 8025 носим его домен в файл /etc/postfix/reject и выполняем ко-
манду:
Тем, кто читал в журнале мои предыдущие статьи о па-
кетном фильтре операционной системы OpenBSD, все бу- # postmap /etc/postfix/reject
дет понятно. Для остальных поясню – фильтр перенаправля-
ет весь трафик с 25-го порта на порт 8025. Но если трафик Утилита postmap создаст хеш из файла /etc/postfix/reject,
на 25 порт идет с IP-адреса, который находится в «белом который будет использоваться самим Postfix для отказа в
списке», то PF пропускает трафик сразу «реальному» МТА. приеме почты.
Готово. Теперь осталось запустить spamd. Проверяем наличие «верного» имени домена для полу-
Можно запустить spamd вручную, но лучше будет – пе- чателей, отказываем всем, чьё имя домена не соответству-
резагрузить сервер, т.к. при запуске spamd создает нуж- ет требованиям FQDN, или не существует вообще.

32
администрирование
smtpd_recipient_restrictions = reject_invalid_hostname, Spam Received See:
reject_non_fqdn_sender, http://www.dnsbl.sorbs.net/lookup.shtml?195.2.80.59;
reject_non_fqdn_recipient, from=<user@domain.name>
reject_unknown_sender_domain,
to=<user@ourhost.com> proto=SMTP helo=<domain.name>
reject_unknown_recipient_domain,
reject_unauth_pipelining,
permit_mynetworks, Система работает, как часы, все четко и точно. Если
reject_unauth_destination, вам не нравится, как spamd распределяет IP-адреса отпра-
reject_rbl_client relays.visi.com,
reject_rbl_client relays.ordb.org, вителей по «черному» и «белому» списку, используем ути-
reject_rbl_client list.dsbl.org, литу spamdb.
reject_rbl_client dnsbl.sorbs.net,
reject_rbl_client dnsbl.void.ru,
reject_rbl_client blackholes.mail-abuse.org, # spamdb | more
reject_rbl_client relays.mail-abuse.org,
reject_rbl_client dul.mail-abuse.org, WHITE|12.111.30.74|||1105460517|1105466496|1108576943|2|0
reject_rbl_client relays.ordb.org, WHITE|129.215.166.64|||1106681432|1106683445|1109793856|2|0
reject_rbl_client blackholes.wirehub.net, WHITE|13.16.138.21|||1105587869|1105591107|1108701528|3|0
reject_rbl_client dynablock.wirehub.net, WHITE|130.126.232.30|||1106168619|1106170545|1109281002|6|0
reject_rbl_client dnsbl.njabl.org,
reject_rbl_client list.dsbl.org, WHITE|134.130.3.130|||1107270887|1107274487|1110384920|2|0
reject_rbl_client opm.blitzed.org, WHITE|138.220.29.7|||1105954380|1105956190|1109066641|6|0
reject_rbl_client http.dnsbl.sorbs.net,
reject_rbl_client socks.dnsbl.sorbs.net,
reject_rbl_client misc.dnsbl.sorbs.net, Данный листинг показывает ваши «белый список» и
reject_rbl_client smtp.dnsbl.sorbs.net, Grey Lists. Если вы намеренно хотите добавить в таблицу
reject_rbl_client web.dnsbl.sorbs.net,
reject_rbl_client bl.spamcop.net, хост, помеченный как White, используем параметр -a, что-
reject_rbl_client dev.null.dk, бы удалить -d:
reject_rbl_client blackholes.mail-abuse.com,
reject_rbl_client relays.mail-abuse.com,
reject_rbl_client dialups.mail-abuse.com, spamdb –a xxx.xxx.xxx.xxx
reject_rbl_client relays.ordb.org, spamdb –d xxx.xxx.xxx.xxx
reject_rbl_client list.dsbl.org,
reject_rbl_client multihop.dsbl.org, Примечание. Добавить или удалить можно только IP-
reject_rbl_client argentina.blackholes.us,
reject_rbl_client brazil.blackholes.us, адреса, помеченные как White. Для добавления IP-адреса
reject_rbl_client china.blackholes.us, в ваш «черный список» отредактируйте файл, указанный в
reject_rbl_client cn-kr.blackholes.us,
reject_rbl_client hongkong.blackholes.us, директиве file файла /etc/spamd.conf.
reject_rbl_client japan.blackholes.us, Основная настройка закончена. Остаются «рюшечки».
reject_rbl_client korea.blackholes.us,
reject_rbl_client malaysia.blackholes.us, Спам это, конечно, вредная вещь, но вирусы, трояны и про-
reject_rbl_client mexico.blackholes.us, чее может принести вам еще больше проблем. Приступим.
reject_rbl_client nigeria.blackholes.us,
reject_rbl_client singapore.blackholes.us, Берем последнюю версию DrWeb на сайте http://download.
reject_rbl_client taiwan.blackholes.us, drweb.com/unix/OpenBSD+3.6 и оттуда же фильтр для Postfix.
reject_rbl_client thailand.blackholes.us,
reject_rbl_client turkey.blackholes.us Установка DrWeb очень проста. Нужно распаковать ар-
хив и расположить файлы в системе так, как это сказано в
Строчка reject_rbl_client relays.visi.com … добавляет так readme. Также вам потребуется наличие демонстрацион-
называемую RBL-проверку. Принцип тот же, что и у spamd. ного ключа для запуска антивируса в демо-режиме. Если
Хост проверяется в «черном списке» у всех добавленных понравится работа DrWeb (а я надеюсь, так и будет), то вы
нами «reject_rbl_client», и, если будет обнаружен там, пись- можете без проблем приобрести нормальный ключ.
мо отбрасывается, как спам. Переходим к Postfix. Тут тоже все довольно просто.
После данной настройки системы и Postfix в качестве
MTA в протоколах мы можем наблюдать следующее: /etc/postfix/master.cf

# tail /var/log/daemon Заменяем строчку:


Feb 15 12:10:22 bastion spamd[17434]: 66.94.237.32: connected (1/0)
Feb 15 12:10:23 bastion spamd[17434]: 66.94.237.32: smtp inet n - n - - smtpd
disconnected after 1 seconds.
Feb 15 12:13:29 bastion spamd[17434]: 222.67.37.40:
connected (103/100), lists: china на
Feb 15 12:13:32 bastion spamd[17434]: 222.67.37.40:
disconnected after 3 seconds. lists: china
smtp inet n - n - - ↵
Feb 15 12:13:53 bastion spamd[17434]: 63.209.157.52: smtpd -o content_filter=filter:dummy
connected (1/1), lists: spamhaus
Feb 15 12:21:11 bastion spamd[17434]: 63.209.157.52:
disconnected after 438 seconds. lists: spamhaus
и добавляем в конец файла:

Из протоколов видно, какой IP-адрес и сколько раз пы- filter unix - n n - - pipe
flags=R user=drweb argv=/usr/local/drweb/drweb-postfix ↵
тался соединиться и отправить нам спам. -f ${sender} -- ${recipient}

# grep –i spam /var/log/maillog Вот, в общем-то, и все. Отличная антивирусная защита


Feb 15 01:19:34 bastion postfix/smtpd[8447]: NOQUEUE: reject:
к вашему Postfix готова.
RCPT from domain.name[195.2.80.59]: 554 Service unavailable; На сим заканчиваю, надеюсь, описанные мной способы
Client host [195.2.80.59] blocked using dnsbl.sorbs.net; помогут отбить все почки вашим спамерам.

№2, февраль 2005 33


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

УНИВЕРСАЛЬНЫЙ ПРОКСИ-СЕРВЕР
– Извини, Пух, – сказала САВА. – Тигра сжевал все
провода от почтового сервера, и почта долго никак
не приходила...
– Провода, – подумал Пух злобно. – Носки вязать из
таких проводов.
Андрей Щербаков
«9600 бод и все-все-все...»

ВАЛЕНТИН СИНИЦЫН
В этой статье мы поговорим о протоколе SOCKS1. С его по- К слову сказать, название протокола не имеет ничего об-
мощью можно решать самые разные задачи: организовы- щего с упомянутыми в эпиграфе чулочными изделиями и яв-
вать защищенный доступ к службам, расположенным за ляется простым сокращением от «SOCK-et-S» – «гнезда»,
межсетевым экраном (firewall), скрывать свой истинный IP- или, в более привычном уху компьютерного специалиста пе-
адрес во время работы с недружелюбными сетевыми ресур- реводе – «сокеты». Термин был предложен создателями в
сами или реализовать универсальный прокси-сервер, под- качестве рабочего варианта, да так и прижился. Как извест-
держивающий любые протоколы прикладного уровня (HTTP, но, сокеты лежат в основе любого API, реализующего сете-
FTP, POP3/SMTP, ICQ и т. д.). К сожалению, несмотря на всю вое взаимодействие – UNIX, Winsock и т. п. Чтобы послать
простоту и богатство возможностей SOCKS, многие систем- данные по сети, приложению достаточно просто записать их
ные администраторы недостаточно хорошо знакомы с ним и в сокет, подобно тому, как это делается при сохранении ин-
не представляют, чем он может быть полезен. Хочется наде- формации в локальном файле. И в том, и в другом случае
яться, что после прочтения данного материала незаслужен- программе не приходится заботиться о происходящем «за
но забытый протокол займет достойное место в их арсена- кулисами». Дополнение пользовательских данных служеб-
ле. Сразу же оговоримся: все последующее изложение бу- ной информацией, разбивка на сегменты с их последующей
дет относиться к пятой версии SOCKS, SOCKS5. Предыду- инкапсуляцией в датаграммы и физическая отправка осу-
щая, четвертая версия (SOCKS4), все еще имеет хождение ществляются другими частями операционной системы – сте-
в Сети, однако ее возможности ограничены. ком TCP/IP и драйверами устройств, о которых приложению

1
Socks (англ.) – носки, чулочки.

34
администрирование
ничего не известно. Такое «разделение труда» позволяет как ICMP, используемый утилитами ping и traceroute, находит-
угодно изменять процедуру доставки сообщений при усло- ся ниже транспортного уровня, а потому соксификации, к
вии, что интерфейс прикладного программирования остает- сожалению, не поддается2.
ся постоянным. Именно эта особенность и лежит в основе Прежде чем отправлять какие-либо данные, клиент дол-
идеологии SOCKS. Основная задача данного протокола – жен пройти процедуру авторизации. Для этого он создает
внедрить в «нормальный» процесс обмена данными некое- TCP-соединение с SOCKS-сервером (стандартный порт –
го посредника, называемого SOCKS-сервером или SOCKS- 1080) и отправляет по нему специальное сообщение, со-
прокси. Когда клиент (поддерживающее SOCKS приложе- держащее кодовые номера поддерживаемых методов
ние: веб-браузер Mozilla, клиент ICQ Miranda IM и др., см. аутентификации (см. таблицу 1). SOCKS-сервер выбирает
ниже) желает отправить какую-либо информацию по сети, один из них по своему усмотрению и сообщает его номер
он устанавливает соединение не с реальным адресатом, а с клиенту. Как легко видеть, аутентификация может отсут-
SOCKS-сервером, который, в свою очередь, пересылает дан- ствовать (на практике это скорее всего означает, что
ные по назначению, но уже от своего имени. С точки зрения SOCKS-сервер различает клиентов по их IP-адресам) или
«настоящего» сервера (например, веб-узла, который пользо- производиться на основании имени пользователя и паро-
ватель желает просмотреть в Mozilla Firefox) SOCKS-прокси ля. В последнем случае возможно большое количество раз-
является самым обыкновенным клиентом. Таким образом, личных вариантов, от тривиального «Username/Password
сущность (IP-адрес) истинного клиента оказывается скры- Authentication» (RFC 1929), предусматривающего передачу
той от обслуживающего его сервера. Это весьма удобное пароля в открытом виде, до куда более безопасного CHAP
обстоятельство таит в себе потенциальную опасность (мо- (зашифрованный пароль, открытые данные) и GSSAPI (RFC
жете спрятаться вы, но ведь могут и от вас), поэтому реаль- 1961), которое может использоваться для полной криптог-
но существующие SOCKS-сервера имеют развитые схемы рафической защиты трафика. После успешной авториза-
контроля доступа (запрет входящих и исходящих соедине- ции клиент получает возможность посылать запросы (ко-
ний по заданному перечню адресов) и поддерживают авто- манды), устанавливать исходящие соединения и даже при-
ризацию пользователей по паролю (см. ниже). нимать входящие.
Отметим, что коль скоро SOCKS работает на более низ-
ком по сравнению с прикладным (а именно транспортном) Установка исходящего TCP-соединения
уровне модели OSI, его поддержка не потребует никаких из- Для установки исходящего TCP-соединения клиент отправ-
менений в логике работы клиента, а тем более сервера. Дей- ляет SOCKS-серверу запрос «CONNECT», в котором указы-
ствительно, все что нужно, – это модифицировать реализа- вает адрес и порт доставки. Для идентификации узла-полу-
цию функций, отвечающих за создание сетевого подключе- чателя могут использоваться как IP-адреса (поддерживают-
ния и отправку данных: connect(), bind(), send() и т. п. На прак- ся IPv4/IPv6), так и полноценные доменные имена. В после-
тике это обычно достигается перехватом системных вызо- днем случае SOCKS-сервер берет на себя заботу по их раз-
вов с их последующей подменой поддерживающими SOCKS решению, так что сеть, в которой работает клиент, в принци-
пользовательскими аналогами. Никаких правок в исходном пе может обходиться и без DNS-сервера. В ответном сооб-
коде клиентских приложений, а тем более самого доступа к щении SOCKS-сервер сообщает код ошибки (как обычно, 0
исходным текстам, как правило, не требуется. Эта мощная обозначает, что операция прошла успешно), а также IP-ад-
процедура известна как «соксификация» и будет подробно рес (BND.ADDR) и TCP-порт (BND.PORT), которые будут ис-
рассмотрена ниже. пользоваться для фактической связи с запрошенным уз-
Теперь, когда мы получили общее представление о лом. Поскольку SOCKS-сервера, как правило, имеют бо-
SOCKS, можно перейти к более детальному рассмотрению лее одного сетевого интерфейса, данный IP-адрес может
данного протокола. отличаться от того, с которым было установлено управля-
ющее соединение. После этого клиент открывает новый
Спецификация SOCKS5 TCP-сеанс с BND.ADDR:BND.PORT и осуществляет отправ-
Протокол SOCKS5 подробно описан в RFC1928. В отличие ку данных. Исходящее TCP-соединение разрывается одно-
от монстроподобных стандартов вроде «HTTP 1.1», специ- временно с закрытием управляющей сессии. Заметим, что
фикация SOCKS умещается на 9-ти страницах и может быть запрос «CONNECT» может быть отклонен SOCKS-прокси,
без труда разобрана любым желающим. Предлагаемые если адреса источника (клиента) или получателя (сервера)
здесь сведения являются ее кратким конспектом и призва- запрещены3 к обслуживанию системным администратором.
ны помочь вам в этом несложном деле.
Как уже отмечалось ранее, SOCKS5 является протоко- Установка исходящего UDP-соединения
лом транспортного уровня. Его «соседи» – TCP и UDP не- В отличие от потокового протокола TCP, подразумевающего
посредственно используются для передачи данных, посту- установку сеанса, протокол UDP является датаграммным,
пающих с прикладного уровня (от пользовательских при- а потому несколько более сложным в обращении. Его под-
ложений), а значит, SOCKS-прокси должен уметь коррект- держка появилась лишь в SOCKS5.
но работать с каждым из них. Отметим также, что протокол Перед отправкой UDP-датаграмм клиент запрашивает у

2
Существуют нестандартные расширения протокола SOCKS, позволяющие работать и с ICMP, однако в данной статье они рассматривать-
ся не будут.
3
Или явно не разрешены, в зависимости от конкретной реализации и выбранной политики.

№2, февраль 2005 35


администрирование
SOCKS-сервера UDP-ассоциацию, используя для этого ко- единение) и «сервером» (стороной, инициирующей входя-
манду «UDP ASSOCIATE». UDP-ассоциация – это своего рода щее соединение) уже установлен «прямой» канал связи при
виртуальный сеанс между клиентом и SOCKS-сервером. В помощи команды «CONNECT». Для открытия «обратного»
исходящем запросе клиент указывает предполагаемые ад- канала «клиент» должен послать SOCKS-серверу команду
рес и порт, которые будут выступать в качестве источника «BIND», указав в ее параметрах IP-адрес и порт, которые
будущих UDP-датаграмм. Если на момент установки UDP- будут использоваться им для приема входящего соединения.
ассоциации эта информация еще неизвестна, клиент дол- В ответ на это SOCKS-сервер сообщает IP-адрес и порт, вы-
жен использовать комбинацию 0.0.0.0:0 (или, скажем, деленные им для поддержания «обратного» канала. Пред-
x.x.x.x:0, если неизвестен только номер порта). В ответном полагается, что «клиент» передаст эти параметры «серве-
сообщении SOCKS-сервер указывает IP-адрес (BND.ADDR) ру», используя средства, предоставляемые протоколами
и UDP-порт (BND.PORT), на которые следует направлять прикладного уровня (например, команду «PORT» протоко-
исходящие датаграммы. При этом адрес и порт их реально- ла FTP). После того, как SOCKS-сервер примет (или отбро-
го получателя указываются прямо в теле (можно сказать, что сит) входящее соединение, он повторно уведомляет об этом
имеет место UDP-инкапсуляция). Эти параметры, наряду с «клиента», сообщая ему IP-адрес и порт, используемые
адресом и портом отправителя используются для принятия «сервером». Отметим, что прием входящих соединений мо-
решения о допустимости отправки датаграммы. Как легко жет осуществлять лишь приложение, разработчики кото-
видеть, это создает дополнительную нагрузку на SOCKS- рого позаботились о поддержке SOCKS еще на этапе про-
сервер: правила фильтрации необходимо применять к каж- ектирования. В противном случае (если приложение рабо-
дой UDP-датаграмме, тогда как в случае TCP-соединения тает с SOCKS-сервером через программу-соксификатор)
его легитимность оценивается один раз, в момент испол- оно не сможет предоставить корректную информацию об
нения SOCKS-сервером команды «CONNECT». Согласно адресе ожидающего «обратной связи» сокета (т.е. сфор-
требованиям стандарта, SOCKS-сервер должен следить за мирует неверную команду «PORT» в рассмотренном выше
тем, чтобы IP-адрес отправителя датаграммы совпадал с примере с FTP).
адресом узла, создавшего UDP-ассоциацию. UDP-ассоци-
ация разрушается одновременно с закрытием управляю- «Цепочки» SOCKS
щего TCP-сеанса, в рамках которого была послана коман-
Давайте, работайте. Шесть арендованных «на раз»
да «UDP ASSOCIATE». роутеров, через которые пробегает сигнал. И все
Многие из существующих SOCKS-серверов испытыва- достаточно стойкие к взлому.
ют серьезные проблемы, если между ними и клиентом, зап-
росившим UDP-ассоциацию, располагается межсетевой Сергей Лукьяненко
экран с функцией NAT (Network Address Translation). При- «Лабиринт отражений»
чина этого кроется в изменении адреса и порта отправите- Архитектура протокола SOCKS5 позволяет легко объеди-
ля, которое происходит в тот момент, когда UDP-датаграм- нять SOCKS-сервера в каскады, или, как их еще называ-
ма пересекает межсетевой экран. Как следствие, сервер и ют, «цепочки» (chains). Примечательно, что все необходи-
ничего не подозревающее клиентское приложение начина- мые для этого действия могут быть произведены на сторо-
ют говорить на разных языках: предполагаемый адрес и не клиента. К «звеньям» цепочки предъявляется единствен-
порт источника, указанные в команде «UDP ASSOCIATE», ное требование: они должны «доверять» друг другу (т.е.
перестают соответствовать реальным параметрам получа- допускать установку входящих и исходящих соединений).
емых SOCKS-сервером датаграмм. В результате они ока- Если образующие каскад SOCKS-сервера не являются ано-
зываются отброшенными как не принадлежащие UDP-ас- нимными (т.е. используют схемы аутентификации Username/
социации. Проблему можно было бы решить, указав в ка- Password, CHAP или подобные), необходимо также, чтобы
честве предполагаемого источника 0.0.0.0:0 (см. выше), что пользователь мог успешно пройти процедуру авторизации
должно интерпретироваться SOCKS-сервером как «любая на каждом из них.
UDP-датаграмма, пришедшая с того же адреса, что и ко- Предположим, что у нас имеется набор из N SOCKS-
манда на создание ассоциации». К сожалению, большин- серверов с именами socks1, socks2, ..., socksN, удовлетво-
ство из реально существующих SOCKS-серверов трактуют ряющих всем вышеперечисленным требованиям. Тогда для
стандарт более узко и не позволяют одновременно устано- создания каскада клиент может поступить следующим об-
вить в ноль и предполагаемый адрес, и порт отправителя. разом:
Из протестированных автором реализаций описанный здесь ! В случае исходящего TCP-соединения: клиент подклю-
«фокус с пробросом UDP через NAT» позволяет проделать чается к socks1, проходит (при необходимости) проце-
лишь одна – Dante. дуру авторизации и посылает команду «CONNECT»,
указав в качестве адреса доставки socks2. Выполняя
Прием входящих соединений этот запрос, socks1 создаст новое соединение с socks2
Эта достаточно оригинальная возможность может оказаться и будет исправно передавать всю идущую по нему ин-
полезной в случаях, когда клиент и «настоящий» сервер в формацию клиенту, при этом socks2 не будет даже до-
описанной выше схеме меняются местами, что может про- гадываться, с кем он общается на самом деле. Далее
изойти, например, в протоколах типа FTP. В целях даль- процедура повторяется до тех пор, пока не будет уста-
нейшего рассмотрения будем предполагать, что между новлено соединение между socks(N-1) и socksN. После-
«клиентом» (стороной, собирающейся принять входящее со- дний сервер каскада подключается непосредственно к

36
администрирование
узлу, который интересует клиента. Передача данных новки SOCKS-сервера, гораздо проще набрать «cd /usr/
происходит в обычном режиме: клиент отправляет па- ports/net/socks5 && make && make install», чем разбираться
кет на сервер socks1, который, в свою очередь, переда- во всем многообразии существующих на рынке решений.
ет его socks2, и так до тех пор, пока не будет достигнут Продукт имеет поддержку GSSAPI и распространяется в
конечный узел. исходных текстах, но по несвободной лицензии. Коммер-
! В случае исходящего UDP-соединения: клиент подклю- ческое применение данного сервера запрещено.
чается к socks1, проходит процедуру авторизации и пос- Следом за ним идет Dante, разработанный норвежской
ледовательно посылает две команды: «CONNECT» (ад- компанией Inferno Nettverk и поддерживающий все основ-
рес доставки – socks2) и «UDP ASSOCIATE». Таким об- ные UNIX-системы. Продукт развивается, хотя и не очень
разом, создаются два новых соединения: виртуальный бурно (последняя версия, 1.1.15, датирована 31 января 2005
UDP-канал между клиентом и socks1, а также TCP-сес- года) и вполне пригоден для практического применения. Как
сия между socks1 и socks2. Используя эту TCP-сессию, уже упоминалось ранее, Dante позволяет корректно рабо-
клиент (от имени socks1) посылает команду «UDP тать с UDP-ассоциациями даже в том случае, если они про-
ASSOCIATE» на сервер socks2 (открывает UDP-канал ходят через NAT Firewall. Программа распространяется в
между socks1 и socks2) и «CONNECT» на сервер socks3. исходных текстах по лицензии BSD. В состав Dante входит
Процедура продолжается до тех пор, пока между всеми библиотека для прозрачной соксификации UNIX-приложе-
SOCKS-серверами каскада не будут установлены вир- ний (см. ниже).
туальные UDP-каналы. Чтобы отослать какие-либо дан- Antinat (http://antinat.sourceforge.net) – динамично разви-
ные, клиент предварительно производит N-кратную ин- вающийся, но еще не завершенный открытый продукт, ра-
капсуляцию UDP-датаграммы, указывая в качестве ад- ботающий на платформах UNIX и Windows. Поддерживает
реса доставки последовательно: socks1, socks2, socks3, интересные схемы аутентификации, например CHAP или
socksN и адрес реального получателя, а затем отправ- HMAC-MD5. Умеет работать с цепочками SOCKS-серверов.
ляет ее на сервер socks1. Отметим, что на практике дан- В комплект поставки входит библиотека для разработки
ный вариант каскадирования встречается крайне ред- пользовательских приложений, поддерживающих SOCKS.
ко. Это связано с тем, что SOCKS-сервера, как и NAT Распространяется в исходных текстах. Лицензирован по GPL.
Firewall, могут изменить порт источника датаграммы, что Среди других разработок следует упомянуть отечествен-
приведет к проблемам, подробно описанным в разделе ный 3proxy (http://security.nnov.ru/soft/3proxy), имеющий род-
«Установка исходящего UDP-соединения». ную поддержку UNIX и Win32, Delegate (www.delegate.org)
и коммерческий SOCKS-сервер Hopster (www.hopster.com)
Используя цепочки SOCKS-серверов, не требующих для Microsoft Windows.
аутентификации, клиент может значительно повысить ано- Приведенный здесь список далеко не полон. Думается,
нимность работы в Интернете (см. эпиграф). В Сети можно что читателю не составит труда найти и другие сервера.
найти множество программ, реализующих описанные здесь Для этого можно воспользоваться поисковыми панелями
схемы. Таковыми, например, являются SocksChain (http:// репозитариев Freshmeat (http://www.freshmeat.net) или
www.ufasoft.com/socks) для Windows или ProxyChains (http:// SourceForge (http://www.sf.net), а также поисковыми маши-
proxychains.sourceforge.net) для UNIX. Каскадирование нами общего назначения.
SOCKS-серверов является также неотъемлемой частью не- Учитывая многообразие существующих SOCKS-серве-
которых соксификаторов, в первую очередь FreeCap (http:// ров, мы не будем подробно останавливаться на процедуре
www.freecap.ru). их настройки. Вся необходимая для этого информация мо-
жет быть найдена в сопроводительной документации к кон-
SOCKS-сервера кретному программному продукту. Как правило, SOCKS-
Теперь, когда принципы работы SOCKS-сервера нам хоро- сервера имеют один или несколько конфигурационных
шо знакомы, пора переходить от теории к практике. В мире файлов, позволяющих указать предпочтительные схемы
существует большое количество программ, реализующих авторизации и, что более важно, ограничить доступ к сер-
протокол SOCKS5. Они охватывают все популярные опе- вису по списку IP-адресов. Не пренебрегайте этой возмож-
рационные системы (UNIX, Windows, ...) и способы распро- ностью! Неправильно настроенный SOCKS-прокси может
странения (freeware, shareware, open-source и т. д.). Здесь быть использован злоумышленниками для рассылки спа-
мы вкратце рассмотрим наиболее известные (или интерес- ма через корпоративный почтовый сервер (с точки зрения
ные с точки зрения автора) реализации. которого SOCKS-прокси – это один из установленных в
Начнем, пожалуй, с SOCKS5 Reference Implementation фирме компьютеров, поэтому отправка почты с его IP-ад-
(http://www.socks.permeo.com), выполненной компанией NEC реса, скорее всего, не будет запрещена) и выполнения дру-
и принадлежащей в настоящий момент фирме Permeo. Те- гих антиобщественных действий.
кущая версия имеет номер 1.0r11 и датирована августом
2000 года. Как легко догадаться по названию, этот сервер SOCKS-клиенты
является справочной реализацией протокола и, вообще Некоторые настольные приложения обладают встроенной
говоря, не предназначен для промышленного использова- поддержкой SOCKS. В их число входят веб-браузеры, по-
ния. Тем не менее он является стандартом де-факто на плат- строенные на коде Mozilla и ряд клиентов сетей мгновенно-
форме FreeBSD. Вероятно, большинству системных адми- го обмена сообщениями (Miranda IM, Mirabilis ICQ). Для
нистраторов, волею судеб столкнувшихся с задачей уста- включения поддержки SOCKS в этих программах достаточ-

№2, февраль 2005 37


администрирование
но указать необходимые параметры в файле или диалоге тированные возможности) родных функций операционной
настроек. Но что делать в случае, если приложение не уме- системы, что, согласитесь, не всегда легкодостижимо.
ет работать с SOCKS напрямую (классическим примером Чтобы не быть голословными, приведем примеры конк-
является Microsoft Internet Explorer)? ретных программ-соксификаторов. В среде Windows мож-
Существует несколько вариантов решения данной про- но использовать SocksCap (http://www.socks.permeo.com) от
блемы. Если исходные тексты приложения доступны, мож- все той же фирмы Permeo (и с все той же неудобной лицен-
но собрать их заново, используя готовые клиентские биб- зией, ограничивающей коммерческое применение) или от-
лиотеки, например, входящие в состав Dante или Antinat. крытый (распространяющийся по GPL) продукт FreeCap
Однако, как уже упоминалось выше, наличие «исходников» (http://www.freecap.ru), написанный нашим соотечественни-
не является обязательным требованием. Откомпилирован- ком Максимом Артемьевым. В последнем случае в вашем
ное приложение можно заставить работать с SOCKS «об- распоряжении окажутся также исходные тексты на языке
манным путем» при помощи программ-соксификаторов, Object Pascal (Delphi), с помощью которых вы сможете глу-
подменяющих стандартные функции для работы с сокета- боко разобраться во всех обсуждаемых в статье вопросах,
ми их аналогами, поддерживающими SOCKS. Так, моди- от процедуры внедрения в чужой процесс до точного фор-
фицированная функция connect(), устанавливающая соеди- мата SOCKS-сообщений. В UNIX можно воспользоваться
нение с заданным узлом, на самом деле отсылает команду сценарием оболочки socksify, входящим в состав Dante.
«CONNECT» на адрес указанного пользователем SOCKS- Наконец, рассмотрим особый случай – программы, обес-
сервера, а «соксифицированная» функция sendto() выпол- печивающие соксификацию всей системы целиком. В
няет инкапсуляцию UDP-датаграммы и отправляет ее, ис- Windows этого можно достичь, подменив на диске файл
пользуя заранее установленную UDP-ассоциацию. Проце- wsock32.dll или более корректным образом, используя спе-
дура подмены функций существенно зависит от типа опе- цификацию Winsock Service Provider. В UNIX достаточно до-
рационной системы. бавить команду, устанавливающую значение переменной
Так, в мире Windows для этих целей применяются «ви- LD_PRELOAD в один из стартовых сценариев (например,
русные» методики. Например, соксификатор может запус- rc.local) или внести изменения в файл /etc/ld.so.preload. При-
кать указанный пользователем процесс в режиме «Suspend», мером такого «общесистемного соксификатора» могут слу-
после чего внедрять в его память код, загружающий специ- жить WideCap Максима Артемьева (пребывающий пока в
альную DLL-библиотеку, перехватывающую обращения к состоянии бета-версии) или Permeo Security Driver.
API-вызовам LoadLibrary/GetProcAddress, ответственным за
подключение сторонних DLL и поиск в них экспортируемых Вместо заключения
функций. После этого соксификатор отслеживает момент Вот и подошло к концу наше повествование. Теперь, когда
загрузки wsock32.dll и подменяет запрашиваемые адреса вы хорошо представляете себе, что такое SOCKS и с чем
функций Winsock указателями на их SOCKS-аналоги. его едят, вам не составит труда придумать тысячу и одно
В мире UNIX, как это часто случается, все обстоит зна- применение данному протоколу. Например, на базе SOCKS-
чительно проще. Динамический компоновщик ld.so исполь- сервера можно организовать шлюз для доступа из локаль-
зует специальную переменную окружения, LD_PRELOAD, ной сети организации в Интернет. Это будет особенно удоб-
а также файл /etc/ld.so.preload, чтобы определить список но в случае, когда использование традиционного HTTP-про-
разделяемых библиотек, подлежащих предварительной кси не может дать требуемых результатов (например, не-
загрузке до непосредственно запрашиваемых исполняемым обходимо реализовать поддержку дополнительных прото-
файлом. Поскольку большая часть современных приложе- колов, не связанных с web), а открывать полноценный дос-
ний использует динамическую компоновку, соксифициро- туп через NAT почему-либо представляется нецелесообраз-
ванные аналоги сетевых функций, оформленные в виде ным. Предлагаемую схему можно инвертировать и возло-
разделяемой библиотеки, перечисленной в LD_PRELOAD, жить на SOCKS-сервер функции «стража», допускающего
будут найдены и использованы вместо стандартных вызо- выделенных пользователей (скажем, находящихся в коман-
вов, определенных в glibc. Этот метод, очевидно, не будет дировке сотрудников службы технической поддержки) к
работать для приложений, использующих статическое свя- внутренним ресурсам компании (корпоративной базе дан-
зывание с glibc. Встречаться с таковыми (кроме низкоуров- ных). Можно... да мало ли чего можно придумать, имея не-
невых системных утилит) автору не приходилось. Кроме обходимые знания и смекалку! Дерзайте!
того, значение переменной LD_PRELOAD обрабатывается Автор выражает благодарность Максиму Артемьеву за
особым образом для исполняемых файлов, имеющих бит ценные замечания, высказанные в ходе обсуждения дан-
SUID. Среди клиентских (настольных) приложений они, как ной статьи.
правило, не встречаются. Òàáëèöà 1. Íåêîòîðûå ìåòîäû SOCKS-àóòåíòèôèêàöèè
Любая ли программа поддается соксификации описан-
ными выше методами? Как легко видеть по ходу рассужде-
ния, нет. Процедура внедрения кода Windows-соксифика-
тора в чужой процесс может не сработать, если исполняе-
мый файл имеет особую структуру, например, он сжат ори-
гинальным образом или зашифрован. Кроме этого, пользо-
вательские SOCKS-аналоги должны максимально точно Полный вариант таблицы можно найти по адресу: http://
повторять поведение (в том числе эмулировать недокумен- www.iana.org/assignments/socks-methods.

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

СТРОИМ ВИРТУАЛЬНУЮ СЕТЬ С TINC

СЕРГЕЙ ЯРЕМЧУК
Когда зарождались протоколы, используемые в сегодняш- личной инициативой администратора, которому надоели по-
нем Интернете, никто и не думал о том, что спустя некото- стоянно возникающие проблемы. Да и отношение к бес-
рое время к нему без проблем смогут подключаться мил- платному софту как к некачественному, второсортному по-
лионы пользователей, а компании будут вести свой бизнес степенно проходит. Большая часть свободных утилит для
с его помощью. Со временем начали всплывать просчеты создания VPN доступна только под UNIX, и если админист-
создателей и постепенно стали появляться проекты, основ- ратор до этого не работал с такими системами, то у него не
ная цель которых – минимизировать допущенные ошибки. сразу получится разобраться с настройкой софта. Также
Сегодня после антивирусов и межсетевых экранов наибо- не все проекты имеют реализации для различных опера-
лее популярным и востребованным средством являются ционных систем. Выход один – нужен удобный, простой и в
виртуальные частные сети (Virtual Private Network – VPN), то же время функциональный инструмент. Основной идеей
которые, несмотря на первоначальную возню с установкой проекта tinc (сокращение от There Is No Cabal) как раз и
и отладкой, все-таки делают жизнь админа спокойнее и уп- является простота настройки VPN-сети.
рощают настройку многих сетевых сервисов.
Хотя на рынке присутствует большое количество ком- Что может tinc?
мерческих продуктов, имеющих в том числе и аппаратные Особенностью tinc является использование одного испол-
решения, большой интерес вызывают именно свободные няемого файла – демона tincd, который является одновре-
проекты. Причин много. Так, не сразу становится ясно, по- менно и сервером, и клиентом. Какие преимущества это
дойдет ли конкретной организации схема сети с VPN, а вкла- дает? В tinc подключить новый компьютер в уже работаю-
дывать деньги эксперимента ради вряд ли кто рискнет. С щую виртуальную сеть довольно легко, для этого необхо-
другой стороны, очень часто переход сети на VPN является димо добавить всего лишь один файл, без запуска нового

№2, февраль 2005 39


администрирование
демона или еще одного виртуального сетевого устройства. которых процесс настройки диаметрально отличается. Одна
Удаленные компьютеры могут обмениваться информаци- построена на базе Linux, в качестве платформы для второй
ей между собой, по прямому каналу, а не через основной выбрана Windows XP. При этом в BSD и Solaris процесс на-
сервер, как это реализовано в том же vtun. В vtun для об- стройки совсем немного отличается от Linux и, зная осо-
мена напрямую придется создавать еще один туннель, что бенности работы сетевых сервисов в этих системах и уло-
при большом количестве клиентов затрудняет настройку. вив смысл производимых действий, установить tinc в них
Хотя возможен запуск и нескольких экземпляров tinc на труда особого не составит.
одном компьютере, что позволяет создавать несколько вир-
туальных сетей. При этом демон самостоятельно осуще- Особенности установки tinc в Linux
ствляет маршрутизацию и направляет пакеты по назначе- Система tinc использует для работы универсальные драй-
нию кратчайшим путем. веры tun и tap. Tun применяется при туннелировании IP-
Процесс обработки информации происходит в user space пакетов, а tap, он же ethertap, – при туннелировании фрей-
и не требует обязательной перекомпиляции ядра. Принято мов Ethernet. Драйвер TUN/TAP позволяет пользовательс-
считать, что такие реализации работают медленнее и на- ким программам самостоятельно обрабатывать соответ-
гружают систему больше, но я, признаюсь, дотошных тес- ствующие пакеты. Поэтому эти устройства должны быть
тов не видел, а работа VPN зависит от многих обстоя- включены при конфигурировании ядра. В большинстве ди-
тельств, среди которых и используемое оборудование, ка- стрибутивов это уже сделано, но если команды:
нал, общая нагрузка на сеть, поэтому вряд ли можно гово-
рить о полном и безоговорочном преимуществе VPN-сис- # ls -al /dev/net/tun
тем, встроенных в ядро, все зависит от конкретной обста-
новки. Но вот устанавливать user space-реализации про- и
ще, хотя после включения IPSec в ядра серии 2.6 некото-
рые вопросы по настройке отпали сами по себе. # ls -al /dev/tap*
Также tinc способен создавать мост для Ethernet-сегмен-
тов и соединять несколько сетей в одну, позволяя, напри- ничего не выводят, то либо придется их создать самому, либо
мер, использовать программы, нормально работающие поручить это системе, прописав в файле /etc/modules.conf
только по LAN. На сегодняшний день поддерживаются опе- строку (для ядер 2.4.0 и выше):
рационные системы Linux, FreeBSD, OpenBSD, NetBSD,
MacOS/X, Solaris, Windows 2000 и XP. alias char-major-10-200 tun
На момент написания статьи последней версией была
1.0.3, которую и рекомендуется использовать. В более ран- После обновления зависимостей модуля ядра командой:
них версиях были обнаружены серьезные проблемы с безо-
пасностью, заключающиеся в отсутствии порядковых номе- # /sbin/depmod –a
ров и опознавательного кода сообщения для каждого паке-
та, что позволяло производить атаку на отказ в обслужива- вы должны увидеть необходимые устройства. Более под-
нии, повторно запуская старые пакеты. Устранение этого не- робно это все описано в файлах tuntap.txt и ethertap.txt, ко-
достатка привело к тому, что более новые версии програм- торые находятся в каталоге /usr/src/linux/Documentation/
мы несовместимы со старыми, которые к тому же имеют networking (при установленных исходниках ядра). Иначе при-
реализацию не для всех платформ. Хотя криптография на дется ядро все-таки пересобирать, включив следующие
месте не стоит и на сегодняшний день считается, что исполь- строки.
зование 32 бит для порядковых номеров и 4 бит, используе-
мых по умолчанию для кода аутентификации сообщения Code maturity level options
[*] Prompt for development and/or incomplete code/drivers
(message authentication code – MAC), является уже недоста- Network device support
точным. Поэтому в конфигурации по умолчанию tinc менее <M> Universal tun/tap device driver support
защищен чем TLS или IPsec, а полностью переработать tinc
разработчики планируют к версии 2.0. Я раньше думал, что Для шифрования трафика используется OpenSSL (http://
самым простым в настройке и использовании является vtun www.openssl.org), и для сжатия потока в системе должны
(http://vtun.sourceforge.net), но после знакомства с героем быть установлены библиотеки zlib (http://www.gzip.org/zlib)
сегодняшней статьи свое мнение пересмотрел. и lzo (http://www.oberhumer.com/opensource/lzo). При этом
zlib является опциональной и используется для сжатия UDP-
Установка tinc пакетов, а вот наличие lzo в системе обязательно, иначе
Разработчиками взят курс на упрощение процесса установ- получите ошибку при конфигурировании. В ближайшем бу-
ки и настройки систем на базе tinc, да и документации на дущем планируется избавить пользователя от поиска про-
сайте хотя и сравнительно немного, но в ней отражены прак- грамм для удовлетворения всех зависимостей, собрав все
тически все основные вопросы, которые могут возникнуть необходимое в единый архив.
при настройке tinc, в том числе и особенности установки в После того как все библиотеки установлены, берем с
различных операционных системах. Поэтому рассказывать сайта проекта http://www.tinc-vpn.org бинарные пакеты,
обо всех возможных вариантах смысла, думаю, нет. Оста- скомпилированные под используемую операционную сис-
новлюсь на установке VPN между двумя системами, для тему, либо исходные тексты. Размер архивов не превыша-

40
администрирование
ет 600 Кб. Установка из исходников обычно проблем не и остановки сетевых VPN-интерфейсов (для UNIX-систем),
вызывает и заключается в стандартном ./configure, make и и в отдельном файле (rsa_key.priv) находятся закрытые клю-
make install. После чего в /usr/local/bin появится всего один чи сервера. В подкаталоге doc-архива с исходными текста-
бинарный файл tincd. ми программы находится архив sample-config.tar.gz, содер-
жащий примеры конфигурационных файлов. По умолчанию
Установка под Windows демон tincd будет искать свои конфигурационные файлы в
Демон tinc в этой операционной системе использует драйвер каталоге /usr/local/etc/tinc/, если вы решили положить их,
TAP-Win32, который можно взять с сайта OpenVPN (http:// например, в /etc/tinc/, то при запуске необходимо будет до-
openvpn.sourceforge.net). Этот драйвер в настоящее время полнительно использовать опцию --config=/etc/tinc/.
включен в последнюю версию пакета 1.0.3 для Windows и
устанавливается вместе с tinc (рис. 1), поэтому отдельно ус-
танавливать его уже не надо. Также для запуска демона по-
надобится наличие Cygwin (http://www.cygwin.com) или MinGW
(http://www.mingw.org). Со второй работать не пробовал, а вот
при работе через Cygwin потребуется только cygwin.dll.

Ðèñóíîê 3

Ðèñóíîê 1
После установки всех необходимых библиотек и tinc, за-
ходим в каталог C:\Program Files\tinc\tap-win32 и запускаем
файл addtap.bat. Теперь в меню «Сетевые подключения»
должно появиться новое соединение, которому можно при-
своить более осмысленное имя.

Ðèñóíîê 4
Для одной виртуальной сети такого расположения фай-
лов вполне достаточно, но если планируется организация на
Ðèñóíîê 2 компьютере нескольких виртуальных сетей, то для каждой
Выбираем «Свойства → Протокол Интернета TCP/IP» и необходимо будет создать подкаталог, выбрав в качестве его
редактируем его параметры, в которых указываем адрес и имени название VPN-сети. Например, для виртуальной сети
сетевую маску компьютера в виртуальной сети (рис. 3). vpn_net создаем каталог /usr/local/etc/tinc/vpn_net/. Теперь
В последней версии tinc сам прописывает себя в авто- при запуске демона tincd при помощи опции –n vpn_net ука-
матически запускаемые сервисы после первого успешного зываем название нужной виртуальной сети, в логах инфор-
запуска, но на всякий случай проверьте его наличие в ме- мация о ней будет отображаться как tinc.vpn_net. В создан-
ню «Настройка → Панель Управления → Администрирова- ном подкаталоге должны обязательно лежать два скрипта
ние → Службы» (рис. 4). tinc-up и tinc-down, в которых описываются команды для се-
тевого интерфейса. Для Linux эти файлы выглядят так.
Конфигурационные файлы tinc
Tinc во время своей работы использует два вида конфигу- Ôàéë tinc-up
рационных файлов, плюс в двух скриптах записываются си- #!/bin/sh
стемно-зависимые параметры, необходимые для поднятия ifconfig $INTERFACE 192.168.10.1 netmask 255.255.0.0

№2, февраль 2005 41


администрирование
Ôàéë tinc-down. метры нет необходимости, в самом общем случае файл
#!/bin/sh будет выглядеть так:
ifconfig $INTERFACE down

Естественно, что для других UNIX-подобных систем эти # Sample tinc configuration file
Name = office
строки будут немного другими, подробности смотрите в tinc ConnectTo = home
Manual. Раздел 7. «Platform specific information». Для Windows ConnectTo = stock-room
Device = /dev/net/tun
эти файлы не требуются.
Для работы в UNIX-подобных системах желательно на- То есть демон, носящий имя office, будет пытаться со-
личие в файле /etc/services следующих строк. единиться с двумя компьютерами home и stock-room, описа-
ние которых находится в одноименных файлах, лежащих в
tinc 655/tcp TINC подкаталоге hosts. В Windows вместо Device удобнее исполь-
tinc 655/udp TINC
зовать параметр Interface, т.е. файл будет выглядеть так:
И в /etc/networks должно быть указано символическое
имя будущей VPN. Name = home
ConnectTo = office
ConnectTo = stock-room
vpn_net 192.168.10.0 Interface = VPN

Как говорилось выше, tincd является одновременно как В случае если VPN-интерфейсов два, нужно написать
клиентом, так и сервером. За счет этого существенно уп- Interface = VPN2 и назвать его так в «Сетевых подключени-
рощена настройка системы, а также дальнейшее наращи- ях».
вание сети в любом направлении. Все опции, которые можно использовать в файле опи-
Для работы серверной части демона используется файл сания удаленного узла, приведены в таблице 2. В простей-
tinc.conf, в нем клиенты, с которыми должен соединяться шем файл home будет выглядеть так:
сервер, определяются параметром ConnectTo и более под-
робно описываются отдельным файлом, лежащим тут же в # Sample host configuration file
Address = 10.10.1.67
подкаталоге hosts и имеющим такое же название, как и в Port = 655
опции ConnectTo. При этом на противоположной стороне Subnet = 192.168.10.0/24
-----BEGIN RSA PUBLIC KEY-----
можно прописать встречное соединение, указав параметр ...
ConnectTo, демоны на этих системах не передерутся за то, -----END RSA PUBLIC KEY-----
кто из них самый главный, но таким образом можно спо-
койно наращивать в дальнейшем виртуальную сеть, не за- Так как в Windows все параметры задаются при настрой-
ботясь о конфликтах. Все параметры файла tinc.conf при- ке сетевого соединения, то в файле клиентов достаточно
ведены в таблице 1. Использовать все приведенные пара- только секции Subnet.
Òàáëèöà 1. Ïàðàìåòðû, êîòîðûå ìîãóò áûòü èñïîëüçîâàíû â ôàéëå tinc.conf

42
администрирование
Но кроме правильно описанных параметров в конфигу- все необходимые каталоги, либо указать новое место для
рационных файлах, для нормальной работы всей системы pid-файла, использовав опцию --pidfile=/path/to/file.
необходимо наличие пары ключей, при помощи которых бу- После этого узлы должны соединиться между собой и
дет происходить закрытие информации. Для генерации клю- образовать единый канал. Для контроля можно проверить
чей запускается демон с ключом -К, а если на компьютере наличие необходимых интерфейсов командами ifconfig -a
запускается несколько виртуальных сетей, то добавляется (ipconfig для Windows) и просмотреть открытые порты при
опция -n. Например, на компьютере office, выполняем та- помощи netstat -a.
кую команду:

# tincd –K -n vpn_net
Generating 1024 bits keys:
............++++++ p
.........++++++ q
Done.
Appending key to existing contents.
Make sure only one key is stored in the file.

При этом по умолчанию закрытый ключ будет записан в


файл /usr/local/etc/tinc/vpn_net /rsa_key.priv, а открытый ключ
в файл /usr/local/etc/tinc/vpn_net/hosts/office. Для Windows
это будет естественно немного другой путь, C:\Program Files\
tinc\vpn_net\rsa_key.priv, а открытый – C:\Program Files\
tinc\vpn_net\hosts\home.
Отсюда наиболее оптимальным будет такой вариант
настройки виртуальной сети. На каждом узле создается Ðèñóíîê 5
свой host-файл, в который кроме параметров записывает- Для выявления возможных ошибок могут пригодиться
ся и открытый ключ. А затем администраторы обменива- дополнительные параметры запуска. Опция --logfile[=file]
ются этими файлами между собой и подключают опцией указывает на необходимость ведения журнала (по умолча-
ConnectTo. Теперь, когда все настроено, можно пробовать нию запись будет вестись в /usr/local/var/log/tinc.netname.log),
запустить демон. опция --debug задает уровень отладочных сообщений (0-5)
и --bypass-security отключает шифрование.
# tincd -n vpn_net Вот в принципе и все. Несмотря на то, что написано
много, настройка сервиса на отдельном компьютере не за-
Скорее всего, при первом запуске выскочит такая ошиб- нимает времени больше 10-15 минут. Со временем разра-
ка. ботчики собираются интегрировать все приложения, от ко-
торых зависит работа tinc, в единый пакет, что еще больше
Could write pid file /usr/local/var/run/tinc.vpn_net.pid: должно упростить установку. А так tinc представляет собой
No such file or directory
довольно удобный, гибкий и простой инструмент, позволя-
Означающая, что демон не может найти файл tinc.vpn_ ющий быстро создавать и легко наращивать виртуальные
net.pid. Вероятной причиной появления такого сообщения сети, доступный к тому же для всех популярных сегодня
является отсутствие нужных каталогов. Выход: либо создать операционных систем.
Òàáëèöà 2. Ïàðàìåòðû ôàéëà îïèñàíèÿ êëèåíòîâ

№2, февраль 2005 43


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

FreeBSD TIPS: NAT ПО СТАРИНКЕ

СЕРГЕЙ СУПРУНОВ
В наши дни, когда свободных IP-адресов становится все мень- ется адресом NAT-сервера (он должен быть «реальным», то
ше и меньше, трансляция сетевых адресов (Network Address есть входить в диапазон адресов, предоставленный вам про-
Translation – NAT) становится все более актуальной. Трудно вайдером). В отличие от прокси-серверов, которые берут на
найти провайдера, который, не сопротивляясь, даст вам нуж- себя обработку запросов в соответствии с тем или иным про-
ное количество реальных адресов. Наиболее типичная ситу- токолом, сервер NAT просто заменяет адрес и, как правило,
ация – когда в «комплекте» с подключением к сети Интер- порт отправителя (или получателя). Он не пытается разби-
нет выделяется один-единственный IP-адрес. В результате раться в сути передаваемых данных, и благодаря этому ис-
внутреннюю сеть приходится строить на одной из приват- пользование NAT не ограничено списком поддерживаемых
ных подсетей (что это такое, мы рассмотрим немного поз- протоколов.
же), и эти «левые», как их называют в народе, адреса нужно Говоря упрощенно, NAT работает так: клиент, имеющий
каким-то образом транслировать в тот единственный реаль- адрес «A», отправляет через порт «a» пакет на некоторый
ный, данный провайдером. Cразу стоит указать и на опреде- удаленный сервер. Этот пакет заворачивается (пока не бу-
ленное преимущество такого подхода – в большинстве слу- дем уточнять, как именно) на сервер NAT, который вместо
чаев локальная сеть становится невидимой снаружи, то есть адреса «A» подставляет свой адрес «B» и отправляет этот
любой внешний хост может общаться только с сервером NAT, пакет уже от своего имени через порт «b». Одновременно с
ничего не подозревая о наличии (не говоря уже о структуре) этим в памяти сервера делается запись о выполненной под-
вашей внутренней сети. В данной статье будет показано, как становке, чтобы при получении ответного пакета на порт «b»
настроить NAT-сервер на базе FreeBSD. В качестве инстру- знать, на кого из клиентов его пересылать. Описанная схе-
мента будет использоваться демон natd в связке с ipfw. В ма работы носит название «маскарадинг» (masquarading).
современных версиях системы такая схема считается не са- Помимо маскарадинга существуют также понятия SNAT
мой лучшей в плане гибкости и нагрузки на систему, и более и DNAT (особенно хорошо известные пользователям Linux).
предпочтительным является вариант на базе IPFilter – ipnat Первый из них (Source NAT) отвечает за преобразования ад-
(этот NAT будет рассмотрен в одной из следующих статей). реса-источника и во многом подобен маскарадингу, с тем
Тем не менее старый добрый natd до сих пор честно служит исключением, что работает только со статическими адреса-
на просторах Сети, и оставлять его без внимания было бы, ми источников, и потому менее требователен к ресурсам.
по меньшей мере, невежливо. DNAT (Destination NAT) осуществляет преобразование адре-
Сначала – немного теории. Как известно, в сети Интер- са назначения, что используется для проброса внешних со-
нет каждый хост, взаимодействующий с другими, должен единений, приходящих на конкретный порт (например, 80-й)
иметь уникальный IP-адрес, по которому он и распознает- на внутренние хосты, не имеющие реального адреса. Об-
ся. Несколько сетей (10.0.0.0/8, 172.16.0.0/12 и 192.168.0.0/ щий случай DNAT – статический NAT, когда все внешние
16) выделяются в так называемый «нерегистрируемый» ди- соединения, поступающие на указанный адрес, перенап-
апазон, то есть они могут использоваться для нужд внут- равляются на внутренний хост.
ренних сетей без какой-либо регистрации. Эти адреса име- Более полную информацию по технологии NAT можно
нуют также приватными, или «серыми». Чтобы избежать найти в Интернете, а сейчас приступим к рассмотрению
конфликтов адресов в глобальной сети, пакеты с такими natd. Эта программа включена в систему FreeBSD, и пото-
адресами не должны выходить за пределы шлюза, ограни- му никакая инсталляция не требуется. Перед началом ее
чивающего соответствующую внутреннюю сеть. Поэтому использования должно быть выполнено следующее:
такие адреса иногда называют немаршрутизируемыми (хотя ! Ядро должно быть собрано с опциями IPFIREWALL и
внутри локальной сети они замечательно маршрутизиру- IPDIVERT – это необходимо для перенаправления паке-
ются). Вообще нужно заметить, что деление на реальные и тов на сервер natd.
приватные весьма условно. Я, например, учитывая дефи- ! Должна быть включена маршрутизация между интер-
цит «настоящих» адресов, выданных на наш узел, широко фейсами, что можно сделать, добавив в /etc/rc.conf сле-
практикую раздачу клиентам адресов из сети 192.168.x.x, дующую опцию: «gateway_enable=YES».
«пряча» их за NAT. Таким образом, с точки зрения клиента ! Должен быть разрешен брандмауэр опцией «firewall_
эти адреса будут реальными. enable=YES» в том же rc.conf.
Суть NAT заключается в том, что в процессе преобразо-
вания адрес отправителя (который может быть любым, в том Теперь можно запускать и сам сервер. Как было сказа-
числе принадлежать немаршрутизируемой подсети) заменя- но выше, пакеты, нуждающиеся в трансляции адреса, дол-

44
администрирование
жны быть перенаправлены на сервер NAT. При использо- этого можно использовать опцию -same_ports, однако не
вании natd это выполняется с помощью правила divert бран- забывайте, что при этом NAT не обязуется сохранять но-
дмауэра ipfw. Например, чтобы вывести в Интернет внут- мер порта, а будет делать это по возможности. То есть в
реннюю сеть 192.168.0.0/24, имея один реальный адрес принципе порт может и поменяться (например, если нуж-
190.190.190.190 на интерфейсе ed0, «смотрящем» наружу, ный номер уже используется другим соединением, NAT «за-
нужно сделать следующее: будет» про ключ -same_ports и будет работать как обычно).
! Запустить сервер natd (ключ -interface означает, что в Если natd запущен с опцией -interface, то есть привязы-
качестве внешнего адреса будет использоваться адрес вается к адресу конкретного интерфейса, то при измене-
указанного интерфейса): нии IP-адреса интерфейса IP-адрес, используемый демо-
ном natd, останется прежним. Чтобы NAT отслеживал и ав-
# natd –interface ed0 томатически учитывал изменения IP-адреса интерфейса,
используется опция -dynamic.
! Перенаправить на демон natd пакеты, адресованные с Опция -unregistered_only указывает, что NAT должен об-
внутренних адресов во внешнюю сеть, то есть нуждаю- рабатывать только пакеты, адрес источника которых вхо-
щиеся в трансляции: дит в указанные выше «нерегистрируемые» сети.
Ключи -redirect_port, -redirect_proto и -redirect_address слу-
# ipfw add 100 divert natd ip from 192.168.0.0 ↵ жат для реализации «проброса» внешних соединений на
to any out via ed0
внутренний адрес в зависимости от номера порта, протоко-
! Завернуть на NAT входящие пакеты, адресованные не- ла или адреса назначения входящих пакетов соответствен-
посредственно на внешний интерфейс (поскольку имен- но. Например, если во внутренней сети имеется HTTP-сер-
но сюда будут приходить ответы): вер 192.168.0.125, к которому нужно предоставить доступ
снаружи, это можно сделать с помощью опции «-redirect_port
# ipfw add 110 divert natd ip from ↵ tcp 192.168.0.125:80 80».
any to 190.190.190.190 in via ed0
Все опции можно вынести в конфигурационный файл,
В результате произойдет следующее: демон natd запус- где в каждой строчке указывается одна опция с парамет-
тится с параметрами по умолчанию, то есть будет ждать па- рами либо с пометкой «yes / no» для непараметрических
кеты на порту 8668 и в качестве внешнего IP-адреса исполь- опций. При запуске natd этот файл следует указать с помо-
зовать адрес указанного интерфейса, в данном случае – ed0. щью опции -config.
Отправленные клиентами пакеты ipfw будет заворачивать на Теперь, чтобы natd запускался автоматически при старте
порт 8668 (в /etc/services для него задано имя natd, поэтому системы, в /etc/rc.conf можно указать следующие строки (по-
можно использовать и его). Сервер NAT отправит эти паке- казан конкретный пример):
ты по адресу назначения, но уже с адреса 190.190.190.190.
Получив пакеты в ответ, NAT перенаправит их клиенту. natd_enable = “YES”
natd_interface = “ed0”
Если вы хотите использовать в качестве внешнего адре- natd_flags = “-config /etc/natd.conf”
са какой-то другой, вместо ключа -interface при запуске сер-
вера следует использовать опцию -alias_address с указани- При этом параметр «natd_interface» при запуске демо-
ем нужного адреса в качестве параметра. Какая-то из этих на natd «превратится» в параметр -nterface, остальные па-
опций должна быть задана обязательно, но не обе одновре- раметры можно задать в строке natd_flags. Обычно здесь
менно. указывается только путь к конфигурационному файлу, в ко-
Дополнительно при запуске natd может быть задано до- торый выносятся все остальные настройки.
статочно большое количество опций, получить информа- Ну и как обычно – если режим работы сервера позволя-
цию по которым можно на страницах руководства man natd. ет перезагрузку, то лучше это сделать, чтобы лишний раз
Здесь рассмотрим только наиболее интересные. убедиться в правильности всех настроек и отсутствии опе-
Например, можно задавать отличный от используемого чаток в конфигурационных файлах.
по умолчанию номер divert-порта, с которым будет связан В заключение отмечу несколько недостатков natd. Преж-
сервер natd. Для этого предназначен ключ -port <port>. Это де всего это все-таки демон, и, следовательно, по произво-
свойство часто используется, если необходимо запустить дительности он несколько проигрывает тому же ipnat, кото-
несколько демонов natd. К сожалению, этот инструмент мо- рый более тесно интегрирован с ядром. Реализация слож-
жет обрабатывать пакеты только в соответствии с одним ной политики предоставления доступа в Интернет, диффе-
правилом. Поэтому, если вам нужно использовать свои па- ренцированная по различным группам пользователей, мо-
раметры для различных клиентов, приходится запускать от- жет потребовать запуска нескольких демонов natd, что че-
дельные демоны на разных для каждой группы клиентов рез rc.conf уже не получится, и потребуется писать свой стар-
портах. Соответственно, в правилах ipfw перенаправление товый сценарий.
должно выполняться на те же порты, которые связаны с natd. Тем не менее в большинстве случаев natd вполне справ-
Кроме того, с помощью опций -in_port и -out_port можно за- ляется с возложенными на него обязанностями, и если в си-
давать отдельные порты для входящих и исходящих паке- стеме уже работает ipfw, то такая схема может оказаться наи-
тов соответственно. более простым способом построения NAT-сервера. Допол-
Иногда может быть полезно, чтобы NAT пересылал па- нительная информация, как обычно, в man natd(8), divert(4),
кеты с того же порта, с которого их отправлял клиент. Для rc.conf(5), ipfw(8).

№2, февраль 2005 45


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

ВСЕГДА НА СВЯЗИ,
ИЛИ IP-РОУМИНГ: ВВОДНЫЙ КУРС

СЕРГЕЙ ЯРЕМЧУК
Сегодняшний мир – мир мобильности. Действительно, для пьютеры в Интернете, абсолютно прозрачную для прило-
того чтобы быть в курсе событий уже не надо находиться жений и протоколов более высокого уровня вроде TCP. В
на одном месте. Те, кто пользуется мобильными устрой- схеме, предлагаемой RFC 3344, компьютер всегда иденти-
ствами, имеют большие возможности по выбору каналов фицируется своим домашним адресом, независимо от те-
для доступа в Интернет – встроенный модем, Ethernet, Wi-Fi, кущей точки доступа в Интернет, хотя, естественно, в но-
GPRS и пр. Чтобы оценить прогресс в этой области, доста- вой точке и получает новый адрес. Протокол предоставля-
точно вспомнить изменения, произошедшие в обычной те- ет заботу о регистрации нового адреса домашнему агенту
лефонной связи с появлением сотовой. Сегодня пользова- (Home Agent – HA). Такой агент распознает сеансы связи,
тели мобильных сетей третьего поколения могут просмат- заботится об их сохранении и пересылает датаграммы,
ривать фильмы из Интернета прямо на своем телефоне. предназначенные мобильному компьютеру (mobile node –
Пользователи мобильных компьютеров также хотят пользо- MN) на его новый адрес, используя специальный IP-туннель.
ваться Интернетом всегда и везде, однако поход за «на- При этом, когда MN находится в домашней сети, обмен про-
стоящей мобильностью» еще только начинается. В неда- исходит обычным образом. Однако когда компьютер пере-
леком будущем планируется покрыть беспроводными се- мещается в другую сеть и получает новый IP-адрес (его
тями целые города. Не надо путать настоящую мобильную называют «care-of»-адресом), он сообщает последний сво-
работу с тем, что мы имеем сегодня. В настоящей мобиль- ему HA, который в свою очередь подтверждает или откло-
ной сети активные сеансы не прерываются, когда пользо- няет регистрацию. «Care-of»-адрес может быть получен
ватель меняет точку доступа в Интернет. Все необходимые различными методами. В общем случае его выдает «по-
переключения производятся автоматически, подобно тому, сторонний агент» (Foreign Agent – FA). При этом различают
как это происходит при перемещении абонента мобильной два альтернативных способа выдачи такого адреса. В пер-
телефонной связи от одной соты к другой. Конечно, между вой схеме, известной как «foreign agent care-of address»,
мобильной связью и TCP-сеансами существует множество «care-of»-адрес является IP-адресом FA, который и поддер-
отличий, однако с ростом популярности различных видов живает один из концов IP-туннеля (другой конец в любом
мобильных компьютеров возможность подобного «IP-роу- случае принадлежит HA). Получив информацию из тунне-
минга» быстро найдет свое применение. ля, FA декапсулирует пакет, после чего передает его в сеть,
Основная проблема состоит в том, что один и тот же где он подхватывается мобильным компьютером. Второй
компьютер в различное время имеет разный IP-адрес, что способ, «co-located care-of address», заключается в выдаче
не вполне соответствует понятию «настоящая мобиль- «care-of»-адреса непосредственно мобильному компьюте-
ность», поскольку применяемые сейчас протоколы опреде- ру. В этом случае MN является конечной точкой туннеля и
ляют место назначения пакетов на основе IP-адресов, ко- сам занимается декапсуляцией пакетов. Агенты Foreign Agent
торые привязываются к конкретному сетевому интерфей- и Home Agent сообщают о своем присутствии посредством
су. Для наиболее популярного в Интернете транспортного сообщений «Agent Advertisement». При необходимости мо-
протокола TCP сеанс идентифицируется четырьмя парамет- бильный узел может сам дополнительно попросить такое
рами: IP-адресом источника, IP-адресом приемника и дву- сообщение от локальных агентов, используя сообщение
мя номерами портов. Потеря любой из этих составляющих «Agent Solicitation». Сообщения «Agent Solicitation» исполь-
ведет к прекращению сеанса. Поэтому все изменения то- зуются для определения маршрутизатора в новой сети и
чек прикрепления, а значит, и IP-адресов после перехода в обнаружения любых изменений в установках FA. По отве-
другую сеть ведут к неизбежным потерям активных связей, там на эти сообщения MN определяет, где он находится – в
а значит, и к отсутствию мобильности как таковой. Данная своей домашней сети или в чужой. При возврате мобильно-
проблема не могла остаться незамеченной, и на сегодняш- го узла из внешней сети в домашнюю он отменяет внешнюю
ний момент уже существуют технологии, позволяющие зак- регистрацию у домашнего агента посредством пары сооб-
репить за компьютером постоянный IP-адрес. Первые офи- щений «Registration Request» и «Registration Reply». Таким
циальные документы по этой теме датированы октябрем образом, сообщения «Agent Advertisement» преследуют не-
1996 года: RFC 2002 «IP Mobility Support». Последний и пока сколько целей: обнаружение мобильных компьютеров, вы-
окончательный вариант «IP Mobility Support for IPv4» извес- дачу «care-of»- адресов, назначение новых параметров мар-
тен под номером 3344 и датирован августом 2002 года. В шрутизации, информирование мобильного компьютера об
этом документе определены расширения протокола, допус- особенностях работы FA (например, наличии альтернатив-
кающие маршрутизацию IP-датаграмм на мобильные ком- ных методов инкапсуляции).

46
администрирование
Информация, отправленная на домашний адрес мобиль- всех систем, либо унифицировать оборудование в отдель-
ного узла, перехватывается домашним агентом и переправ- но взятой организации, что не всегда приемлемо и возмож-
ляется по туннелю на «care-of»-адрес либо через FA, кото- но. Опять же убедить провайдера или системного админи-
рый в свою очередь зная, где сейчас MN, передает инфор- стратора в установке постороннего ПО или устройства не
мацию ему (схема «foreign agent care-of address»), либо не- всегда удается, поэтому говорить о глобальной мобильно-
посредственно к MN. Для успешной доставки требуется, что- сти пока еще рано, а вот в отдельной компании все выше-
бы «care-of»-адрес выступал в качестве адреса назначе- описанное вполне возможно.
ния каждого из пакетов. Когда пакет приходит на «care-of»-
адрес, происходит обратное преобразование, и пакет сно- Проект TMIP
ва в качестве адреса назначения получает домашний ад- Другой весьма интересной альтернативой Mobile IP являют-
рес мобильного узла. Так как служебная информация для ся разработки открытого проекта TMIP (Transparent Mobile
протоколов более высокого уровня остается постоянной, то IP). С их помощью каждый мобильный узел с произвольным
все активные сеансы начатые, например, в домашней сети, внешним IP-адресом также будет всегда идентифицировать-
не будут разорваны. В обратном направлении информация ся по одному домашнему IP-адресу, который не будет зави-
проходит обычным путем, используя стандартные механиз- сеть от местоположения компьютера. Кроме этого, TMIP га-
мы IP-маршрутизации и не обязательно затрагивая домаш- рантирует, что все активные сеансы TCP не будут разорва-
него агента. В качестве IP-адреса приемника выступает ны при перемещении. Отличие этого проекта от Mobile IP
адрес узла, с которым в данный момент установлено со- состоит в том, что на стороне клиента не применяется ника-
единение, а в качестве адреса источника – домашний ад- кого дополнительного программного обеспечения, а также
рес компьютера, т.е. HA. При отправлении, как и при при- не происходит вмешательства в структуру IP-стека. Для обес-
еме пакета, MN может сам заниматься отправкой или де- печения связей между узлами, сеть сама изменяется, исполь-
лать это через FA. При перемещении MN он снова регист- зуя технику IP-туннелей. Сеть TMIP состоит из одного-двух
рируется у нового FA, после чего информация направляет- реестров Mobile Location Register (MLR), нескольких коррес-
ся по новому «care-of»-адресу. Некоторые реализации по- пондентских узлов (Correspondent Nodes – CN) и мобиль-
зволяют назначить мобильному компьютеру сразу несколь- ных клиентских станций (Mobile Station – MS). MLR пред-
ко «care-of»-адресов, в этом случае HA пересылает инфор- назначен для руководства клиентами (точнее, их Ethernet
мацию по всем известным ему адресам. Такой подход мо- MAC-адресами), выяснения текущей позиции в сети и рас-
жет быть полезен при постоянном перемещении клиентов. пределения IP. Для этого MLR хранит в памяти местополо-
В течение последних лет стартовало несколько проек- жение всех клиентских станций. При обнаружении новой
тов, реализующих идею Mobile IP. К сожалению, большая станции он регистрирует ее, отмечая родительский и теку-
часть этих программ развивается не очень активно, и в ре- щий CN. Так как потеря этой информации критична, то, как
зультате готовые реализации можно найти только для ста- правило, применяется резервирование. Присоединением
рых ядер Linux версий 2.0 и 2.2. Среди этих проектов сле- мобильных узлов занимается CN. Происходит это так. Мо-
дует упомянуть Linux Mobile IP [1] и Mosquito Net Mobile IP бильный компьютер, находясь в одной из сетей, получает
[2]. Довольно неплохие наработки имеются у проекта IP-адрес при помощи интегрированного в CN сервера DHCP.
Dynamics Mobile IP [3]. Кроме ядер Linux версий 2.2 и 2.4, Когда узел мигрирует в другую сеть и попадает к новому
это приложение посредством Cygwin портировано и в CN, этот переход обнаруживается при помощи различных
Microsoft Windows (98SE, ME, NT4, 2000). К сожалению, с методов1, после чего новый CN вступает в контакт с исход-
осени 2001 года Dynamic Mobile IP больше не развивается. ным (родительским) CN (обслуживающим домашнюю сеть
Подход, заложенный в rfс 3344, имеет и недостатки. Са- узла) и, возможно, с предыдущим CN (обслуживающим
мые существенные среди них – это большое количество сеть, откуда узел только что ушел). Вся необходимая ин-
туннелей, серьезная нагрузка на домашнего агента, от ис- формация берется у MLR. На этом этапе возможна повтор-
правной работы которого, по сути, и зависит возможность ная аутентификация клиента, в результате которой разре-
реализации вышеописанной схемы и достижимость мобиль- шается или запрещается дальнейшая работа. В настоящий
ного узла. Эту проблему может решить централизованное момент она производится только на основе МАС-адресов.
управление всей системой, а не контроль за отдельными Абсолютно прозрачно, в пределах одной транзакции (в две
сеансами. В таком случае возможно резервирование ин- стадии) узел передается новому CN с обновленными пара-
формации. Кроме того, централизация позволит оптими- метрами сети и старым IP-адресом. При этом миграции
зировать связи, уменьшить количество туннелей, облегчит клиентов не влияют на таблицы маршрутизации конкрет-
управление и защиту. Но, наверное, самым большим недо- ного сегмента сети. Исходящие от мобильного узла пакеты
статком является необходимость использования дополни- достигают места назначения обычным путем. Учитывая, что
тельного программного обеспечения, декапсулирующего их исходный адрес не всегда соответствует текущему по-
пакеты и обеспечивающего взаимодействие с FA, на кли- ложению узла, родительский CN (при помощи MLR) узнает
ентских компьютерах, а также сам факт существования FA. текущую позицию узла (точку доступа) и пересылает от-
Учитывая сегодняшнее разнообразие операционных систем ветные пакеты нужному CN по туннелю. Последний в свою
и устройств, придется либо адаптировать программу для очередь передает их в локальную сеть, где они перехваты-

1
Например, по DHCP-запросу или попытке отослать информацию на старый шлюз, демонстрируя при этом «неродной» IP и незарегистри-
рованный MAC-адрес.

№2, февраль 2005 47


администрирование
ваются мобильным компьютером. При таком подходе мак- рационного файла с детальными описаниями настроек на-
симально возможное число туннелей, которые можно по- ходится в подкаталоге tmipd и называется tmipd.rc.
лучить, равняется n ∗ (n – 1), где n – общее число CN в сети.
# tmipd.rc
mlr primary.my-tmip-mobility.com
Установка и настройка TMIP cn_name wlan. primary.my-tmip-mobility
Основной сайт проекта расположен по адресу: http:// cn_if eth0
mobile_if wlan0
www.slyware.com/projects_tmip.shtml. Здесь можно найти до- # èëè êàê âàðèàíò
кументацию, а исходные тексты доступны с http://tmip.source #mobile_if eth0
network_name my-tmip-mobility
forge.net. Текущая версия утилиты – 0.14a, архив имеет имя # ñëåäóþùàÿ îïöèÿ ïîíàäîáèòñÿ ïðè çàïóñêå íåñêîëüêèõ êîïèé
tmip_0.14a_release.tar.gz. Как вариант можно использовать # CN íà îäíîì êîìïüþòåðå
# tunnel_prefix tmip
пре-релиз tmipcore_0.5a-pre.tar.gz. Из принципа работы си- # ðàçðåøèòü ðåãèñòðàöèþ òîëüêî çàíåñåííûõ â áàçó MLR-õîñòîâ
стемы TMIP следует, что настраивать необходимо один-два registered_only false
# ÷èñòêà òóííåëÿ ïðè çàïóñêå
MLR и несколько CN. Клиентские компьютеры не требуют purge_tunnels true
настроек, но для упрощения работы они должны получать # òàê êàê CN çàíèìàåòñÿ ðàñïðåäåëåíèåì àäðåñîâ,
# òî ðåàëèçîâàíà âîçìîæíîñòü çàäàíèÿ äèàïàçîíà
IP-адрес при помощи DHCP. MLR и CN должны работать под addr_pool wlan0 * *
управлением ОС Linux, в которой необходимо установить # èëè êàê âàðèàíò
# addr_pool eth1 10.10.15.32 +10.10.15.48
библиотеку libpcap и включить поддержку «IP: Tunneling» в dns_server 10.10.15.7
ядре (вкладка «Networking Options»). debug_level 2
log true
Рассмотрим процедуру установки TMIP. В первую оче- log_file /var/log/tmipd.log
редь распакуем полученный архив. Для компиляции MLR status_file /var/log/tmipd.status
foreground true
следует зайти в подкаталог mlrd и дать команду «make», а # pid_file /var/run/tmipd.pid
образовавшийся в итоге исполняемый файл mlrd скопиро- # íàñòðîéêà ñåðâåðà DHCP
enable_dhcp true
вать, например, в /usr/local/sbin. Аналогично поступаем с # domain_name my-tmip-mobility.com
CN, работа которого управляется при помощи демона tmipd. # dhcp_lease_time 300 # DHCP lease time in seconds
# âîçìîæíî èãíîðèðîâàíèå ïåðåìåùåíèÿ îòäåëüíûõ êëèåíòîâ
Для компиляции демона необходимо выполнить команду # ignore_mac aa:bb:cc:11:22:33
«make» в каталоге tmipd. Для работы первичного и вторич-
ного MLR-серверов необходимы два конфигурационных Для проверки работоспособности системы запустите:
файла. Первый, mlrd-primary.rc, может выглядеть так:
# /usr/local/sbin/tmipd -Ef tmipd.rc
# mlrd-primary.rc + Starting TMip Correspondent Node [v0.14a]
# CN äîëæíû èñïîëüçîâàòü àíàëîãè÷íîå èìÿ ñåòè
network_name my-tmip-mobility + Loading settings from configuration file...
port 6554 + Using mlrd.rc
foreground true
log_file /var/log/mlrd.log Network Connectivity Evaluation
status_file /var/log/mlrd.status ===============================
logtrue
#ñòðîêà íèæå óêàçûâàåò íà âòîðè÷íûé MLR-ñåðâåð + MLR @ 10.10.14.100: Passed.
cc_mlr secondary.my-tmip-mobility.com:5555 + CN @ 10.10.15.1 [Oakhurst directional]: Passed.
+ CN @ 10.10.16.1 [Si's room]: Passed.
Для вторичного сервера используется файл mlrd- + CN @ 10.10.17.1: Passed.
+ CN @ 10.10.18.1 [ECS Roof]: Passed.
secondary.rc.
Просмотрите полученные сообщения. Если все прошло
# mlrd-secondary.rc нормально, то каждый CN должен соединяться с MLR по
network_name my-tmip-mobility
port 5555 протоколу TCP, порт 6554 и обмениваться информацией с
foreground true остальными CN по порту 5554. После этого можно произ-
log_file /var/log/mlrd.log
status_file /var/log/mlrd.status вести запуск в рабочем режиме.
log true
grant primary.my-tmip-mobility.com # /usr/local/sbin/tmipd
После этого можно запустить mlrd. + Starting TMip Correspondent Node [v0.14a]

+ Loading settings from configuration file...


# /usr/local/sbin/mlrd -f mlrd-primary.rc + Using tmipd.rc
+ Starting MLR Server [v0.14a]
+ Switching into daemon mode (Logging to /var/log/tmipd.log)
+ Loading settings from configuration file...
+ Using mlrd-primary.rc Все сообщения об ошибках, регистрациях новых узлов
+ Switching into daemon mode (Logging to /var/log/mlrd.log) находятся в файле журнала.
Аналогично запускаем сервис и на вторичном MLR-сер-
вере. # cat /var/log/tmipd.log

# /usr/local/sbin/mlrd -f mlrd-secondary.rc Если включена опция «registered_only true», то в регис-


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

48
администрирование
-> Mobile station detected in my cell [00:0D:18:01:1C:05] вым экраном, так как настройки большинства провайде-
(via DHCP activity - Discover) ров исключают выход из сети пакетов с «неродным» IP-ад-
+ Establishing host's address allocation ресом. Было предложено несколько вариантов выхода из
+ [WARNING]: MLRP communications failure!
(Mobile host not registered in MLR) ситуации [16], самым простым из которых является обрат-
+ [WARNING]: Failure to bind host locally! ный туннель от HA. Кроме того, судя по сообщениям, ос-
новные поставщики маршрутизаторов уже имеют модели,
-> Ignoring host [00:0D:18:01:1C:05] for 600 second(s)
адаптированные под технологии Mobile IP.
Для регистрации компьютеров, просмотра записей и Проблема сохранения активных связей при перемеще-
обновления информации в MLR используется специализи- нии пользователей назревает уже давно. По мере увеличе-
рованный инструмент mlrp_query, компиляция которого про- ния количества мобильных пользователей она будет ста-
изводится в одноименном подкаталоге. Так, например, что- новиться более остро. Вероятнее всего, ни о какой глобаль-
бы привязать компьютер с МАС-адресом 00:0D:18:01:1C:05 ной мобильности в настоящее время не может быть и речи.
к CN 10.10.15.1 в MLR, находящемуся по адресу 10.10.15.100, К сожалению, текущие реализации протоколов и операци-
следует выполнить команду. онных систем просто не предусматривают этого. Наверное,
мобильность будет доступна только тем, кто использует для
# mlrp_query -M10.10.15.100 -A -m00:0D:18:01:1C:05 ↵ выхода в Интернет GPRS-модем. Вероятно, ситуацию мо-
-p10.10.15.1
жет изменить вмешательство в IP-стек, ведь только в этой
Кроме того, в настоящее время идет разработка веб-ин- ситуации будут работать системы защиты информации вро-
струмента, предназначенного для регистрации мобильных де VPN. Однако разработки проекта TMIP и других вполне
клиентов и вывода различной статистической информации. пригодны для использования на отдельно взятом предпри-
После произведенных настроек клиенты могут спокой- ятии и могут служить реальной заменой табличкам, изве-
но перемещаться по сетям. Единственной проблемой мо- щающим об окончании зоны действия той или иной точки
жет стать использование на компьютере сменных адапте- доступа. Поход за «настоящей мобильностью» еще только
ров (например, PCMCIA), которые имеют различный MAC- начинается!
адрес. Единственно возможным выходом в такой ситуации
будет подмена МАС-адреса. Ссылки:
1. Linux Mobile IP: http://gunpowder.stanford.edu/mip/index.html.
# /sbin/ifconfig wlan0 hw ether 00:0D:18:01:1C:05 2. Mosquito Net Mobile IP: http://mosquitonet.stanford.edu/
software/mip.html.
3. Dynamics Mobile IP: http://dynamics.sourceforge.net.
Проблемы Mobile IP 4. Проект SOWN (the Southampton Open Wireless Network:
Чтобы не создавать идеальную картину мобильного мира, http://www.sown.org.uk/index.php/TransparentMobility?
просто необходимо сказать пару слов и о проблемах. Ос- SESSID=6710e661be4e106c64143950e3dc04ea.
новной помехой при использовании Mobile IP являются за- 5. «An implementation of Mobile IP under Linux»: http://
щитные механизмы, так как реализовать подмену IP-адре- www.hpl.hp.com/personal/Jean_Tourrilhes/MobileIP/
сов не просто, а очень просто. Поэтому описанные выше схе- index.html.
мы потребуют введения дополнительной идентификации или 6. Сингапурский университет: http://mip.ee.nus.sg.
шифрования трафика. Решений многих проблем ожидают 7. «IP Routing for Wireless/Mobile Hosts (mobileip)»: http://
от перехода на IPv6, для которого разрабатывается ряд рас- www.ietf.org/html.charters/mobileip-charter.html.
ширений, позволяющих направлять потоки непосредствен- 8. Monarch – MObile Networking ARCHitectures: http://
но на мобильный узел, полностью отказавшись от HA и FA www.monarch.cs.rice.edu.
[15]. Например, расширение Neighbor Discovery позволяет 9. Реализация под Windows проект FOKUS (http://
сообщать домашнему маршрутизатору о своем местонахож- www.mobile-ip.de/home.html).
дении и таким образом корректировать маршрут. 10. Birdstep Intelligent Mobile IP: http://www.birdstep.com.
Вероятно, по этой причине подавляющее большинство 11. Mobile Networking Through Mobile IP: http://www.computer.org/
информации по вопросу Mobile IP имеет чисто теоретичес- internet/v2n1/perkins.htm.
кий и рекомендательный характер, так как после глобаль- 12. Secure Mobile Networking Project: http://www.cs.pdx.edu/
ного перехода на IPv6 (когда это еще будет?) картина силь- research/SMN.
но изменится, и многие проблемы, если не отпадут полнос- 13. Mobile IP Security page: http://www.ir.bbn.com/projects/
тью, будут выглядеть совсем иначе. Во всяком случае во moips/moips-index.html.
время эксперимента в Гонконге, проходившего осенью 2000 14. RFC 3344 «IP Mobility Support for IPv4»: http://www.ietf.org/
года в сетях WiFi и GPRS использовался именно IPv6, а для rfc/rfc3344.txt.
связи с остальными узлами применялись специальные 15. Mobility Support in IPv6: ftp://ftp.ietf.org/internet-drafts/draft-
шлюзы (см. например: http://www.tdap.co.uk/uk/archive/ ietf-mobileip-ipv6-07.txt.
mobile/mob(ipv6_0103).html). Кроме того, использование 16. «Firewall Traversal for Mobile IP: Guidelines for Firewalls
IPsec для аутентификации источника и защиты целостнос- and Mobile IP Entities»: ftp://ftp.ietf.org/internet-drafts/draft-
ти данных в IPv6 позволяет повысить безопасность таких ietf-mobileip-firewall-trav-00.txt и «Reverse Tunneling for
соединений. Далее, не исключена возможность пропада- Mobile I»: ftp://ftp.ietf.org/internet-drafts/draft-ietf-mobileip-
ния пакетов по причине их устаревания и отсечки межсете- tunnel-reverse-04.txt.

№2, февраль 2005 49


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

САГА О БИЛЛИНГЕ,
ИЛИ СЧИТАЕМ ТРАФИК НА FreeBSD
(ng_ipacct + Perl+ MySQL)
ЧАСТЬ 1

ВЛАДИМИР ЧИЖИКОВ
Рано или поздно перед каждым системным администрато- чае как промежуточное звено, как маленькое кольцо, через
ром встает вопрос подсчета интернет-трафика. И тут уже которое проходят пакеты, считаются и перенаправляются
не важны причины – проверить ли провайдера или прокон- дальше. Одно из его преимуществ – он работает на уровне
тролировать, какой объем трафика израсходовал подклю- ядра, используя минимум времени процессора и памяти.
ченный пользователь, и выставить счет. Конечно, систем Тонкости работы и его возможности описаны в статье «Все
биллинга сейчас много. И найти их в Интернете не пробле- о NETGRAPH» Арчи Коббса (перевод статьи на русский язык
ма, если задаться целью это сделать. Но многие хорошие и можно посмотреть на http://www.opennet.ru/docs/RUS/
гибкие системы учета трафика, как правило, дороги или netgraph_freebsd/index.html). Мы же разберем, как устано-
имеют достаточно сложный интерфейс, а некоторые зат- вить ng_ipacct и сам NETGRAPH. Что ж, приступим.
рудняют использование тех же squid или oops. Перед тем, как делать какие-либо шаги, скажу, что все
В общем, из этой ситуации мне виделось два выхода – это протестировано на FreeBSD 5.2.1-RELEASE-p10, 5.3-
либо писать что-то свое, либо переделывать существую- RELEASE-p4, 4.10-RELEASE-p3, 4.11-RELEASE. Стоит об-
щее. Исходя из соображений, что в компании уже создан ратить внимание, что с переходом на верссию 5.3 и выше
корпоративный сервер статистики с единой системой ав- потребуется пересборка ng_ipacct. Также пересобрать его
торизации и прочего, у меня не возникало особого жела- потребуется и при каждой новой компиляции ядра (на 5-й
ния прикручивать, например, тот же NetAms к нему, хотя ветке).
последний и не лишен ряда достоинств и преимуществ. Таким образом, исходные данные есть. Возьмемся за
Да и многим организациям, которым предоставлен до- netgraph. Загружать в память его можно, используя два ме-
ступ в Интернет нашей компанией, не нужно то море стати- тода: запускать нужные модули при старте либо вкомпили-
стики, которое выдает система биллинга. ровать сразу же в ядро. Мне предпочтителен последний ва-
В итоге решение создать свою систему учета перевеси- риант. Для этого нужно просто перекомпилировать ядро с
ло все остальное. Необходимо было просто посчитать, его поддержкой.
сколько трафика прошло через интерфейс. Делается все достаточно просто. Рассмотрим на при-
Так все начиналось. Развилось это в большой набор мере для FreeBSD-4.10.
скриптов, которые не только считали объем трафика, но и Первым делом идем в /usr/src/sys/i386/conf/ и смотрим
определяли, локальный он или нет, какова доля локально- LINT-файл:
го трафика от общего объема, а также позволяли просмот-
реть все задействованные порты и протоколы, и сколько # cd /usr/src/sys/i386/conf/
# less LINT
именно трафика пришлось на каждый из них.
Что ж, скрипты это хорошо, но без самого главного, сер- .............
options NETGRAPH #netgraph(4) system
дца всей этой системы, программы ng_ipacct, автором ко- options NETGRAPH_ASYNC
торой является Роман Палагин, ничего бы и не было. Эта options NETGRAPH_BPF
options NETGRAPH_CISCO
программа, если так можно выразиться, является вариаци-
options NETGRAPH_ECHO
ей на тему ipacctd. options NETGRAPH_ETHER
Ipacctd работает с ipfw, а вот ng_ipacct уже с NETGRAPH, options NETGRAPH_FRAME_RELAY
options NETGRAPH_HOLE
плюс она работает как модуль ядра. Почему именно ng_ipacct, options NETGRAPH_IFACE
а не просто ipacctd? NETGRAPH имеет ряд преимуществ. На- options NETGRAPH_KSOCKET
options NETGRAPH_L2TP
верняка многие замечали, как отличается объем трафика,
options NETGRAPH_LMI
который считаешь при помощи ipfw, и тот, который прислал # MPPC compression requires proprietary files (not included)
провайдер со счетом. Объясняется все достаточно просто, #options NETGRAPH_MPPC_COMPRESSION
options NETGRAPH_MPPC_ENCRYPTION
ipfw отрабатывает не все пакеты, поступившие в bpf – пакет- options NETGRAPH_ONE2MANY
ный фильтр системы. NETGRAPH выступает в данном слу- options NETGRAPH_PPP

50
администрирование
options NETGRAPH_PPPOE ся. Основное отличие – синхронизация. В RELENG_4 она
options NETGRAPH_PPTPGRE осуществляется через уровни прерываний, о которых мож-
options NETGRAPH_RFC1490
options NETGRAPH_SOCKET
но почитать в man 9 spl. Весь код netgraph должен выпол-
options NETGRAPH_TEE няться на уровне splnet.
options NETGRAPH_TTY Все граничные ноды, осуществляющие связь между
options NETGRAPH_UI
options NETGRAPH_VJC NETGRAPH и другой подсистемой, например, ng_ether, пе-
............. реходят в уровень splnet, перед тем как отправить данные
То есть опций достаточно много и есть из чего выбрать. в граф. Если это невозможно, то данные ставятся в оче-
Для избежания проблем с разного рода устройствами мож- редь и позже раздаются в нужной последовательности.
но их все включить в наше ядро, но в самом простом слу- Любые внешние вызовы, которые работают с netgraph, тоже
чае (считаем только с ethernet-устройства) нам потребуют- должны первым делом вызывать splnet(). Таким образом, в
ся только такие опции в ядре: одну единицу времени может существовать только один кон-
текст выполнения NETGRAPH, и конфликтовать ему не с кем.
options NETGRAPH В RELENG_5 ядро многонитевое (multithreads), и синх-
options NETGRAPH_ETHER
options NETGRAPH_SOCKET ронизация netgraph осуществляется с помощью мьютексов
options NETGRAPH_TEE (блокировок, используемых для реализации гарантирован-
ной исключительности) и атомарных операций. Ноды пере-
Дальнейшие наши действия заключаются в компиляции дают друг другу объекты (items) различных типов: данные
ядра. (mbufs), сообщения (ng_mesg), ссылки на функции. У объек-
та есть атрибут – reader или writer.
# config SKIF Нода может одновременно обрабатывать сколько угод-
но reader items или только одну writer item. По умолчанию
– конфигурирование файла ядра, в моем случае это SKIF. объекты с данными – readers, а все остальные writers. Од-
Если ошибок в файле не было выявлено, то она выдаст: нако это можно указать как на уровне конкретных объек-
тов, так и на уровне хуков (hooks).
Don't forget to do a ``make depend'' Важным является то, что в момент, когда выполняется
Kernel build directory is ../../compile/SKIF
код внутри ноды, тред не держит ни одного мьютекса, что
Это маленькое напоминание о том, что необходимо сде- позволяет граничным нодам вызывать методы других под-
лать make depend, и где это сделать. систем, избегая LOR (Lock order reversal – блокирования
устанавливаемых изменений).
# cd ../../compile/SKIF && make depend ↵ То есть это грозит нам как минимум тем, что один и тот
&& make && make install && make clean && rehash
же ng_ipacct не будет работать на разных ветках FreeBSD.
– полный список команд, необходимый для того, чтобы пе- Что ж, скачиваем и распаковываем.
рейти и скомпилировать наше ядро. Достаточно удобный,
если никаких ошибок не ожидается, но если возникнут, то # tar xfvz ng_ipacct-20040109.tar.gz
# cd ng_ipacct/
выяснить, на каком этапе они произошли, будет проблема- # make && make install && make clean && rehash
тично. Посему команды лучше выполнять по отдельности.
После всех этих манипуляций перезагрузим сервер. Ничего особо сложного здесь нет, и программа без осо-
бых проблем проинсталлируется. В принципе это все, что
# shutdown -r now было необходимо для установки ng_ipacct. В комплекте к
ней идут четыре скрипта, которые объясняют, как запус-
После перезагрузки мы получаем чистое ядро с поддер- тить и остановить программу для подсчета трафика. Гото-
жкой NETGRAPH. вый скрипт для запуска и остановки: ng_ipacct_init.sh, он
Что ж, часть работы выполнена. Устанавливаем ng_ipacct. находится в распакованной папке ng_ipacct/script. Слегка
Первым делом смотрим порты, имеющиеся в системе. Там подкорректировав, его можно смело поместить в /usr/local/
присутствует только ipacct: etc/rc.d/.
Все, что нужно в нем прописать, это:
# cd /usr/ports/ ! Прослушиваемые интерфейсы INTERFACES=«ed0» –
# make search key=ipacct
здесь это будет ed0. Для того чтобы указать более од-
Port: ipacctd-1.46 ного интерфейса, нужно перечислить их через запятую.
Path: /usr/ports/net-mgmt/ipacctd
Info: IP accounting using divert socket ! VERBOSE=1 – уровень расширенного вывода статис-
Maint: skv@FreeBSD.org тики, по умолчанию в скрипте 1, которая выведет нам
B-deps:
дополнительно, кроме IP-адреса источника и назначе-
R-deps:
ния количества пакетов и байт, еще и порты и протоко-
Сам же ng_ipacct можно найти здесь: ftp://ftp.wuppy.net.ru/ лы, которые использовались. Стоит обратить внимание,
pub/FreeBSD/local/kernel/ng_ipacct. что названия протоколов, если указан расширенный
На сервере присутствуют версии как для четвертой, так вывод (VERBOSE=1), будут отображены в числовом, а
и для пятой ветки FreeBSD. Они неидентичны, так реализа- не буквенном виде. Что обозначает каждый номер, мож-
ция NETGRAPH в этих версиях FreeBSD заметно отличает- но посмотреть в /etc/protocols/.

№2, февраль 2005 51


администрирование
! THRESHOLD=50000 – количество записей, которые бу- ! База должна разделять трафик за текущий и предыду-
дут храниться программой в памяти. На этот параметр щий месяцы самостоятельно и иметь возможность пре-
стоит обратить особое внимание, так как неправильно доставить пользователю отчет за каждый из них, чтобы
подобранный размер threshold может привести к поте- таблицы бессмысленно не росли. Гораздо проще обра-
ри части данных или даже к панике ядра. Это возможно ботать одну маленькую за месяц, чем одну большую за
по той причине, что ng_ipacct работает на уровне ядра и год с выборкой за месяц. Просмотр статистики за пре-
ей не будет доступна полностью вся память, имеющая- дыдущие месяцы может быть необходим для отчета пе-
ся на машине, а только малая часть, зарезервирован- ред начальством или выставления счета клиенту, если
ная непосредственно под ядро. В результате перепол- такой имеется.
нения памяти, выделенной системе на ядро, может про- ! В случае недоступности MySQL-сервера необходимо
изойти паника со всеми вытекающими последствиями, хранить полученные данные локально до тех пор, пока
в лучшем случае остановка сервера и потеря записей не будет устранена причина недоступности сервера
относительно трафика, прошедшего через него. Поэто- базы данных. После чего данные автоматически долж-
му если у вас менее 128 Мб памяти, стоит себя ограни- ны быть перенесены в базу при следующем сеансе.
чить 4000-5000 записями и чаще снимать статистику, ! Единый конфигурационный файл с удобным и интуитив-
чтобы не потерять нужные данные. но понятным содержанием.
! Графический или веб-интерфейс для удобного отобра-
Для снятия статистики в ng_ipacct необходимо проде- жения статистики.
лать следующее: передать данные в checkpoint (конт- ! Неплохо было бы, чтобы система, где необходимо, от-
рольную точку), вывести статистику при помощи show из личала локальный трафик от внешнего.
контрольной точки и очистить контрольную точку.
Вот так это делается для интерфейса rl0: В принципе этот список можно продолжить, приведен-
ные же требования являются ключевыми.
# ipacctctl rl0_ip_acct:rl0 checkpoint Итак, создадим, исходя из этого, наш конфигурацион-
# ipacctctl rl0_ip_acct:rl0 show
# ipacctctl rl0_ip_acct:rl0 clear ный файл. Все свои скрипты и программы я размещаю в
папки, расположенные в /usr/local/script. В дальнейшем я
После show вы увидите все пакеты, которые проходили буду отталкиваться именно от такого расположения папки,
через интерфейс. Статистика выводится в достаточно удоб- если у вас путь будет отличен от моего, внесите необходи-
ном CISCO-формате: мые коррективы.
Создаем рабочую папку со скриптами:
ip_èñòî÷íèêà port_èñòî÷íèêà ip_íàçíà÷åíèÿ port_íàçíà÷åíèÿ
ïðîòîêîë ïàêåòîâ áàéò # mkdir -p /usr/local/script/ng_stat
# chown skif:wheel /usr/local/script/ng_stat
Обычный режим имеет несколько другой формат выво-
да: Смена владельца выполняется с целью защитить сис-
тему, в случае если наши скромные потуги в области про-
ip_èñòî÷íèêà ip_íàçíà÷åíèÿ ïàêåòîâ áàéò граммирования окажутся небезопасны. По крайней мере
никто не увидит, что написано внутри скрипта, а значит, ло-
Стоит отметить, что имеется проблема с кодировками в мать его будет труднее.
man ipacctctl, просмотреть его удастся разве что в браузе-
ре. # mkdir /usr/local/script/ng_stat/etc
# mkdir /usr/local/script/ng_stat/bin
Но это легко вылечить:
Этим мы создали папки, где будут лежать наши конфи-
# zcat /usr/share/man/man8/ipacctctl.8.gz ↵ гурационные и исполняемые файлы.
| nroff -man | gzip > /usr/share/man/cat8/ipacctctl.8.gz
Что ж, создадим конфигурационный файл и внесем пер-
Если вас интересует исключительно возможность под- вые параметры. По мере продвижения мы будем дополнять
нять ng_ipacct, то на этом можно остановиться. его нужными параметрами.
Мы же проследуем дальше, ибо этого мне было мало.
Мне требовалось, чтобы все данные хранились в базе # cd /usr/local/script/ng_stat/etc
MySQL для каждого хоста и интерфейса, разнесенные по
дате и времени. Здесь мы создадим файл настройки ng_stat.conf и вне-
Вот теперь опишем основные требования, которые были сем следующие строки.
предъявлены биллингу (системе учета трафика – кому как
больше нравится). # Èìÿ ñåðâåðà, ãäå íàõîäèòñÿ áàçà äàííûõ ñòàòèñòèêè
server_db = freebsd
! Система должна хранить данные не только поинтерфей- # Èìÿ áàçû äàííûõ, ãäå áóäåò ñîõðàíÿòüñÿ ñòàòèñòèêà
сно, но и по хостам, чтобы быстро разделить трафик db_name = ng_stat
# Èìÿ ïîëüçîâàòåëÿ äëÿ äîñòóïà ê áàçå
между разными хостами/роутерами, с которых считы- db_user = nguser
вается статистика. При этом количество интерфейсов # Ïàðîëü äëÿ äîñòóïà ê áàçå
db_pass = rfn.if
различно и их наименование может совпадать (куда ни # Èìÿ õîñòà, ñ êîòîðîãî ñíèìàåòñÿ ñòàòèñòèêà
глянь, почти везде есть rl0 или fxp0 или ed0). listen_host = freebsd2

52
администрирование
# Èìåíà èíòåðôåéñîâ, êîòîðûå ïðîñëóøèâàþòñÿ íà êîìïüþòåðå. }
# Óêàçûâàòü ÷åðåç çàïÿòóþ else {
listen_interfaces = rl0 # ðàçáîð ñòðîê, íå îãðàíè÷åííûõ êîììåíòàðèåì
}
Думаю пояснений к строкам приведенного конфигура-
ционного файла не нужно. Объясним конструкцию if ... else: если в начале строки
Вначале откажемся от поставляемого в комплекте с присутствует символ комментария, то на экран будет вы-
ng_ipacct скрипта для его старта и остановки. Лучше напи- ведено сообщение «Комментарий», в противном случае
шем свой: строка пойдет по else. Вывод сообщений о наличии ком-
ментариев нам необходим только на этапе отладки. Кста-
# cd /usr/local/script/ng_stat/bin ти, можете проверить, как скрипт работает, впоследствии
# touch ng_stat_start.pl
он будет закомментирован. Но этого мало, необходимо ра-
Данный скрипт будет служить нам скелетом для после- зобрать и полезную строку.
дующих.
Итак, первое, что мы сделаем, это объявим основной ($param,$arg) = split("=",$_);
chomp $param;
набор переменных: chomp$arg;
$param =~ s/\s//g;
#!/usr/bin/perl -w $arg =~ s/\s//g;
#########################
# Ñïèñîê îñíîâíûõ ïåðåìåííûõ Для разбора использовалась функция split, которая на
######################### основе разделителя «=», заданного еще в конфигурацион-
my $serverdb = "test";
my $dbname = "test"; ном файле, разбила все полезные строки на две части:
my $dbuser = "test"; параметр и аргумент. Чтобы избавиться от пробельных сим-
my $dbpass = "test";
my $table_auth = "test"; волов, используется оператор замены s/шаблон/замена/
my $table_proto = "test"; ограничитель.Так как необходимо избавиться от пробель-
my $listen_host = "test";
my @listen_interf; ных символов, а не поменять их на что-то другое, мы не
используем параметр «замена», оставляя его пустым. Мо-
Все переменные созвучны описанным в конфигураци- дификатор \s означает любой пробельный символ.
онном файле и являются глобальными для него. Внеся за- Перед этим были убраны из обоих переменных симво-
ранее значение «test» в них, мы избежали проблемы полу- лы перевода строки при помощи chomp.
чить в самом неподходящем месте undef. Но обратите вни- Если в строке присутствуют не только символы пробе-
мание, что прослушиваемые интерфейсы обозначены не пе- ла, но и табуляции или если их несколько, то придется при-
ременной, а массивом. Сделано это потому, что интерфей- бегнуть к следующей конструкции:
сов может быть несколько, а не один.
Почему были внесены такие непонятные значения пе- $param =~ s/[\s\t]+//g;
$arg =~ s/[\s\t]+//g;
ременных? Объясняется все достаточно просто. Во-первых,
сюда можно внести значения реальных данных по умолча- Теперь необходимо присвоить каждой объявленной пе-
нию, которые будут считываться. Во-вторых, если на этапе ременной ее истинное значение, находящееся в конфигу-
отладки будут проблемы, изменив значения, вы сможете рационном файле. В этом нам поможет конструкция следу-
выяснить, с какой переменной у вас непорядок и где. ющего вида:

open (CONFIG, "/usr/local/script/ng_stat/etc/ng_stat.conf"); if ($param eq "server_db"){


while (<CONFIG>) { $serverdb = $arg;
}
}
close (CONFIG);
Объясним. Если левая часть полученной из файла стро-
Этими строками открывается конфигурационный файл ки соответствует server_db (смотрим наш конфигурацион-
и при помощи while полностью считывается и закрывается. ный файл), то правая часть присвоится соответственной пе-
Обратите внимание, что в данном случае используется пол- ременной.
ное указание пути к файлу в явном виде, а впоследствии Но у нас же есть еще несколько значений параметра в
будем указывать его неявно, через переменные. одной из строк. Их мы должны, предварительно разобрав,
Что ж, первое, что нам нужно сделать, это разобрать стро- занести в массив.
ки, которые поочередно считывает while до тех пор, пока не
дойдет до конца файла. Но среди полезной информации #!/usr/bin/perl -w
конфигурационный файл несет в себе комментарии. От них use DBI;
нужно избавиться. Для этого в Perl имеется мощнейшие ин- use POSIX ":sys_wait_h";
#########################
струменты поиска в строках/словах. Один из них – конст- # Ñïèñîê îñíîâíûõ ïåðåìåííûõ
рукция вида m/шаблон/ограничитель, им и воспользуемся, #########################
my $serverdb = "test";
условившись, что комментарием будет символ #: my $dbname = "test";
my $dbuser = "test";
$comment = '#'; my $dbpass = "test";
if(/^$comment/) { my $table_auth = "test";
my $table_proto = "test";
print "Êîììåíòàðèé\n";

№2, февраль 2005 53


администрирование
my $listen_host = "test"; Как видите, мы считали все параметры, и в случае если
my @listen_interf; интерфейс по какой-либо причине установлен не будет, то
my $iface_set = "no";
my @ng_modules; на экран будет выдано сообщение об этом. А если все нор-
my $ng_modules_def = "netgraph,ng_ether,ng_socket, ↵ мально, то в массив будут внесены необходимые имена
ng_tee,ng_ipacct";
my$threshold = 5000; интерфейсов (например, rl0, rl1,rl2,fxp0) и после проверки
#########################
массива @listen_interf на наличие в нем не пустых значе-
# ×èòàåì êîíôèãóðàöèîííûé ôàéë. ний будут выполнены подпрограммы: &check_kld_ modules
######################### и &listening.
open (CONFIG, "/usr/local/script/ng_stat/etc/ng_stat.conf");
Первая проверяет, какие из обязательных модулей заг-
while (<CONFIG>) { ружены. При необходимости будет проведена их загрузка.
$comment = '#';
if(/^$comment/) { Вторая включает режим прослушивания интерфейсов.
# print "Êîìåíòàðèé\n"; Рассмотрим первую.
}
else {
($param,$arg) = split("=",$_); subcheck_kld_modules {
chomp $param; my @modules;
chomp $arg; my $pid;
my $razdel = ""; my $ng_module_cfg;
$param =~ s/[\s\t]+/$razdel/g; my $chk_ng_file = "/tmp/ng_file";
$arg =~ s/[\s\t]+/$razdel/g; my $check_ng = 'kldstat -v | grep ng';
if ($param eq "server_db"){ $check_ng = "$check_ng";# " > $chk_ng_file";
$serverdb = $arg; my $check_netgraph = 'kldstat -v | grep netgraph';
} $check_netgraph = "$check_netgraph";#" >> $chk_ng_file";
if ($param eq "db_name"){ # $pid = fork;
$dbname = $arg;
} @modules =split ("\n", `$check_ng && $check_netgraph`);
if ($param eq "db_user") { my $mod;
$dbuser = $arg; if (defined $modules[0]) {
} foreach my $modules (@modules) {
if ($param eq "db_pass") { $modules=~ s/\d+//g;
$dbpass = $arg; if ($modules =~ s/.ko//g) {
} #
if ($param eq "table_auth") { }
$table_auth = $arg; else {
} $modules =~ s/[\s\t]+//g;
if ($param eq "table_protocols") { $mod = "$mod $modules ";
$table_proto = $arg; }
} }
if ($param eq "listen_host") { chop $mod;
$listen_host = $arg;
} foreach my $ng_modules (@ng_modules) {
if ($param eq "listen_interfaces") { if ($mod=~m/$ng_modules/g){
my $coma = ','; # print "$mod ñîäåðæèò $ng_modules\n";
if (defined $arg) { }
$iface_set = "ok"; else {
if ($arg ne ""){ my ($pid,$kid);
if ($arg =~ m/$coma/ ) {
$pid = fork;
@listen_interf=split($coma,$arg); if (defined $pid) {
} if ($pid == 0){
else { print ↵
@listen_interf = $arg; "Çàãðóçêà íåîáõîäèìîãî ìîäóëÿ ",$ng_modules,"\n";
} exec "/sbin/kldload ↵
} $ng_modules > /dev/null 2>&1" or die ↵
} "Îøèáêà çàãðóçêè ìîäóëÿ $ng_modules !\n";
} exit;
if ($param eq "ng_modules") { }
}
my $coma = ','; else {
if ($arg =~ m/$coma/ ){ print "Ôàòàëüíàÿ îøèáêà ↵
@ng_modules = split($coma,$arg); âåòâëåíèÿ!\n.................\n";
} die "Ðàçäåëåíèå íà ïðîöåññû ↵
else { íåâîçìîæíî.\n Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ↵
ïðîöåññà: $!\n";
@ng_modules = split ($coma,$ng_modules_def); }
} do {
$kid = waitpid $pid,0;
} if ($kid == -1) {
print "Äî÷åðíèõ ïðîöåññîâ ↵
} â ñèñòåìå íåò èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n ↵
} Îøèáêà!" and die "Âûõîä!\n";
close (CONFIG); } elsif ($kid == 0) {
print "Çàäàí ↵
if (!defined $listen_interf[0]) { íå áëîêèðóþùèé âûçîâ è ïðîöåññ åùå íå çàâåðøåí!\n";
print "Óñòàíîâèòå, ïîæàëóéñòà, â ðåæèì ïðîñëóøèâàíèÿ ↵ }
õîòÿ áû îäèí èíòåðôåéñ.\n"; } until $kid=$pid;
} undef $pid;
else { }
}
&check_kld_modules; }
&listening; else {
foreach my $ng_modules (@ng_modules) {
} my ($pid,$kid);

54
администрирование
$pid = fork; В данном случае информация о том, из какого файла
if (defined $pid) { был загружен модуль (linux.ko, logo_server.ko или что-то
if ($pid == 0){
print "Çàãðóçêà íåîáõîäèìîãî ↵ другое), не нужна. Также не нужны ID загруженных моду-
ìîäóëÿ ",$ng_modules,"\n"; лей. Для их удаления используется все тот же m//:
exec "/sbin/kldload ↵
$ng_modules > /dev/null 2>&1" or die "Îøèáêà ↵
çàãðóçêè ìîäóëÿ $ng_modules !\n"; $modules=~ s/\d+//g;
exit;
}
} «\d» означает любой цифровой символ.
else {
print "Ôàòàëüíàÿ îøèáêà ↵ После удаления ID проверяется, что присутствует в вы-
âåòâëåíèÿ!\n.................\n"; воде – информация о том, из какого модуля загрузился
die "Ðàçäåëåíèå íà ïðîöåññû ↵
íåâîçìîæíî.\n Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ↵ файл или сам модуль. На файл указывает присутствие рас-
ïðîöåññà: $!\n"; ширения «.ko» в строке. А потому все полученные строки,
}
do { где присутствует «.ko», подлежат удалению. В листинге вы
$kid = waitpid $pid,0; видите, что на месте совпадения if с «.ko» стоит коммента-
if ($kid == -1) {
print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå ↵ рий. Если хотите, можете провести синтаксический разбор
íåò èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵ и вывести на экран имя того модуля, который был загру-
and die "Âûõîä!\n";
} elsif ($kid == 0) { жен вручную.
print "Çàäàí íå áëîêèðóþùèé ↵ Нам же интересно только то, что находится после else.
âûçîâ è ïðîöåññ åùå íå çàâåðøåí!\n";
} Вывод kldstat имеет пять колонок (Id,Refs,Address,Size,Name).
} until $kid=$pid; Все они разделены между собой пробельными символами.
undef $pid;
} К тому же первые колонки пусты и заполнены именно этими
}
самыми пробельными символами. Так как нам необходима
} только одна колонка Name, то необходимо удалить все про-
бельные символы. Для удобства дальнейших манипуляций
Сначала объявляются действующие только в переделах мы заносим отобранные элементы в одну строку:
этого модуля массивы и переменные. В нашем случае это
@modules, куда будут заноситься все модули netgraph, при- if ($modules =~ s/.ko//g) {
#
сутствующие в ядре или загруженные на данный момент. }
$check_netgraph и $check_ng переменные, в которых запи- else {
$modules =~ s/[\s\t]+//g;
саны команды, проверки загруженных модулей ядра. $mod = "$mod $modules ";
Команда эта достаточно проста и имеет вид: }

# kldstat -v Здесь необходимо остановиться и вернуться немного на-


............... зад. Только что мы получили список загруженных модулей.
234 dummynet Хорошо, но этого мало. Необходимо еще знать, какие нам
235 if_gif нужны для работы, и если их нет – загрузить.
236 ipfw
237 if_loop
238 ng_async # Çàãðóæàåìûå ìîäóëè NETGRAPH, íåîáõîäèìûå äëÿ èíòåðôåéñîâ,
239 ng_bpf # êîòîðûå áóäåò îáñëóæèâàòü ïðîãðàììà.
# Ïî óìîë÷àíèþ çàãðóæàþòñÿ ñëåäóþùèå ìîäóëè: netgraph,
4 1 0xc272d000 4000 ng_ipacct.ko # ng_ether,ng_socket,ng_tee,ng_ipacct
Containsmodules: ng_modules = netgraph,ng_ether,ng_socket,ng_tee,ng_ipacct
Name
246 ng_ipacct И соответственно считать их. Для этого нужно также
....................
ввести еще несколько основных переменных. Точнее, мас-
Как вы можете заметить, вывод немаленький, поэтому сив и переменную.
пришлось его урезать. Нам нужны не все модули, а только
те, которые имеют отношение к NETGRAPH. Этим и зай- my@ng_modules;
my$ng_modules_def = "netgraph,ng_ether,ng_socket, ↵
мутся переменные, когда их используют как значения для ng_tee,ng_ipacct";
оператора exec.
Чтобы получить список загруженных модулей, исполь- Данные из последней переменной будут загружены в
зуется split и обратные кавычки, в качестве разделителя массив в случае отсутствия в конфигурационном файле
выступает символ переноса строки: хотя бы одного модуля netgraph.
Считывание необходимых к загрузке модулей нужно
@modules =split ("\n", `$check_ng && $check_netgraph`); добавить к open ... close(CONFIG):

Дальше пойдем по проверенному пути, а именно – вы- if ($param eq "ng_modules") {


my $coma = ',';
ясним, имеются ли в массиве хоть какие-то данные. if ($arg =~ m/$coma/ ){
Если полученный массив не пустой, то мы выполним про- @ng_modules = split($coma,$arg);
} else {
верку, какие модули нам необходимо подгрузить для рабо- @ng_modules = split ($coma,$ng_modules_def);
ты. }

№2, февраль 2005 55


администрирование
Теперь у нас есть необходимый список модулей. Можем Так же обратите внимание на такие строчки кода:
проверить, нужно что-то загружать или нет.
Для этого необходимо проделать достаточно простую do {
$kid = waitpid $pid,0;
операцию. Проверить наличие значения каждого элемента if ($kid == -1) {
полученного массива @ng_modules в строке $mod. Осно- print "Äî÷åðíèõ ïðîöåññîâ ↵
â ñèñòåìå íåò èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n ↵
вываясь на том, есть или нет такое значение массива в стро- Îøèáêà!" and die "Âûõîä!\n";
ке, и будет производиться загрузка соответствующего мо- } elsif ($kid == 0) {
print "Çàäàí ↵
дуля. íå áëîêèðóþùèé âûçîâ è ïðîöåññ åùå íå çàâåðøåí!\n";
}
foreach my $ng_modules (@ng_modules) { } until $kid=$pid;
if ($mod=~m/$ng_modules/g){
# print "$mod ñîäåðæèò $ng_modules\n"; На данном этапе они не так актуальны. Здесь не силь-
} но важна последовательность загрузки модулей и прочих
else {
my $pid; процессов, но ниже, когда будет происходить запуск сбора
$pid = fork; статистики на интерфейсах, придерживание последова-
if (defined $pid) {
if ($pid == 0){ тельности выполняемых команд будет первостепенным. Что
print "Çàãðóçêà íåîáõîäèìîãî ↵ же делает этот блок? Ключевым к нему является всего одна
ìîäóëÿ ",$ng_modules,"\n";
exec "/sbin/kldload ↵ функция waitpid. Она аналогична в некоторой степени фун-
$ng_modules > /dev/null 2>&1" or die "Îøèáêà ↵ кции wait, но ждет завершения определенного дочернего
çàãðóçêè ìîäóëÿ $ng_modules !\n";
exit; процесса с указанным ID, в данном случае полученного при
} fork $pid. Функция возвращает одно из трех возможных зна-
}
else { чений:
print "Ôàòàëüíàÿ îøèáêà ↵ ! PID завершенного процесса.
âåòâëåíèÿ!\n.................\n";
die "Ðàçäåëåíèå íà ïðîöåññû ↵ ! 0 – если флаги, что указаны, задают не блокирующий
íåâîçìîæíî.\n Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ↵ вызов, а процесс еще не завершен.
ïðîöåññà: $!\n";
} ! -1 – если дочерних процессов нет.
do {
$kid = waitpid $pid,0;
if ($kid == -1) { Родительский процесс на время выполнения waitpid как
print "Äî÷åðíèõ ïðîöåññîâ ↵ бы засыпает, ожидая результата. В итоге комбинацией fork
â ñèñòåìå íåò èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n ↵
Îøèáêà!" and die "Âûõîä!\n"; + exec + waitpid мы добиваемся жесткой очередности вы-
} elsif ($kid == 0) { полнения как всех команд, так и сопутствующего программ-
print "Çàäàí ↵
íå áëîêèðóþùèé âûçîâ è ïðîöåññ åùå íå çàâåðøåí!\n"; ного кода. Вот эти особенности и использовались для за-
} пуска внешних программ.
} until $kid=$pid;
undef $pid; Но проверить и загрузить нужные модули мало. Нужно
undef $pid; еще начать собирать статистику на интерфейсе. Для этого
}
} считываем параметр threshold из конфигурационного фай-
ла. Следовательно, необходимо создать глобальную пере-
В этом примере выполнение внешней команды – загруз- менную:
ка модуля – производится посредством exec. Особенностью
exec является то, что по выполнении этой функции произво- my $threshold = 5000;
дится останов программы и выход из процесса. Но так как
присутствует необходимость загрузить не один модуль, то Мы ее создали и присвоили значение 5000 строк по умол-
логичнее было бы использовать system. Но, по соображени- чанию. В конфигурационном файле можно задать и другое
ям безопасности, это произвести нельзя. Решением этой значение.
проблемы является разделение программы на различные
процессы. Для этого уже существует функция fork. # Îòíåñèòåñü âíèìàòåëüíî ê âûáîðó ýòîãî ïàðàìåòðà.
# Îí óêàçûâàåò, ñêîëüêî çàïèñåé áóäåò õðàíèòüñÿ â áóôåðå
Немного поясню, как она работает. По выполнении фун- # Ïî óìîë÷àíèþ çíà÷åíèå ðàâíî 5000, íî åñëè ó âàñ ìåíüøå
кции существующий процесс разделяется на два: родитель- # 128 Ìá ïàìÿòè – óìåíüøèòå åãî. Çíà÷åíèå âî ìíîãîì
# çàâèñèò îò òîãî, êàêàÿ ïîëîñà ïðîïóñêàíèÿ íà âàøåì êàíàëå,
ский и дочерний. Сама функция возвращает два значения # è îò òîãî íàñêîëüêî îí çàãðóæåí. Äëÿ 128 Êá è 64 Ìá
в случае удачного выполнения: номер ID для дочернего про- # ìîæíî áóäåò ñìåëî óñòàíîâèòü è 10000 çàïèñåé, ïðè óñëîâèè
# ñíÿòèÿ còàòèñòèêè õîòÿ áû ðàç â 15-20 ìèíóò. Äëÿ êàíàëà
цесса в родительский и 0 в дочерний. Почему ноль, а не # â 2 Ìáèòà ýòîãî âðåìåíè áóäåò óæå ñëèøêîì ìíîãî
номер полученного процесса? Потому что дочерний про- threshold = 5000
цесс может в любой момент времени получить ID родитель-
ского, вызвав функцию getppid. Родительский же процесс Теперь считаем параметр из файла:
получает ID дочернего потому, что способов узнать из все-
го объема процессов дочерний у него просто нет, или я его if ($param eq "threshold") {
$threshold = $arg;
не знаю. }
Возможен также и третий вариант. Когда fork возвраща-
ет неопределенное значение undef. Это означает, что по ка- Все. Основные переменные заданы, конфигурационный
кой-либо причине разделение на процессы не произошло. файл на данном этапе заполнен полностью.

56
администрирование
Что ж, приступим к запуску. ïðèñâîåíèÿ èìåíè ñîçäàííîìó óçëó!\n";
Я сразу приведу полный листинг модуля, а потом лишь exit;
}
поясню некоторые моменты, ибо сам по себе модуль дос- }
таточно прост, в нем только команды fork и exec. else {
print "Ôàòàëüíàÿ îøèáêà ↵
âåòâëåíèÿ!\n.................\n";
sub listening{ die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵
my $pid; Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n";
$ngctl = "/usr/sbin/ngctl"; }
$ipacctctl = "/usr/local/sbin/ipacctctl"; do {
while (@listen_interf){ $kid = waitpid $pid,0;
if ($kid == -1) {
$interface = shift @listen_interf; print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵
#/usr/sbin/ngctl mkpeer ${IFACE}: tee lower right èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵
$mkpeer = "$ngctl mkpeer $interface\: tee lower right"; and die "Âûõîä!\n";
$pid = fork; } elsif ($kid == 0) {
if (defined $pid) { print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵
($pid == 0){ è ïðîöåññ åùå íå çàâåðøåí!\n";
print "Ñîçäàíèå è ïîäêëþ÷åíèå íîâîãî ↵ }
NETGRAPH-óçëà ê óæå ñóùåñòâóþùåìó:\n $mkpeer\n"; } until $kid=$pid;
exec "$mkpeer" or die "Îøèáêà ↵ undef $pid;
ñîçäàíèÿ íîâîãî óçëà NETGRAPH!\n";
exit; #/usr/sbin/ngctl mkpeer ${IFACE}_acct_tee: ipacct ↵
} right2left ${IFACE}_in
} $mkpeer = "$ngctl mkpeer $interface\_acct_tee: ↵
else { ipacct right2left $interface\_in";
print "Ôàòàëüíàÿ îøèáêà ↵
âåòâëåíèÿ!\n.................\n"; $pid = fork;
die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵ if (defined $pid) {
Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n"; ($pid == 0){
} print "Ñîçäàíèå è ïîäêëþ÷åíèå íîâîãî ↵
do { NETGRAPH-óçëà ê óæå ñóùåñòâóþùåìó:\n $mkpeer\n";
$kid = waitpid $pid,0; exec "$mkpeer" or die "Îøèáêà ↵
if ($kid == -1) { ñîçäàíèÿ íîâîãî óçëà NETGRAPH!\n";
print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵ exit;
èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵ }
and die "Âûõîä!\n"; }
} elsif ($kid == 0) { else {
print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵ print "Ôàòàëüíàÿ îøèáêà ↵
è ïðîöåññ åùå íå çàâåðøåí!\n"; âåòâëåíèÿ!\n.................\n";
} die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵
} until $kid=$pid; Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n";
undef $pid; }
do {
#/usr/sbin/ngctl connect ${IFACE}: lower upper left $kid = waitpid $pid,0;
$connect = "$ngctl connect $interface\: lower upper left"; if ($kid == -1) {
print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵
$pid = fork; èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵
if (defined $pid) { and die "Âûõîä!\n";
if ($pid == 0){ } elsif ($kid == 0) {
print "Ñîåäèíåíèå äâóõ NETGRAPH-óçëîâ ↵ print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵
íà èíòåðôåéñå:\n$connect\n"; è ïðîöåññ åùå íå çàâåðøåí!\n";
exec "$connect" or die "Îøèáêà ñîåäèíåíèÿ ↵ }
äâóõ NETGRAPH-óçëîâ!\n"; } until $kid=$pid;
exit; undef $pid;
}
} #/usr/sbin/ngctl name ${IFACE}_acct_tee:right2left ↵
else { ${IFACE}_ip_acct
print "Ôàòàëüíàÿ îøèáêà ↵ $name = "$ngctl name ↵
âåòâëåíèÿ!\n.................\n"; $interface\_acct_tee:right2left $interface\_ip_acct";
die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵
Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n"; $pid = fork;
} if (defined $pid) {
do { ($pid == 0){
$kid = waitpid $pid,0; print "Ïðèñâîåíèå èìåíè ↵
if ($kid == -1) { ñîçäàííîìó óçëó:\n$name\n";
print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵ exec "$name" or die "Îøèáêà íà ýòàïå ↵
èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵ ïðèñâîåíèÿ èìåíè ñîçäàííîìó óçëó!\n";
and die "Âûõîä!\n"; exit;
} elsif ($kid == 0) { }
print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵ }
è ïðîöåññ åùå íå çàâåðøåí!\n"; else {
} print "Ôàòàëüíàÿ îøèáêà ↵
} until $kid=$pid; âåòâëåíèÿ!\n.................\";
undef $pid; die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵
Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n";
#/usr/sbin/ngctl name ${IFACE}:lower ${IFACE}_acct_tee }
do {
$name = "$ngctl name $interface\:lower ↵ $kid = waitpid $pid,0;
$interface\_acct_tee "; if ($kid == -1) {
print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵
$pid = fork; èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵
if (defined $pid) { and die "Âûõîä!\n";
($pid == 0){ } elsif ($kid == 0) {
print "Ïðèñâîåíèå èìåíè ↵ print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵
ñîçäàííîìó óçëó:\n$name\n"; è ïðîöåññ åùå íå çàâåðøåí!\n";
exec "$name" or die "Îøèáêà íà ýòàïå ↵ }

№2, февраль 2005 57


администрирование
} until $kid=$pid; die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵
undef $pid; Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n";
}
#/usr/sbin/ngctl connect ${IFACE}_acct_tee: ↵ do {
${IFACE}_ip_acct: left2right ${IFACE}_out $kid = waitpid $pid,0;
$connect = "$ngctl connect $interface\_acct_tee: ↵ if ($kid == -1) {
$interface\_ip_acct: left2right $interface\_out"; print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵
èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵
$pid = fork; and die "Âûõîä!\n";
if (defined $pid) { } elsif ($kid == 0) {
if ($pid == 0){ print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵
print "Ñîåäèíåíèå äâóõ NETGRAPH-óçëîâ ↵ è ïðîöåññ åùå íå çàâåðøåí!\n";
íà èíòåðôåéñå:\n$connect\n"; }
exec "$connect" or die "Îøèáêà ñîåäèíåíèÿ ↵ } until $kid=$pid;
äâóõ NETGRAPH-óçëîâ!\n"; undef $pid;
exit; }
}
} }
else {
print "Ôàòàëüíàÿ îøèáêà ↵ Первые две встречающиеся переменные – исполняемые
âåòâëåíèÿ!\n.................\n";
die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵ файлы для netgraph и ng_ipacct, точнее, пути к ним.
Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n"; Следующим шагом является чтение из массива @listen_
}
do { interf поочередно всех занесенных туда интерфейсов и вклю-
$kid = waitpid $pid,0; чение на них «прослушивания».
if ($kid == -1) {
print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵ При помощи mkpeer мы создаем новый узел (nodes) к
èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵ уже существующему.
and die "Âûõîä!\n";
} elsif ($kid == 0) { При помощи connect соединяются узлы.
print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵ При помощи name присваиваем имя узлу.
è ïðîöåññ åùå íå çàâåðøåí!\n";
} Наиболее интересными является $ipacctctl $interface\_ip_
} until $kid=$pid; acct:$interface verbose 1 – здесь мы задаем, в каком режи-
undef $pid;
ме будет отображаться статистика. Нам необходим расши-
#$IPACCTCTL ${IFACE}_ip_acct:$IFACE verbose $VERBOSE ренный, посему устанавливаем значение 1. Должен отме-
$verbose = "$ipacctctl ↵
$interface\_ip_acct:$interface verbose 1"; тить, что в man ipacctctl стоит значение on – вероятнее все-
$pid = fork;
го, что это ошибка, ибо такое значение не влияет на фор-
if (defined $pid) { мат вывода статистики.
($pid == 0){ В последнем – $ipacctctl $interface\_ip_acct:$interface
print "Óñòàíîâêà ðåæèìà âûâîäà ↵
èíôîðìàöèè:\n$verbose\n"; threshold $threshold – мы указываем количество записей
exec "$verbose" or die "Îøèáêà óñòàíîâêè ↵ threshold.
ðåæèìà âûâîäà èíôîðìàöèè\n";
exit; По ходу выполняется разветвление процессов, ожида-
} ние завершения дочернего, с последующим обнулением
}
else { $pid, куда записывалось значение ID дочернего процесса.
print "Ôàòàëüíàÿ îøèáêà ↵ Здесь и всплывает важность waitpid для скрипта. Ибо вы-
âåòâëåíèÿ!\n.................\n";
die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵ полняться все эти команды должны именно в строгой пос-
Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n"; ледовательности, а не как им заблагорассудится.
}
do { В принципе стартовый скрипт создан.
$kid = waitpid $pid,0; Что в итоге получилось, можно глянуть в ng_stat_start.pl
if ($kid == -1) {
print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵ (www.samag.ru/source).
èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵ Сделав при помощи chmod файл исполняемым, можно
and die "Âûõîä!\n";
} elsif ($kid == 0) { пробовать его выполнить. Тут поджидает первый неприят-
print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵ ный сюрприз. Данный скрипт выполняется с правами root.
è ïðîöåññ åùå íå çàâåðøåí!\n";
} Что ж, на данном этапе можно его запустить и с такими пра-
} until $kid=$pid; вами.
undef $pid;
#$IPACCTCTL ${IFACE}_ip_acct:$IFACE threshold $THRESHOLD # sudo ./ng_stat_start.pl
$set_threshold = "$ipacctctl ↵
$interface\_ip_acct:$interface threshold $threshold"; Внимательно смотрите за выводом. Отсутствие «лиш-
$pid = fork; него» говорит о том, что старт прошел без замечаний. Вот
if (defined $pid) { пример того, что скрипт выводит при старте:
if ($pid == 0){
print "Óñòàíîâêà ↵
Загрузка необходимого модуля ng_ether
THRESHOLD:\n$set_threshold\n";
exec "$set_threshold" or die "Îøèáêà ↵ Загрузка необходимого модуля ng_socket
óñòàíîâêè ïàðàìåòðà THRESHOLD\n"; Загрузка необходимого модуля ng_tee
exit; Создание и подключение нового NETGRAPH-узла к уже
}
} существующему:
else {
print "Ôàòàëüíàÿ îøèáêà ↵
âåòâëåíèÿ!\n.................\n"; /usr/sbin/ngctl mkpeer fxp1: tee lower right

58
администрирование
Соединение двух NETGRAPH-узлов на интерфейсе: and die "Âûõîä!\n";
} elsif ($kid == 0) {
/usr/sbin/ngctl connect fxp1: lower upper left print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵
è ïðîöåññ åùå íå çàâåðøåí!\n";
Присвоение имени созданному узлу: }
} until $kid=$pid;
undef $pid;
/usr/sbin/ngctl connect fxp1: lower upper left
# sleep 1;
Создание и подключение нового NETGRAPH-узла к уже $shutdown = "$ngctl shutdown $interface\:";
существующему: $pid = fork;
if (defined $pid) {
if ($pid == 0){
/usr/sbin/ngctl mkpeer fxp1_acct_tee: ipacct right2left fxp1_in print "Îòêëþ÷åíèå NETGRAPH ↵
íà èíòåðôåéñå:\n$shutdown\n";
Присвоение имени созданному узлу: exec "$shutdown";
exit;
/usr/sbin/ngctl name fxp1_acct_tee:right2left fxp1_ip_acct }
}
Соединение двух NETGRAPH-узлов на интерфейсе: else {
print "Ôàòàëüíàÿ îøèáêà ↵
âåòâëåíèÿ!\n.................\n";
/usr/sbin/ngctl connect fxp1_acct_tee: fxp1_ip_acct: left2right fxp1_out die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵
Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n";
Установка режима вывода информации: }
do {
/usr/local/sbin/ipacctctl fxp1_ip_acct:fxp1 verbose 1 $kid = waitpid $pid,0;
if ($kid == -1) {
Установка THRESHOLD: print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵
èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵
and die "Âûõîä!\n";
/usr/local/sbin/ipacctctl fxp1_ip_acct:fxp1 threshold 7000 } elsif ($kid == 0) {
print "Çàäàí íå áëîêèðóþùèé âûçîâ ↵
Для себя можете добавить что-либо, если необходима è ïðîöåññ åùå íå çàâåðøåí!\n";
дополнительная информация при запуске. Для отработки }
} until $kid=$pid;
разных этапов работы скрипта советую ввести конструкции undef $pid;
типа print «Проверяем переменную $lin». Это поможет про- }
}
контролировать получение значений переменными в скрип-
те и получить своеобразный отладчик. Но в данном случае Здесь производится чтение из массива всех нужных
это полностью рабочий скрипт, а посему весь мусор отладки интерфейсов и последовательно выполняется для них от-
убран. ключение.
Запустить мало, необходимо еще и уметь остановить. Посмотреть, как он выглядит полностью, можно в ng_
Для этого создадим похожий на ng_stat_start.pl скрипт stat_stop.pl (www.samag.ru/source).
ng_stat_stop.pl. В принципе их можно было бы объединить Теперь у нас есть скрипты для старта и остановки ng_
в один, но так проще. ipacct. Но и этого мало. Нужно сделать запуск и останов
Итак, содержимое абсолютно идентично первому фай- системы при включении и отключении сервера. А посему
лу, за исключением того, что отсутствуют sub и в конструк- напишем простенький скриптик на shell:
ции if ... else содержится следующее:
#!/bin/sh
if (!defined $listen_interf[0]) { case "$1" in
print "Óñòàíîâèòå, ïîæàëóéñòà, â ðåæèì ïðîñëóøèâàíèÿ ↵ start)
/usr/local/script/ng_stat/bin/ng_stat_start.pl
õîòÿ áû îäèí èíòåðôåéñ.\n"; echo"ng_stat"
}
else { ;;
stop)
foreach my $interface (@listen_interf){ /usr/local/script/ng_stat/bin/ng_stat_stop.pl
#/usr/sbin/ngctl shutdown ${IFACE}_acct_tee: ;;
*)
$shutdown = "$ngctl shutdown ↵ echo ""
$interface\_acct_tee:";
my $pid; echo "Usage: `basename $0` { start | stop }"
""
$pid = fork; ;;
if (defined $pid) {
($pid == 0){ esac
print "Îòêëþ÷åíèå ñîçäàííûõ óçëîâ ↵
íà èíòåðôåéñå:\n$shutdown\n"; Сохраним его под названием ng_stat.sh. Когда система
exec "$shutdown";
exit; учета будет готова, достаточно лишь скопировать скрипт в
} /usr/local/etc/rc.d/, чтобы ng_stat запустился при старте или
}
else { отключился при выключении питания.
print "Ôàòàëüíàÿ îøèáêà ↵ Половина дела, самая важная его часть, готова. Систе-
âåòâëåíèÿ!\n.................\n";
die "Ðàçäåëåíèå íà ïðîöåññû íåâîçìîæíî.\n ↵ ма стартовала там, где надо и с нужными параметрами.
Ïðèíóäèòåëüíûé âûõîä èç äî÷åðíåãî ïðîöåññà: $!\n"; Осталось за малым – получить статистику.
}
do { В следующей части статьи будет рассмотрено, как по-
$kid = waitpid $pid,0; лучить статистику от ng_ipacct, и передать ее в MySQL для
if ($kid == -1) {
print "Äî÷åðíèõ ïðîöåññîâ â ñèñòåìå íåò ↵ последующего хранения и использования, а также приве-
èëè ñèñòåìà íå ïîääåðæèâàåò èõ.\n Îøèáêà!" ↵ ден пример того, как получить наши результаты обратно.

№2, февраль 2005 59


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

АВТОМАТИЧЕСКАЯ УСТАНОВКА ОС
И СОПУТСТВУЮЩЕГО ПРОГРАММНОГО
ОБЕСПЕЧЕНИЯ

ИВАН КОРОБКО
В этой статье речь пойдет о создании загрузочного диска, Создание файла ответов для установки Windows
с помощью которого можно в автоматическом режиме ус- Существует три типа автоматической установки Windows.
тановить Microsoft Windows XP в описанной заранее кон- В каждом из трех случаев используется индивидуальный
фигурации (Windows + Service Pack 1 + MUI + HotFixes ), и файл ответа:
некоторых программ, а именно Office 2003, антивирусной Òàáëèöà 1
программы и т. д. Данный диск может быть использован
как для подготовки рабочей станции к функционированию
в сети (после завершения процесса установки ОС и ПО ос-
танется только изменить имя рабочей станции и ввести ее
в домен), так и для изолированного компьютера.
Файл ответа представляет собой текстовый файл со сле-
Автоматическая установка ОС дующей структурой:
и программного обеспечения
Рассмотрим вариант установки Windows + MUI как более [ðàçäåëM]
ïàðàìåòð1M=çíà÷åíèå1M
сложный. Если читатель предпочитает не использовать MUI, ïàðàìåòð2M=çíà÷åíèå2M
то он может пропустить раздел, который ему посвящен.
……………………….
В типовой набор программ входят следующие: провод- ïàðàìåòðNM=çíà÷åíèåNM
ник (Total Commander, Far, Dos Navigator и др.); антивирус
(DrWeb, Norton Antivirus и др.), архиватор (WinZip, WinRar, Файлы «Winnt.sif», «Sysprep.inf» должны находиться в
WinAce и др.); программа, позволяющая просматривать мно- каталоге i386, в то время как файлы «*.txt» могут распола-
жество графических форматов (ACDsee, InfraView ), гаться в любом месте.
Microsoft Office, программа, предназначенная для записи Чтобы при установке Windows воспользоваться файлом
компакт-дисков (Nero, Easy CD Creator и др.), просмотра ответа с расширением txt, необходимо выполнить следую-
DVD-дисков (Power DVD, AsusDVD), кодек для просмотра щую команду:
видеоматериалов в формате MPEG4 (DivX).
«winnt[32] /u:<ôàéë îòâåòîâ>»;
Подготовка файловой структуры
будущего диска Оптимальным решением является создание базового
Существует несколько способов автоматической установ- шаблона с помощью Setup Manager, который затем надо
ки Microsoft Windows на рабочую станцию. Самым распрос- доработать вручную. Утилита Setup Manager запускается с
траненным из них является использование файла ответов помощью файла «Setupmgr.exe», который находится в ар-
во время инсталляции ОС. Автоматизация процесса уста- хиве «Deploy.cab» на диске с дистрибутивом Windows в пап-
новки ОС позволит специалистам системной поддержки: ке «\Support\Tools». Документация по файлам ответов на-
! минимизировать влияние человеческого фактора (до- ходится в том же архиве – файл «setupmrg.chm». Пример
верить специалисту системной поддержки решать воп- файла ответов см. на www.samag.ru/source.
росы, касающиеся введения регистрационного номера Для получения полной информации о параметрах коман-
ОС, управления разделами жесткого диска); дной строки «WinNT.exe» и «WinNT32.exe» используйте па-
! сократить время на установку ОС. раметр /?, например, «winnt.exe /?».

60
администрирование
Файловая структура и папок осуществляется до запуска графического режима,
дистрибутивного диска Windows поэтому все копируемые файлы и папки должны удовлет-
Расположение папки $OEM$ зависит от используемого фай- ворять стандарту 8.3.
ла ответов. Если установка Windows запускается автома- На втором этапе, на основе информации из файла от-
тически с компакт-диска, т.е. в качестве файла ответов ветов осуществляется запуск скопированных приложений
используется «WinNT.sif», то папка $OEM$, содержащая все с указанием явных путей к файлам, инициализирующих про-
дополнительно устанавливаемые компоненты, должна рас- цесс установки.
полагаться в корневом каталоге загрузочного диска (см. На завершающем этапе установки последнего прило-
рис. 1). Во всех остальных случаях папка $OEM$ должна жения происходит удаление каталогов, созданных во вре-
находиться в каталоге «i386», а файлом ответов является мя установки.
«Unattended.txt» (см. рис. 2).
Подготовка дистрибутива Windows
В этом разделе расскажем о том, как создать дистрибутив
Windows XP с интегрированным ServicePack, быстрыми ис-
правлениями (hotfix) и интегрировать MUI для Windows. На
первом этапе осуществляется интегрирование SP в дист-
рибутив. Данная задача решается успешно, если следовать
инструкциям, предлагаемым Microsoft, а вот с HotFix и MUI
возникают проблемы, если следовать документации, поэто-
му предлагается альтернативный способ решения этой за-
дачи.

Интеграция пакета исправлений Service Pack


Ðèñóíîê 1 Ðèñóíîê 2 в Windows
! Root – корневая папка загрузочного компакт-диска, со- Процесс интеграции Service Pack в Windows осуществляет-
держащего дистрибутив ОС; ся следующим образом: на жестком диске создается две
! i386 – в этой папке находятся установочные файлы папки. В одну из них копируется содержимое компакт-дис-
Windows; ка, содержащего дистрибутив Microsoft Windows XP
! $OEM$ – папка, содержимое которой используется для Professional (C:\BOOTCD\WINDOWS), в другую – дистрибу-
установки дополнительного программного обеспечения. тив Microsoft Service Pack (C:\BOOTCD\SERVICEPACK), ко-
Опишем файловую структуру папки $OEM$ (см. табли- торый представляет собой архив. Его необходимо распа-
цу 2). ковать, выполнив следующую команду:

Замечание: в разделе [Unattended] файла ответов пара- C:\BOOTCD\SERVICEPACK\XP-SP1.EXE /U /X:C:\BOOTCD\SERVICEPACK


метру OEMPreinstall должно быть присвоено значение Yes:
OEMPreinstall=Yes. Интегрировать Service Pack в дистрибутив Windows мож-
Òàáëèöà 2 но таким образом:

C:\BOOTCD\SERVICEPACK\UPDATE.EXE /S:C:\BOOTCD\WINDOWS

Замечание: в папке Windows должен находиться дист-


рибутив Windows, а не содержимое папки «i386».

Установка пакетов быстрых исправлений


в автоматическом режиме

Принципы именования hotfix


Быстрые исправления (hotfix) представляют собой саморас-
крывающиеся архивы с расширением EXE. Имена hotfix
присваиваются в соответствии со следующим шаблоном:

Q######_XXX_YYY_ZZZ _LLL.exe

где:
Механизм инсталляции ! Q###### – номер соответствующей статьи Microsoft
быстрых исправлений Knowledge Base с описанием решения обнаруженной
На первом этапе осуществляется копирование инсталля- проблемы;
ционных файлов различных приложений, в т.ч. и hotfix, в ! XXX – сокращенное название операционной системы,
соответствующий подкаталог $OEM$. Копирование файлов для которой предназначено данное исправление;

№2, февраль 2005 61


администрирование
! YYY – номер пакета исправления (Service Pack), к кото- мо выбрать из списка исправлений только необходимые из
рому относится hotfix; них, нужную языковую версию и версию ОС.
! ZZZ – платформа рабочей станции.

Для Windows XP в соответствии с данным шаблоном, име-


на имеют следующий вид: Q######_WXP_SP#_x86_EN.exe
или Q######_WXP_SP#_x86_RU.exe.

Копирование hotfix из Интернета


Копирование быстрых исправлений осуществляется с сай-
та компании Microsoft: http://v4.windowsupdate.microsoft.com\
catalog (см. рис. 3, 4).

Ðèñóíîê 3
После того как вход на сайт Windows Update успешно Ðèñóíîê 4
выполнен, для получения возможности копирования исправ- Необходимо отметить, что не рекомендуется пользовать-
лений на жесткий диск вашей рабочей станции необходи- ся общим адресом каталога Windows Update http://windows

Ðèñóíîê 5

62
администрирование
update.microsoft.com\catalog, поскольку, если вы зайдете на [GuiRunOnce]
него из операционной системы Windows XP, то будет вы- " C\Install\HotFix\Q######.exe /n /q /z"
"%WinDir%\System32\Cmd.exe /c RmDir C\Install /s /q"
полнен редирект не на четвертую версию Windows Update,
а на пятую: http://v5.windowsupdate.microsoft.com\catalog. К Для простоты восприятия в данном примере приведены
сожалению, в пятой версии еще не реализована возмож- только две строки: в первой строке осуществляется запуск
ность копирования hotfix на жесткий диск: их можно только процесса установки управления в скрытом режиме. Во вто-
установить. рой – удаление каталога «C:\Install» с жесткого диска. Ини-
циализация процесса инсталляции приложений осуществ-
Интеграция hotfix в дистрибутив Windows ляется после завершения процесса установки операцион-
Дистрибутивы рекомендуется расположить в папке «$OEM$\ ной системы.
C\Install\Folder» (C – буква, MICS – Install\Folder), где «Folder» –
соответствующее назначению название папки. Например, Ключи, используемые при установке hotfix
для hotfix рекомендуется использовать следующий путь: ! /F – закрыть все открытые приложения после установки
«$OEM$\C\Install\HotFix». исправления перед перезагрузкой ОС;
В файле ответов необходимо сделать следующие изме- ! /N – не создавать файлы отката (backup files) для вос-
нения. Для того чтобы установка Windows скопировала дан- становления системы;
ные из папки $OEM$ в соответствующие места, необходимо ! /Z – не перезапускать рабочую станцию после внедре-
cделать следующие изменения в разделе [Unattended]: ния hotfix;
! /Q – включить скрытый режим установки исправлений;
[Unattended]
OEMPreinstall=Yes
! /U – использовать автоматический режим установки. Вы-
вод сообщений только о возникающих критических
Управление hotfix осуществляется следующим образом: ошибках;

Ðèñóíîê 6

№2, февраль 2005 63


администрирование
! /L – вывести список установленных исправлений на ра- Òàáëèöà 3
бочей станции. Данная информация также находится в
реестре по пути: HKLM\Software\Microsoft\CurrentVersion\
HotFix\{SP\}Q######; HKLM\Software\Microsoft\Current
Version\Uninstall\Q######.

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


дующую команду: Автоматическая установка антивируса:
Norton Antivirus
Q######.exe /q /n /z Помня о том, что рабочая станция будет функционировать
в сети, необходимо устанавливать клиентскую часть Norton
Antivirus, находящуюся на сервере, где он установлен по
Установка MUI в автоматическом режиме пути \\Server\VPHOME\CLT-INST\WIN32, и сконфигуриро-
Загруженный с сайта Microsoft MUI необходимо распако- вать его для работы в сети. В этой папке находятся дистри-
вать, используя тот же метод, что и при распаковке дистри- бутив и конфигурационный файл: GRC.DAT, представляю-
бутива SP: щий собой текстовый файл. При установке программа ищет
его сама в текущем каталоге и читает из него данные, если
C:\BOOTCD\MUI\MUI_RUS.EXE /U /X:C:\BOOTCD\MUI же его нет, то антивирус устанавливается и работает в ав-
тономном режиме. Команда автоматической установки NAV
Замечание: версия MUI зависит от номера Service Pack. CE выглядит следующим образом:
Будьте внимательны при копировании SP с сайта: не оши-
битесь версией. c:\Install\NAV\setup.exe /qn
Затем необходимо скопировать его в папку $$\Install\MUI
например, а в файле ответов сделать следующие измене-
ния: Автоматическая установка навигатора
Сегодня одним из популярных навигаторов является Total
[GuiRunOnce] Commander. Его дистрибутив представляет собой саморас-
"c:\MUIINST\MUISETUP.EXE /i 0419 /d 0419 /r /s"
"%windir%\system32\cmd.exe /c rmdir c:\MUIINST /s/q" крывающийся ZIP-архив, в котором содержится файл от-
ветов – «install.inf». Распакуйте этот архив с помощью WinZip
Ключ /i указывает на кодовую страницу выбранного язы- и скорректируйте файл «install.inf». Исправленный пример
ка (0419 – русский), а ключ /d назначает язык интерфейса конфигурационного файла с соответствующими коммента-
Windows по умолчанию. Полный список ключей, а также риями находится на www.samag.ru/source. Запуск автома-
значений языков можно найти в файле muisetup.hlp, входя- тической установки осуществляется с помощью исполне-
щем в комплект поставки MUI. ния файла install.exe.

Интеграция драйверов в дистрибутив Автоматическая установка архиватора:


Драйвера устройств, не вошедших в стандартный набор, WinRar 3.x
можно интегрировать в дистрибутив. Для этого необходи- Для реализации автоматической установки WinRar в каче-
мо скопировать дистрибутивы драйверов в папку $OEM$\$1\ стве параметра необходимо указать ключ /s. В этом случае
PnPDrivers, а соответствующие им INF-файлы в каталог WinRar будет ассоциирован со всеми типами архивов, а
$OEM$\$1\INF. В папку PnPDrivers можно сделать соответ- также будет создана соответствующая группа в меню Пуск:
ствующие подпапки, например, Sound, Video.
В файле ответов в разделе [Unattended] необходимо C:\Install\Wrar\Wrar340ru.exe /s
прописать путь к этим драйверам. Каталоги разделяются
точкой с запятой, пробелы в строке не допускаются. Реко- Если же использовать ключ /silent, то пользователю бу-
мендуется также отключить проверку драйверов на «под- дет предложено выбрать, какие из вышеперечисленных
пись», задав соответствующее значение параметру функций ему понадобятся.
DriverSigningPolicy. Обязательным условием, как отмеча- Регистрационный файл wrar.reg, созданный на основе
лось ранее, является значение Yes параметра OEMPreinstall: данных из реестра, необходимо экспортировать в него пос-
ле установки программы с помощью команды:
[Unattended]
OemPnPDriversPath=drivers\video;drivers\sound regedit /s c:\Install\WRar\wrar.reg
DriverSigningPolicy=Ignore
OEMPreinstall=Yes

Автоматическая установка программы записи


Автоматическая установка CD/DVD: Nero Burning Rom 6.3.0.x
стандартных приложений Полноценный режим работы Nero доступен только в том
Предлагается автоматизировать процесс установки следу- случае, если известен серийный номер продукта. Существу-
ющих программ, образующих типовой набор: ет два способа регистрации программы.

64
администрирование
Способ 1 ! Автоматическая установка с настройками по умолчанию.
Указать серийный номер в ходе инсталляции программы в Процесс установки инициализируется следующей коман-
качестве одного из параметров командной строки: дой:

c:\Install\Nero\Nero551054.exe /silent /noreboot ↵ Pro11.msi /qb


/sn=xxxx-xxxx-xxxx-xxxx-xxxx-xxxx /write_sn

где: или
! /silent обеспечивает автоматический режим установки
программы; Setup.exe /qb
! /noreboot не перезагружает рабочую станцию после ус-
тановки программы; ! Автоматическая установка с использованием файла от-
! /sn=xxxx-xxxx-xxxx-xxxx-xxxx-xxxx – вместо xxxx-… ука- ветов с расширением MST, который создается с помо-
зывается серийный номер продукта. Используется вме- щью соответствующего мастера из набора Resource Kit
сте с ключом /write_sn. For Microsoft Office 2003. Установка осуществляется с
помощью:
Способ 2
Cоздать REG-файл, который содержит данные о регистра- Pro11.msi Transforms=FileName.mst /qb
ции программного продукта. Для экспорта этих данных в
реестр необходимо использовать следующую команду: или

Regedit /S c:\Install\Nero\nero.reg Setup.exe Transforms=FileName.mst /qb

Тогда команда, обеспечивающая автоматическую уста- Рассмотрим второй способ установки более подробно.
новку Nero, будет выглядеть следующим образом:
Замечание: чтобы во время автоматической установки
c:\Install\Nero\Nero551054.exe /silent /noreboot не запрашивался серийный номер, необходимо создать ад-
министративную установку, которая хранит в себе такие
Файл Nero.Reg выглядит так: важные параметры установки, как серийный номер Office,
название организации, на которую зарегистрирован про-
Windows Registry Editor Version 5.00 дукт.
[HKEY_LOCAL_MACHINE\SOFTWARE\Ahead\Nero - Burning Rom\Info]
"User"="UserName" Подготовка дистрибутива Office
"Company"="CompanyName"
"Serial6"=" xxxx-xxxx-xxxx-xxxx-xxxx-xxxx "
Создание административной установки
Создание административной установки необходимо для ре-
Автоматическая установка ализации автоматической установки Microsoft Office и воз-
Adobe Acrobat Reader 6 можности интегрировать пакеты исправлений (SP) и обнов-
Дистрибутив Adobe Acrobat Reader 6 представляет собой ления (updates) в дистрибутив.
самораскрывающийся архив. Необходимо запустить уста- По своей сути создание административной установки
новку Adobe Reader и дождаться, пока FEAD Optimizer рас- является установкой Microsoft Office в специальном режи-
пакует все файлы и будет предложено начать установку ме, который инициализируется командой «Setup /a».
программы. В %WinDir%\Cache находится содержимое этого В процессе установки Office будут запрошены серийный
архива в папке «Adobe Reader 6». Все файлы из нее необ- номер и название организации, на которую должен быть за-
ходимо скопировать $OEM$\С\Install\Areader6. Файл «Adobe регистрирован продукт. Впоследствии при установке Office
Reader 6.0.1.msi» необходимо переименовать в файл, удов- с этого дистрибутива серийный номер не будет запраши-
летворяющий формату имен 8.3, например Areader6.msi. ваться.
Команда запуска автоматической установки будет выгля-
деть следующим образом: Интеграция пакета исправлений
и обновлений в Office
C:\Install\Areader\Areader.msi /qb Перед интеграцией в Office дистрибутив пакета исправле-
ний, скопированный с сайта Microsoft, необходимо распа-
ковать, выполнив команду:
Автоматическая установка
Microsoft Office 2003 Office2003SP1-KB842532-fullfile-enu.exe ↵
/q /c /t:Ñ:\Office2003\SP1
и необходимых дополнений
где С:\Office2003\SP1 – путь, куда будет распаковано со-
Способы автоматической установки Office держимое архива.
В настоящее время существует как минимум два способа Интеграция в дистрибутив осуществляется с помощью
автоматической установки Microsoft Office. 2 команд:

№2, февраль 2005 65


администрирование
MsiExec /p C:\Office2003\SP1\MainSp1f.msp /a ↵ www.via.com.tw). Для этого необходимо пометить в дистри-
C:\Office2003\Office\Pro11.msi ShortFileNames=True /qb бутив оба набора и устанавливать их драйвера как прило-
MsiExec /p C:\Office2003\SP1\Owc11Sp1ff.msp /a ↵
C:\Office2003\Office\OWC11.msi ShortFileNames=True /qb жения, т.е. использовать второй вариант. Таким образом,
при установке драйверов один из пакетов выдаст сообще-
где C:\Office2003\SP1\ – путь к распакованной версии SP, а ние об ошибке, которое не будет отображено на экран, т.к.
C:\Office2003\Office\ – путь к дистрибутиву Microsoft Office установка ведется в скрытом режиме, и установка данного
2003. пакета будет завершена. Нужный пакет драйверов будет
Интеграция обновлений осуществляется по такому же установлен успешно.
сценарию: сначала необходимо скопировать обновления с
сайта Microsoft на жесткий диск, затем распаковать их и Создание загрузочного диска
интегрировать в дистрибутив Office 2003. Стоит отметить, В настоящее время практически любая программа, предназ-
что имена файлов обновлений строятся по следующему наченная для записи дисков, поддерживает возможность
принципу: создания загрузочных дисков. Однако перед записью дан-
ных на диск рекомендуется протестировать дистрибутив, а
XXX_KB######_YYY_ZZZ.exe именно создать его образ и установить с этого образа сис-
тему, используя VMWare Workstation (http://www.vmware.com).
! XXX – версия офиса, для которой предназначено обнов- На этом процесс формирования дистрибутивного дис-
ление; ка завершен. Осталось его протестировать и записать на
! KB###### – номер статьи Microsoft Knowledge Base, в диск.
которой приведен список исправлений;
! YYY – тип версии; Создание файла-образа диска
! ZZZ – языковая принадлежность. Для компиляции ISO-файлов на основе предоставляемых
в папке данных существует множество различных про-
Итак, для Office 2003 файлы обновлений строятся по грамм. Рекомендуется использовать программу «CDIMAGE
шаблону: GUI». Это маленькая программа (1,4 Мб) с графическим
интерфейсом, не требующая установки и обладающая не-
Office2003_KB######_FullFile_Enu.exe обходимым функционалом:

Создание файла ответов MST


Файл ответа для Microsoft Office можно создать с помощью
мастера Custom Installation Wizard, входящего в набор
Resource Kit соответствующей версии.
Запустив мастер Custom Installation Wizard, необходи-
мо создать новый MST-файл. Команда для установки Office
в автоматическом режиме будет следующей:

C:\Install\Office\setup.exe ↵
transforms= C:\Install\Office\answer.mst /qb- /noreboot

INF Update от Intel и Via


В том случае если используются материнские платы на мик- Ðèñóíîê 7
росхемах компании Intel или Via, необходимо установить со- Создавая файл-образ с помощью данной программы,
ответствующие наборы драйверов. Можно предложить как необходимо указать метку тома будущего диска (см. таб-
минимум два способа интеграции этих продуктов в дистри- лицу 4), убрать ограничение размера файла в 650 Мб, вклю-
бутив. чить скрытые файлы и каталоги в дистрибутив, указать
Первый – рассматривать дистрибутив как набор INF- файл, содержащий загрузчик диска. Загрузчик диска мож-
файлов и, пользуясь этим фактом, устанавливать эту про- но скачать из Интернета или указать ISO-образ-файл ли-
грамму, как совокупность драйверов, интегрировав соот- цензионного диска, содержащего загрузчик.
ветствующие файлы в папку PnPDrivers и INF. Òàáëèöà 4
Второй вариант – рассматривать дистрибутив как про-
грамму и для автоматической установки использовать сле-
дующую команду: «setup.exe /s». Оба этих способа равно-
значны, следует лишь отметить, что, скопировав дистрибу-
тив из Интернета, его необходимо разархивировать с по-
мощью программы WinZip.
Замечание: можно сделать универсальный дистрибутив,
содержащий набор драйверов для материнских плат на В корневом каталоге дистрибутива, в зависимости от
основе микросхем от Intel (http://www.intel.com) и Via (http:// версии ОС и встроенного SP, должны присутствовать оп-

66
администрирование
ределенные файлы, список которых приведен в таблицах 5 тановки ОС с файла-образа будут ОС и типовые програм-
и 6. мы.
Загрузчик диска ОС, необходимый для автозапуска ус-
тановки с компакт-диска, представляет собой файл с рас- Запись файла-образа на диск
ширением BIN. Его можно скопировать из Интернета или Сегодня почти любая программа, предназначенная для за-
сделать файл с расширением IMG с помощью любой соот- писи компакт-дисков, поддерживает возможность записи
ветствующей программы, например WinImage. дисков из файлов-образов. Опишем процесс записи ISO-
Òàáëèöà 5 файла на диск на примере программы Ahead Nero. После
запуска Nero необходимо выйти из запускаемого по умол-
чанию мастера и открыть ISO-файл: «File-Open File…», за-
тем запустить процесс записи: «Recorder-Burn Compilation…».
В появившемся диалоговом окне необходимо убедиться, что
метод записи диска выбран «disk-at-once» и отмечена оп-
ция «Finalize CD».
Òàáëèöà 6

Тестирование ISO-файла
Для тестирования ISO-файла рекомендуется использовать
VMWare. Эта программа предназначена для эмуляции раз-
личных операционных систем на персональном компьюте-
ре.
После установки VMWare необходимо запустить Virtual
Machine Wizard: «File ® New ® New Virtual Machine…». Ре-
зультатом работы мастера должен быть файл настроек, с Ðèñóíîê 9
помощью которого осуществляется эмуляция ОС Windows Замечание: если вы уверены в том, что вы не допусти-
XP Professional. Затем необходимо изменить свойства заг- ли ошибок в файле ответов и формировании структуры под-
рузки Virtual Machine: «Edit ® Virtual Machine Settings…». Во каталогов дистрибутива Windows, то вы можете сразу при-
вкладке «Hardware» необходимо сделать активной вклад- ступить к записи дистрибутива на диск без создания и тес-
ку «CD-ROM» и в качестве компакт-диска указать путь к тирования файла-образа. При этом необходимо учесть, что
файлу, содержащему образ будущего диска. надо правильно указать метку тома диска; указать путь к
файлу, содержащему загрузчик; отключить имитацию дис-
кеты и выбрать количество загрузочных секторов – 4.

Ðèñóíîê 10
Ðèñóíîê 8
Теперь можно приступить к тестированию ISO-файла, за- Заключение
пустив эмуляцию Windows XP Pro: «Power → Power On Созданный диск предназначен для автоматической уста-
(<CTRL+B>)». После запуска Virtual Machine будет осуществ- новки Windows и типового набора программ как для рабо-
ляться попытка установить ОС с одного из доступных носи- чей станции, которая будет впоследствии введена в домен,
телей, включая CD-ROM. Результатом автоматической ус- так и для домашнего компьютера.

№2, февраль 2005 67


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

ТЕХНИКА ОПТИМИЗАЦИИ ПОД LINUX


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

Дж Вейценбаум Дж
«Возможности вычислительных машин и человеческий
разум. От суждений к вычислениям»

Что находится под черной крышкой оптимизирующего компилятора? Чем один из них
отличается от другого? Правда ли, что Intel C++ намного круче GCC, а сам GCC бьет любой
Windows-компилятор? Хотите узнать, как помочь оптимизатору сгенерировать более
эффективный код? Сегодня мы займемся исследованием двух наиболее популярных Linux-
компиляторов: GCC 3.3.4 и Intel C++ 8.0, а конкретно – сравнением мощности их оптимизаторов.
Для полноты картины в этот список включен Microsoft Visual C++ 6.0 – один из лучших
Windows-компиляторов.
КРИС КАСПЕРСКИ
Общие соображения по оптимизации Остальные компиляторы оптимизируют примерно таким
Качество оптимизирующих компиляторов обычно оценива- же образом, поэтому эта библия вполне приемлема и для
ют по результатом комплексных тестов (мультимедийных, них. «Эффективность оптимизации» из абстрактных цифр
«общесистемных» или математических). Что именно опти- превращается в серию простых тестов, каждый из которых
мизируется и как – остается неясным. Основной «интел- можно прогнать через транслятор и потрогать руками. Ди-
лект» оптимизаторов сосредоточен в высокоуровневом пре- зассемблирование откомпилированных файлов позволяет
процессоре – своеобразном «ликвидаторе» наиболее оче- однозначно установить – справился оптимизатор со своей
видных программистских ошибок. Чем качественнее исход- задачей или нет.
ный код, тем хуже он поддается оптимизации. Только ведь… В данной статье сравниваются два наиболее популяр-
над качественным кодом работать надо! Много знать и оже- ных Linux-компилятора: GCC 3.3.4 (стабильная версия, про-
сточенно думать, ломая карандаши или вгрызаясь в кла- веренная временем, входящая в большинство современных
виатуру. Кому-то это в радость, а кто-то предпочитает пи- дистрибутивов) и Intel C++ 8.0 (далее по тексту icl), позици-
сать кое-как. Все равно, мол, компилятор соптимизирует! онируемый как самый эффективный компилятор всех вре-
Желание перебросить часть работы на транслятор – впол- менен и народов, 30-дневная ознакомительная, а также бес-
не естественное и нормальное (для творчества больше вре- платная для некоммерческого применения полнофункцио-
мени останется), но при этом нужно заранее знать, что имен- нальная Linux-версия которого лежит на ftp-сервере Intel: ftp:/
но он оптимизирует, а что только пытается. Но как это мож- /download.intel.com/software/products/compilers/downloads/
но узнать? На фоне полнейшей терминологической нераз- l_cc_p_8.0.055.tar.gz. Некоммерческую лицензию можно
берихи, когда одни и те же приемы оптимизации в каждом оформить прямо на сайте компании (без лицензии компи-
случае называются по-разному, прячась за ничего не гово- лятор работать не будет). Для полноты картины в этот спи-
рящими штампами типа «copy propagation» (размножение сок включен древний, но все еще используемый Windows-
копий) или «redundancy elimination» (устранение избыточ- компилятор Microsoft Visual C++ 6.0, для краткости обозна-
ности), требуется очень качественная документация на ком- чаемый, как msvc. Если не оговорено обратное, приведен-
пилятор, но она – увы – обычно ограничивается тупым пе- ные примеры должны компилироваться со следующими клю-
речислением оптимизирующих ключей с краткой пометкой чами: -O3 -march= pentium3 (gcc), -O3 -mcpu=pentium4 (icl) и
за что каждый из них отвечает. Какие копии размножает /Ox (msvc). Разница между архитектурами объясняется тем,
компилятор и с какой целью? Какую избыточность он уст- что GCC 3.3.4 еще не поддерживает режима оптимизации
раняет и зачем? Не является ли размножение внесением для Pentium 4, а Intel C++8.0 не имеет специального ключа
избыточности, которую самому же оптимизатору и прихо- для Pentium III, в результате чего между ними возникает не-
дится удалять?! которая «нестыковка». Однако на результаты наших экспе-
Взять хотя бы документацию на компилятор Intel C++ 7.0/ риментов она никак не влияет, поскольку никакие специфич-
8.0. Это просто перечень ключей командной строки, раз- ные для Pentium 4 возможности здесь не используются.
бавленный словесным мусором, в котором нет никакой кон-
кретики. Скачайте для сравнения документацию на компи- Константы
лятор фирмы Hewlett-Packard: http://docs.hp.com/en/B6056-
96002/B6056-96002.pdf. Доходчивое описание архитектуры Cвертка констант
процессора, советы по кодированию, тактика и стратегия Вычисление констант на стадии компиляции (оно же, «раз-
оптимизирующей трансляции на конкретных примерах. множение» или «свертка» констант, constant elimination/
Настоящая библия программиста! folding/propagation, или сокращенно CP) – популярный при-

68
программирование
ем оптимизации, избавляющий программиста от необхо- Ëèñòèíã 1. Íå îïòèìèçèðîâàííûé êàíäèäàò íà îáúåäèíåíèå
димости постоянно иметь калькулятор под рукой. Все кон- êîíñòàíò
стантные выражения (как целочисленные, так и веществен- printf("hello,world!\n"); // îäíà ñòðîêîâàÿ êîíñòàíòà
ные) обрабатываются транслятором самостоятельно и в от- printf("hello,world!\n"); // äðóãàÿ êîíñòàíòà, èäåíòè÷íàÿ
ïåðâîé
компилированный код не попадают. printf("i say hello, world!\n"); // êîíñòàíòà ñ èäåíòè÷íîé
Рассмотрим следующий пример: a = 2 ∗ 2; b = 4 ∗ с / 2; ïîäñòðîêîé
Компиляторы, поддерживающие такую стратегию оптими- Компилятор msvc «честно» генерирует все три строко-
зации, превратят его в: a = 4; b = 2 ∗ с; При этом возникает вые константы, а gcc и icl только две из них: «hello,world!\n»
целый букет побочных эффектов: (4∗a/2) не эквивалентно и «i say hello, world!\n». На то, что первая строка совпадает
(2∗a), потому что при (4∗a) может наступить переполнение, а с концом второй, ни один из компиляторов не обратил вни-
при (a/2) уже может и не наступить! Скажите, что это наи- мания. Приходится напрягаться и писать:
гранный пример? А вот и нет! При работе с битовыми маска-
ми – это норма. Выражение (k∗a/n) часто используется для Ëèñòèíã 2. ×àñòè÷íî îïòèìèçèðîâàííûé âàðèàíò
сброса старших битов переменной с их последующем сдви- char s[]="i say hello, world!\n"; // ðàçìåùàåì ñòðîêó
гом вправо на заданное количество позиций. Но после того â ïàìÿòè
printf(&s[6]); // âûâîäèì ïîäñòðîêó
как над программой поработает оптимизатор, этот эффект printf(&s[6]); // âûâîäèì ïîäñòðîêó
теряется! С вещественной арифметикой еще хуже. Значе- printf(s); // âûâîäèì âñþ ñòðîêó öåëèêîì
ние double (4∗a/2) вполне может и не совпасть с double (2∗a)
даже безо всякого переполнения! В double начинает играть Но ведь позицию подстроки в строке придется опреде-
значение конечная точность. Если (int)4/(int)2 это точно 2, то лять вручную, тупым подсчетом букв! Или использовать мак-
double(4)/double(2) – это 2.0 плюс-минус что-то очень малень- росы, определяя длину строки с помощью sizeof, только…
кое. В научном мире это правило часто формулируют так: это же сколько кодить надо!
«результат вычисления с double не может равняться 0» (по-
этому все конструкции типа if(double_function(x)==0) надо Ëèñòèíã 3. Ïîëíîñòüþ îïòèìèçèðîâàííûé âàðèàíò
заменять на if(fabs(double_function(x))<EPS), иначе не рабо- char *s1 = "I say hello,world!\n";
тает – результат вычислений будет зависеть от версии ком- char *s2 = s1+sizeof("I say ")-1; //"hello, world!\n"
printf(s2);
пилятора и ключей оптимизации). Если оптимизатор превра- printf(s2);
щает (4∗a/2) просто в (2∗a) (выкидывает одну операцию), он printf(s1);
теряет точность не два раза, а один. В нормально написан-
ной программе (не оперирующей с очень малыми или очень В отличие от ситуации с объедением двух полностью тож-
большими числами) это несущественно, т.к. программист из- дественных строк, практическая ценность которой сомни-
начально проектирует код так, чтобы от этих погрешностей тельна, задача объединения подстроки со строкой встреча-
не зависеть. Видимо, разработчики компиляторов на эту ка- ется довольно часто. Код на листинге 3 предпочтительнее,
тегорию людей и ориентируются, а тот, кто умножает 10(-308) чем «частично оптимизированный вариант» (листинг 2), по-
на 10(+307), желая получить именно 0.1, и, таким образом, за- скольку в нем отсутствует двукратное вычисление адресов
вязывается на погрешность, – сам себе и виноват! (&s[6]), которое компилятор может и не догадаться свернуть,
Улучшенная свертка констант, в англоязычной литера- а учет смещения на sizeof(«I say »)-1 == 6 байт производится
туре именуемая «advanced constant folding/propagation», за- еще на этапе трансляции.
меняет все константные переменные их непосредственным
значением, например: a = 2; b = 2 ∗ a; c = b - a; превраща- Константная подстановка в условиях
ется в c = 2. Переменные, использующиеся для «принятия решения» о вет-
Свертку констант в полной мере поддерживают все три влении, в каждой из веток имеют вполне предсказуемые зна-
рассматриваемых компилятора: msvc, icl и gcc. чения, зачастую являющиеся константами. Код вида:
if (a == 4) b = 2 ∗ a; может быть преобразован в: if (a == 4) b = 8,
Объединение констант что компиляторы msvc/gcc и осуществляют, избавляясь от
Несколько строковых констант с идентичным содержимым лишней операции умножения, а вот icl этого сделать не дога-
для экономии памяти могут быть объедены («merge») в одну. дывается.
То же самое относится и к вещественным значениям. Це-
лочисленные 32-битные константы объединять невыгодно, Константная подстановка в функциях
поскольку ссылка на константу занимает больше места1, Если все аргументы функции – константы и она не имеет
чем машинная команда с копией константы внутри, да и никаких побочных эффектов типа модификации глобальных/
выборка константы из памяти быстродействию, в общем- статических переменных (и не зависит от их значения), ре-
то, не способствует. Покажем технику объединения на сле- зультат выполнения функции также будет константой. Ком-
дующем примере: пиляторы в подавляющем большинстве случаев об этом не

1
В 32-разрядном режиме ссылка занимает 32 бита плюс от одного до шести байтов на поля адресации (один байт «съедает» ModR/M,
задающее способ адресации и выбирающее регистры, другой байт приходится на факультативное поле SIB – Scale-Index-Base, использу-
емое для масштабирования, и еще четыре байта отводятся под непосредственное смещение константы в памяти), поэтому ссылки стано-
вятся выгодными только начиная с 64/80-битных констант.

№2, февраль 2005 69


программирование
догадываются. Поле зрения оптимизатора ограничено телом лиотеку), иначе после компоновки ваш код будет перепол-
функции. «Сквозная» подстановка аргументов («свертка нен ненужными приложению функциями. Помещайте в
функций») осуществляется лишь в случае встраиваемых файл только «родственные» функции, которые всегда ис-
(inline) функций или глобального режима оптимизации. пользуются в паре и по отдельности не имеют никакого
Компилятор icl имеет специальный набор ключей -ip/-ipo, смысла. Одна функция на объектный файл – это вполне нор-
форсирующий глобальную оптимизацию в текущем файле мально. Две-три еще терпимо, а вот больше – уже пере-
и всех исходных текстах соответственно, что позволяет ему бор. Присмотритесь, как устроены стандартные библиоте-
выполнять константную подстановку в следующем коде: ки языка Си, и ваши программы сразу похудеют.

Ëèñòèíã 4. Êàíäèäàò íà êîíñòàíòíóþ ïîäñòàíîâêó Удаление неиспользуемых переменных


f1(int a, int b) Объявленные, но неиспользуемые переменные удаляются
{ всеми современными компиляторами. Древние оптимиза-
return a+b;
} торы удаляли лишь переменные, к которым не происходи-
ло ни одного обращения, сейчас же оптимизатор строит
f2 ()
{ своеобразное «абстрактное дерево», и ветви, ведущие в
return f1(0x69, 0x96) + 0x666; никуда, полностью обрубаются. В приведенном ниже при-
}
мере msvc, icl и gcc удаляют все три переменные – a, b и с:
Компилятор gcc достигает аналогичного результата лишь
за счет того, что на уровне оптимизации -O3 он автомати- Ëèñòèíã 5. Ïðèìåð ïðîãðàììû ñ íåèñïîëüçóåìûìè ïåðåìåííûìè
чески встраивает все мелкие функции в тело программы, в main(int n, char **v)
то время как msvc встраивает лишь некоторые из них. И {
int a,b,c;
даже если функция объявлена как «inline», оптимизатор ос- a =n;
тавляет за собой право решать: осуществлять ли встраи- b = a + 1;
c = 6*b; // ïåðåìåííàÿ c íå èñïîëüçóåòñÿ, à çíà÷èò
вание в данном случае или нет. ïåðåìåííûå a è b ëèøíèå
return n;
}
Код и переменные
Удаление мертвого кода Удаление неиспользуемых выражений
«Мертвым кодом» (dead code) называется код, никогда не Неиспользуемые выражения удаляются всеми тремя рас-
получающий управления и впустую транжирящий дисковое сматриваемыми компиляторами. Например:
пространство и оперативную память. В простейшем случае
он представляет собой условие, ложность которых очевид- Ëèñòèíã 6. Ïðèìåð ïðîãðàììû ñ íåèñïîëüçóåìûìè âûðàæåíèÿìè
на еще на стадии трансляции, или код, расположенный пос- main(int n, char** v)
ле безусловного возврата из функции. {
int a,b;
Вот, например: if (0) n++; else n--. Это несложная зада- a = n+0x666; // íå èñïîëüçóåòñÿ, ïåðåêðûâàåòñÿ (2*n)
ча, и с нею успешно справляются все три рассматривае- b = n-0x999; // òåðÿåòñÿ ïðè âûõîäå èç ôóíêöèè
a = 2*n; // åäèíñòâåííîå èñïîëüçóåìîå âûðàæåíèå
мых компилятора. А вот в следующем случае бесполезность return a;
выражения «n++» уже не столь очевидна: for (a = 0; a < 6;
}
a++) if (a < 0) n++. Условие (a < 0) всегда ложно, поскольку
цикл начинается с 0 и продолжается до 6. Из всех трех рас- Выражение (n+0x666) не используется, поскольку пере-
сматриваемых компиляторов это по «зубам» только icl. крывается следующей операцией присвоения (2∗n). Выра-
жение (n-0x999) теряется при выходе из функции. Следо-
Удаление неиспользуемых функций вательно, наш код эквивалентен: return (n – 0x999).
Объявленные, но ни разу не вызванные функции компиля- Не всегда такая оптимизация проходит безболезненно.
тору не так-то просто удалить. Технология раздельной ком- Компиляторы «забывают» о том, что некоторые вычисления
пиляции (один файл исходного текста – один объектный мо- имеют побочные эффекты в виде выброса исключения. Код
дуль) предполагает, что функция, не использующаяся в те- вида: a = b/c; a = d, можно оптимизировать в том, и только в
кущем модуле, вполне может вызываться из остальных. Ре- том случае, если переменная c заведомо не равна нулю. Но
альный расклад выявляется лишь на стадии компоновки. ни один из трех рассматриваемых компиляторов такой про-
Выходит, неиспользуемые функции должен удалить линкер? верки не выполняет! Забавно, но в сокращении арифмети-
Но «выцарапать» мертвую функцию из объектного файла ческих выражений (о которых речь еще впереди) оптимиза-
еще сложнее! Для этого компоновщику необходимо иметь торы ведут себя намного более осторожно – никто из них не
мощный дизассемблер и нехилый искусственный интеллект рискует сокращать выражение (a/a) до единицы, даже если
впридачу. Компилятор icl в режиме глобальной оптимиза- переменная a заведомо не равна нулю! Бардак, в общем.
ции (ключ -ipo) отслеживает неиспользуемые функции еще
на этапе трансляции и в объектный модуль они не попада- Удаление лишних обращений к памяти
ют. Остальные компиляторы ничем подобным похвастать Компиляторы стремятся размещать переменные в регист-
не могут. Поэтому категорически не рекомендуется держать рах, избегая «дорогостоящих» операций обращения к памя-
весь проект в одном файле (особенно если вы пишите биб- ти. Взять хотя бы такой код: «i =*p+c; b = *p - d;». Очевидно,

70
программирование
что второе обращение к *p лишнее и компиляторы посту- Ëèñòèíã 10. Ïåðåìåííûå a è b – ëèøíèå
пают так: t =*p; i = t+c; b = t-d, при этом неявно полагается, main(int n, char** v)
что содержимое ячейки *p не изменяется никаким внешним {
кодом, в противном случае оптимизация будет носить ди- int a,b;
a = n+1;
версионно-разрушительный характер. Что если перемен- b = 1-a; // èçáàâëÿåòñÿ îò ïåðåìåííîé a: (1 – (n + 1));
ная используется для обмена данными/синхронизации не- return a-b; // èçáàâëÿåòñÿ îò ïåðåìåííîé b:
((n + 1) – (1 – (n + 1)));
скольких потоков? Что, если какой-то драйвер возвращает }
через нее результат своей работы? Наконец, что если мы
хотим получить исключение по обращению к странице па- Очевидно, что его можно переписать, как (2∗n+1), изба-
мяти? Для усмирения оптимизатора во всех этих случаях вившись сразу от двух переменных. Все три рассматривае-
необходимо объявлять переменную как volatile (буквально: мых компилятора именно так и поступают. (С технической
«изменчивый», «неуловимый»), тогда при каждом обраще- точки зрения данный прием оптимизации является частным
нии она будет перечитываться из памяти. случаем более общего механизма алгебраического упро-
Указатели – настоящий бич оптимизации. Компилятор щения выражений и распределения регистров, который
никогда не может быть уверен, адресуют ли две перемен- будет рассмотрен ниже.)
ные различные области памяти или обращаются к одной и
той же ячейке памяти. Вот, например: Размножение переменных
На процессорах с конвейерной архитектурой удаление «лиш-
Ëèñòèíã 7. Ïðèìåð ñ ëèøíèìè îáðàùåíèÿìè ê ïàìÿòè, них» копий порождает ложную зависимость по данным, при-
îò êîòîðûõ íåëüçÿ èçáàâèòüñÿ
водящую к падению производительности и переменные при-
f(int *a, int *b) ходится не только «сворачивать», но и размножать!
{
int x; Рассмотрим пример:
x = *a + *b; // ñëîæåíèå ñîäåðæèìîãî äâóõ ÿ÷ååê
*b = 0x69; // èçìåíåíèå ÿ÷åéêè *b, àäðåñ êîòîðîé Ëèñòèíã 11. Ëîæíàÿ çàâèñèìîñòü ïî äàííûì
íå èçâåñòåí êîìïèëÿòîðó
x += *a; // íåò ãàðàíòèè, ÷òî çàïèñü â ÿ÷åéêó *b
íå èçìåíèëà ÿ÷åéêó *a a = x + y;
b = a + 1; // b çàâèñèò îò a
} a = i - j;
c = a – 1; // ñ çàâèñèò îò a, òî÷íåå, îò åå âòîðîé «êîïèè»
Компилятор не может разместить содержимое *a во
временной переменной, поскольку, если ячейки *a и *b ча- Операции (x + y) и (i – j) могут быть выполнены одно-
стично или полностью перекрываются, модификация ячей- временно, но чтобы сохранить результат вычислений, часть
ки *b приводит к неожиданному изменению ячейки *a! процессорных модулей вынуждена простаивать в ожида-
То же самое относится и к следующему примеру: нии, пока не освободится переменная a.
Чтобы устранить эту зависимость, код необходимо пе-
Ëèñòèíã 8. Ïðèìåð ñ ëèøíèìè îáðàùåíèÿìè ê ïàìÿòè, реписать так:
îò êîòîðûõ ìîæíî èçáàâèòüñÿ âðó÷íóþ
f(char *x, int *dst, int n) Ëèñòèíã 12. Ðàçìíîæåíèå ïåðåìåííîé a óñòðàíÿåò çàâèñèìîñòü
{ ïî äàííûì
int i;
for (i = 0; i < n; i++) *dst += x[i]; a1 = x + y;
} b = a1 + 1; // b çàâèñèò îò a1
a2 = i - j;
Компилятор не может (не имеет права) выносить пере- c = a2 – 1; // c çàâèñèò îò a2, íî íå çàâèñèò îò a1
менную dst за пределы цикла, и обращения к памяти будут
происходить на каждой итерации. Чтобы этого избежать, Простейшие зависимости по данным процессоры от
программист должен переписать код так: Pentium Pro и выше устраняют самостоятельно. Ручное раз-
множение переменных здесь только вредит – количество
Ëèñòèíã 9. Îïòèìèçèðîâàííûé âàðèàíò регистров общего назначения ограничено и компиляторам
f(char *x, int *dst, int n) их катастрофически не хватает. Но это только снаружи.
{ Внутри процессора содержится здоровый регистровый
int i,t =0;
for (i=0;i<n;i++) t+=x[i]; // ñîõðàíåíèå ñóììû файл, автоматически «расщепляющий» регистры по мере
âî âðåìåííîé ïåðåìåííîé необходимости.
*dst+=t; // çàïèñü êîíå÷íîãî ðåçóëüòàòà â ïàìÿòü
} Сложные зависимости по данным на микроуровне уже
неразрешимы и чтобы справится с ними, необходимо иметь
доступ к исходному тексту программы. Компилятор icl уст-
Удаление копий переменных раняет большинство зависимостей, остальные же оставля-
Для экономии памяти компиляторы обычно сокращают ко- ют все как есть.
личество используемых переменных, выполняя алгебраи-
ческое развертывание выражений и удаляя лишние копии. Распределение переменных по регистрам
В англоязычной литературе за данной техникой оптимиза- Регистров общего назначения всего семь, а чаще и того мень-
ции закреплен термин «copy propagation», суть которого ше. Регистр EBP используется для организации фреймов
поясняется в следующем примере: (так же называемых стековыми кадрами), регистр EAX по

№2, февраль 2005 71


программирование
общепринятому соглашению используется для возвраще- женности» той или иной переменной. Судя по всему, ком-
ния значения функции. Некоторые команды (строковые пилятор msvc использует большое количество эвристичес-
операции, умножение/деление) работают с фиксированным ких шаблонов, поэтому с большим отрывом и побеждает
набором регистров, который на протяжении всей функции всех остальных.
приходится держать «под сукном» или постоянно гонять
данные от одного регистра к другому, что также не добав- Регистровые ре-ассоциации
ляет производительности. Для преодоления катастрофической нехватки регистров,
Стратегия оптимального распределения переменных по некоторые компиляторы стремятся совмещать счетчик цик-
регистрам (global registers allocation) – сложная задача, ко- ла с указателем на обрабатываемые данные. Код вида
торую еще предстоит решить. Пусть слово «global» не вво- «for (i = 0; i < n; i++) n+=a[i];» превращается ими в «for (p= a;
дит вас в заблуждение. Эта глобальность сугубо локально- p < &a[n]; p++) n+=*p;» Экономия налицо! Впервые (насколь-
го масштаба, ограниченная одной-единственной функци- ко мне известно) эта техника была применена в компилято-
ей, а то и ее частью. рах фирмы Hewlett-Packard, где она фигурировала под тер-
Компиляторы стремятся помещать в регистры наиболее мином register reassociation. А что же конкуренты?! Рассмот-
интенсивно используемые переменные, однако, под «интен- рим следующий код (кстати, взятый из документации на ком-
сивностью» здесь понимается отнюдь не частота использо- пилятор HP):
вания, а количество «упоминаний». Но ведь не все «упоми-
нания» равнозначны! Вот, например, if (++a % 16) b++; else Ëèñòèíã 14. Íåîïòèìèçèðîâàííûé êàíäèäàò íà ðåãèñòðîâóþ
ðå-àññîöèàöèþ
c++; обращение к переменной c происходит в 16 раз чаще!
Статистка обращений не всегда может быть получена путем int a[10][20][30];
void example (void)
прямого анализа исходного кода программы, так что ждать {
помощи со стороны машины – наивно. int i, j, k;
for (k = 0; k < 10; k++)
Языки Си/Си++ поддерживают специальное ключевое for (j = 0; j < 10;j++)
слово «register», управляющее размещением переменных, for (i = 0; i < 10; i++)
a[i][j][k] = 1;
однако, оно носит характер рекомендации, а не императи- }
ва и все три рассматриваемых компилятора его игнориру-
ют, предпочитая интеллекту программиста свой собствен- Грамотный оптимизатор должен переписать его так:
ный машинный интеллект.
Представляет интерес сравнить распределение пере- Ëèñòèíã 15. Îïòèìèçèðîâàííûé âàðèàíò — ñ÷åò÷èê öèêëà
ñîâìåùåí ñ óêàçàòåëåì íà ìàññèâ
менных по регистрам в глубоко вложенных циклах, посколь-
ку его вклад в общую производительность весьма значите- int a[10][20][30];
void example (void)
лен. Рассмотрим следующий пример: {
int i, j, k;
Ëèñòèíã 13. Ãëóáîêî âëîæåííûé öèêë ÷óâñòâèòåëåí ê êà÷åñòâó register int (*p)[20][30];
ðàñïðåäåëåíèÿ ïåðåìåííûõ ïî ðåãèñòðàì for (k = 0; k < 10; k++)
for (j = 0; j < 10; j++)
int *a, *b; for (p = (int (*)[20][30]) &a[0][j][k], ↵
main(int n, char **v) i = 0; i < 10; i++)
*(p++[0][0]) = 1;
{ }
int i,j; int sum=0;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) Эксперимент показывает, что ни msvc, ни gcс не выпол-
sum += sum*a[n*i + j] + sum/b[j] + x++; няют регистровых реассоциаций ни в сложных, ни даже в
return sum+x;
} простейших случаях. С приведенным примером справился
один лишь icl. Впрочем, это его все равно не спасает, и msvc
Компилятору msvс регистров общего назначения уже не оказывается впереди за счет более оптимального распре-
хватило и три переменных, обрабатываемых внешним цик- деления регистров.
лом, «вылетели» в стек. Компилятор icl «уложился» в 14 (!)
стековых переменных, 5 (!) из которых обрабатываются во Выражения
внутреннем цикле! О какой производительности после этого
можно говорить?! Второе место занял gcc – из 10 стековых Упрощение выражений
переменных 5 расположены во внутреннем цикле. А вы еще Выполнять алгебраические упрощения оптимизаторы на-
Microsoft ругаете… учились лишь недавно, но эффект, как говорится, превзо-
За счет чего достигается такой выигрыш? Обычно для шел все ожидания. Редкий программистский код не содер-
распределения регистров используются графы, которые в жит выражений, которые нельзя было бы сократить. Открой-
зависимости от интенсивности использования регистров те документацию по MFC в разделе «Changing the Styles of
раскрашиваются в различные цвета – от «холодного» до a Window Created by MFC» и поучитесь, как нужно писать
«горячего» (поэтому эта техника часто называется color- программы.
map). Однако это в теории. На практике же для достижения
приемлемого качества распределения приходится прибе- Ëèñòèíã 16. Ýòî òàê Microsoft íàñ ó÷èò ïèñàòü ïðîãðàììû
гать к некоторому набору эвристических шаблонов, дела- BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
ющих «интуитивные» предположения о реальной «загру- {

72
программирование
// Create a window without min/max buttons or sizable int x,y;
// border x = n-n; y = n+n;
cs.style = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER; return x+y-2*n+(n/n);
}
// Size the window to 1/3 screen size and center it
cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3;
cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3; Казалось бы, чего в нем сложного? Компиляторы msvc
cs.y = ((cs.cy * 3) - cs.cy) / 2; и gcc выкидывают все кроме (n/n), оставляя его на тот слу-
cs.x = ((cs.cx * 3) - cs.cx) / 2;
чай, если переменная n окажется равной нулю. Поразитель-
// Call the base-class version но, но icl выполняет все вычисления целиком, не произво-
return CFrameWnd::PreCreateWindow(cs);
} дя никаких упрощений.
Таким образом, выполнение алгебраических упроще-
Неудивительно, что Windows так тормозит! Чтобы понять ний – весьма капризная и непредсказуемая операция. Не
очевидное, парням из Microsoft потребовалось две операции надейтесь, что компилятор выполнит ее за вас!
умножения, две – деления и две – сложения. Итого: шесть
операций. Упрощение алгоритма
Проверим, сможет ли оптимизатор избавиться от мусор- Наибольший прирост производительности дает именно ал-
ных операций, предварительно переписав код так: горитмическая оптимизация (например, замена пузырько-
вой сортировки на сортировку вставками). Никакой компи-
Ëèñòèíã 17. Íåîïòèìèçèðîâàííûé êàíäèäàò íà àëãåáðàè÷åñêîå лятор с этим справиться не в состоянии, во всяком случае,
óïðîùåíèå
пока. Но первый шаг уже сделан. Современные компиля-
struct CS{int x;int y;}; торы распознают (или во всяком случае пытаются распоз-
f(int n,)
{ нать) смысловую нагрузку транслируемого кода и при не-
struct CS cs; обходимости заменяют исходный алгоритм другим, намно-
cs.y = n; cs.x = n;
y = ((cs.y * 3) - cs.y) / 2; го более эффективным.
x = ((cs.x * 3) - cs.x) / 2; Вот, например:
return y - x;
}
Ëèñòèíã 20. Êàíäèäàò íà óïðîùåíèå àëãîðèòìà
Компилятор msvc выбрасывает лишь часть операций, main(int n, char **v)
но чем он руководствуется при этом – непонятно. Оптими- {
int a = 0; int b = 0;
затор легко раскрывает скобки ((cs.y∗3) – cs.y), но дальше for(i=0; i<n; i++) a++; // ìíîãîêðàòíîå ñëîæåíèå –
этого он не идет, послушно выполняя бессмысленную опе- ýòî óìíîæåíèå
for(j=0; j<n; j++) b++;
рацию (cs.y∗2 / 2). И тут же, словно одумавшись, принуди- return a*b;
тельно обнуляет регистр EAX, возвращая константный ноль. }
Создается устойчивое впечатление, что результат выраже-
ния вычисляется компилятором еще на стадии трансляции, Для человека очевидно, что этот код можно записать
но он никак не решается им воспользоваться: так: (n∗n). Мой любимый msvc именно так и поступает, а
вот icl и gcc накручивают циклы на кардан.
Ëèñòèíã 18. Çàãàäî÷íûé êîä, ñãåíåðèðîâàííûé êîìïèëÿòîðîì msvc
Использование подвыражений
mov eax, [esp+arg_0] Хорошие оптимизаторы никогда не вычисляют значение
; çàãðóçêà n
одного и того же выражения дважды.
add eax, eax Рассмотрим следующий пример:
; n *= 2; ( áåç ó÷åòà çíàêà)
cdq Ëèñòèíã 21. Ïîäâûðàæåíèå (x*y) – îáùåå
; ïðåîáðàçîâàòü äâîéíîå çíàêîâîå ñëîâî
a = x*y + n;
sub eax, edx b = x*y - n; // âûðàæåíèå (x*y) óæå âñòðå÷àëîñü! È x,y
; ó÷åñòü çíàê ñ òåõ ïîð íå ìåíÿëèñü!
sar eax, 1 Чтобы избавиться от лишнего умножения, этот код не-
; n /= 2;
xor eax, eax обходимо переписать так:
; n = 0;
Ëèñòèíã 22. Îïòèìèçèðîâàííûé âàðèàíò
Компилятор icl выбрасывает мусорный код полностью, t = x*y; // âû÷èñëèòü âûðàæåíèå (x*y) è çàïîìíèòü ðåçóëüòàò
генерируя честный XOR EAX,EAX, а вот gcc вообще не вы- a = t + n; // ïîäñòàíîâêà óæå âû÷èñëåííîãî çíà÷åíèÿ
b = t - n; // ïîäñòàíîâêà óæå âû÷èñëåííîãî çíà÷åíèÿ
полняет никаких упрощений! Однако могущество icl очень
переменчиво. Американцы называют это «удалением избыточности»
Возьмем такой пример: (redundancy elimination) или «совместным использованием
общих выражений» (Share Common Subexpressions). Полное
Ëèñòèíã 19. Åùå îäèí êàíäèäàò íà àëãåáðàè÷åñêîå óïðîùåíèå удаление избыточности (оно же Full Redundancy Elimination
f(int n) или сокращенно FRE) предполагает, что совместное исполь-
{ зование выражений происходит только в основных путях

№2, февраль 2005 73


программирование
(path) выполнения программы. Ветвления при этом игнори- Компилятор msvc уже не справляется и генерирует две
руются. Частичное удаление избыточности (оно же Partial операции умножения, вместо одной. А вот компиляторы icl
redundancy elimination или сокращенно PRE) охватывает и gcc поступают правильно, вычисляя выражение (x∗y) всего
весь программный код – как внутри ветвлений, так и сна- один раз.
ружи. То есть частичное удаление избыточности удаляет
избыточность намного лучше, чем полное, хотя при полном Сводная таблица качества оптимизации
программа компилируется чуть-чуть быстрее. Вот такая тер- Òàáëèöà 1. Ìåõàíèçìû îïòèìèçàöèè, ïîääåðæèâàåìûå ðàçëè÷íûìè
минологическая путаница. êîìïèëÿòîðàìè
Вся заковырка в том, что выражение «Partial redundancy
elimination» переводится на русский язык отнюдь не как
«частичное удаление избыточности» (хоть это и общепри-
нятый вариант), а «удаление частичной избыточности», и
«full redundancy elimination» – «удаление полной избыточ-
ности», что совсем не одно и то же!
Все три рассматриваемых компилятора поддерживают
совместное использование выражений. С приведенным при-
мером они справляются легко. Но давайте усложним зада-
чу, предложив им код подсчета суммы соседних элементов
массива:

Ëèñòèíã 23. Ïðèìåð ñ íåî÷åâèäíîé ðàçáèâêîé íà ïîäâûðàæåíèÿ

/* Sum neighbors of i,j */


up = a[(i-1)*n + j ];
down = a[(i+1)*n + j ];
left = a[i*n + j-1];
right = a[i*n + j+1];
sum = up + down + left + right;

Даже человеку не всегда очевидно, что его можно пе-


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

Ëèñòèíã 24. Ïîëíîñòüþ îïòèìèçèðîâàííûé âàðèàíò (ðó÷íàÿ


îïòèìèçàöèÿ)
inj = i*n + j; // îäíîêðàòíîå âû÷èñëåíèå ïîäâûðàæåíèÿ
up = val[inj - n]; // èçáàâëåíèå îò ëèøíåãî ñëîæåíèÿ
// èçáàâëåíèÿ îò îäíîãî ñëîæåíèÿ è óìíîæåíèÿ
down = val[inj + n];
// èçáàâëåíèå îò îäíîãî ñëîæåíèÿ è óìíîæåíèÿ
left = val[inj - 1];
// èçáàâëåíèå îò îäíîãî ñëîæåíèÿ è óìíîæåíèÿ
right = val[inj + 1];
Заключение
sum = up + down + left + right; Современные методики оптимизации носят довольно про-
тиворечивый характер. С одной стороны, они улучшают код,
Компилятор msvc успешно удалил лишнее выражение с другой – страдают непредсказуемыми побочными эффек-
(i∗n), избавившись от одного умножения, и сгенерировал тами. Опытные программисты подобных «вольностей» не
довольно туманный и медленный код, не оправдывающий одобряют и режимом агрессивной оптимизации пользуют-
возлагаемых на него надежд. Аналогичным образом посту- ся с большой осторожностью. Однако полностью отказы-
пил и gcc. Его основной конкурент – icl хоть и сократил ко- ваться от машинной оптимизации даже самые закорене-
личество умножений наполовину, сгенерировал очень гро- лые консерваторы уже не решаются. Ручное «вылизыва-
моздкий код, сводящий на нет весь выигрыш от оптимиза- ние» кода обходится слишком дорого, правда, последствия
ции. иной оптимизации выходят еще дороже. Наращивая мощь
Короче говоря, с предложенным примером в полной оптимизаторов, разработчики компиляторов допускают все
мере не справился никто и для достижения наивысшей про- больше ошибок и в ответственных случаях программистам
изводительности программист должен выполнять все пре- приходится идти на компромисс, поручая оптимизатору
образования самостоятельно. По крайней мере необходи- только ту часть работы, в результате которой можно быть
мо добиться, чтобы все совместно используемые выраже- полностью уверенным (свертка констант, константная под-
ния в исходном тексте присутствовали в явном виде. становка и т. д.).
А как обстоят дела с удалением частичной избыточнос- Собственно говоря, наше исследование компиляторов
ти? еще не закончено, и перечисленные приемы оптимизации
Вот, например: это даже не верхушка айсберга, а небольшой его кусочек.
В следующей статье этого цикла мы рассмотрим трансфор-
Ëèñòèíã 25. Ñëó÷àé óäàëåíèÿ ÷àñòè÷íîé èçáûòî÷íîñòè мацию циклов и прочие виды ветвлений. Уверяю вас, это
if (n) a = x*y + n; else a = x*y - n; очень интересная тема и здесь есть чему поучиться!

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

ZEND STUDIO 4.0 – НОВАЯ ВЕРСИЯ,


НОВЫЕ ВОЗМОЖНОСТИ

ЕВГЕНИЙ ВОЯКИН
Данный обзор посвящен рассмотрению функциональных Новая, четвертая версия отличается от предыдущей це-
возможностей одной из наиболее продвинутых интегриро- лым рядом улучшений. В пакет добавлена возможность ра-
ванных сред разработки приложений на языке PHP – Zend боты с базами данных напрямую из интерфейса среды. Под-
Studio версии 4.0, созданной самими разработчиками язы- держиваются такие наиболее популярные БД, как MySQL,
ка – компанией Zend. В январе 2005 года Zend объявила о PostgreSQL, Oracle, IBM DB2, MS SQL Server, SQLite. Те-
доступности бета-версии Zend Studio четвертого поколения. перь в распоряжении разработчика библиотека шаблонов
Zend Studio представляет собой среду разработки, от- программных фрагментов, средство документирования.
ладки и оптимизации программного кода PHP-приложений. Рассмотрим, что же представляет собой Zend Studio, и
Как гласит краткая аннотация в справочной системе паке- что нового появилось в 4 версии. Программный пакет Zend
та, полностью интегрированный интерфейс предназначен Studio включает в себя два приложения – Zend Studio Server
упростить процесс разработки приложений как для начи- и Zend Studio Client. Zend Studio Server – это отладчик, уп-
нающих, так и для опытных пользователей. равляемый средой Zend Studio Client и контролирующий про-

№2, февраль 2005 75


программирование
цесс выполнения PHP-кода. При выполнении кода управля- ! библиотеку шаблонов программного кода (в термино-
ющие команды, например информация о точках останова логии Zend Studio называемых Snippets). Библиотека по-
(breakpoints), поступают от Zend Studio Client в Server. Пос- стоянно обновляется, возможна автоматическая загруз-
ледний, в свою очередь, управляет интерпретатором, выпол- ка более новых шаблонов из сети или создание своих
няющим команды языка PHP. Кроме того, в интерпретаторе шаблонов (появилось в версии 4.0);
накапливается информация о работе программы, такая как ! выделение различных лексических элементов кода раз-
результат выполнения, или вывод (output), значения перемен- ными цветами, выравнивание текста при вводе;
ных, стека и данные о возникших ошибках. Zend Studio Server ! настраиваемые горячие клавиши на наиболее часто ис-
отдает собранную информацию из интерпретатора в Client, пользуемые задачи;
где она отображается в соответствующих окнах. Пользова- ! справочную систему.
тельский интерфейс Zend Studio Server представляет собой
веб-оснастку, которая позволяет просматривать и изменять Пользовательский интерфейс «клиентской» части па-
параметры настройки интерпретатора языка PHP и опции кета (см. рис. 2) существенно изменился по сравнению с
среды Zend. Пример вида оснастки приведен на рис.1. предыдущей версией. Подавляющая часть интерфейса сре-
Разработка программ пользователем осуществляется ды переведена на русский язык. Работать с полноцветны-
в Zend Studio Client. Наиболее существенные возможности ми кнопками панели инструментов удобно, обозначения по-
этой среды включают в себя: нятны и просты. Число «окошек» в рамках рабочего поля
! управление процессом исполнения кода с возможнос- среды увеличилось, однако управление их отображением
тью просмотра значений используемых переменных, сте- на экране не вызывает затруднений: по периметру главно-
ка, ошибок и результата работы; го окна среды разработки идет дополнительная «панель ин-
! средство анализа кода, позволяющее, например, отсле- струментов», отвечающая за отображение на экране тех
дить фрагменты кода, которые никогда не будут выпол- или иных рабочих зон среды: окна вывода, окно сообще-
нены, или выявить объявленные, но неиспользуемые пе- ний отладки и т. п.
ременные; Рабочее поле среды состоит из 7 окон, каждое из кото-
! работу с базами данных, выполнение запросов напря- рых может менять отображаемую информацию в зависи-
мую в интерфейсе среды (появилось в версии 4.0); мости от необходимости. Все окна, кроме главного окна
! отслеживание версий (CVS); редактора, могут быть скрыты. Окно «Менеджера файлов»
! автонабор кода со словарем, включающим лексемы язы- служит для осуществления навигации: 3 режима, в кото-
ков PHP, HTML, переменные, переменные в составе клас- рых оно может «работать», позволяют перемещаться по
сов и т. п.; дереву каталогов на локальных и удаленных дисках (по-

Ðèñóíîê 1. Ïîëüçîâàòåëüñêèé èíòåðôåéñ Zend Studio Server

76
программирование
средством подключения по FTP), по файлам проекта или выбор конкретной базы сервера и навигация по ней. Запро-
дереву баз данных. (см. рис. 4). Окно «Инспекторы» пред- сы набираются в отдельном окне «SQL», а результат их вы-
назначено для просмотра иерархической структуры файла полнения может быть просмотрен в основном окне редакто-
проекта, включений в него других файлов, объявленных ра, также переключенном в режим SQL (см. рис. 4).
переменных, классов. В окне «Сообщения» можно просмот- Однако при анализе средств для работы с БД склады-
реть информацию о запуске/окончании отладки, предупреж- вается ощущение некой незаконченности данного функ-
дения об ошибках интерпретации. В этом же окне выводят- ционала – по сути, все эти средства представляют собой
ся сообщения встроенной системы документирования и лишь интерфейс для просмотра данных и выполнения SQL-
оптимизатора кода (см. рис. 6). В окне отладчика во время команд. Более интересным был бы какой-либо функцио-
процедуры отладки кода отображается текущее значение нал, который позволял бы строить обращения к базам
переменных, включая глобальные (см. рис 2.), состояние данных на языке PHP путем, к примеру, перетаскивания
стека и т. д. SQL-запросов напрямую в окно редактора кода, с авто-
Результат интерпретации PHP-сценария помещается в матическим превращением такого запроса в реализующий
окно «Вывод». Данная функция неоценима при пошаговой его PHP-код.
отладке кода, так как сразу же позволяет отследить про- К недостаткам также можно отнести и то, что в програм-
цесс интерпретации и быстро обнаружить логические ошиб- ме отсутствует поддержка русского языка для данных в БД.
ки. Выбрав пункт в контекстном меню окна, можно открыть Как и в предыдущих версиях пакета, разработка про-
результат выполнения сценария в окне браузера. грамм осуществляется в режиме текстового редактора.
Как следует из анонса версии, работа с базами данных Основное окно редактора, находящееся в центре рабочей
(БД) является одной из наиболее существенных особеннос- области среды, представляет собой многофункциональный
тей, отличающих 4-ю версию от предыдущих. Для работы с текстовый редактор, довольно удобный в использовании.
БД некоторые окна среды имеют соответствующие режимы, Вводимые лексемы языка PHP (переменные, строковые и
названные «SQL». Добавление подключения к серверу баз числовые константы, операторы и прочее) автоматически
данных осуществляется в «менеджере файлов» в режиме выделяются с помощью различных цветовых схем, которые
SQL через контекстное меню. В этом же окне выполняется разработчик может настроить по своему усмотрению. Все

Ðèñóíîê 2. Zend Studio Client

№2, февраль 2005 77


программирование
строки кода программ нумеруются автоматически, что су- В словарь этой системы также входят глобальные и ло-
щественно облегчает навигацию по файлам проекта при кальные переменные, константы, теги. Появившаяся в этой
получении сообщения об ошибке: все подобные сообще- версии система шаблонов программного кода позволяет
ния содержат номер строки. Редактор обладает возможно- включать в проект функции из библиотеки шаблонов, на-
стью автоматического выравнивания набранного программ- писанной другими программистами. Библиотека постоян-
ного кода с помощью отступов, что позволяет сделать код но обновляется, возможна загрузка новых шаблонов из
более читаемым. Интернета. Кроме того, разработчик может создавать соб-
Заметно улучшена система предиктивного набора тек- ственные шаблоны функций или просто участков кода под
ста: при вводе первых букв названия какой-либо функции свои нужды. К недостаткам этой системы следует отнести
появляется выпадающий список функций языка PHP, на- некоторую ее «скрытость» от разработчика – по сравне-
чинающихся с этих букв. При выборе функции появляется нию с поиском пункта в главном меню среды более удоб-
окно-подсказка с кратким описанием этой функции и ее па- ным был бы вызов библиотеки напрямую с помощью кноп-
раметров. ки на панели инструментов.
Zend Studio Client поддерживает разработку как отдель-
ных файлов на PHP, так и проектов, состоящих из несколь-
ких файлов. Файлы, входящие в проект, отображаются в
окне «менеджера файлов». При работе с многофайловы-
ми проектами полезной может оказаться функция, позво-
ляющая отследить доступность всех файлов, используемых
в проекте (в случае включения в один из файлов других
директивами require и т. п.).
Отдельного внимания заслуживает функция анализа
программного кода. Данная операция позволяет выявить
некоторые логические ошибки, допущенные разработчиком
Ðèñóíîê 3. Ïðåäèêòèâíûé íàáîð òåêñòà при программировании, например найти фрагменты кода,

Ðèñóíîê 4. Ðàáîòà ñ áàçàìè äàííûõ â Zend Studio Client

78
программирование
которые никогда не будут выполнены. Так, анализ фраг- да существенно отличается от предыдущей удобством ин-
мента программы, содержащей такой текст: терфейса, его локализацией. Тенденция встраивания в сре-
ду интерфейсов к смежным сферам разработки, с которы-
16 if (0<-1){ ми сталкивается программист при написании кода – базам
17 for ($i=0; $i<strlen($source);$i++){
18 print(chr(ord($source[$i]) / 2)); данных, документации, – доказывает, что компания Zend
19 } стремится вывести процесс разработки приложений на язы-
20 }
ке PHP на качественно более высокий уровень интеграции.
приведет к предупреждающему сообщению (см. рис. 6) ана-
лизатора: «Some code in the function cannot be reached. This
part of the code is useless.» («Некоторые участки кода в фун-
кции никогда не будут выполнены. Эти участки бесполезны»).
К сожалению, несмотря на локализацию интерфейса
программы, рассмотренная версия имеет справочную сис-
тему на английском языке. Кроме того, справочная систе-
ма еще явно «не обновлена» до четвертой версии. Вероят-
но, это связано именно с тем, что рассмотренная версия
является бета-версией продукта. Отсутствует описание
наиболее существенных нововведений, появившихся в но-
вом пакете – работы с базами данных, средства докумен-
тирования «PHPDocumenter». Ввиду полного отсутствия
информации по последнему разобраться с принципом его
работы автору так и не удалось.
В заключение данного обзора хочется сказать, что Zend
Studio 4.0 явно может претендовать на звание одного из
наиболее серьезных средств разработки на PHP. Новая сре- Ðèñóíîê 5. Îòñëåæèâàíèå öåëîñòíîñòè ïðîåêòà

Ðèñóíîê 6. Àíàëèçàòîð êîäà

№2, февраль 2005 79


hardware

ЗАПИСЬ CD-R/RW-ДИСКОВ В LINUX


ЧАСТЬ 4

ВЛАДИМИР МЕШКОВ

80
hardware
В статье рассматривается порядок записи информации на Для Lead-In и Lead-Out-областей значение байта CTL/
CD-R/RW-диски в режиме Session-at-once (SAO). ADR должно быть равно 0x01 (за исключением случая, ког-
Работоспособность всех примеров программ была про- да поле Data Form = 0x41, однако он в этой статье не рас-
верена для ОС Linux, ядро 2.4.28. В ядре включены режим сматривается). Байт TNO и INDEX для Lead-In-области при-
SCSI-эмуляции для ATAPI-устройств и поддержка SCSI нимают значение 0x00. Lead-Out-область, согласно специ-
Generic-драйвера. Использовались следующие модели при- фикации, кодируется как трек под номером 0xAA, поле
водов: INDEX всегда равно 0x01.
! TEAC CD-W524E Rev.1.0E
! ASUS DRW-1604P Rev.1.09
! MITSUMI CR-48XATE Rev.1.0E Ðèñóíîê 3. Ñòðóêòóðà ïîëÿ DATA FORM
Поле Data Form of Main Data определяет формат блоков
Особенности записи информации данных основного канала – CD-DA (аудиоданные), CD-ROM
в режиме SAO Mode 1, CD-ROM XA. При записи аудио это поле принимает
В отличие от ранее рассмотренного режима записи Track- значение 0x00, и устройству передается блок аудиоданных
at-once (TAO) (см. [1, 2]), в режиме Session-at-once (SAO) размером 2352 байта. При записи данных в формате Mode 1
треки примыкают друг к другу вплотную, промежутки (пау- (см. [1], таблица 1) поле Data Form of Main Data может при-
зы) между ними отсутствуют. Для управления процессом нимать следующие значения:
записи устройству передается специальная структура, со- ! 0x10 – приложение передает устройству блок данных
держащая информацию о расположении (координатах) тре- User Data размером 2048 байт, поля Sync/Header и EDC/
ков, форматах блоков основного канала и субканалов тре- ECC генерируются устройством;
ка. Эта структура, которая называется CUE SHEET, явля- ! 0x11 – приложение передает устройству блок данных
ется своего рода картой, на основании которой устройство размером 2352 байт в составе полей User Data (2048
сформирует входную (Lead-In) и выходную (Lead-Out) об- байт), Sync/Header (16 байт) и EDC/ECC (288 байт), од-
ласти сессии (диска). нако устройство игнорирует содержимое полей Sync/
Структура CUE SHEET состоит из последовательности Header и EDC/ECC и генерирует собственные значения.
8-байтовых блоков, самый первый блок описывает вход-
ную область сессии, последний – выходную область, осталь- Поле Data Form of Sub-Channel определяет формат дан-
ные блоки содержат информацию о треках. ных субканалов, передаваемых устройству, но в рамках дан-
Блоки имеют следующий формат: ной статьи структура этого поля не рассматривается. Соглас-
но спецификации [3], данные субканалов P и Q, переданные
в структуре CUE SHEET, устройство игнорирует и генериру-
ет собственные значения. Формат поля Data Form of Sub-
Ðèñóíîê 1. Ôîðìàò áëîêà ñòðóêòóðû CUE SHEET Channel определен в [3], табл. 516. Значение поля DATA FORM
Назначение полей: при записи данных в формате CD-ROM XA представлены в
! CTL/ADR – значение байта CTL/ADR-трека. табл. 514 спецификации [3]. Для Lead-In и Lead-Out облас-
! TNO – номер трека. тей значение поля DATA FORM всегда равно 0x01.
! INDEX – индекс трека. После того как структура CUE SHEET сформирована,
! DATA FORM – формат данных трека. она передается устройству при помощи команды SEND CUE
! SCMS – байт системы управления копированием. SHEET.
! ABSOLUTE TIME – стартовые координаты трека в MSF-
формате.

Формат байта CTL/ADR представлен на рис. 2. Старшие


4 разряда байта CTL/ADR занимает поле управления CTL,
младшие 4 разряда – поле ADR.

Ðèñóíîê 2. Áàéò CTL/ADR


Поле CTL определяет тип информации, находящейся в
треке, и может принимать следующие значения: Ðèñóíîê 4. Ôîðìàò êîìàíäû SEND CUE SHEET
! 00xxb – 2 аудиоканала; Параметр Cue Sheet Size содержит размер структуры
! 10xxb – 4 аудиоканала; CUE SHEET в байтах.
! 01xxb – трек данных;
! 11xxb – зарезервировано. Примеры программ для записи дисков
в режиме SAO
Поле ADR может принимать следующие значения:
! 01b – начальное время трека; Запись данных на компакт-диск
! 10b – код носителя по каталогу; Рассмотрим пример программы, выполняющей запись од-
! 11b – код ISRC. носессионного CD-R/RW-диска в режиме SAO.

№2, февраль 2005 81


hardware
В сессии находится только один трек, формат данных – get_conf_cmd[0] = 0x46; // êîä êîìàíäû GET CONFIGURATION
get_conf_cmd[1] = 2; // RT = 10b, ñ÷èòûâàåì òîëüêî
CD-ROM Mode 1. // çàïðàøèâàåìîå ñâîéñòâî
Алгоритм работы программы следующий: get_conf_cmd[2] = *((__u8 *)&f_num + 1);
get_conf_cmd[3] = *((__u8 *)&f_num);
! проверяем возможность записи информации в режиме get_conf_cmd[8] = FEATURE_LEN;
SAO;
send_cmd(get_conf_cmd, 10, SG_DXFER_FROM_DEV, ↵
! в странице параметров режима записи указываем тре- data_buff, FEATURE_LEN, 20);
буемый режим записи – SAO: Write Type = 0x02 (см. [1]);
memcpy((void *)&data_length, data_buff, 4);
! формируем структуру CUE SHEET и отправляем ее уст- data_length = __swab32(data_length);
ройству; if(data_length == 4) return -1; // ñâîéñòâî
// íå ïîääåðæèâàåòñÿ
! выполняем запись данных на носитель.
/* Ïðîâåðÿåì, ÿâëÿåòñÿ ëè ñâîéñòâî òåêóùèì */
if(cd_sao->current != 1) return -1;
Для возможности записи в режиме SAO устройство дол-
жно обладать свойством CD Mastering (код 0x002E). /* Îïðåäåëÿåì òåêóùèé ïðîôèëü */
*((__u8 *)&cur_prof) = data_buff[7];
*((__u8 *)&cur_prof + 1) = data_buff[6];
printf("\nÒåêóùèé ïðîôèëü - 0x%04X\n", cur_prof);
/* Âîçâðàùàåì çíà÷åíèå áèòà SAO */
return (cd_sao->sao);
}

Установку требуемого режима записи – SAO – выпол-


няет связка функций mode_sense() и mode_select(). Эти
функции были рассмотрены в [1] и [2], здесь мы только не-
Ðèñóíîê 5. Ôîðìàò äåñêðèïòîðà ñâîéñòâà CD Mastering много модифицируем функцию mode_sense() – при вызове
Устройство поддерживает режим записи SAO, если бит этой функции сначала определяется реальная длина стра-
SAO установлен в единицу. Формат дескриптора свойства ницы параметров режима записи, а после этого считыва-
можно описать при помощи следующей структуры: ется сама страница.

/* Ñâîéñòâî CD Mastering */ /* Ãëîáàëüíûå ïåðåìåííûå */


typedef struct { __u16 page5_len;
__u16 f_code; __u8 *page5_data;
__u8 current :1; wpm_t *wpm; // äàííûå ñòðàíèöû ïàðàìåòðîâ çàïèñè
__u8 persistent :1;
__u8 version :4; int mode_sense()
__u8 res1 :2; {
__u8 add_length; __u8 mode_sense_cmd[10];
__u8 rw :1;
__u8 cd_rw :1; test_unit_ready();
__u8 test_write :1;
__u8 raw :1; /* Îïðåäåëÿåì ðàçìåð ñòðàíèöû ïàðàìåòðîâ çàïèñè – ïåðâûå
__u8 raw_ms :1; * äâà áàéòà áëîêà äàííûõ, âîçâðàùàåìûõ óñòðîéñòâîì
__u8 sao :1; * ïî êîìàíäå MODE_SENSE
__u8 BUF :1; */
__u8 res2 :1; page5_data = (__u8 *)malloc(2);
__u8 max_cue_len[3]; memset(mode_sense_cmd, 0, 10);
} cd_sao_t; mode_sense_cmd[0] = MODE_SENSE_10;
mode_sense_cmd[2] = 5; // ñòðàíèöà ïàðàìåòðîâ çàïèñè
mode_sense_cmd[8] = 2;
Проверка наличия свойства выполняет при помощи ко-
манды GET CONFIGURATION (см. [1], «Свойства и профи- send_cmd(mode_sense_cmd, 10, SG_DXFER_FROM_DEV, ↵
page5_data, 2, 200);
ли устройства», [3]). Проверку выполняет функция check_
feature(). Входные параметры функции – код проверяемого *((__u8 *)&page5_len) = page5_data[1];
*((__u8 *)&page5_len + 1) = page5_data[0];
свойства, в нашем случае это 0x002E: page5_len += 2;

int check_feature(__u16 f_num) printf("Ðàçìåð ñòðàíèöû ïàðàìåòðîâ çàïèñè – ↵


{ %d áàéò\n", page5_len);
free(page5_data);
#define FEATURE_LEN 16
/* Ðàçìåð ñòðàíèöû ïàðàìåòðîâ ðåæèìà çàïèñè èçâåñòåí,
* âûäåëÿåì ïàìÿòü äëÿ ñòðàíèöû
__u8 get_conf_cmd[10]; // CDB */
__u8 data_buff[FEATURE_LEN]; // ðåçóëüòàòû ÷òåíèÿ
__u32 data_length = 0; // ðåàëüíàÿ äëèíà äàííûõ page5_data = (__u8 *)malloc(page5_len);
memset(page5_data, 0, page5_len);
__u16 cur_prof = 0; // òåêóùèé ïðîôèëü, Current Profile
cd_sao_t *cd_sao; /* Ñòðóêòóðà wpm_t *wpm õðàíèò äàííûå ñòðàíèöû ïàðàìåòðîâ
* çàïèñè, åå ôîðìàò áûë ðàññìîòðåí â [2]. wpm óêàçûâàåò
test_unit_ready(); * íà íà÷àëî ñòðàíèöû ïàðàìåòðîâ ðåæèìà çàïèñè
*/
wpm = (void *)(page5_data + 8);
memset(data_buff, 0, sizeof(data_buff));
cd_sao = (void *)(data_buff + 8);
/* Ôîðìèðóåì êîìàíäó MODE_SENSE_10 */
memset(mode_sense_cmd, 0, 10);
/* Äëÿ îïðåäåëåíèÿ ñâîéñòâ óñòðîéñòâà èñïîëüçóåòñÿ mode_sense_cmd[0] = MODE_SENSE_10;
* êîìàíäà GET CONFIGURATION
*/ mode_sense_cmd[2] = 5; // ñòðàíèöà ïàðàìåòðîâ çàïèñè
mode_sense_cmd[8] = page5_len;
memset(get_conf_cmd, 0, 10);

82
hardware
send_cmd(mode_sense_cmd, 10, SG_DXFER_FROM_DEV, ↵ /* Çàïîëíÿåì ïîëÿ CUE SHEET. Íà÷èíàåì ñ Lead-In-îáëàñòè */
page5_data, page5_len, 200); cue_buff[0] = 0x01; // CTL/ARD
cue_buff[1] = 0x00; // íîìåð òðåêà, âñåãäà 0
return 0; cue_buff[2] = 0x00; // èíäåêñ òðåêà, âñåãäà 0
} cue_buff[3] = 0x01; // DATA FORM, âñåãäà 1
cue_buff[4] = 0x00; // SCMS
Установку режима записи SAO выполняет функция mode_ cue_buff[5] = 0x00; // Minute = 0
select(): cue_buff[6] = 0x00; // Second = 0
cue_buff[7] = 0x00; // Frame = 0

int mode_select() /* Pre-gap îáëàñòü ïåðâîãî òðåêà */


{ cue_buff[8] = 0x41; // CTL = 4 – òðåê ñîäåðæèò äàííûå
__u8 mode_select_cmd[10]; cue_buff[9] = 0x01; // íîìåð òðåêà = 1
cue_buff[10] = 0x00; // èíäåêñ òðåêà = 0
/* Ñ÷èòûâàåì ñòðàíèöó ïàðàìåòðîâ ðåæèìà çàïèñè */ cue_buff[11] = 0x10; // äàííûå â ôîðìàòå Mode 1
mode_sense(); cue_buff[12] = 0x00; // SCMS

/* Óñòàíàâëèâàåì íåîáõîäèìûé ðåæèì */ /* Êîîðäèíàòû Pre-Gap-îáëàñòè – (-150) â ôîðìàòå LBA,


wpm->write_type = 2; // ðåæèì SAO * èëè 0/0/0 â MSF-ôîðìàòå
wpm->multises = 0; // îäíîñåññèîííûé äèñê */
cue_buff[13] = 0x00; // Minute
test_unit_ready(); cue_buff[14] = 0x00; // Second
cue_buff[15] = 0x00; // Frame
/* Ôîðìèðóåì êîìàíäó MODE_SELECT_10 */
memset(mode_select_cmd, 0, 10); /* Ïåðâûé òðåê */
mode_select_cmd[0] = MODE_SELECT_10; cue_buff[16] = 0x41; // CTL = 4 – òðåê ñîäåðæèò äàííûå
mode_select_cmd[1] = 0x10; cue_buff[17] = 0x01; // íîìåð òðåêà = 1
mode_select_cmd[7] = *((__u8 *)&page5_len + 1); cue_buff[18] = 0x01; // èíäåêñ òðåêà = 1
mode_select_cmd[8] = *(__u8 *)&page5_len; cue_buff[19] = 0x10; // äàííûå â ôîðìàòå Mode 1
cue_buff[20] = 0x00; // SCMS
if(send_cmd(mode_select_cmd, 10, SG_DXFER_TO_DEV, ↵
page5_data, page5_len, 200) < 0) return -1; /* Êîîðäèíàòû ïåðâîãî òðåêà – 0 â ôîðìàòå LBA,
* èëè 0/2/0 â MSF-ôîðìàòå
free(page5_data); */
return 0; cue_buff[21] = 0x00; // Minute
} cue_buff[22] = 0x02; // Second
cue_buff[23] = 0x00; // Frame
Формирование структуры CUE SHEET выполняет фун- /* Lead-Out */
кция send_cue_sheet(). По условиям задачи на диск запи- cue_buff[24] = 0x01; // CTL/ADR
сывается сессия, состоящая из одного трека, формат дан- cue_buff[25] = 0xAA; // íîìåð òðåêà âûõîäíîé îáëàñòè
cue_buff[26] = 0x01; // èíäåêñ, äëÿ Lead-Out âñåãäà 1
ных – CD-ROM Mode 1. Структура CUE SHEET будет состо- cue_buff[27] = 0x01; // DATA FORM, âñåãäà 1
ять из четырех 8-байтовых блоков, и ее размер равен 32 cue_buff[28] = 0x00; // SCMC
байта (4х8). Первый и последний блоки описывают вход- /* Îïðåäåëÿåì êîîðäèíàòû Lead-Out-îáëàñòè. Ýòà îáëàñòü
ную и выходную области сессии, второй блок – Pre-Gap- * ðàñïîëîæåíà ñðàçó çà ïåðâûì òðåêîì. Ðàçìåð òðåêà íàì
* èçâåñòåí
область трека, третий блок описывает сам трек. */
Для указания стартовых координат (поле ABSOLUTE min = LBA2MIN(trk_size);
sec = LBA2SEC(trk_size, min);
TIME) необходимо выполнить преобразование адреса из frame = LBA2FRAME(trk_size, min, sec);
формата LBA в MSF. Для этого спецификацией [3] (табл. 584) printf("\nMIN/SEC/FRAME: %.2d/%.2d/%.2d\n", min, sec, frame);
предусмотрены следующие формулы: cue_buff[29] = min;
cue_buff[30] = sec;
cue_buff[31] = frame;
M = IP((LBA + 150) / (60 * 75))
S = IP((LBA + 150 - M * 60 * 75) / 75) /* Ôîðìèðóåì êîìàíäó SEND CUE SHEET */
F = IP(LBA + 150 - M * 60 *7 5 - S * 75) cue_sheet_cmd[0] = 0x5D;
cue_sheet_cmd[8] = 32;
Здесь IP – это Integer Part (целая часть), параметр LBA if(send_cmd(cue_sheet_cmd, 10, SG_DXFER_TO_DEV, ↵
принимает значение: -151 < LBA < 404850. cue_buff, 32, 200) < 0) return -1;
Пересчет координат из LBA в MSF выполняется при по- return 0;
мощи следующих макроопределений: }

#define LBA2MIN(LBA) ((LBA + 150) / (60 * 75)) После того как структура CUE SHEET отправлена уст-
#define LBA2SEC(LBA, MIN) ((LBA + 150 - ↵
(MIN * 60 * 75)) / 75) ройству, можно приступить к записи данных на носитель.
#define LBA2FRAME(LBA, MIN, SEC) ((LBA + 150 - ↵ Запись выполняет функция write_iso(), параметр функции –
(MIN * 60 * 75)) - (SEC * 75))
имя файла-образа. Вначале записывается Pre-Gap-область
В параметрах функции send_cue_sheet() передается первого трека, а затем сам трек. Стартовый адрес Pre-Gap-
размер трека, исчисляемый в блоках по 2048 байт. области в формате MSF равен 0/0/0 (-150 в LBA-формате),
размер Pre-Gap-области составляет 150 секторов.
int send_cue_sheet(__u32 trk_size)
{ int write_iso(__u8 *file_name)
__u8 cue_sheet_cmd[10]; {
__u8 cue_buff[32]; // ñòðóêòóðà CUE SHEET,
// ðàçìåð 32 áàéòà #define PREGAP_SIZE 307200 // ðàçìåð Pre-Gap-îáëàñòè:
__u8 min, sec, frame; // êîîðäèíàòû Lead-Out-îáëàñòè // 150 ñåêòîðîâ ïî 2048 áàéò
memset(cue_sheet_cmd, 0, 10); int ret, in_f;
memset(buff, 0, 32);

№2, февраль 2005 83


hardware
__u8 write_cmd[10]; drv_mmc.c), в результате чего функция приобретает следую-
__u8 *write_buff; щий вид:
int lba, lba1 = -150;
in_f = open(file_name, O_RDONLY); LOCAL void
memset(write_cmd, 0, 10); fillcue(cp, ca, tno, idx, dataform, scms, mp)
write_cmd[0] = WRITE_10; struct mmc_cue *cp; /* The target cue entry */
write_cmd[8] = 150; // ðàçìåð Pre-Gap â ñåêòîðàõ int ca; /* Control/adr for this entry */
int tno; /* Track number for this entry */
write_buff = (__u8 *)malloc(PREGAP_SIZE); int idx; /* Index for this entry */
memset(write_buff, 0, PREGAP_SIZE); int dataform; /* Data format for this entry */
int scms; /* Serial copy management */
/* Çàïèñûâàåì Pre-gap-îáëàñòü. Îíà íà÷èíàåòñÿ ñ ñåêòîðà – msf_t *mp; /* MSF value for this entry */
* 150 è ñîäåðæèò íóëè {
*/ cp->cs_ctladr = ca; /* XXX wie lead in */
lba = __swab32(lba1); cp->cs_tno = tno;
memcpy((write_cmd + 2), (void *)&lba, 4); cp->cs_index = idx;
lba1 += 150; cp->cs_dataform = dataform;/* XXX wie lead in */
cp->cs_scms = scms;
while(1) { cp->cs_min = mp->msf_min;
ret = send_cmd(write_cmd, 10, SG_DXFER_TO_DEV, ↵ cp->cs_sec = mp->msf_sec;
write_buff, PREGAP_SIZE, 200); cp->cs_frame = mp->msf_frame;
if(ret == 0) break;
if(ret < 0) return -1; /* Ýòîò êîä äîáàâëåí íàìè â ó÷åáíûõ öåëÿõ! */
} printf("\n0x%.2X\t", cp->cs_ctladr);
printf("0x%.2X\t",cp->cs_tno);
free(write_buff); printf("0x%.2X\t",cp->cs_index);
printf("0x%.2X\t",cp->cs_dataform);
/* Äàëüøå âûïîëíÿåòñÿ çàïèñü äàííûõ ïåðâîãî òðåêà printf("0x%.2X\t",cp->cs_scms);
* àíàëîãè÷íî ðàññìîòðåííûì ðàíåå ïðèìåðàì (ñì. [2]) printf("0x%.2X\t",cp->cs_min);
*/ printf("0x%.2X\t",cp->cs_sec);
. . . . . . . printf("0x%.2X\n",cp->cs_frame);
} }

Функция посылки команды устройству send_cmd() так- После внесения изменений пересоберем утилиту и за-
же претерпела некоторые изменения (полный текст не при- пишем с ее помощью три аудиотрека:
водится):
# cdrecord -dev=X,Y,Z -dao -pad -audio trk1.wav ↵
int send_cmd(__u8 *cmd, __u8 cmdlen, int direction, ↵ rk2.wav trk3.wav
__u8 *data, __u32 datalen, unsigned int timeout)
{ Размер первого трека равен 17087 блоков, размер вто-
............ рого трека – 12923, размер третьего трека – 20580. Струк-
rep:
if(ioctl(sg_fd, SG_IO, &io_hdr) < 0) { тура CUE SHEET имеет следующее содержание:
perror("SG_IO ioctl");
return -1;
}
if((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
if(io_hdr.sb_len_wr > 0) {
/* Åñëè SK/ASC/ASCQ == 02/04/08 (Not Ready. Long Write
* in Progress), òî íåîáõîäèìî ïîâòîðèòü êîìàíäó WRITE_10
*/ Структура CUE SHEET состоит из восьми блоков, ее раз-
if((SK == NOT_READY) && (ASC == 0x04) && ↵
(ASCQ == 0x08)) goto rep; мер равен 64 байта. Первый и последний блоки – это вход-
........... ная и выходная области сессии. Блок 2 – Pre-Gap-область
}
первого трека, стартовый адрес равен 150. Третий блок опи-
Здесь в случае возникновения ошибки типа «NOT READY. сывает первый трек, стартовый адрес трека равен 0. Чет-
LONG WRITE IN PROGRESS» сразу выполняется переход вертый блок – Pre-Gap-область второго трека, стартовый
на метку rep и повтор команды WRITE, без необходимости адрес трека 16937. Пятый блок – второй трек, стартовый
формирования командного пакета. Отметим, что эти изме- адрес трека равен размеру первого трека – 17087 блоков.
нения никак не связаны с рассматриваемым режимом за- Шестой блок – Pre-Gap-область третьего трека, стартовый
писи. адрес равен 29860. Седьмой блок содержит описание тре-
Полный текст программы для записи данных на CD-R/ тьего трека, его стартовый адрес равен 30010 (17087 +
RW диск в режиме SAO находится по адресу: http://bob. 12923). Параметр DATA FORM равен 0x00. Это означает,
netport.com.ua/sao.tar.gz. что на диск выполняется запись аудиоданных, и размер
блока равен 2352 байта.
Запись Audio-CD Таким образом, опытным путем установлено, что треки
При записи аудиоданных на компакт-диск в режиме SAO в действительно расположены вплотную друг к другу, и Pre-
одной сессии будет находиться несколько треков. Рассмот- Gap-область трека захватывает последние 150 секторов
рим, как в этом случае формируется структура CUE SHEET, области данных предыдущего трека. Исключение состав-
и для начала изучим ее формат на реальном примере. С этой ляет Pre-Gap-область первого трека.
целью внесем небольшое дополнение в исходный код ути- Перепишем функцию send_cue_sheet для возможности
литы cdrecord, а именно в функцию fillcue() (файл cdrecord/ записи на диск трех аудиотреков.

84
hardware
Входные параметры функции – размеры треков в бло- cue_buff[56] = 0x01; cue_buff[57] = 0xAA;
ках по 2352 байта: cue_buff[58] = 0x01; cue_buff[59] = 0x01;
cue_buff[60] = 0x00; cue_buff[61] = min;
cue_buff[62] = sec; cue_buff[63] = frame;
int send_cue_sheet(int trk1_size, int trk2_size, int trk3_size)
{ /* Ôîðìèðóåì êîìàíäíûé ïàêåò */
__u8 cue_sheet_cmd[10]; cue_sheet_cmd[0] = 0x5D;
__u8 *cue_buff; cue_sheet_cmd[8] = cb_size;
__u8 min, sec, frame;
int cb_size = 0; /* Îòïðàâëÿåì óñòðîéñòâó êîìàíäó SEND_CUE_SHEET,
int trk = -150; * îñâîáîæäàåì ïàìÿòü è âûõîäèì èç ôóíêöèè
*/
/* Îïðåäåëÿåì ðàçìåð ñòðóêòóðû CUE SHEET. Â åå ñîñòàâ if(send_cmd(cue_sheet_cmd, 10, SG_DXFER_TO_DEV, ↵
* âõîäÿò òðè Pre-Gap-îáëàñòè, òðè òðåêà, âõîäíàÿ cue_buff, cb_size, 200) < 0) return -1;
* è âûõîäíàÿ îáëàñòè free(cue_buff);
*/ return 0;
cb_size = 3 * 8 + 3 * 8 + 16; // Èòîãî 64 áàéòà }

cue_buff = (__u8 *)malloc(cb_size); Отправив устройству структуру CUE SHEET, приступа-


memset(cue_sheet_cmd, 0, 10); ем к записи данных.
memset(cue_buff, 0, cb_size);
Запись данных выполняет функция write_audio(). Вход-
/* Ôîðìèðóåì Lead-In-îáëàñòü */ ные параметры функции – имя файла в формате WAV и
cue_buff[0] = 0x01; cue_buff[1] = 0x00;
cue_buff[2] = 0x00; cue_buff[3] = 0x01; номер записываемого трека.
cue_buff[4] = 0x00; cue_buff[5] = 0x00; Если записывается первый трек, то перед записью дан-
cue_buff[6] = 0x00; cue_buff[7] = 0x00;
ных этого трека выполняется запись Pre-Gap-области раз-
/* Pre-gap ïåðâîãî òðåêà */ мером 150 секторов.
cue_buff[8] = 0x01; cue_buff[9] = 0x01;
cue_buff[10] = 0x00; cue_buff[11] = 0x00;
cue_buff[12] = 0x00; cue_buff[13] = 0x00; int write_audio(__u8 *file_name, int flag)
cue_buff[14] = 0x00; cue_buff[15] = 0x00; {
/* Ïåðâûé òðåê */ #define PREGAP_SIZE 352800 // 150 ñåêòîðîâ ïî 2352 áàéòà
cue_buff[16] = 0x01; cue_buff[17] = 0x01;
cue_buff[18] = 0x01; cue_buff[19] = 0x00; int ret, i;
cue_buff[20] = 0x00; cue_buff[21] = 0x00; int in_f;
cue_buff[22] = 0x02; cue_buff[23] = 0x00; __u8 write_cmd[10];
__u8 *write_buff;
/* Pre-gap-îáëàñòü âòîðîãî òðåêà çàõâàòûâàåò ïîñëåäíèå int lba = 0;
* 150 ñåêòîðîâ ïåðâîãî òðåêà static int lba1 = -150; // ñòàðòîâûé àäðåñ äëÿ çàïèñè
*/
trk += trk1_size; in_f = open(file_name, O_RDONLY);
min = LBA2MIN(trk);
sec = LBA2SEC(trk, min); /* Ïåðåøàãèâàåì ÷åðåç WAV-çàãîëîâîê */
frame = LBA2FRAME(trk, min, sec); lseek(in_f, 44, 0);

cue_buff[24] = 0x01; cue_buff[25] = 0x02; memset(write_cmd, 0, 10);


cue_buff[26] = 0x00; cue_buff[27] = 0x00; write_cmd[0] = WRITE_10;
cue_buff[28] = 0x00; cue_buff[29] = min;
cue_buff[30] = sec; cue_buff[31] = frame; if(flag == 1) { // çàïèñûâàåì ïåðâûé òðåê
/* Âòîðîé òðåê ðàñïîëîæåí ñðàçó çà ïåðâûì, ò.å. ïàóçà write_buff = (__u8 *)malloc(PREGAP_SIZE);
* ìåæäó òðåêàìè îòñóòñòâóåò memset(write_buff, 0, PREGAP_SIZE);
*/ write_cmd[8] = 150;
sec += 2; // äëèíà Pre-Gap – 2 ñåêóíäû, èëè 150 ñåêòîðîâ
cue_buff[32] = 0x01; cue_buff[33] = 0x02; /* Çàïèñûâàåì Pre-gap-îáëàñòü ïåðâîãî òðåêà */
cue_buff[34] = 0x01; cue_buff[35] = 0x00; lba = __swab32(lba1);
cue_buff[36] = 0x00; cue_buff[37] = min; memcpy((write_cmd + 2), (void *)&lba, 4);
cue_buff[38] = sec; cue_buff[39] = frame; lba1 += 150;
/* Pre-gap-îáëàñòü òðåòüåãî òðåêà çàõâàòûâàåò ïîñëåäíèå while(1) {
* 150 ñåêòîðîâ âòîðîãî òðåêà ret = send_cmd(write_cmd, 10, SG_DXFER_TO_DEV, ↵
*/ write_buff, PREGAP_SIZE, 200);
trk += trk2_size; if(ret == 0) break;
min = LBA2MIN(trk); if(ret < 0) return 0;
sec = LBA2SEC(trk, min); }
frame = LBA2FRAME(trk, min, sec);
free(write_buff);
cue_buff[40] = 0x01; cue_buff[41] = 0x03; }
cue_buff[42] = 0x00; cue_buff[43] = 0x00;
cue_buff[44] = 0x00; cue_buff[45] = min; /* Äàëüøå âûïîëíÿåòñÿ çàïèñü äàííûõ àóäèîòðåêà */
cue_buff[46] = sec; cue_buff[47] = frame; . . . . . . .
}
/* Òðåòèé òðåê */
sec += 2; Из всех Pre-Gap-областей на диск записывается только
cue_buff[48] = 0x01; cue_buff[49] = 0x03;
cue_buff[50] = 0x01; cue_buff[51] = 0x00; Pre-Gap-область первого трека, остальные просто обозна-
cue_buff[52] = 0x00; cue_buff[53] = min; чены в структуре CUE SHEET.
cue_buff[54] = sec; cue_buff[55] = frame;
Возникает вопрос – если не все Pre-Gap-области подле-
/* Lead-Out-îáëàñòü */ жат записи, то зачем их указывать в структуре CUE SHEET?
trk += trk3_size + 150;
min = LBA2MIN(trk); Исключим «лишние» Pre-Gap-области из структуры CUE
sec = LBA2SEC(trk, min); SHEET, и функция send_ cue_sheet() примет следующий
frame = LBA2FRAME(trk, min, sec);
вид:

№2, февраль 2005 85


hardware
int send_cue_sheet(int trk1_size, int trk2_size, int trk3_size) __u8 cue_sheet_cmd[10];
{ __u8 *cue_buff = NULL;
__u8 cue_sheet_cmd[10]; __u8 min, sec, frame;
__u8 *cue_buff; struct stat s;
__u8 min, sec, frame; int cb_size = 0;
int cb_size = 0; int trk = 0;
int trk = 0;
cb_size = trk_num * 8 + 8 + 16;
/* Âû÷èñëÿåì ðàçìåð CUE SHEET – Pre-Gap-îáëàñòü ïåðâîãî
* òðåêà, òðè òðåêà, Lead-In- è Lead-Out-îáëàñòè cue_buff = (__u8 *)malloc(cb_size);
*/ memset(cue_sheet_cmd, 0, 10);
cb_size = 3 * 8 + 8 + 16; // Èòîãî 48 áàéò memset(cue_buff, 0, cb_size);
cue_buff = (__u8 *)malloc(cb_size); /* Lead-In-îáëàñòü, Pre-gap ïåðâîãî òðåêà, ïåðâûé òðåê
memset(cue_sheet_cmd, 0, 10); * (ñì. ïðåäûäóùèé ïðèìåð)
memset(cue_buff, 0, cb_size); */
.......
/* Îïèñàíèå Lead-In-îáëàñòè, Pre-gap-îáëàñòè ïåðâîãî òðåêà
* è íåïîñðåäñòâåííî ïåðâîãî òðåêà òî÷íî òàêèå æå, /* Çàïèñûâàåì â ñòðóêòóðó CUE SHEET èíôîðìàöèþ î òðåêàõ.
* êàê è â ïðåäûäóùåì ïðèìåðå * Íà÷èíàåì ñî âòîðîãî òðåêà, ò.ê. äëÿ ïåðâîãî çàïèñü
*/ * óæå ñôîðìèðîâàíà
*/
/* Lead-In-îáëàñòü */
for(i = 1, n = 24; i < trk_num; i++, n += 8) {
.......
/* Îïðåäåëÿåì ðàçìåð òðåêà */
/* Pre-gap ïåðâîãî òðåêà */ memset((void *)&s, 0, sizeof(struct stat));
stat(argv[i], &s);
.......
/* Ñòàðòîâûå êîîðäèíàòû òðåêà */
/* Ïåðâûé òðåê */ trk += s.st_size/CD_FRAMESIZE_RAW;
min = LBA2MIN(trk);
....... sec = LBA2SEC(trk, min);
frame = LBA2FRAME(trk, min, sec);
/* Âòîðîé òðåê */
trk += trk1_size; /* Ôîðìèðóåì â ñòðóêòóðå CUE SHEET çàïèñü äëÿ òðåêà */
min = LBA2MIN(trk); cue_buff[n] = 0x01; cue_buff[n + 1] = i + 1;
sec = LBA2SEC(trk, min); cue_buff[n + 2] = 0x01; cue_buff[n + 3] = 0x00;
frame = LBA2FRAME(trk, min, sec); cue_buff[n + 4] = 0x00; cue_buff[n + 5] = min;
cue_buff[n + 6] = sec; cue_buff[n + 7] = frame;
cue_buff[24] = 0x01; cue_buff[25] = 0x02; }
cue_buff[26] = 0x01; cue_buff[27] = 0x00;
cue_buff[28] = 0x00; cue_buff[29] = min;