Uploaded by Igor Vasilenko

oa A.i.i. - e ua « PF (2-N na N) - 2011

advertisement
Книга о PF
by Peter N.M. Hansteen
Предисловие
из первого издания
Перевод выполнил Михайлов Алексей aka iboxjo
Homepage: iboxjo.h1.ru
blog: iboxjo.livejournal.com
Предисловие
из первого издания
Пакетный фильтр PF из OpenBSD, пользующийся значительным успехом и вниманием, впервые был
выпущен в составе OpenBSD 3.0 в конце 2001 года. Прежде чем вы узнаете о истории PF больше, в
двух словах можно сказать, что PF появился в связи с необходимостью разработчикам и
пользователям OpenBSD. С первого выпуска, PF значительно развился и стал мощным и бесплатным
инструментом для создания межсетевого экрана, балансировки нагрузки и управления трафиком.
Когда PF используется в сочетании с CARP и pfsync, он позволяет системным администраторам не
только защитить свои сервисы от атак, но и повысить их надёжность за счёт резервирования,
повысить скорость работы сервисов за счёт масштабирования с помощью пулов серверов
управляемых PF и relayd.
Пока я был связан с развитием PF, я в первую очередь ориентировался на крупномасштабных
пользователей PF. Я использовал PF для обеспечения безопасности и управления внутренними и
внешними угрозами, что помогало мне избегать критических проблем в инфраструктурах с
резервированием и масштабируемостью. Это экономило средства моего работодателя (Университета
Альберты, где я являюсь системным администратором), как в плане простоев так и с точки зрения
аппаратного и програмного обеспечения. Вы можете использовать PF для достижения тех же целей.
Однако широкая функциональность приводит к неизбежному злу высокой сложности. Для того, кто
хорошо разбирается в TCP/IP и OpenBSD, документация по системе PF является самодостаточной.
Однако, не смотря на обширные примеры присутствующие в системе документации, она никогда не
сможет вместить всё, что вы можете сделать используя PF и связанный с ним набор инструментов.
Большой объём документации может сделать её бесполезной для людей которым она необходима
лишь в качестве справочника.
Эта книга планировалась как мост через пропасть. Если вы являетесь новичком, она быстро
приведёт вас к OpenBSD и PF. Если вы опытный пользователь, эта книга может показать вам
некоторые примеры более сложных приложений PF, решающих проблемы выходящие за рамки
типичных.
В течение нескольких лет Питер М. Ханстен поддерживал отличный ресурс, позволяющий узнать,
как использовать PF "больше чем просто брандмауэр", а эта книга ещё больше расширяет его
традицию делиться знаниями с другими.
В настоящее время брандмауэры широко распространены, и большинство пользователей используют
один или несколько типов брандмауэров. Эта книга не просто расскажет о построении брандмауэра,
а поведёт речь о методах обучения по управлению сетевым трафиком. Понимание этих методов
может упростить жизнь системных и сетевых администраторов.
Простой брандмауэр легко построить или купить "из коробки", но управление и поддержка
брандмауэра - вещь более сложная. Эта книга проходит долгий путь к сглаживанию кривой
обучения и учит вас думать не только о том, как построить межсетевой экран, но и тому как
работает PF и как использовать его сильные стороны. Фактически эта книга является инвестицией
экономящей ваше время. Она позволит вам работать быстрее и правильнее, получать меньше
фальшстартов и затрачивать меньше времени на эксперименты.
Боб Бек
Директор фонда OpenBSD
http://www.openbsdfoundation.org
Эдмонтон, штат Альберта, Канада
Благодарности
Эта рукопись началась как лекция группе пользователей, впервые представленная 27 января 2005
года на совещании BLUG (BSD and Linux User Group)в Бергене. Затем я перевёл рукопись на
английский язык и немного расширил её. Грег Лей (Greg Lehey) предложил мне развернуть её ещё
немного и представить как учебник на полдня для конференции AUUG в 2005 году.
После ряда изменений учебника, я начал работать над первой версией книги 2007 года.
Следующие два параграфа сохранились из рукописи учебника и до сих пор существуют в книге:
Рукопись представляет собой дальнейшее развитие лекции которая была объявлена как (в
переводе с норвежского):
"Лекция
о брандмауэрах и функциях, примеры использования PF OpenBSD из реальной жизни. PF реализует брандмауэр, NAT,
контроль трафика и управление полосой пропускания в единой гибкой и дружественной системе. Питер надеется, что лекция
даст вам некоторые идеи о том, как управлять сетевым трафиком конкретных хостов или сервисов, и конечно, как усложнить
жизнь спамерам".
Некоторые части содержимого учебника (в основном все полезные темы) появились в этой книге в
той или иной форме. В процессе превращения в полезную книгу я учёл множество интересных идей
и предложений различных людей. Значительный и весьма полезный вклад в ранние версии этой
рукописи внесли Eystein Roll Aarseth, David Snyder, Peter Postma, Henrik Kramshøj, Vegard Engen,
Greg Lehey, Ian Darwin, Daniel Hartmeier, Mark Uemura, Hallvor Engen, и множество других которые
потеряны в моём почтовом архиве до тех пор пока я не смогу найти их там. Я хотел бы
поблагодарить следующие организации за их поддержку: фонд NUUG, организации AUUG, UKUUG,
SANE, BSDcan и AsiaBSDCon за приглашения на конференции; фонд FreeBSD за спонсирование моих
поездок на BSDCan 2006 и EuroBSDCon 2006.
Как и первая редакция, эта книга была написана в основном в ночное время и по выходным. Я хочу
поблагодарить своих бывших коллег по FreeCode за облегчение нагрузки позволившее мне
выкроить некоторое время для работы над вторым изданием в первых месяцах 2010 года. Так же я
хочу поблагодарить некоторых клиентов, которые просили, чтобы я не опубликовывал их имена, за
их сложные и интересные проекты, которые вдохновили меня на создание некоторых описываемых
конфигураций.
Наконец, в процессе превращения рукописи в книгу, некоторые люди сделали удивительные вещи,
которые помогли этой книге стать намного лучше. Я очень обязан Боллу Поллоку и Адаму Райту (Bill
Pollock and Adam Wright) за отличное редактирование и хочу поблагодарить Хеннинга Брауэра
(Henning Brauer) за техническое редактирование; сердечно благодарю Eystein Roll Aarseth, Jakob
Breivik Grimstveit, Hallvor Engen, Christer Solskogen, Ian Darwin, Jeff Martin, и Lars Noodén за ценный
вклад в различные части рукописи и наконец Megan Dunchak и Linda Recktenwald за их усилия
приложенные к созданию первого издания книги в её окончательном виде. Особую благодарность
приношу Dru Lavigne за создание концепции, благодаря чему книга стала целостной, а не
превратилась в интерактивное пособие и случайный набор материалов.
Не в последнюю очередь, я хочу поблагодарить свою жену Бирте и дочь Нору за их любовь и
поддержку до и во время написания книги. Это было бы не возможно без всех Вас.
Введение
Эта книга о том как построить вашу сеть. Мы погрузимся в тему брандмауэров и связанных с ними
функций, основываясь на базовой теории. Вы увидите множество примеров фильтрации и других
способов управления трафиком. Я предполагаю, что у вас имеются базовые знания о TCP/IP,
сетевых концепциях и администрировании UNIX.
Вся информация в этой книге предоставляется со следующим предупреждением: как и в прочих
случаях, все обсуждаемые решения могут быть реализованы другими способами. Кроме того, вы
должны знать, что в мире ПО что-то может измениться за то время когда писалась эта книга.
Информация содержащаяся в книге может считаться правильной и актуальной на момент её
написания, и относится к OpenBSD версии 4.8, FreeBSD 8.1 и NetBSD 5.0 включая патчи доступные
до конца августа 2010 года.
Это не HOWTO
Книга является популярным учебником по PF. Учебник можно считать источником наставлений и
может применяться в реальных сутуациях, но:
Этот документ не предназначен в качестве книги рецептов типа "вырезал вставил"
Просто повторяйте за мной как клятву:
Закон сетевого администратора
-------------------------------------------------------------------------------------Это моя сеть.
Это моё, или технически, моего работодателя.
Это моя ответственность и я забочусь о ней от всего сердца.
Есть много сетей таких же как моя, но не одна не подобна ей.
Я торжественно клянусь что не буду бездумно выполнять всё как HOWTO.
---------------------------------------------------------------------------------------
Дело в том, что я строю конфигурации (которые я тестировал и каким-то образом вводил в работу)
которые могут быть слишком упрощённые, поскольку многие из них были предназначены для
демонстрации конкретных задач. Почти наверняка они не будут соответствовать конфигурации
вашей сети или совершенно не подойдут для неё.
Пожалуйста, имейте в виду, что эта книга предназначена для демонстрации нескольких полезных
приёмов и вдохновления вас на дальнейшую работу. Стремитесь понять вашу сеть и ваши задачи
для достижения лучшего результата. Не следуйте тупому копирования информации из этого
документа, как в прочем и из любого другого.
Что рассматривает эта книга.
Книга предназначена для самостоятельного изучения, позволяя вам работать используя лишь
незначительные ссылки к справочным страницам, иногда ссылась на внешние ресурсы (доступные в
сети или в печатном виде), доступные в приложении А. Вероятно, ваша система будет исходить из
стандартной конфигурации pf.conf, содержащего некоторые закомментированые предложения к
возможным конфигурациям, и некоторых примеров из документации в директории /usr/share/pf/.
Эти примеры можно использовать в качестве ссылки, но непосредственно использовать их в книге
мы не будем. Вместо этого, вы узнаете как построить pf.conf с нуля, шаг за шагом.
Вот краткое изложение того что вы найдёте в этой книге:
Глава 1 "Строим сеть которая вам необходима" - пройдётся по основным концепциям сети,
даст краткий обзор истории PF и предоставит некоторые советы приспособления к BSD если вы
новичок в данной системе. Именно в этой главе вы можете получить основы работы с BSD
системами.
Глава 2 "Основы конфигурирования PF" - показывает, как включить PF на вашей системе и
охватывает самые основные наборы правил для отдельной машины. Эта глава является ключевой,
поскольку все поздние конфигурации основываются на этой главе.
Глава 3 "В реальном мире" - основана на конфигурации отдельной машины из Главы 2 и
проводит вас через основы создания шлюза, который послужит точкой контакта между отдельными
сетями. По окончанию третьей главы вы создадите конфигурацию, которая является достаточно
типичной для домашней сети или сети небольшого офиса, а кроме того у вас в рукаве будут
некоторые трюки, позволяющие облегчить управление сетью. Также, вы ощутите вкус того, как
работать с различными сервисами, такими ка FTP, и получите советы о том, как облегчить решение
проблем с мало понятными протоколами и сервисами.
Глава 4 "Беспроводные сети: Легко!" - проведёт вас через настройку беспроводных сетей.
Беспроводная среда предоставляет некоторые проблемы безопасности, но к концу главы вы
сможете решать проблемы посредством контроля доступа и аутентификации через authpf. Некоторая
полученная информация будет полезна и при работе с проводными сетями.
Глава 5 "Сети больше или сложнее" - решает проблемные ситуации по внедрению серверов и
сервисов доступных из вне вашей сети. К концу этой главы, вы создадите сеть с одной или
несколькими подсетями и зоной DMZ, и попробуете свои силы в различных вариантах балансировки
нагрузки с помощью схем перенаправления и relayd с целью повышения качества предоставляемых
услуг.
Глава 6 "Использование таблиц для проактивной защиты" - демонстрирует некоторые
инструменты PF для борьбы с попытками несанкционированной активности и их продуктивное
использование. Мы рассмотрим атаки методом брутфорса (подбора паролей) и сетевого флуда, а так
же инструмент антиспама spamd, демон OpenBSD для борьбы со спамерами. Эта глава должна
сделать вашу сеть более удобной для работы пользователей.
Глава 7 "Очереди, формирование трафика и избыточность" - рассматривает формирование
трафика посредством ALTQ. Далее переходит к созданию избыточной конфигурации с
использованием CARP для целей отказоустойчивости и балансировки нагрузки. Эта глава должна
позволить вам лучше адаптировать использование трафика к потребностям вашей сети и увеличить
доступность благодаря использованию резервирования и CARP интерфейса.
Глава 8 "Журналирование, мониторинг и статистика" - рассказывает о журналировании PF. Вы
узнаете, как извлекать и обрабатывать журналы и данные статистики ваших конфигураци,
используя базовые системные инструменты, а так же дополнительные пакеты. Здесь же вы
познакомитесь с NetFlow и SNMP.
Глава 9 "Достижение правильного развёртывания" - рассматривает различные варианты
настройки вашей системы. Она связывает знания накопленные в предыдущих главах.
Приложения А "Источники" - аннотированный список печатных и онлайновых документов,
которые могут оказать помощь в расширении знаний о PF и сетях.
Приложение B "Замечания по поддерживаемому оборудованию" - даёт обзор некоторых
вопросов, связанных с созданием лучшего инструмента на свободном ПО.
Если вы уверены в своих силах, вы можете сразу перейти к разделу который вас интересует больше
всего. Тем не менее, каждая глава основывается на работе сделанной в предыдущих главах, таким
образом может быть полезно читать главы в определённой последовательности. Основное
центрирование книги проводится на OpenBSD 4.8, с заметками о других системах, имеющих
некоторые отличия.
Глава 1
СТРОИМ СЕТЬ, КОТОРАЯ НАМ НЕОБХОДИМА
PF, подсистема пакетного фильтра (Packet Filter) OpenBSD - один из лучших инструментов
доступных для надёжного контроля вашей сети. Прежде чем погрузиться в особенности
того, как настроить сеть на пределе ваших мечтаний, ознакомьтесь с этой главой. Она
рассматривает базовые сетевые термины и понятия, предоставляет некоторые данные из
истории развития PF, а так же даёт краткий обзор того, что вы можете найти в этой книге.
Ваша сеть: Высокая производительность, низкие затраты
и высокая безопасность
Если заголовок точно описывает вашу сеть, вероятно вы читаете эту книгу для
развлечения, и я надеюсь, что остальная часть книги доставит вам удовольствие.
С другой стороны, если вы всё ещё изучаете, как строить сети, или не слишком уверены в
своих навыках, вам может быть полезно короткое резюме основных сетевых терминов и
терминов безопасности.
Безопасность информационных технологий (IT) - это большая, сложная и часто
запутывающая тема. Даже если ограничиться только исследованием терминов сетевой
безопасности, возникает ощущение, что мы не сильно сократили своё поле деятельности.
Дела стали намного хуже несколько лет назад, когда персональные компьютеры начали
подсоеденяться в глобальную сеть и стали оснащаться программами и приложениями для
работы с сетевым окружением, которые были не всегда удачно спроектированы.
Результат оказался вполне предсказуем. Ещё до того, как малые компьютеры стали
сетевыми, они были целью для вирусов (полуавтоматическому программному
обеспечению, которое может заражать другие файлы и размножаться) и трояны
(первоначально - троянские кони, программы заставляющие компьютер жертвы
выполнять определённые действия). Став сетевыми,
компьютеры подверглись ещё
одному типу вирусов - worms или сетевые черви, использующие сеть для размножения. 1
Попутно, на горизонте сетевой безопасности появились различные варианты сетевого
мошенничества и сегодня, значительная часть активной компьютерной безопасности
сконцентрировано на управлении угрозами, с упором на борьбу и каталогизацию
вредоносного ПО или так называемого malware.
Бесполезно перечислять всё зло — это было прекрасно сделано в другом месте (смотрите
приложение A, например отличное эссе Марка Ранума - «Шесть самых тупых идей в
компьютерной безопасности»).
Подход OpenBSD заключается, в первую очередь, в
способе разработки дизайна и кода. Если в дальнейшем, вы обнаруживаете ошибки и эти
ошибки оказываются эксплуатируемыми, после их исправления код возвращается в
дерево, даже если это может означать радикальный пересмотр дизайна, и в худшем
случае привести к потере совместимости.2
1 До эпохи Windows был только один известный червь IBM Christmas Tree EXEC (1987 год) и первый интернет червь, известный
как червь Мориса (1988 год), информацию о которых легко найти в любом поисковике. Эпоха сетевых червей Windows, как
считается, началась в мае 2000 года с появлением червя ILOVEYOU.
2 Некоторые презентации о подходе OpenBSD к вопросам безопасности можно найти на http://www .openbsd.org/papers/. Одни
из моих любимых - Тео де Раад (Theo de Raadt’s ) "Методы ликвидации брешей безопасности", Дэмиен Миллер (Damien Miller’s)
"Меры безопасности в OpenSSH" и "Паффи на работе - Получение правильного кода и безопасность, путь OpenBSD" Хеннинга
Брауера (Henning Brauer) и Свена Демлоу (Sven Dehmlow).
В PF, а так же в этой книге, основное внимание концентрируется на сетевом трафике
сетевого уровня. Введение divert(4) сокетов в OPenBSD 4.7. сделало проще настройку
системы, где PF используется для глубокой инспекции пакетов. Тем не менее, не всё
свободное ПО имеет специфический интерфейс пользователя, поэтому мы сфокусируемся
на некоторых методах основаных на поведении присущем сетевому уровню (наиболее
очевидно это показано в примере конфигурации главы 6) что поможет снизить нагрузку
на программы контроля контекста, если они у вас имеются. В следующих главах вы
увидите, что сетевой уровень предлагает множество возможностей кроме блокирования и
разрешения пакетов.
Где размещается фильтр пакетов
Основная функция фильтра пакетов, как следует из названия, состоит в фильтрации
сетевых пакетов путём сопоставления свойств отдельных пакетов и сетевых соединений с
критериями фильтрации или правилами пакетного фильтра, определёнными его
конфигурационным файлом. пакетный фильтр отвечает за решение относящееся к
действию производимому с пакетом. Это означает, что решается вопрос о том, следует ли
передавать пакет к месту назначения или отклонить его, должно ли возникнуть какоелибо событие операционной системы или внешних приложений настроенных на обработку
события.
PF позволяет администратору создавать собственные критерии фильтрации для контроля
сетевого трафика, основываясь на содержимом пакета или параметрах подключения, в
том числе адресах источника и назначения, интерфейсе, протоколе, портах и
направлении. Основываясь на этих критериях, пакетный фильтр применяет указанное
действие. Одним из простейших и наиболее общих действий является блокирование
трафика.
Пакетный фильтр может сдерживать нежелательный сетевой трафик. Кроме того, он
может помочь контролировать внутри сетевой трафик вашей собственной внутренней
сети. Обе эти функции очень важны в концепции брандмауэра, однако блокирование
трафика далеко не единственная полезная и интересная функциональная особенность
пакетного фильтра.
Вы можете использовать критерии фильтрации для непосредственного определения
видов сетевого трафика специфических хостов, назначить классификацию трафика в
очереди, выполнить формирование трафика (шейпер) и даже перенаправить проблемный
трафик к специализированному ПО для специальной обработки.
Все эти обработки производятся на сетевом уровне, основываясь на свойствах пакетов и
соединений. PF является частью сетевого стека, встроенного в ядро операционной
системы. Существовали примеры фильтрации пакетов в пространстве пользователя (user
space), однако в большинстве операционных систем функции фильтрации реализуются в
ядре системы, что обеспечивает высокую скорость работы.
Развитие PF
Если вас интересует история, вероятно вы знаете, что OpenBSD и другие BSD 3 ОС
являются прямыми потомками системы BSD (иногда говорят о BSD Unix), операционной
системы включающей эталонную реализацию протоколов стека TCP/IP начала 80-х годов.
Как исследовательский проект BSD был свёрнут в начале 90-х годов и его код был
освобождён для дальнейшего развития небольшими группами энтузиастов по всему миру.
некоторые из этих энтузиастов были ответственны за сохранение жизненно важных
частей инфраструктуры Интернет и развитие BSD продолжалось несколькими
параллельными направлениями под эгидой различных групп. OpenBSD стала известна как
наиболее безопасная ОС основанная на BSD. в качестве системы фильтрации пакетов,
данная система использовала подсистему названную IPFilter, написанную Дарреном Ридом
(Darren Reed).
3 Если аббревиатура BSD звучит для вас незнакомо, вот краткое разъяснение. Абревиатура расшифровывается как Berkeley
Software Distribution и первоначально являлась набором полезных программ разработаных для операционной системы Unix
сотрудниками и студентами Университета Калифорнии в Беркли. С течением времени набор программ оформился в полноценную
операционную систему, которая, в свою очередь, стала основой целого семейства ОС, в том числе OpenBSD, FreeBSD, NetBSD,
DragonFlyBSD, и в некоторых смыслах даже Apple Mac OS X. Для лёгкого понимания, что такое BSD, обратитесь к статье "Что
такое BSD" по адресу http://www.freebsd.org/doc/en/articles/explaining-bsd (ну и конечно к официальным сайтам проектов).
В начале 2001 года, сообщество OpenBSD было шокировано заявлением Рида который
объявил, что IPFilter, который на тот момент был тесно интегрирован с OpenBSD, не
попадает под лицензию BSD. Вместо этого, он использует практически аналогичную
лицензию, исключая право внесения изменений в код и распространение результата
изменений. Проблема заключалась в том, что версия IPFilter OpenBSD включала несколько
изменений и настроек, которые, как оказалось, не попадали под действие лицензии. В
результате, 29 мая 2001 года, IPFilter был удалён из дерева исходных кодов OpenBSD и в
течении нескольких недель, OpenBSD (-current) не включала никакого ПО бранмауэра.
К счастью, в это время, в Швейцарии, Даниэль Хартмейер (Daniel Hartmeier) производил
некоторые эксперименты с сетевой частью кода ядра. Он начал с подключения
собственной небольшой функции к сетевому стэку, а затем пропустил через неё сетевые
пакеты. Затем он задумался о фильтрации. Когда наступил описанный ранее кризис с
лицензией, PF уже находился в стадии разработки. Первый коммит кода PF пришёлся на
воскресенье 24 июня 2001 года в 19:48:58 UTC. Через несколько месяцев интенсивной
работы результирующая версия PF была выдвинута в качестве основной части базовой
системы OpenBSD 3.0 в декабре 2001 года. 4 Эта версия включала достаточно полную
реализацию пакетного фильтра, в том числе включая NAT, который был достаточно
похожим на IPFilter, т.ч. переход на новую версию OpenBSD не составил особых проблем. 5
PF оказался хорошо разработанным ПО. В 2002 году Хартмейер получил подтверждение
USENIX, доказывающее что тесты производительности OpenBSD 3.1 PF выполняются
одинаково хорошо или даже лучше чем IPFilter на OpenBSD 3.1 или IPTables на Linux.
Кроме того, тесты выполненные на PF OpenBSD 3.0 показали, что код повышает
эффективность с версии 3.0 до версии 3.1.6
Код OpenBSD PF, написаный с помощью нового движка фильтрации пакетов, опытными
разработчиками, естетственно вызвал интерес других групп BSD. Проект FreeBSD
постепенно принял PF, сначала в качестве пакета, а затем, начиная с версии 5.3 в
качестве одного из трёх компонентов фильтрации пакетов базовой системы. Кроме того,
PF был включён в NetBSD и DragonFlyBSD.7
Врезка: Новые версии PF работают лучше!
Как и всё в мире компьютеров, OpenBSD и PF были затронуты быстрыми изменениями аппаратных средств с
сетей связи. Я не видел тестов сопоставимости USENIX, однако пользователи PF находят, что накладные
расходы при использовании PF весьма скромные. В качестве примера (в основном, чтобы показать, что даже
слабые конфигурации оборудования вполне применимы), одна из фирм использовала в качестве сетевых
шлюзов машины в конфигурации Pentium III 450МГц c 384Мб памяти. При этом я не могу припомнить, чтобы
простой машины составлял менее 96%!
Стоит отметить, что текущие разработчики PF, в основном Хеннинг Брауэр (Henning Brauer) и Райан Мак'Брид
(Ryan McBride), при участии ряда других, внесли ряд оптимизаций в код OpenBSD PF в нескольких последних
релизах, что делало каждый последующий релиз с 4.4 по 4.8 заметно лучше предыдущего.
4 Эпизод с авторскими правами IPFilter стимулировал команду OpenBSD на выполнение аудита лицензий всего дерева исходных
кодов и портов, что позволило избежать подобных проблем в будущем. Несколько потенциальных проблем были решены в
течении последующих месяцев, что привело к удалению некоторого числа потенциальных лицензионных ловушек, угрожавших
разработчикам свободного ПО. Тео де Раадт подвёл итоги в сообщении списка рассылки openbsd-misc 20 февраля 2003 года.
Кризис лицензионной драмы миновал, а чистой прибылью стала новая система фильтрации пакетов под свободной лицензией и с
лучшим качеством кода, а так же более свободные лицензии, как для большой части кода OpenBSD, так и для другого широко
используемого ПО.
5 Совместимость с конфигурацией IPFilter
стало значительным плюсом для разработчиков PF, но это перестало быть
приоритетом, как только стало возможно с уверенностью предположить, что все пользователи OpenBSD перешли на PF
(примерно во время выхода релиза OpenBSD 3.2). Вам не следует считать, что существующая конфигурация IPFilter будет
работать без изменений с любой версией PF. С учётом изменений синтаксиса внесёнными в OpenBSD 4.7, даже обновление
ранних версий PF потребует проведения некоторых дополнительных работ.
6 Статью предоставляющую подробную информацию о тестах, можно получить на сайте
Даниеэля Хартмейера http://www.benzedrine.cx/pf-paper.html.
7 Одно время производители персонального брандмауэра Core Force утверждали, что он основан на PF. В начале 2010 года, Core
Security, компания разработавшая Core Force (http://force.coresecurity.com/) переключилась на другие области безопасности,
такие как тестирование проникновения, однако продукт по прежнему доступен для скачивания.
Эта книга посвящена PF доступном в OpenBSD 4.8, и, в случае необходимости, я буду
отмечать значительные различия между этой версией и теми, которые интегрированы в
другие системы. Если вы гготовы погрузиться в конфигурирование PF, вы можете перейти
к Главе 2, чтобы сразу начать работу. Если вы
хотите потратить немного времени и прокатиться по незнакомой территории BSD, можете
продолжить чтение этой главы.
Если вы пришли из другого места
Если вы читаете это по той причине, что планируете переместить настройки PF из другой
системы - этот раздел для вас. Если вы хотите использовать PF, необходимо установить и
запустить системы такие как OpenBSD, FreeBSD, NetBSD или DragonFly BSD. Всё это прекрасные ОС, но лично мне больше нравится OpenBSD, в основном по той причине, что
это та операционная система в которой, по существу, происходит развитие PF, и мне
нравится деловой подход к её разработке. Иногда, небольшие изменения и исправления
ошибок присходят в реализациях PF на других системах, но новый и самый современный
код PF всегда можно найти в OpenBSD.
Некоторые из особенностей описанные в этой книге доступны только в последних
версиях OpenBSD. Другие BSD системы, как правило портируют последние релизы PF
OpenBSD в свой базовый код, однако синхронизация обновлений далеко не
гарантирована и отставание может быть значительным.
Если вы планируете использовать PF на FreeBSD, NetBSD, DragonFly BSD или других
системах, вы должны проверить замечания к релизу для вашей системы и прочую
документацию, в целях получения подробной информации о включённой версии PF.
Указания для пользователей Linux
Сходство и различие между Linux и BSD - тема потенциально большая, если копать
достаточно глубоко, но если вы имеете базовые навыки эта проблема не займёт у вас
слишком много времени. В остальной части книги, я буду считать, что вы можете найти
свой путь базовой конфигурации сети BSD. Т.ч., если вы больше знакомы с настройкой
Linux
или
прочих
систем,
стоит
отметить
несколько
моментов
присущих
конфигурированию BSD.
–
–
–
Linux и BSD используют различные соглашения для именования сетевых
интерфейсов. Конвенция Linux - маркировка всех сетевых интерфейсов на машине
в виде последовательности eth0, eth1 и так далее (хотя для некоторых драйверов и
их комбинаций вы можете встретить wlan0, wlan1 и т.д. например для
беспроводных интерфейсов). В системах BSD, интерфейсам присваиваются имена,
состоящие из имени драйвера и порядкового номера интерфейса. Например старые
карты 3Com использующие драйвер ep появляются в системе как ep0, ep1 и так
далее; карты Intel Gigabit, определяются как em0, em1 и так далее. Некоторые
карты SMC представляются как sn0, sn1... Эта система вполне логична, и позволяет
проще найти данные для специфичного интерфейса. Если сообщения ядра (в
процессе загрузки или выводе ifconfig), говорят, что у вас есть интерфейс
названный em0, вам необходимо обратится к странице руководства системы, чтобы
узнать, какую скорость он поддерживает, какие прошивки ему нужны и тому
подобное.
Вы должны знать, что BSD-системы конфигуриются посредством /etc/rc.conf. В
общем, BSD системы организованы так, чтобы читать конфигурацию из файла
/etc/rc.conf, который читается скриптом /etc/rc при начальной загрузке. OpenBSD
рекомендует использовать /etc/rc.conf.local для локальных настроек, поскольку
rc.conf содержит значения по умолчанию. FreeBSD использует /etc/defaults/rc.conf
для хранения значений по умолчанию, предоставляя /etc/rc.conf для внесения
собственных изменений. Кроме того, OpenBSD использует конфигурационные
файлы для каждого отдельного интерфейса, называемые hostname.<if>, где <if>
заменяется именем интерфейса.
В целях изучения PF, вам необходимо сконцентрироваться на файле /etc/pf.conf,
который вы, по большей части, будете создавать сами.
Если вам требуются более широкие и тщательные сведения о вашей BSD системе,
обратитесь к документации по системе, в том числе FAQ, спискам рассылки и
официальным сайтам проектов. Некоторые рекомендации для прочтения вы можете найти
в Приложение А.
Часто задаваемые вопросы (FAQ) о PF
Этот раздел основан на вопросах, которые мне задавали по электронной почте или на
конференциях, а так же тех, которые появились в списках рассылки и форумах.
Некоторые из наиболее общих вопросов рассматриваются здесь в формате FAQ 8.
Могу ли я запустить PF на своей Linux машине?
Если отвечать одним словом - нет. На протяжении многих лет в списках рассылки
появлялись заявления, что начато портирование PF на Linux, но на момент написания этой
книги, всё ещё нет утверждения что задача решена. Основная причина этого, вероятно,
состоит в том, что PF разработан, прежде всего, как неотъемлемая часть сетевого стека
OpenBSD. Даже после более чем десятилетнего параллельного развития код OpenBSD
содержит достаточно много общего с другими BSD системами, что позволяет осуществить
перенос, но портирование PF на не-BSD системы потребует переписывания значительных
кусков кода PF, и частей интеграции на целевой системе. Несколько простых советов
ориентирующих пользователей Linux в BSD представлены в на странице 6 "Указания для
пользователей Linux".
Можете ли вы порекомендовать графический интерфейс для управления
набором правил PF?
Эта книга, большей частью, ориентирована на пользователей, которые будут
редактировать набор правил в своём любимом текстовом редакторе. Образцы наборов
правил, приведённых в книге, достаточно просты, и возможно, вы не получите
преймущества от различных вариантов инструментов визуализации графического
интерфейса. Общая проблема в том, что конфигурационные файлы PF легко читаемы, т.ч.
графический интерфейс, на самом деле, не является крайне необходимым.
В любом случае, существует несколько графических инструментов, которые позволяют
редактировать и/или генерировать конфигурацию PF, в том числе и специализированный
дистрибутив FreeBSD называемый pfSense (http://pfsense.org), включающий в себя
достаточно комплексный GUI редактор.
Я рекомендую изучить эту книгу, особенно части относящие к вашей ситуации, а затем
решить вопрос о необходимости использования GUI.
Имеется ли инструментарий, позволяющий преобразовать мои настройки другого
брандмауэра в конфигурацию PF?
Лучшая стратегия переноса настроек сети, в том числе и настроек брандмауэра, с одного
ПО на другое - собрать спецификации и политики конфигурации вашей сети или
брандмауэра, а затем реализовать политики используя новый инструмент.
Прочие продукты неизбежно будут иметь иной набор функциональных возможностей и
отличную конфигурацию, отражающую различные подходы к конкретным проблемам,
которые может быть непросто сопоставить с особенностями PF и связанных с ним
инструментов.
Документирование политики с поддержанием актуального состояния документации по
мере внесения изменений сильно облегчает вам жизнь. Данная документация должна
содержать полную спецификацию того, достижению чего способствуют ваши настройки.
(Вы можете начать с комментирования файла конфигурации для объяснения целей
каждого создаваемого правила). Это позволяет убедиться, является конфигурация
рациональной реализацией проектируемых целей.
8 Трёх буквенная абревиатура FAQ расшифровывается как часто задаваемые вопросы или как часто отвечаемые вопросы - оба
значения имеют силу.
Обычно системный администратор ищет пути автоматического преобразования настроек,
и это вполне понятно. Я призываю вас противостоять таким желаниям и выполнять
перенос настроек только после переоценки вашего технического оснащения и
потребностей бизнес-процесса, и, желательно, после создания или обновления
формальной спецификации и политики.
Некоторые из инструментов обладающих адинистративным интерфейсом имеют
возможность формирования файлов конфигурации для нескольких различных типов
брандмауэров и, вполне очевидно, могут использоваться в качестве инструментов
преобразования настроек. Однако, при этом возникает эффект создания нового уровня
абстракции между вами и вашим набором правил, что ставит вас в зависимость от
понимания автора инструмента о том, как работает набор правил PF. Я рекомендую
ознакомиться с соответствующими частями этой книги, прежде чем начинать тратить
время на серьёзное рассмотрение проблемы автоматизированного преобразования
настроек.
Почему вдруг изменился синтаксис правил PF?
Мир меняется, а вместе с ним меняется и PF. В частности, разработчики OpenBSD очень
активно и весьма критично относятся к своему коду, и соответственно как и все части
OpenBSD, код PF находится под постоянным контролем. Уроки извлечённые в течение
почти десяти лет развития и использования PF привели к внутренним изменениям кода,
который в конечном счёте ясно дал понять разработчикам, что незначительное изменение
синтаксиса имело бы смысл. Для пользователей, результатом стало то, что PF стал проще
в использовании и работает лучше чем в более ранних версиях. Если вы обновите свою
систему до OpenBSD 4.7 или выше, вы почувствуете реальное удовольствие от работы.
Где я могу узнать больше?
Существует несколько хороших источников информации о PF и системах на которых он
работает. Один из них вы найдёте в этой книге. Ссылки на печатные издания вы можете
обнаружить в Приложении А.
Если у вас есть BSD системы с установленным PF, обратитесь к man страницам
руководства для получения информации о особенностях текущей версии PF. Если не
указано иное, информация этой книги относится к системе OpenBSD 4.8.
Маленькое восхваление: Хайку о PF
Если вы всё таки не совсем уверены - предложим небольшую долю восхваления. За
прошедшие годы многие люди много говорили и писали о PF - иногда странное, иногда
прекрасное, а иногда совершенно странное. Стихотворение приведённое здесь, является
хорошим показателем того чувства, которое PF вызывает у своих пользователей. Это
стихотворение (поэма) появилась в списке рассылки PF, в потоке начинавшемся с
сообщения "Вещи которое не может PF?" в мае 2004 года. Сообщение было написано кемто, кто имел совсем мало опыта работы с брандмауэром и не мог добиться желаемого
результата. Конечно, это привело к некоторой дискуссии среди участников, обсуждающей
трудность освоения PF новичками, возможные альтернативы типа Bitdefender и пр. Поток
закончился следующей восхвалительной хайку, написанной Джейсоном Диксоном (Jason
Dixon), 20 мая 2004 года.
Сравнение работы iptables и PF подобно этому хайку
A breath of fresh air,
floating on white rose petals,
eating strawberries.
Now I'm getting carried away:
Hartmeier codes now,
Henning knows not why it fails,
fails only for n00b.
Tables load my lists,
tarpit for the asshole spammer,
death to his mail store.
CARP due to Cisco,
redundant blessed packets,
licensed free for me.
(Стихи переводить я вообще никогда не брался, а уж мысловые хайку и подавно, поэтому не судите строго, скажем глядя в
глаза правде, перевод весьма далёк от оригинала - п.п.)
Дыша свежим воздухом,
плывя на лепестках белых роз,
поедаю клубнику.
Теперь я увлёкся:
Хартмейера коды сейчас,
Хеннинг не знает неудач,
неудачи только для нубов.
Мои списки в таблицах загрузки,
тарпиты для долбаных спамеров,
смертью грозят его почте.
CARP с Cisco связующий,
благославляя надёжность пакетов,
свободно даровано мне.
Некоторые из концепций которые Диксон использует здесь могут звучать незнакомо, но
если вы продолжите читать книгу, они скоро обретут смысл.
Глава 2
PF: Основы конфигурирования
В этой главе мы создадим очень простую настройку PF. Начнем с наипростейшей
конфигурации, которая только возможна: единственная машина сконфигурирована для
соединения с единственной сетью. Этой сетью вполне может быть Интернет.
Два основных инструмента для конфигурирования PF: Ваш любимый текстовый редактор
и pfctl - инструмент администрирования командной строки. Конфигураця PF обычно
хранится в файле /etc/pf.conf и называется набором правил, ппоскольку каждая строка
в конфигурационном файле это правило, которое определяет, как фильтровать сетевой
трафик. Повседневное управление состоит в том, чтобы редактировать свою
конфигурацию в файле /etc/pf.conf, а после загружать изменения используя pfctl.
Существует веб интерфейс для управления правилами PF, но он не является частью
базовой системы. Разработчики PF не враждебно настроены к этим опциям, но они не
видели еще графического интерфейса для PF, который явно был бы более предпочтителен
прямого редактирования pf.conf и использования команды pfctl.
Шаг первый: Активизация PF
Прежде чем мы перейдем к части конфигурирования сети и использования связанных с
этим инструментов, нам необходимо, чтобы PF был доступен и активизирован. Детали
зависят от вашей операционной системы: OpenBSD, FreeBSD или NetBSD. Проверьте вашу
установку следуя инструкциям для вашей ОС и затем перейдите к разделу «Настройка
простых правил PF: единственная, автономная машина» на странице 16.
Команда pfctl это программа, которой необходимо больше прав чем по умолчанию
имеется у обычного пользователя. В оставшейся части книги, вы будете видеть команды,
которым необходимы экстра привилегии, как выполняемые с префиксом sudo. Если вы
ещё не использовали sudo, вам придётся это сделать. Sudo присутствует в базовой
системе OpenBSD. В FreeBSD и NetBSD, sudo доступно через систему портов или систему
пакетов, соответственно в security/sudo.
Вот несколько общих замечаний по использованию pfctl:
•
•
Команда деактивации PF pfctl –d. Однажды введя эту команду, все основанное на
pf фильтрации может быть пропущено в системе, поскольку pf будет отключен и
весь трафик будет разрешен.
Для удобства, pfctl позволяет производить несколько операций в одной командной
строке. Для того, чтобы активизировать PF и загрузить установленные правила в
единственной строке введите следующую команду:
sudo pfctl –ef /etc/pf.conf
Установка PF на OpenBSD
В OpenBSD 4.6 и позже, вам нет необходимости активизировать PF, поскольку PF
активизирован и установлен в минимальной конфигурации по умолчанию1.
1. Если вы устанавливаете первый раз PF конфигурацию на OpenBSD версии предыдущей чем эта, лучшим советом будет сделать
модернизацию до самой последней стабильной версии. Если по какой-то причине вы должны остаться с более старой версией,
вы должны будете проконсультироваться с первым изданием данной книги, а также с страницами мануалов и другой
документацией для той версии, которую вы используете.
Если вы посмотрите сообщения выводимые на системную консоль в процессе загрузки
системы, вы сможете заметить сообщение pf enables, которое появится вскоре после
завершения сообщений ядра.
Если вы не увидели сообщения pf enabled в консоли во время загрузки, у вас есть
несколько возможностей, позволяющих проверить, действительно ли PF активизирован.
Один простой путь для проверки - ввести команду, которая используется для
активизации PF в командной строке, похожую на эту:
$ sudo pfctl –e
Если PF уже активизирован, система ответит на это сообщением:
pfctl: pf already enabled
Если PF не активизирован команда pfctl –e актвизирует PF и отобразит:
pf enabled
В версиях предшествующих OpenBSD 4.6, PF был не активизирован по умолчанию. Вы
можете переопределить значение по умолчанию отредактировав ваш /etc/rc.conf.local (или
создав файл, если он не существует). Хотя в этом нет необходимости в последних версиях
OpenBSD, не сложно добавить строку в ваш /etc/rc.conf.local файл:
pf=YES
# enable PF
Если обратиться к содержимому файла /etc/pf.conf на свежей инсталляции OpenBSD,
первое, вы увидите свое первое работающее правило.
По умолчанию файл pf.conf в OpenBSD начинается с установки правила для интерфейса
lo позволяющее сохранить уверенность, что трафик на интерфейсе петли не фильтруется.
Следующая активная строка это правило pass, по умолчанию позволяющий проходить
вашему сетевому трафику. И, наконец, правило block, блокирует удаленный трафик X11 к
вашей машине.
Как вы возможно заметили, по умолчанию pf.conf файл также содержит несколько
закомментированных строк начинающихся с хэш символа (#). В этих комментариях вы
будете находить предлагаемые правила, которые намекают на полезные настройки, такие
как FTP проксирование (смотрите Главу 3) и spamd, демон блокирования спама OpenBSD
(смотрите Главу 6). Эти опции потенциально полезны в различных реальных сценариях,
но, поскольку они не могут быть актуальны во всех конфигурациях, они
закомментированы по умолчанию.
Если вы рассмотрите настройки связанные с PF в файле /etc/rc.conf, вы найдете строку
pf_rules=. В принципе, вы можете указывать в этом файле конфигурацию отличную от
файла /etc/pf.conf. Однако, изменение этого параметра на стоит траты времени.
Используя установки по умолчанию вы даете преимущество для большого количества
домашних приложений, таких как автоматическое ночное резервное копирование вашей
конфигурации в /var/backups. На OpenBSD скрипт /etc/rc имеет встроенный механизм
который поможет вам, если вы перезагрузили pf или при отсутствии файла pf.conf или
если он содержит недопустимый набор правил. Перед активизацией любых сетевых
интерфейсов, rc скрипт загружает правило позволяющее несколько базовых сервисов:
SSH откуда угодно, базовое разрешение имен и монтирование NFS. Это позволяет вам
залогиниться и исправить любые ошибки в вашем наборе правил, загрузить корректный
набор правил и продолжить работу.
Установка PF на FreeBSD
Хороший код хорошо распространяется, и пользователи FreeBSD скажут вам, что
хороший код откуда угодно, рано или поздно, найдет путь в FreeBSD. PF не исключение, и
с FreeBSD 5.2.1 и 4.х серий и далее, PF и связанные с ним инструменты стали частью
FreeBSD.
Если вы прочли предыдущий абзац по установке PF на OpenBSD, вы видели, что на
OpenBSD, PF был активизирован по умолчанию. С FreeBSD дела обстоят не так, поскольку
PF является только одним из трех доступных вариантов пакетного фильтра системы. В
FreeBSD вам необходимо сделать несколько явных действий для того, чтобы включить PF
и при сравнении с OpenBSD, кажется, что нужно немного больше поколдовать в вашем
/etc/rc.conf. Загляните в файл /etc/defaults/rc.conf - там показаны значения по умолчанию
для FreeBSD связанные с PF :
pf_enable="NO"
pf_rules="/etc/pf.conf"
pf_program="/sbin/pfctl"
pf_flags=""
pflog_enable="NO"
pflog_logfile="/var/log/pflog"
pflog_program="/sbin/pflogd"
pflog_flags=""
pfsync_enable="NO"
pfsync_syncdev=""
pfsync_ifconfig=""
#
#
#
#
#
#
#
#
#
#
#
Установить YES для активизации packet filter (PF)
файл для определения правил для PF
путь, где находится исполняемый файл PF
дополнительные флаги для pfctl
установить YES для включения логирования packet filter
где pflogd должен хранить logfile
где находится исполняемый файл pflogd
дополнительные флаги для pflogd
необходимо для синхронизации состояния pf для других хостов
интерфейс через который работает pfsync
дополнительные опции для ifconfig(8) для pfsync
К счастью, вы можете игнорировать многие из них – по крайней мере сейчас. Следующие
опции это только те, что вам необходимо добавить в вашу конфигурацию /etc/rc.conf:
pf_enable="YES"
pflog_enable="YES"
# Включение PF (загружается модулем если нужно)
# включаем pflogd(8)
Есть некоторые различия между FreeBSD 4.х, 5.х, и более поздних версиях в отношении
PF. Ссылаясь на хэндбук FreeBSD, а именно раздел о PF главы Брандмауэры, доступный
на http://www.freebsd.org ознакомьтесь с информацией которая применима в вашем
случае. Код PF на FreeBSD 7 и 8 такой же, как код на OpenBSD 4.1 с некоторыми
исправленными ошибками. Мы будем предполагать, что вы работаете на FreeBSD 7.0 или
новей.
На FreeBSD, PF компилируется как модуль ядра по умолчанию. Если ваша система
FreeBSD установлена с ядром GENERIC, вы можете запустить PF написав следующее:
$ sudo kldload pf
$ sudo pfctl –e
Предполагаю, что вы вставили строчки упомянутые в вашем /etc/rc.conf и создали
/etc/pf.conf файл, а так же, вы должно быть используете rc скрипт для запуска PF.
Следующие строки включают PF:
$ sudo /etc/rc.d/pf start
А эти выключают пакетный фильтр(packet filter):
$ sudo /etc/rc.d/pf stop
Замечание
На FreeBSD скрипту /etc/rc.d/pf необходима по крайней мере строка pf_enable=”YES” в /etc/rc.conf и корректный /etc/pf.conf
файл. Если какое либо из этих требований не выполняется, скрипт завершит работу с ошибкой. По умолчанию в инсталляции
FreeBSD файла /etc/pf.conf нет, и вам нужно будет создать его перед тем как перезагружать систему с включенным PF. Для
наших целей, создадим пустой /etc/pf.conf файл командой touch, но вы могли бы также работать если бы скопировали файл
из /usr/share/examples/pf/pf.conf поставляемый с системой.
Файл примера /usr/share/examples/pf/pf.conf содержит неактивные настройки. Он
включает только закомментированные строки начинающиеся с символа # и
закомментированные правила, что дает обзор того, как выглядят рабочие правила. Для
примера, если вы удалите знак # перед строкой, которая говорит нам, что нужно
пропускать все на loopback интерфейс, а затем сохраните файл как /etc/pf.conf, вы
включите PF и загрузите устаноленное правило на ваш loopback интерфейс, который не
фильтрует трафик. Однако, если PF включен на системе FreeBSD, а мы не удосужились
написать актуальные правила, PF ничего делать не будет и все пакеты будут пропущены.
На момент написания статьи (Сентябрь 2010) в rc скриптах FreeBSD не установлены
правила по умолчанию как резервные и если конфигурация читается из /etc/pf.conf то она
не будет загружена. Это означает что включение PF без установленных правил или с
содержимым pf.conf, которое синтаксически неверно оставит пакетный фильтр
включенным с правилом по умолчанию пропускать все.
Установка PF на NetBSD
На NetBSD 2.0, PF стал доступен как загружаемый модуль ядра, который может быть
установлен посредством пакетов (security/pflkm) или скомпилирован статически в ядро. В
NetBSD 3.0 и более поздних версиях, PF является часть базовой системы. На NetBSD PF один из нескольких возможных систем пакетной фильтрации, и вам явно включить его.
Некоторые детали конфигурации PF изменились в разных NetBSD релизах. В этой книге
предполагается что вы используете NetBSD 5.02 или более поздние версии.
Для использования загружаемого модуля PF в NetBSD добавим следующие строки в
/etc/rc.conf для включения загружаемого модуля ядра, PF и интерфейса журналирования
PF соответственно.
lkm="YES" # do load kernel modules
pf=YES
pflogd=YES
Загрузить модуль PF вручную и включить PF можно введя следующие команды:
$ sudo modload /usr/lkm/pf.o
$ sudo pfctl -e
Кроме того, вы можете запустить rc.d скрипт для включения PF и журналирования, как
показано ниже:
$ sudo /etc/rc.d/pf start
$ sudo /etc/rc.d/pflogd start
Для автоматической загрузки
следующие строку в /etc/lkm.conf
модуля
в
процессе
начальной
загрузки,
добавьте
/usr/lkm/pf.o - - - - BEFORENET
Если ваша файловая система /usr находится в отдельном разделе, добавьте строку в
файл /etc/rc.conf:
critical_filesystems_local="${critical_filesystems_local} /usr"
Если ошибок в этой части не возникло, значит вы успешно включили PF на вашей системе
и готовы перейти к создание законченной конфигурации.
Поставляемый файл /etc/pf.conf не содержит актвиных установок. Там есть только
закомментированые строки, начинающиеся с хэш символа (#) и закомментированные
правила, но это дает вам обзор правил, которые могут работать. Для примера, если вы
удалите хэш символ перед строкой, которая говорит пропускать на loopback интерфейс,
раскомментировав ее, а затем сохранив файл, вы включите PF и загрузите установленное
правило, а ваш интерфейс loopback не будет фильтровать трафик, проходящий через
него. Однако, даже если PF включен на вашей NetBSD системе, и мы не удосужимся
написать актуальные правила, то PF не будет выполнять правила, а будет пропускать
пакеты.
В NetBSD реализованы набор правил по умолчанию или резервных правил в файле
/etc/defaults/pf.boot.conf. Это набор правил предназначен только для того, чтобы система
завершила загрузку в случае если файл /etc/pf.conf не существует или содержит
некорректный набор правил. Вы можете переопределить набор правил по умолчанию
установив собственные настройки в /etc/pf.boot.conf.
2. Для инструкций по использованию PF в более ранних релизах, смотрите документацию для ваших релизов, а также смотрите
литературу по поддержке в списке Приложения А этой книги.
Простой набор правил PF:
Для единственной, или автономной машины
Главным образом, имея общую, минимальную базу, мы начнем строить набор правил с
простейшей конфигурации.
Минимальный набор правил
Самая простейшая конфигурация правил PF — набор правил для автономной машины,
которая не предоставляет сервисов и соединяется только с одной сетью (которая может
быть и непосредственно Интернетом). Мы начнем работать с файлом /etc/pf.conf, который
выглядит примерно как этот:
block in all
pass out all keep state
Такой набор правил запрещает весь входящий трафик, позволяя исходящий, и сохраняет
информацию о состоянии наших соединений. PF читает правила сверху вниз; выполняется
последнее правило в наборе правил приложимо к пакету или соединению.
Любое входящее в нашу систему соединение, независимо от источника, будет подпадать
под правило block in all. Даже с этой предварительной оценкой результата будет
осуществлён переход к следующему правилу (pass out all keep state), если трафик не
будет подпадать под первый критерий (направление out). Не имея больше правил для
оценки, статус не будет меняться и трафик будет заблокирован. В похожей манере, любое
инициированное соединение исходящее от машины с этим набором правил не будет
совпадать с первым правилом, а будет совпадать со вторым (еще раз неправильном
направлении); совпадение с pass правилом, позволило пропустить. Мы будем проверять
путь, которым PF оценивает правила и в каком порядке, эти вопросы более детально мы
будем рассматривать в Главе 3, в контексте чуть большего набора правил.
Для любого правила, которое относится к части keep state, PF хранит информацию о
соединении (включая различные счётчики и порядковые номера) как запись в таблице
состояний (state table). Таблица состояний - это то место, куда PF сохраняет информацию
о существующих соединениях, которые уже попали под правило, и новые пакеты которые
сравниваются с существующей таблицей состояния в поисках первого вхождения в
таблицу. Только если пакет не совпадает с любым существующим состоянием, PF начнёт
полную оценку набора правил, проверяя, совпал ли пакет с правилом в загруженном
наборе правил. Мы можем также инструктировать PF о действиях состояния информации
различными путями, но в самом простом случае как этот, наша главная цель это
позволить вернуть трафик для соединений, которые возвращаются к нам.
Обратите внимание, что в OpenBSD 4.1 и более поздних версиях, по умолчанию для pass
правила хранится информации о состояние 3 и нам не нужно сохранять состояние явно в
самом простом случае как этот. Это значит, что набор правил может быть записан так:
# минимальный набор правил, OpenBSD 4.1 и более поздних версиях сохраняет состояние # по умолчанию
block in all
pass out all
Фактически, вы можете даже оставить здесь ключевое слово all, если вам нравится.
В других BSD системах дела обстоят примерно так же, и в оставшейся части книги, мы
будем придерживаться нового стиля правил, с редкими напоминаниями, в том случае если
вы используете старые системы. Само собой, мы будем считать, что весь трафик
генерируемый от хоста, о котором идет речь, по сути заслуживает доверия.
Когда вы приготовитесь использовать этот набор правил, загрузите их следующей
строкой:
$ sudo pfctl -ef /etc/pf.conf
3. На самом деле, новое значение по умолчанию соответствует хранению состояния флагов S/SA, гарантируя, что только
инициированные SYN пакеты при установлении соединения создадут состояние, устраня некоторые загадочные сценарии
ошибки.
Набор правил должен быть загружен без каких либо ошибок или предупреждений. Во
всех системах, кроме самых медленных, вам должно сразу же вернуться приглашение
командной строки.
Тестирование набора правил
Это неплохо протестировать ваш набор правил, это дает уверенность в том , что они
работают как ожидается. Правильное тестирование станет существенным, как только вы
перейдете к более сложным конфигурациям.
Для тестирования простого набора правил следует убедиться, может ли он выполнять
разрешение доменных имен. Для примера, вы могли бы увидеть что хост nostarch.com
вернул информацию такую как IP адрес хоста nostarch.com и имена почтовых хостов
домена. Или просто проверьте можете ли вы выйти в сеть. Если вы можете соединиться с
внешним веб сайтом по имени, значит набор правил выполняет разрешение доменных
имен. В основном, любые службы к которым вы попытаетесь получить доступ со своей
собственной системы должны работать, и любые службы, которые попытаются получить
доступ к вашей система с другой машины получат сообщение отказа соединения
(connection refused).
Более строгие: использование списков и макросов для
удобства чтения
Набор правил в предыдущем разделе чрезвычайно прост – возможно слишком прост для
практического использования. Но это полезная отправная точка для построения немного
более структирированной и законченной установки. Мы начнем с запрещения всех служб
и протоколов, а затем позволим только те, необходимость в которых мы имеется 4,
используя спискои и макросы для лучшего удобства чтения и управления.
Список - два или более объектов одного типа, на которые вы можете сослаться в наборе
правил, таких как:
pass proto tcp to port { 22 80 443 }
Здесь { 22 80 443 } - список.
Макрос является более читабельным инструментом. Если вы имеете объекты на которые
нужно сослаться более одного раза в конфигурации, такие как IP адреса для важного
хоста, может быть полезным определить макрос вместо их прямого указания. Для
примера, вы должны определить определить этот макрос ранее в наборе правил:
external_mail = 192.0.2.12
Теперь вы можете ссылаться на этот хост как $external_mail в наборе правил:
pass proto tcp to $external_mail port 25
Эти две возможности имеют огромный потенциал для сохранения вашего набора правил
более читабельными, и они являются важным фактором, который вносит вклад в общую
цель - держать под контролем вашу сеть.
Базовый запрещающий набор правил
До этого момента, мы разрешали любой трафик в отношении себя. Разрешающий набор
правил может быть очень полезен пока мы проверяем наши основные соединения
находятся на месте, или проверяем какую-нибудь фильтрацию, которая является частью
проблемы, которую мы видим. Но, как только фаза «У нас есть связь?» закончилась,
пришло время начать ужесточение, чтобы создать базовую линию, которая обеспечит
контроль.
4. Зачем писать набора запрещающих правил по умолчанию? Самый короткий ответ это дает вам лучший контроль. Задача
пакетного фильтра держать под контролем, не дать попасться, что плохие парни могут сделать. Маркус Ранум написал очень
увлекательную и информативную статью, которая называется “Шесть самых тупых идей в компьютерной безопасности”
(http://www.ranum.com/security/computer_security/editorials/dumb/index.html)
Начнем, с добавления следующего правила в /etc/pf.conf:
block all
Это правило полностью запрещающее и будет блокировать весь трафик во всех
направлениях. Оно инициирует базовую линию правил фильтрации, которую мы будем
использовать полностью во всех наборах правил в следующих нескольких главах. Мы
начали с нуля, с конфигурации где нет ничего, разрешающей прохождение всего
трафика. Позже мы добавим правила, которые еще немного сократят наш трафик, но мы
будем делать это постепенно и таким образом это будет держать нас под твердым
контролем.
Теперь, мы определим несколько макросов в наборе правил, которые используем позже:
tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s }"
udp_services = "{ domain }"
Здесь вы можете видеть как комбинация списков и макросов может использоваться для
получения некоторого преимущества. Макросы могут быть списками, и как
демонстрировалось в примере, PF понимает правила которые используют имена служб
также хорошо, как и номера портов, перечисленных в вашем файле /etc/services. Мы
позаботимся об использовании всех этих элементов и некоторых других трюках для
большей читабельности в решении сложных ситуаций, которые требуют более сложных
наборов правил. Имея эти макросы, мы можем использовать их в наших правилах,
которые мы будем сейчас редактировать:
block all
pass out proto tcp to port $tcp_services
pass proto udp to port $udp_services
Замечание
Не забудьте добавить сохранение состояния для этих правил, если ваша система имеет версию PF старше чем OpenBSD 4.1
Строки $tcp_services и $udp_services являются ссылками на макрос. Макросы, которые
появляются в наборе правил в этом месте расширяются, когда набор правил загружается
и работающий набор правил будет иметь полные списки, которые вставляются в макросы
на которые ссылаются. В зависимости от точной природы макросов, они могут вызываться
одним правилом с ссылкой на макрос, расширяющуюся на несколько правил.
Даже в маленьких наборах правил, таких как этот, использование макросов делает
правила легче для понимания и поддержки. Количество информации, которая необходима
для появления сжатого набора правил, а также с осмысленными именами макросов,
логика становится понятней. Следуя логике типичного набора правил, чаще всего, мы не
должны видеть полный список IP адресов или номера портов в месте каждой ссылки на
макрос. С практической точки зрения, с перспективой обслуживания набора правил,
важно иметь ввиду каким службам и какой протокол позволять для того, чтобы сохранить
одновременно и комфортный и жесткий режим. Сохранение отдельных списков
разрешенных служб в соответствии с протоколом, будет сохранять ваш набор правил
функциональным и читабельным.
TCP ПРОТИВ UDP
Мы позаботились, чтобы отделить TCP службы от UDP служб. Некоторые службы работают в основном на хорошо
известных номерах портов и на TCP или UDP, а также несколько альтернативных между использованием TCP и UDP
в соответствии с конкретными условиями.
Два протокола совершенно различных в некоторых отношениях. TCP является ориентированным на соединение и
надежным, идеальный кандидат для динамической фильтрации. В отличие от UDP, который является не без
основания не ориентированным на соединение, но PF создает и поддерживает данные эквивалентно о состоянии
информации для UDP трафика, чтобы обеспечить возврат разрешенного UDP трафика назад, если он соответствует
существующим состояниям.
Один общий пример где состояние информации для UDP полезно для обработки разрешения имен. Когда вы
запрашиваете имя сервера разрешить доменное имя по IP адресу или разрешить IP адрес по имени хоста, то
разумно предположить, что вы хотите получить в ответ. Сохранение информации или функциональный эквивалент
о вашем UDP трафике сделает это возможным.
Перезагрузка набора правил и просмотр ошибок
После изменений в файле pf.conf, нам нужно загрузить новые правила как показано
далее:
$ sudo pfctl -f /etc/pf.conf
Если нет синтаксических ошибок, pfctl не должен отобразить никаких сообщение в ходе
загрузки правил.
Если вы предпочитаете подробный вывод, используйте –v флаг:
$ sudo pfctl -vf /etc/pf.conf
Когда вы используете подробный режим вывода, pfctl должен расширять свои макросы в
отдельные правила, прежде чем вернут вас в командную строку как показано далее:
$ sudo pfctl -vf /etc/pf.conf
tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s }"
udp_services = "{ domain }"
block drop all
pass out proto tcp from any to any port = ssh flags S/SA keep state
pass out proto tcp from any to any port = smtp flags S/SA keep state
pass out proto tcp from any to any port = domain flags S/SA keep state
pass out proto tcp from any to any port = www flags S/SA keep state
pass out proto tcp from any to any port = pop3 flags S/SA keep state
pass out proto tcp from any to any port = auth flags S/SA keep state
pass out proto tcp from any to any port = https flags S/SA keep state
pass out proto tcp from any to any port = pop3s flags S/SA keep state
pass proto udp from any to any port = domain keep state
$_
Сравните этот вывод с содержанием файла /etc/pf.conf, который вы на самом деле
написали. Для нашей единственной TCP службы правило разворачивается в восьми
различных контекстах: по одному для каждой службы в списке. Одно правило UDP
заботиться только об одной службе, и оно расширяется от того, что мы включили опцию
по умолчанию. Обратите внимание, что правила отображаются в полном объеме, с
значениями по умолчанию, такие как флаги S/SA хранящие состояние применяемое в этом
месте для любой опции не указаной в явном виде. Эта конфигурация та, которая
загружается на самом деле.
Проверка ваших правил
Если вы сделали внешние изменения в вашем наборе правил, проверьте их перед тем,
как попытаетесь загрузить набор правил :
$ pfctl -nf /etc/pf.conf
Опция –n говорит PF о том, что нужно только проверить правила, без их загрузки –
покажет вам что вы имеете в сухом остатке и позволит вам просмотреть и исправить
возможные ошибки. Если pfctl найдет какие-либо синтаксические ошибки в вашем наборе
правил, он выйдет с сообщением об ошибке, которая указывает на номер строки, где
произошла ошибка.
Некоторые руководства по брандмауэрам посоветуют вам убедиться что ваша старая
конфигурация действительно работает, или, если вы столкнулись с проблемами,
брандмауэр может быть в каком-то промежуточном состоянии, которое не соответствует
состоянию ни до, ни после. Это просто не верно, когда вы используете PF. Последний
допустимый загруженный набор правил будет активным до тех пор пока вы не отключите
PF или пока не загрузите новый набор правил. pfctl проверяет синтакс, а затем загружает
новый набор правил полностью перед переходом на новые. Как только допустимый набор
правил был загружен, нет промежуточного состояния с частичным набором правил или
вообще с незагруженными правилами. Одним из следствий этого является то, что трафик,
который соответсвует состоянию которые действительны в обоих, старого и нового набора
правил не будет нарушена. Если вы на самом деле следовали советам из некоторых этих
старых руководств и покраснели за существующие правила (это возможно, используя pfctl
–F all или аналогичного) прежде чем пытаться загрузить новые из вашего
конфигурационного файла, последняя допустимая конфигурация будет оставаться
загруженной. На самом деле, сброс набора правил иногда хорошая идея, так как это
эффективно устанавливает ваш пакетный фильтр в режим разрешить все, и с достаточно
высоким риском нарушения полезного трафика пока вы готовитесь загрузить ваши
правила.
Тестирование измененного набора правил
Если у вас есть набор правил, которые pfctl загрузил без каких-либо ошибок, пришло
время посмотреть работают ли ваши правила так, как ожидалось. Проверка разрешения
имен с командой такой как $ host nostarch.com (как мы делали ранее) должно все еще
работать, но выберите домен, который недоступен в последнее время (например, одной из
политических партий, которая не прошла голосование), чтобы убедиться, что вы не
тянете DNS-информацию из кеша. Вы должны способны серфить Web и использовать
несколько связанных с почтой служб, но из-за природы этого обновленного набора
правил, пытается получить доступ к TCP службам другие, чем те, которые определены
(SSH, SMTP и т.д.) на любой удаленной системе не сможет. И как и наш простой набор
правил, ваша система должна отказаться от всех соединений, которые не соответствуют
существующим записям в таблице состояний; только обратный входящий трафик будет
разрешено инициировать на этой машине.
Отображение информации о вашей системе
Тесты, которые вы выполняли должны были показать, что PF запущен и что ваши
правила ведут себя так как и ожидалось. Есть несколько способов, чтобы отслеживать,
что происходит в вашей работающей системе. Один из наиболее простых способов
получения информации о PF это использовать уже знакомую программу pfctl. После того
как PF включен и работает, система обновлений различных счетчиков и статистики
ответственна за сетевую активность. Для подтверждения того, что PF действительно
работает и просматривает статистику своей деятельности, вы можете использовать pfctl –
s, а затем выведется информация, которую вы хотели видеть. Довольно длинный список
информации которую нужно отобразить (смотрите man 8 pfctl найдите опцию -s). Мы
будем возвращаться к некоторым из этих параметров в главе 8 и вдаваться в дальнейшие
подробности о некоторой статистике, которую она предоставляет в главе 9, когда мы
используем данные для оптимизации конфигурации, которую мы строим. Ниже приведен
пример верхней части информации вывода команды pfctl –s (взято с моего домашнего
шлюза). Информация высокого уровня о том, что система действительно пропускает
трафик может быть найдена в этой верхней части.
$ sudo pfctl -s info
Status: Enabled for 24 days 12:11:27 Debug: err
Interface Stats for nfe0 IPv4 IPv6
Bytes In 43846385394 0
Bytes Out 20023639992 64
Packets In
Passed 49380289 0
Blocked 49530 0
Packets Out
Passed 45701100 1
Blocked 1034 0
State Table Total Rate
current entries 319
searches 178598618 84.3/s
inserts 4965347 2.3/s
removals 4965028 2.3/s
Первая строка pfctl вывода показывает, что PF включен и работает уже в течение чуть
более трех недель, равный времени с тех пор как я последний раз производил
обновление системы, которое требовало перезагрузки.
Состояние статистики интерфейса, отображается количество байт входящего и
исходящего трафика обрабатываемого интерфейсом. Следующие несколько пунктов,
вероятно, будут более интересны в нашем контексте, показывая количество пакетов,
заблокированных или переданных в каждом направлении. Именно здесь мы находим
ранние признаки фильтрующих правил, блокирующих весь трафик, которые мы писали. В
этом случае, либо набор правил ожидаемого трафика хорош, либо мы имеем
пользователей и гостей, которые достаточно хорошо себя ведут, при этом число пакетов
пропущенных гораздо больше тех, что были заблокированы в обоих направлениях.
Следующий важный показатель работающей системы, которая обрабатывает трафик это
блок статистики таблицы состояний. Состояние текущей строки таблицы показывает, что
есть 319 активных состояний или соединений, в то время как в таблице состояний
проходил поиск на совпадение существующих состояний в среднем чуть больше чем 84
раза в секунду, в обще сложности чуть более 178 миллионов раз счетчики были
сброшены.
Вставки и удаленные счетчики показывают, сколько раз состояния были созданы и
удалены, соответсвенно. Как и ожидалось, количество вставок и удалений отличаются по
количеству активных состояний, счетчики показывают, что за время прошедшее со
времени последнего сброса счетчиков, скорость состояний создаваемых и удаляемых с
точностью совпадают до этого просмотра.
Информация здесь примерно соответствует статистике, которую вы ожидаете увидеть на
шлюзе для маленькой сети сконфигурированной только с IPv4. Не существует никаких
оснований для беспокойства по пакетам, пришедшим в IPv6 колонке. OpenBSD
поставляется с встроенным IPv6. Во время сетевой конфигурации интерфейса, по
умолчанию, TCP/IP стэк посылает IPv6 с запросом на ссылку соседнего локального адреса.
В нормальной только IPv4 конфигурации, только первые несколько пакетов на самом деле
пройдет, и к тому времени набор правил PF из /etc/pf.conf полностью загружены, IPv6
пакеты блокируются блоком набора правил по умолчанию. (В данном примере они не
отображаются в статистике nfe0 потому, что протокол IPv6 туннелируется через другой
интерфейс).
Забегая вперед
Теперь у вас есть машина, которая может общаться с другими соединенными с интернет
машинами, используя очень простой набор правил, который служит отправной точкой для
контроля сетевого трафика. Как вы прочитаете эту книгу, вы узнаете, как добавить
правила, которые делают различные полезные вещи.
В главе 3, мы будем расширять конфигурацию выступающую в качестве шлюза для
небольшой сети. Обслуживание потребностей нескольких компьютеров имеет некоторые
последствия, и мы увидим, как разрешить некоторый ICMP и UDP трафик на основе наших
собственных потребностей устранения неполадок, если ничего больше нам не нужно.
Глава 3
В реальном мире
Предыдущая глава демонстрировала базовую конфигурацию фильтра пакетов на
единственной машине. В этой главе, мы будем строить сеть основываясь на базовых
настройках, но постепенно переходить к более традиционным пространствам: таким как
шлюз с фильтрацией пакетов. Хотя большинство пунктов этой главы являются
потенциально полезными для конфигурирования простой машины, основной фокус
направлен на создание шлюза, который занимается перенаправлением выбраного
сетевого трафика и управляет общими сетевыми сервисами локальной сети.
Простой шлюз
Мы начнём с постройки того, что для многих ассоциируется с термином брандмауэра:
машина которая действует в качестве шлюза, по крайней мере для одной другой машины.
В дополнение к форвардингу пакетов между различными сетями, миссия этой машины
будет заключаться в улучшение отношения сигнал/шум в сетевом трафике который она
обрабатывает.
Прежде чем погрузиться в практические детали конфигурации, нам необходимо
окунуться в некоторую теоритическую часть и конкретизировать некоторые понятия. В
конечном счёте это избавит вас от головной боли, которую я слишком часто наблюдал в
списках рассылки и группах новостей.
Делай это просто: как избежать ловушек in, out и on
При конфигурировании единственной машины, всё выглядит достаточно просто.Трафик
который вы создаёте должен выпускаться во внешний мир или блокироваться вашими
правилами фильтрации; и вы сами решаете, что вы хотите впустить к себе из вне. При
настройке шлюза приоритеты меняются. Вы переходите от мышления "Я здесь - сеть там"
к мышлению вида "Я тот кто решает что разрешить для тех кто ко мне подключен".
Машина шлюз имеет несколько, или по крайней мере два сетевых интерфейса
подключенных к разным сетям, и его основная функция (или по крайней мере та функция
в которой мы заинтересованы) - передача трафика между сетями.
Вполне разумно считать, что, если вы хотите разрешить трафик с сетевого соединения
интерфейса re1 к хостам на сетевом интерфейсе re0, вам необходимо правило подобное
следующему1.
pass in proto tcp on re1 from re1:network to re0:network port $ports keep state
Однако, одними из наиболее общих и наиболее часто обсуждаемыми ошибками в
конфигурации брандмауэра является непонимание того, что само по себе, ключевое слово
не гарантирует перехода к конечной точке. В данном случае, ключевое слово означает
только то, что пакет или соединение должно иметь адрес назначения, который
удовлетворяет конкретным критериям, благодаря чему и соответствует правилу. Правило,
которое мы только что написали, позволяет трафику приходить только в сам шлюз, на
1 На самом деле хранение состояний является поведением по умолчанию, и является избыточным, если вы работаете с PF
OpenBSD 4.1 или выше. Однако, как правило, нет необходимости удалять спецификации существующих правил, с которыми вы
сталкивались при обновлении с ранних версий. Для облегчения перехода, примеры этой книги упоминают об этом когда это
необходимо
именованый интерфейс указанный в правиле. Для того, чтобы пакеты двигались дальше и
перешли в другую сеть, вам необходимо соответствующее правило, которое говорит чтото вроде этого:
pass out proto tcp on re0 from re1:network to re0:network port $ports keep state
Пожалуйста, остановитесь и прочитайте эти правила ещё раз. Последнее правило
позволяет проходить только пакетам с назначением в сети непосредственно
подключенной к re0, и больше ничего. Если это именно то, чего вы добивались прекрасно. В другом контексте, такие правила, вполне правильные, могут оказаться
слишком конкретизированными чем того требует ситуация. Весьма легко погрузиться в
специфические детали и потерять более высокую точку зрения на цели
конфигурирования, тем самым заработав несколько дополнительных раундов на отладку.
Если есть веские причины для написания очень конкретных правил, таких как
предыдущие, вероятно вы уже знаете почему нуждаетесь в них. К тому времени, как вы
закончите читать эту книгу (а может быть и раньше) вы должны быть в состоянии ясно
сформулировать обстоятельства необходимости использования слишком детальных
правил.
Вполне вероятно, что для базовой конфигурации шлюза, создаваемой в этой главе, вы
захотите написать правила не специфичные для конкретного интерфейса. На самом деле,
в ряде случаев, это бесполезно для указания направления, а для доступа в интернет из
локальной сети вы будете просто использовать правило подобное следующему.
pass proto tcp from re1:network to port $ports keep state
Для простых настроек, интерфейсно-связанные правила in и out скорее добавят больше
беспорядка в ваш набор правил, чем принесут пользу. Для загруженных сетевых
администраторов удобочитаемый набор правил гораздо безопасней. В ходе оставшейся
части книги, за небольшим исключением, мы постараемся придерживаться как можно
более простых правил.
Трансляция сетевых адресов против IPv6
Прежде чем мы начнём управлять трафиком между различными сетями, полезно
взглянуть на то как работают сетевые адреса и почему можно встретить несколько
различных схем адресации. Область сетевых адресов всегда была богатым источником
путаницы. Иногда факты установить достаточно сложно, если вы не обратитесь к
источникам и не погрузитесь в пучину RFC. В течение нескольких следующих параграфов
я попытаюсь внести некоторые разъяснения в эту путаницу.
Например, существует широко распространённое убеждение, что если у вас есть
локальная сеть, использующая отличный диапазон адресов, чем тот который назначен
интерфейсу соединённому с интернет, вы находитесь в полной безопасности, и никто из
вне не может получить доступ к вашим сетевым ресурсам. Это заблуждение тесно связано
с идеей, что IP адрес вашего брандмауэра в локальной сети должен быть либо 192.168.0.1
или 10.0.0.1.
В обоих заблуждениях существует элемент правды и поэтому, данные адреса часто
присутствуют в настройках по умолчанию. Однако в реальной истории существуют пути
обхода NAT (хотя PF предлагает ряд трюков значительно усложняющих эту задачу).
Реальная причина использования определённого набора внутренних адресов, отличного
от диапазона внешних адресов связана, в первую очередь, не с безопасностью, а с тем,
что это был самый простой способ обойти проблемы возникшие при разработке
протоколов Интернет: ограничение на диапазон возможных адресов.
В 80-х, когда были разработаны протоколы Интернет, большинство компьютеров в сети
Интернет (в тот момент более известной как ARPANET) были большими компьютерами с
десятками и тысячами пользователями. В это время, 32-х битное адресное пространство, с
более чем 4 миллиардами адресов казалось вполне достаточным, но время и некоторые
дополнительные факторы показали, что это не так. Одним из факторов стало то, что
процесс распределения адресов привел к ситуации, когда крупные куски доступного
адресного пространства оказались уже распределёнными, ещё до того, как некоторые из
густонаселённых стран мира получили доступ к Интернет. Другим, и возможно более
существенным фактором, стало то, что в начале 90-х годов Интернет стал уже не
исследовательским проектом, а скорее сообществом коммерческих ресурсов и число
потребителей адресного пространства продолжало стремительно рости.
Долгосрочным решением стало использование большего адресного пространства. В 1998
году был опубликован RFC 2460, содержащий спецификацию IPv6, с разрядностью адреса
128-бит и емкостью адресного пространства 2^128 адресов.
Однако, пока мы ждали IPv6, нам требовалось временное решение проблемы. Это
решение пришло в виде ряда документов RFC, которые определяли как шлюз может
пересылать трафик с трансляцией IP адресов, так чтобы большая локальная сеть
выглядела подобно единственному компьютеру подключенному к Интернет. Для частных
сетей были зарезервированы некоторые нераспределённые диапазоны IP адресов. Они
были свободны для любого использования, при соблюдении условия, что эти диапазоны
не могут использоваться для интернет без транслянции. Таким образом в середине 90-х
годов появился NAT, который быстро превратился в основной способ управления
адресацией в локальные сети2.
PF поддерживает IPv6, а так же различные трюки трансляции адресов IPv4. (На самом
деле BSD системы стали одними из первых принявших IPv6, в большей степени благодаря
проекту KAME3). Все системы в которых есть PF поддерживают оба протокола семейств
IPv4 и IPv6. Если ваша сеть использует NAT для IPv4, вы можете, по мере необходимости,
интегрировать переход на IPv6 в наборе правил PF. Другими словами, если вы
используете систему которая поддерживает PF, вы можете быть уверены, что ваши
потребности в IPv6 уже учтены, по крайней мере на уровне операционной системы.
Примеры этой книги, в основном используют IPv4 и NAT, однако большая часть материала
будет актуальна и в сетях использующих протокол IPv6.
Завершение подготовки: Определим вашу локальную сеть
В главе 2 мы создали конфигурацию для единственной, автономной машины. Мы
собираемся развернуть эту конфигурацию в конфигурацию версии шлюза, и поэтому
полезно определить несколько макросов, способствующих повышению читабельности и
концептуальному разделению отдельных уровней локальной сети, на каждом из которых
существуют определённые меры контроля отличные от других. Так как же определить
свою локальную сеть в терминах PF?
Ранее в этой главе, вы уже видели нотацию интерфейс:сеть (interface:network). Это
хороший пример записи, однако, вы можете сделать свой набор правил даже более
удобным для чтения и обслуживания, создав некоторые макросы. Например, вы можете
определить макрос $localnet, как сеть напрямую соединённую с вашим внутренним
интерфейсом (в нашем примере это re1). Или вы можете изменить определение $localnet
на нотацию IP адрес/маска сети (IP address/netmask) для обозначения сети, например
192.168.100.0/24 для частной подсети адресов IPv4, или fec0:dead:beef::/64 для
диапазона IPv6.
Если ваша сетевая среда того требует, вы можете определить ваш $localnet как список
сетей. Для примера, разумно определить $localnet в комбинации с разрешающими
правилами использующими макрос, такими как следующие, что в итоге избавит вас от
некоторой головной боли.
pass proto { tcp, udp } from $localnet to port $ports
Мы будем придерживаться соглашения использования макросов, таких как $localnet для
удобства чтения.
2 RFC 1631, "Преобразование сетевых IP адресов (NAT)" опубликовано в мае 1994 года, и RFC 1918, "Распределение частных
адресов Интернет", датированное февралём 1996 года, предоставляют детальную информацию о NAT.
3 По слова проекта KAME (http://www.kame.net), совместными усилиями шести компаний Японии решено было реализовать
свободный стек IPv6, IPsec и Mobile IPv6 для BSD систем. Основные направления деятельности исследований и разработки
должны были быть завершены в 2006 году, с продолжением поддержки важных частей включённых в основные операционные
системы.
Настройка шлюза
Мы используем конфигурацию простой машины которую построили в предыдущей главе в
качестве основы для построения конфигурации фильтра пакетов шлюза. Предположим,
что на машину установлена дополнительная сетевая карта (или вы создали сетевое
подключение из локальной сети к одной или более сетей через Ethernet, PPP или другим
способом). В нашем контексте детали настроек интерфейсов незначительны. Мы просто
должны знать, что интерфейс поднят и работает.
Для последующего обсуждения и примеров, различаются только имена интерфейсов
между настройками PPP и Ethernet, и мы сделаем всё возможное чтобы избавиться от
фактических имён интерфейсов как можно скорее.
Во-первых, поскольку пересылка пакетов отключена по умолчанию во всех BSD
системах, нам необходимо её включить, чтобы машина имела возможность передавать
трафик с одного интерфейса в другие сети с помощью одного или нескольких
интерфейсов. Первоначально, мы сделаем эту операцию в командной строке, используя
команду sysctl для традиционного IPv4:
# sysctl net.inet.ip.forwarding=1
Если нам необходимо передавать трафик IPv6, используем следующую команду:
# sysctl net.inet6.ip6.forwarding=1
Теперь всё прекрасно. Однако, чтобы изменения сохранились после перезагрузки
компьютера,
вам
требуется
записать
эти
изменения
в
соответствующие
конфигурационные файлы. В OpenBSD и NetBSD, вы можете сделать это
отредактировав /etc/sysctl.conf, добавив или изменив строки IP форвардинга следующим
образом:
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
В FreeBSD, произведите изменения внеся следующие строки в /etc/rc.conf:
gateway_enable="YES" #for ipv4
ipv6_gateway_enable="YES" #for ipv6
Эффект одинаковый; RC скрипт FreeBSD установит два значения посредством
выполнения команды sysctl. Тем не менее, большая часть конфигурации FreeBSD
сконцентрирована в rc.conf.
Теперь пришло время проверить, все ли интерфейсы, которые вы собираетесь
использовать, подняты и работают. Используйте для этого команду ifconfig -a или
ifconfig <имя_интерфейса>. Вывод ifconfig -a на моей системе выглядит примерно
так:
$ ifconfig -a
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33224
groups: lo
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x5
xl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:60:97:83:4a:01
groups: egress
media: Ethernet autoselect (100baseTX full-duplex)
status: active
inet 194.54.107.18 netmask 0xfffffff8 broadcast 194.54.107.23
inet6 fe80::260:97ff:fe83:4a01%xl0 prefixlen 64 scopeid 0x1
fxp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:30:05:03:fc:41
media: Ethernet autoselect (100baseTX full-duplex)
status: active
inet 194.54.103.65 netmask 0xffffffc0 broadcast 194.54.103.127
inet6 fe80::230:5ff:fe03:fc41%fxp0 prefixlen 64 scopeid 0x2
pflog0: flags=141<UP,RUNNING,PROMISC> mtu 33224
enc0: flags=0<> mtu 1536
Скорее всего, ваши установки несколько иные. Здесь видны физические интерфейсы
шлюза xl0 и fxp0. Логический интерфейс lo0 (интерфейс заглушка или обратная петля),
enc0 (интерфейс инкапсуляции для использования IPSEC) и pflog0 (устройство
журналирования pf) скорее всего так же присутствую в вашей системе. Если вы работаете
с модемного соединения, вы вероятно используете какой либо вариант PPP для
соединения с Интернет, и ваш внешний интерфейс - псевдоустройство tun0.
Если подключение осуществляется через какое либо широкополосное подключение,
возможно вы имеете какой либо Ethernet интерфейс. Однако, если вы попадаете в
подмножество пользователей ADSL которые используют PPPoE, корректным внешним
интерфейсом будет одно из псевдо-устройств tun0 или pppoe0 (в зависимости от того,
используете ли вы pppoe(8) в пространстве пользователя или pppoe(4) в режиме ядра), а
не физический интерфейс Ethernet.
В зависимости от вашей конкретной установки, вам может понадобиться создать
специфические настройки для устройств вашего интерфейса. После того, как вы
завершите их настройку, можете перейти на уровень TCP/IP и начать работать с
конфигурацией пакетного фильтра.
Если вы всё-таки решили разрешить любой трафик, инициированный машинами
внутренней сети, ваш файл конфигурации /etc/pf.conf для шлюза может выглядеть
следующим образом:
ext_if = "re0" # макрос для внешнего интерфейса - используйте tun0 или pppoe0
для PPPoE
int_if = "re1" # макрос для внутреннего интерфейса
localnet = $int_if:network
# ext_if IP address could be dynamic, hence ($ext_if)
match out on $ext_if from $localnet nat-to ($ext_if)
block all
pass from { lo0, $localnet }
Обратите внимание на использование макросов для назначения логических имён сетевым
интерфейсам. В данном случае используются Ethernet карты Realtek, но это последний
раз, когда мы обращаемся к типу интерфейса в нашем контексте. Для столь простой
конфигурации как эта, мы не можем получить видимого эффекта от использования
макросов, но как только набор правил начинает расти, вы сможете оценить удобство
чтения, привносимое использованием макросов.
Кроме того, следует обратить внимание на правило содержащее элемент nat-to. Здесь вы
управляете NAT с не маршрутизируемым адресом внутри вашей локальной сети, т.е.
адресом предоставленным вам ISP. Если ваша сеть использует оффициальные,
маршрутизируемые адреса, просто уберите эту строку в вашей конфигурации.
Соответствующие правила, которые были введены в OpenBSD 4.6, могут быть
использованы для применения действий к соединениям соответствующим определённым
критериям безпринятия решения о блокировании или пропуске соединения.
Круглые скобки последней части правила ($ext_if) необходимы для компенсации
возможности динамического назначения IP адреса внешнего интерфейса. Это будет
гарантировать, что при изменение IP адреса интерфейса, трафик вашей сети будет
двигаться без значительных перебоев. Если ваша система работает на базе версии preOpenBSD 4.7 PF, ваш набор правил для шлюза может выглядеть примерно так:
ext_if = "re0" # macro for external interface - use tun0 or pppoe0 for PPPoE
int_if = "re1" # macro for internal interface
localnet = $int_if:network
# ext_if IP address could be dynamic, hence ($ext_if)
nat on $ext_if from $localnet to any -> ($ext_if)
block all
pass from { lo0, $localnet } to any keep state
Здесь, правило nat управляет трансляцией аналогично правилу nat-to из предыдущего
примера.
С другой стороны, этот набор правил позволяет несколько больше того, что вы хотите
разрешить на выходе из вашей сети. В одной из сетей, с которой я много работал,
основная часть набора правил была основана на макросе названном client_out:
client_out = "{ ftp-data, ftp, ssh, domain, pop3, auth, nntp, http,https, 446,
cvspserver, 2628, 5999, 8000, 8080 }"
pass inet proto tcp from $localnet to port $client_out
Возможно, здесь присутствует несколько своеобразный набор портов, но это именно то
что было необходимо. Некоторые из портов были необходимы для ряда других систем,
находящихся в других местах. Ваши потребности, с большой долей вероятности, будут
отличаться в некоторых деталях, но большей частью здесь присутствуют полезные
сервисы. Вот ещё один пример пропускающего правила, которое может быть полезно тем,
кто хочет управлять машиной по ssh:
pass in inet proto tcp to port ssh
Или используйте такую форму если вам удобно:
pass in inet proto tcp to $ext_if port ssh
Когда вы используете часть from, по умолчанию используется from any, которая
является весьма разрешительной. Это позволяет вам входить в систему из любого места,
что весьма удобно для доступа по SSH из неизвестного места. Если вы не на столько
мобильны - скажем, вы не слишком любите соединение из неизвестных мест или вы
хотите бросить своих коллег на произвол судьбы, пока находитесь в отпуске - вы можете
указать from с включением только тех мест, из которых администратор может входить в
систему.
Наш простой набор правил до сих пор не завершён. Нам необходимо создать названия
рабочих сервисов для наших клиентов. Мы начнём с другого макроса в начале нашего
набора правил.
udp_services = "{ domain, ntp }"
Это дополнит правило пропускающее трафик через наш брандмауэр:
pass quick inet proto { tcp, udp } to port $udp_services
Обратите внимание на ключевое слово quick в этом правиле. Мы начали писать набор
правил, состоящий из нескольких правил, и теперь настало время пересмотреть
отношения и взаимосвязи между ними. Как уже отмечалось в предыдущей главе, правила
оцениваются сверху вниз, в последовательности их записи в файле конфигурации. Для
каждого
пакета
или
соединения
оцениваемого
PF,
применяется
последнее
соответствующее правило набора.
Ключевое слово quick предлагает уйти от обычной последовательности проверки. Когда
пакет соответствует правилу quick, он обрабатывается в соответствии с данным
правилом.Обработка правил останавливается, без учёта любых дополнительных правил,
которые так же могут соответствовать пакету. Поскольку, со временем, набор правил
становится больше и сложнее, вы можете посчитать это удобным. Например, это весьма
полезно, когда вам необходимо несколько изолированных исключений для ваших
основных правил. Это правило quick обрабатывает протокол NTP, который используется
для синхронизации времени. Общим для сервиса разрешения имён и протокола
синхронизации времени является то, что они могут, при определённых обстоятельствах,
взаимодействовать попеременно через TCP и UDP.
Тестирование вашего набора правил
Возможно вы ещё не можете провести формальную проверку записанного набора правил,
но есть все основания проверить, что ваша конфигурация работает так как ожидалось. В
силе остаются все теже основные принципы тестирования, которые мы использовали для
автономного примера из предыдущей главы. Однако, теперь вам необходимо произвести
проверку с других хостов сети, и с вашего шлюза фильтрации пакетов. Необходимо
убедится, что для каждого из сервисов, котрые мы указали в нашем правиле пропуска,
машины в локальной сети получат положительный результат. С любого компьютера,
находящегося в вашей локальной сети, введите команду подобную следующей:
$ host nostarch.com
Она должна возвратить тот же результат , который вы получили когда тестировали набор
правил для автономной машины в предыдущей главе, а трафик для сервиса который вы
указали должен быть пропущен.4
Врезка: Почему только IP адреса, а не имена хостов или доменные имена?
Если рассматривать примеры, с которыми мы работали до этого момента, можно заметить, что набор правил
содержит макросы, которые развёртываются в IP дареса или диапазоны IP адресов, но никогда в имена хостов
или доменные имена. Вам наверно интересно почему? В конце концов, вы видели, что PF позволяет
использовать имена сервисов в наборе правил, так почему бы не включать и имена хостов или доменные
имена?
Ответ таков: если бы вы использовали имена хостов или доменные имена в своём наборе правил, набор
правил был бы действителен только после того, как заработает и станет доступна служба имён. В
конфигурации по умолчанию, PF загружается раньше чем запускаются любые сетевые службы. Это означает,
что если вы хотите использовать доменные имена или имена хостов в вашей конфигурации PF, вам
необходимо изменить последовательность запуска системы (путём редактирования файла /etc/rc.local) для
загрузки набора правил зависимого от сервиса разрешения имён только после доступности сервиса
разрешения имён.
Этот старый FTP
Краткий перечень реальных портов TCP мы уже рассматривали раньше, и в том числе FTP
- классический протокол передачи файлов. FTP является реликтом раннего Интернета,
времени, когда эксперименты были нормой и вопросы безопасности ещё не были столь
важными в современном смысле этого слова. Фактически FTP является предвестником
TCP/IP5, и развитие протокола можно отследить обратившись к RFC 50. После, более чем
30 лет, FTP, одновременно является раритетной вещью и проблемным ребёнком, для тех
кто пытается объединить FTP и брандмауэр. FTP старый и странный протокол, не любимый
многими. Вот наиболее распространённые причины за которые его не взлюбили:
•
•
•
пароли передаются в открытом виде
протокол требует использования по крайней мере двух TCP соединений
(управления и данных) на отдельных портах.
после установления сеанса, данные передаются через порты выбраные случайным
образом
Все эти факторы создают проблемы с точки зрения безопасности, ещё до того, как можно
начать рассматривать любые потенциальные недостатки в программном обеспечение
клиента и сервера. При любых обстоятельствах, существуют другие, более современные и
более безопасные средства передачи файлов, например SFTP и SCP, которые включают
возможности аутентификации и передачи данных через защищённое соединение.
Компетентные специалисты IT всегда должны предпочесть формы передачи файлов
отличные от FTP.
Независимо от вашего профессионализма и предпочтений, иногда приходится обращаться
к вещам, которые мы предпочли бы не использовать. В случае использования FTP через
брандмауэр, мы можем бороться с возникающими проблемами путём перенаправления
трафика на специальную программу. созданную именно для этих целей.
4 Если конечно информация не изменилась за прошедшее время. некоторые системные администраторылюбят розыгрыши,
однако большую часть времени информация зоны DNS изменяется только в связи с реальной потребностью конкретной
организации или сети.
5 Ранний RFC описывающий FTP протокол - RFC 114, датированный 10 апреля 1971 года. Переключение на TCP/IP произошедшее
в FTP версии 5 определяется в RFC 765 и 775, датированных июнем и декабрём 1980 года соответственно.
Наиболее лёгкий путь для управления FTP - создать в PF перенаправление трафика на
внешний сервис, который действует в качестве прокси-сервера для данного сервиса.
Далее, прокси будет взаимодействовать с вашим пакетным фильтром через чётко
определённый интерфейс.
Если мы должны: FTP-прокси с перенаправлением
Включить передачу FTP через ваш шлюз удивительно просто, благодаря тому, что
программа FTP-прокси включена в базовую систему OpenBSD. Как вы можете догадаться,
программа называется - ftp-proxy.
Прокси необходимо динамически вставлять правила в ваш набор правил. ftp-proxy
взаимодействует с конфигурацией с помощью якоря (именованой секции в наборе
правил) в которой прокси вставляет или удаляет правила конструируя общение с вашим
трафиком FTP.
Для включения ftp-proxy, вам необходимо добавить эту строку в ваш файл
/etc/rc.conf.local:
ftpproxy_flags=""
Вы можете запустить прокси вручную выполнив /usr/bin/ftp-proxy, чтобы убедится,
что изменения в конфигурации PF, которые вы сделали принесли ожидаемый эффект.
Для базовой конфигурации, вам необходимо добавить всего три элемента в ваш файл
/etc/pf.conf: якорь и два правила пропуска. Якорь объявляется примерно так:
anchor "ftp-proxy/*"
В версии pre-OpenBSD 4.7, необходимо объявить два якоря:
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
Сюда прокси будет вставлять правила сгенерированные для сессий FTP. Так же вам
необходимо правило пропуска для FTP трафика в прокси:
pass in quick proto tcp to port ftp rdr-to 127.0.0.1 port 8021
Обратите внимание на часть rdr-to. Она перенаправляет трафик на локальный порт, на
котором слушает прокси.
Для версии pre-OpenBSD 4.7 это правило выглядит так:
rdr pass on $int_if proto tcp from any to any port ftp -> 127.0.0.1 port 8021
Наконец, добавим пропускающее правило для разрешения движения пакетов от прокси
во внешний мир:
pass out proto tcp from $proxy to any port ftp
$proxy расширяется в адрес с которым связан демон прокси. Перезагрузите вашу
конфигурацию PF:
$ sudo pfctl -f /etc/pf.conf
Знайте, что ваши пользователи будут благодарны вам за возможность использования FTP.
Этот пример охватывает основные настройки, необходимые для доступа ваших клиентов к
удалённому FTP серверу. Данная базовая конфигурация должна хорошо работать в
большинстве случаев и в различных комбинациях FTP клиентов и серверов.
Вы можете изменить поведение прокси, добавляя опции к строке ftpproxy_flags =. Вы
можете столкнуться и с причудливыми клиентами и серверами, однако большинство
проблем можно компенсировать дополнительным конфигурированием прокси. По этим
вопросам, вам лучше всего обратится к страницам руководства. Если вы заинтересованы в
способах запуска FTP сервера защищённого PF и ftp-proxy, вы можете обратить внимание
на запуск отдельно ftp-proxy в реверсном режиме (используя опцию -R), на отдельном
порте с собственным пропускающим правилом перенаправления.
Замечание:
Если ваша версия PF более ранняя чем описано здесь, обратитесь к первому изданию этой книги и документации
на вашу систему для получения более полной информации о использовании ранних версий ftp-proxy.
Сделаем решение проблем вашей сети простым
Упрощение разрешения проблем сети - тема потенциально большая. Как правило,
отладка и устранение неполадок сети TCP/IP зависит от того, как вы относитесь к
специальным протоколам созданным для отладки, и в частности к ICMP. ICMP - протокол
предназначенный для отправки и приема управляющих сообщений между хостами и
шлюзами, предоставляющий обратную связь с отправителем информирующую о какихлибо необычных и проблемных условиях на пути к целевому хосту.
В сети присутствует значительный объём трафика ICMP, проходящего в фоновом режиме,
в то время, когда вы занимаетесь сёрфингом в Интернет, читаете почту или передаёте
файлы. Маршрутизаторы (один из которых вы строите, верно?) используют ICMP для
сообщения размера пакетов и других параметров передачи в процессе которй часто
называют исследованием MTU. Возможно вы слышали, что администраторы упоминают
ICMP как "зло", или если их понимание работает несколько глубже - как "необходимое
зло". Причина такого отношения сложилась исторически. несколько лет назад, при
исследовании сетевых стеков некоторых операционных систем, обнаружилось содержание
кода, который мог приводить к сбою, в случае отправки большого ICMP запроса. Одной из
компаний сильно пострадавшей от этой проблемы стала Microsoft, и до сих пор, можно
найти множество информации от так называемом пинге смерти (ping of death). Тем не
менее, все эти события происходили во второй половине 90-х годов и все современные
операционные системы имеют откорректированный код сетевой подсистемы (по крайней
мере мы хотим в это верить).
Одним из первых решений стала блокировка эхо-запросов ICMP или даже всего ICMP
трафика. Такие наборы правил существовали примерно 10 лет, и люди которые их
создали до сих пор боятся этой проблемы. Однако, скорее всего, довольно мало
оснований беспокоиться по поводу разрушительного ICMP трафика, по этому здесь мы
будем рассматривать только то как управлять входящим и исходящим ICMP трафиком.
Будем пропускать всё?
Возникает вполне очевидный вопрос - "Если ICMP такая полезная вещь, может следует
разрешить весь трафик и всё время?". Ответ таков: в зависимости от обстоятельств.
Разрешение движения диагностического трафика конечно упростит отладку, но и упростит
другим работу по извлечению полезной информации о вашей сети. Таким образом, могут
оказаться полезными правила позволяющие скрыть внутреннюю работу вашей сети
подобные следующим:
pass inet proto icmp
Лёгкий путь: Остановка здесь
Самым простым решением может оказаться, что весь ICMP трафик локальной сети
останавливается на вашем шлюзе:
pass inet proto icmp icmp-type $icmp_types from $localnet
pass inet proto icmp icmp-type $icmp_types to $ext_if
Остановка тестовых сообщений на уровне шлюза может быть привлекательным
вариантом в любом случае, однако давайте рассмотрим несколько других вариантов,
которые продемонстрируют гибкость PF.
Разрешение прохода пинга
Набор правил, который мы разработали до сих пор имеет один явный недостаток: общие
команды диагностики, такие как ping и traceroute не будут работать. Возможно это и не
имеет большого значения для пользователей, поскольку большинство пользователей
никогда не используют эти команды, но тем кому они нужны будет приятно иметь
возможности диагностики. Для этого понадобится всего пара дополнений в наборе
правил. ping использует ICMP, и для того, чтобы поддерживать наш набор правил в
аккуратном виде, мы начнём с определения нового макроса:
icmp_types = "echoreq"
Теперь добавим правило которое будет использовать определение:
pass inet proto icmp icmp-type $icmp_types
Если вы хотите использовать другие типы пакетов ICMP, вы можете расширить icmt_types
в список требуемых типов пакетов.
Поможем traceroute
traceroute - другая команда, которая является весьма полезной, особенно в случае
когда пользователи заявляют вам что Интернет не работает. По умолчанию, UNIX
traceroute использует UDP соединения согласно формуле основанной на назначении.
следующее правило работает с командой traceroute на всех формах Unix с которыми я
работал, в том числе и на Linux:
# allow out the default range for traceroute(8):
# "base+nhops*nqueries-1" (33434+64*3-1)
pass out on $ext_if inet proto udp to port 33433 >< 33626
Это даёт вам понимание того как выглядит диапазон портов. Они весьма полезны в
некоторых контекстах.
Опыт показывает, что реализации трассировки на других операционных системах
работают примерно аналогичным образом. Заметным исключением является только
Microsoft Windows. Таким образом, если вы хотите, чтобы трассировка работала в
Windows, вам необходимо только первое правило, и, кроме того, необходимо разрешение
ping. Программе трассировки Unix может быть указано использование другого протокола,
и она будет вести себя аналогично трассировке Microsoft если вы используете опцию
командной строки -l. Для получения большей информации обратитесь к man-странице
traceroute.
Это решение основано на образце правила, которое я нашёл в одном из постов openbsdmisc. Я обнаружил, этот список рассылки и архив списка (доступный на http://marc.info/),
который может стать ценным ресурсом информации по OpenBSD или PF.
Исследование MTU
Ещё раз хочу напомнить, что когда дело доходит до устранения неполадок - это путь
исследования MTU. Протоколы Интернет разработаны так, чтобы быть аппаратно
независимыми, и одним из последствий этого, является то, что вы не всегда можете
предсказать наверняка, каков оптимальный размер пакета для данного соединения.
Основное ограничение на размер пакета называется максимальным размером
передаваемого блока данных, или MTU, который устанавливает верхний предел на размер
пакета для интерфейса. Команда ifconfig может показать вам MTU для сетевых
интерфейсов. Современная реализация TCP/IP имеет возможность поределить правильный
размер пакета для процесса подключения, который включает в себя передачу пакетов
различного размера в рамках MTU локального линка с установленным флагом "not
fragment". Если пакет превышает MTU, гдето на пути следования к назначению, хост с
более низким MTU вернёт ICMP пакет указывающий "type 3, code 4" при достижении
локального верхнего предела.
Теперь вам не нужно сразу нырять в RFC. type 3 означает недоступность назначения, а
code 4 -требование фрагментации, при установленном флаге "not fragment". Таким
образом, если ваше соединение с другими сетями, имеющими отличные значения MTU,
окажется не оптимальным, вы можете попытаться изменить список типов ICMP, чтобы
пропускать пакеты недоступности назначения:
icmp_types = "{ echoreq, unreach }"
Как вы можете видеть, вам не нужно менять само правило пропуска:
pass inet proto icmp icmp-type $icmp_types
Сейчас я открою вам маленький секрет: для целей исследования MTU эти правила не
всегда необходимы (однако они не помешают). Хотя, по умолчанию, PF хранит состояния
о поведении большинства ICMP трафика необходимого вам, он позволяет иметь фильтры
на все варианты типов и кодов ICMP. Если вы хотите подробно разобраться в типах и
кодах, обратитесь к man-страницам icmp(4) и icmp(6). Дополнительную справочную
информацию можно получить из RFC6.
Таблицы сделают вашу жизнь проще
Сейчас вы можете решить, что конфигурация слишком статичная и жёсткая. В конце
концов, здесь будут некотрые виды данных, имеющие отношение к фильтрации и
перенаправлению трафика, однако они не заслуживают того, чтобы находится в
конфигурационном файле. Это вполне справедливо, и PF предлагает механизм для
решения этой ситуации.
Таблицы - одна из таких возможностей. Они полезны в качестве списков IP адресов,
которыми можно манипулировать без перезагрузки всего набора правил, и кроме того,
полезны для быстрого поиска. Имена таблиц всегда заключаются в < >, например:
table <clients> persist { 192.168.2.0/24, !192.168.2.5 }
Здесь сеть 192.168.2.0/24 является частью таблицы с одним исключением: адрес
192.168.2.5 исключается путём использования оператора ! (логический NOT). Ключевое
слово persist гарантирует, что сама таблица будет существовать. даже если нет никаких
правил, в настоящее время использующих её. Кроме того, можно загрузить таблицы из
файлов, в которых каждый элемент стоит в отдельной строке, например таких как
/etc/clients:
192.168.2.0/24
!192.168.2.5
Он, в свою очередь, используется для инициализации таблицы в /etc/pf.conf:
table <clients> persist file "/etc/clients"
Так, например, вы можете изменить одно из предыдущих правил для управления
исходящим трафиком компьютеров ваших клиентов:
pass inet proto tcp from <clients> to any port $client_out
Имея это вы можете уравлять содержимым таблиц вживую, подобно следующему:
$ sudo pfctl -t clients -T add 192.168.1/16
6 Основные RFC описывающие ICMP и некоторые связанные с ним методы - 792, 950, 1191, 1256, 2521 и 2765. Обновление ICMP
для IPv6 описано в документах RFC 1885, RFC 2463, RFC 2466. Эти документы можно найти на http://www.ietf.org/ и
http://www.faqs.org/.
Обратите внимание, что при этом копия таблицы изменяется только в памяти, а значит
после перезагрузки или сбоя питания изменения не сохранятся. вы можете выбрать путь
сохранения копии таблицы на диске, используя задания cron для создания дампа
таблицы с регулярными интервалами, используя примерно следующую команду:
$ sudo pfctl -t clients -T show >/etc/clients
Альтернативно, вы можете отредактировать файл /etc/clients и заменить содержимое
таблицы в памяти данными из файла:
$ sudo pfctl -t clients -T replace -f /etc/clients
Для тех операций, которые вы планируете выполнять часть, рано или поздно, дело
закончится написанием скриптов. Вполне вероятно, что рутинные операции, такие как
вставка или удаление элементов, замена содержимо таблицы или прочие, станут в
ближайшем времени целью написания некоторых скриптов.
Одним из распространённых примеров, является обеспечние доступа к сети с помощью
заданий cron, которые заменяют содержимое таблиц в определённое время. в некоторых
сетях, могут понадобиться различные правила доступа для разных дней недели.
Единственно реальные ограничения лежат в ваших потребностях и возможностях.
Мы будем возвращаться к удобству использования таблиц в дальнейших главах и
взглянем на несколько программ, предоставляющих удобный интерфейс для работы с
таблицами.
Глава 4
Беспроводные сети: Легко!
Довольно заманчиво сказать, что на BSD и OpenBSD в частности, нет необходимости
"делать беспроводную сеть", поскольку она уже есть. Создание беспроводной сети не
сильно отличается от создания проводной, однако есть некоторые вопросы, которые
возникают благодаря использованию радиоканала. Мы кратко рассмотрим некоторые
вопросы теории прежде чем перейти к практическим шагам установки.
После того, как мы рассмотрим базовые вопросы создания беспроводной сети и принцип
её работы, мы обратимся к некоторым опциям позволяющим сделать ваш беспроводную
сеть более интересной и устойчивой к взлому.
Немного о IEEE 802.11
Настройка любого сетевого интерфейса, обычно, проходит в два этапа: вы
устанавливаете линк, а затем переходите к конфигурированию интерфейса для передачи
трафика TCP/IP.
В случае использования проводных интерфейсов Ethernet, процесс создания линка
состоит из подключения кабеля и контроля индикатора карты. Тем не менее, некотрые
интерфейсы могут потребовать дополнительных действий. Например для модемного
соединения, требуются специфические шаги, например набор номера.
В случае выбора беспроводной сети IEEE 802.11, получение несущего сигнала
предусматривает несколько шагов на низком уровне. Во-первых, необходимо выбрать
соответствующий канал в заданном частотном спектре. Как только вы обнаружите сигнал,
вам необходимо установить некоторые параметры идентификации канального уровня.
Наконец, если точки, которые вы хотите связать используют шифрование на канальном
уровне, вы должны выбрать соответствующий тип шифрования и, возможно, некоторые
другие параметры.
К счастью, на BSD системах, всё конфигурирование беспроводных устройств
производится посредством команды ifconfig, как и для любых других интерфейсов 1. Тем не
менее, поскольку мы рассматриваем беспроводные сети, необходимо ознакомиться с их
безопасностью на различных уровнях сетевого стека. В основном существуют три вида
популярных и простых механизмов безопасности IEEE 802.11, и в следующих разделах мы
их кратко рассмотрим.
Примечание
Для более полного представления вопросов связанных с безопасностью беспроводных сетей обратитесь к статьям и
презентациям профессора Кьелл Йоргена на http://www.kjhole.com и http://www.kjhole.com/Standards/WiFi/WiFiDownloads.html.
Ознакомиться со свежей информацией в области WiFi можно на сайте Wi-Fi Net News (http://wifinetnews.com
/archives/cat_security.htm) и The Unofficial 802.11 Security Web Page ((http://www.drizzle.com/~aboba/IEEE/).
Фильтрация MAC адресов
Значительное число беспроводных точек доступа потребительского класса (я так
понимаю имеется в виду SOHO/Small Office оборудование - п.п.) предлагают возможность
фильтрации MAC адресов, однако, вопреки распространённому мнению, они не добавляют
дополнительный уровень безопасности.
1. На некоторых системах, в основных старых, до сих пор используются аппаратно зависимые программы wicontrol и ancontrol,
но в большинстве случаев они заменяются ifconfig. В OpenBSD консолидация ifconfig была завершена полностью.
Маркетинг этого оборудования успешен благодаря тому, что большинство потребителей
просто не знают, что сегодня имеется возможность изменить MAC адрес практически на
любом беспроводном адаптере2.
Примечание
Если вы действительно хотите использовать фильтрацию MAC адресов, вы можете обратиться к brconfig(8) (на OpenBSD 4.6 и
ниже) или вариантах правил связанных с мостом в ifconfig(8) (на OpenBSD 4.7 и выше). В главе 5 мы будем рассматривать мосты
и некоторые наиболее полезные способы их использования с фильтром пакетов.
WEP
Одним из следствий использования радиоволн для передачи данных вместо проводов
является то, что посторонним сравнительно легко доступен сбор данных передаваемых по
радиоканалу. Разработчики семейства стандартов 802.11, знали об этом факте и пришли к
решению которое появилось на рынке под названием Wired Equivalent Privacy или WEP.
К сожалению, разработчики WEP занимались его разработкой не уделяя достаточного
внимания современным исследованиям в этой области. Таким образом, эта схема
шифрования канального уровня считается весьма примитивной среди профессионалов. Не
стало сюрпризом и то, что в течении нескольких месяцев была произведена реверсная
разработка и взлом первых представленных продуктов использующих данную
технологию.
Однако, даже учитывая то, что можете скачать множество программ позволяющих
произвести дешифровку WEP трафика в считанные минуты, по различным причинам, WEP
по прежнему широко используется. По существу, всё современное обрудование 802.11
продолжает поддерживать WEP и фильтрацию MAC адресов.
Вы должны понять, что сетевой трафик, защищённый только с помощью WEP шифрования
не намного безопасней открытой передачи данных. С другой стороны, отметка наличия
WEP шифрования может стать сдерживающим фактором для ленивых или неопытных
атакующих.
WPA
Разработчики довольно быстро поняли, что WEP не совсем то, что нужно, поскольку он
был быстро взломан. Результатом стал пересмотр концепции и получено новое решение
названое Wi-FI Protected Access или WPA. WPA выглядит лучше чем WEP, по крайней мере
на бумаге, но его спецификации были достаточно сложные и его широкое внедрение было
отложено на некоторое время. Кроме того, WAP досталась некоторая доля критики
связанная с рядом ошибок в проектировании. Из-за различных проблем доступа к
документации поддержка WPA в оборудовании и ПО несколько разнообразна.
Большинство систем поддерживает WPA, однако он может быть не доступен для всех
устройств. если ваш проект включает в себя спецификацию WPA, вам следует
внимательно ознакомиться с документацией операционной системы и драйверов. И, само
собой разумеется, вам потребуются дополнительные меры безопасности для сохранения
конфидециальности потока данных, такие как SSH и SSL шифрование.
Выбор правильного оборудования для ваших задач
Выбор правильного оборудования не всегда бывает сложной задачей. На системе BSD,
следующая простая команда позволит получить список всех man страниц со словом
wireless в их контексте3.
$ apropos wireless
Даже в только что установленной системе, эта команда предоставит вам полный список
драйверов беспроводной сети встроенных в операционную систему. Следующим
шагомявляется чтение страниц руководства и сравнение списка совместимых устройств с
доступными в вашей системе. Найдите время чтобы продумать конкретные требования.
2. Быстрый поиск по man-страницам OpenBSD подскажет вам команду для замены MAC адреса для интерфейса rum0 - ifconfig
rum0 lladdr 00:ba:ad:f0:0d:11.
3. Кроме того, можно обратиться к страницам в Интернет. Обратитесь к http://www.openbsd.org и другим страницам проекта.
Для целей тестирования можно использовать драйвера rum или ural USB. Позже, когда вы
будете строить реальную инфраструктуру, вы можете использовать более дорогое
оборудование. Вам так же следует ознакомиться с Приложение Б в конце этой книги.
Примечание переводчика
Вопрос использования rum или ural драйверов достаточно спорный. По крайней мере, как и другого беспроводного
оборудования. Из своей практики я убедился, что подобрать беспроводной адаптер нормально работающий в BSD системе
намного сложнее чем в Linux. Конечно оборудование существует, но в большинстве лучший вариант - достаточно старые
адаптеры с чипами Atheros, которые найти сегодня уже достаочно сложно. Большинство работающих USB донглов требуют
некоторой физической переделки из-за отсутствия физической возможности подключения внешних антенн. И, хотя много пишут
о разработке драйверов для новых чипсетов беспроводных устройств под BSD системы, в реальной ситуации дела обстоят не
лучшим образом .
Установка простой беспроводной сети
Для нашей первой беспроводной сети, в качестве отправной точки, имеет смысл
использовать конфигурацию шлюза созданную в предыдущей главе. При разработке сети,
с большой вероятностью, беспроводная сеть не напрямую подключается к интернет, но
какой-то шлюз ей понадобится. Именно по этой причине имеет смысл повторно
использовать рабочую конфигурацию шлюза для нашей беспроводной точки доступа,
внеся ряд незначительных изменений, которые мы рассмотрим в нескольких последующих
абзацах. В конце концов, это удобней чем начинать конфигурацию с нуля.
Примечание
Мы будем работать с режимом инфораструктуры, и в первую очередь установим точку доступа. Если вы предпочитаете заняться
настройками клиента, вам следует обратиться к странице 51.
Первым делом следует убедиться, что у вас есть поддерживаема беспроводная карта и
что её драйвер загружается и инициализирует карту соответствующим образом. В
процессе загрузки системы системные сообщения будут отображаться на экране, но кроме
того их можно обнаружить в файле /var/run/dmrsg.boot. Вы можете самостоятельно
просмотреть этот файл или использовать команду dmesg для просмотра сообщений. при
успешной настройке PCI карты вы должны увидеть нечто подобное:
ral0 at pci1 dev 10 function 0 "Ralink RT2561S" rev 0x00: apic 2 int 11 (irq
11), address 00:25:9c:72:cf:60
ral0: MAC/BBP RT2561C, RF RT2527
Если интерфейс который вы собираетесь настраивать - горячего подключения, например
устройство USB или PC Card, вы можете видеть сообщения ядра в файле
/var/log/messages; например, выполнив tail -f для файла перед подключением устройства.
(наверное всётаки после подключения - п.п.)
Затем, вам необходимо сконфигурировать интерфейс, сперва включив линк, и наконец
сконфигурировать систему для TCP/IP. Вы можете использовать для этого командную
строку подобную следующей:
$ sudo ifconfig ral0 up mediaopt hostap mode 11g chan 1 nwid unwiredbsd nwkey 0x1deadbeef9
Эта команда выполняет несколько вещей. Конфигурирует интерфейс ral0, включает
интерфейс используя параметр up, и определяет интерфейс в качестве точки доступа
беспроводной сети используя mediaopt hostap. Кроме того, явно устанавливается режим
работы 11g и выбирается 11-й канал. Наконец, используется nwid параметр для установки
имени сети unwiredbsd, с WEP ключом (nwkey) в виде шестнадцатеричной строки
0x1deadbeef9. Теперь используйте команду ifconfig для проверки успешной настройки
интерфейса:
$ ifconfig ral0
ral0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:25:9c:72:cf:60
priority: 4
groups: wlan
media: IEEE802.11 autoselect mode 11g hostap
status: active
ieee80211: nwid unwiredbsd chan 1 bssid 00:25:9c:72:cf:60 nwkey <not displayed> 100dBm
inet6 fe80::225:9cff:fe72:cf60%ral0 prefixlen 64 scopeid 0x2
Обратите внимание на содержание строк media и ieee80211. Информация отображённая в
них должна соответствовать той, которую вы ввели в командной строке ifconfig. Установив
линк, можно назначить IP адрес вашему интерфейсу:
$ sudo ifconfig ral0 10.50.90.1
На OpenBSD вы можете объединить оба шага в один создав файл /etc/hostname.ral0
подобный следующему:
up mediaopt hostap mode 11g chan 1 nwid unwiredbsd nwkey 0x1deadbeef9
inet 10.50.90.1
Выполните sh /etc/netstart ral0 с правами root, или перезагрузите систему для
применения изменений.
Обратите внимание, что конфигурация состоит из двух строк. Первая строка генерирует
команду ifconfig для установки интерфейса с корректными параметрами физической
беспроводной сети. Вторая строка генерирует команду установки IP адреса после
завершения первой команды. Поскольку это наша точка доступа, мы установили канал
явно и включили слабое WEP шифрование, используя параметр nwkey.
На NetBSD, вы можете объединить все эти параметры в файле rc.conf:
ifconfig_ral0="mediaopt hostap mode 11g chan 1 nwid unwiredbsd nwkey 0x1deadbeef inet 10.50.90.1"
В FreeBSD 8 и более новых версиях, используется другой подход, привязывающий
беспроводные устройства к единому драйверу WLAN(4). В зависимости от конфигурации
вашего ядра, вам может понадобиться добавить соответствующие строки для загрузки
модулей в файле /boot/loader.conf. На одной из моих тестовых систем /boot/loader.conf
выглядел примерно так:
if_rum_load="YES"
wlan_scan_ap_load="YES"
wlan_scan_sta_load="YES"
wlan_wep_load="YES"
wlan_ccmp_load="YES"
wlan_tkip_load="YES"
После загрузки соответствующих модулей, требуется выполнить несколько команд, и
лучше использовать файл start_if.if для вашей беспроводной сети. Здесь приведён пример
файла /etc/start_if.rum0 для точки доступа WEP на FreeBSD 8:
wlans_rum0="wlan0"
create_args_wlan0="wlandev rum0 wlanmode hostap"
ifconfig_wlan0="inet 10.50.90.1 netmask 255.255.255.0 ssid unwiredbsd \
wepmode on wepkey 0x1deadbeef9 mode 11g"
После создания конфигурации, команда ifconfig должна вывести информацию о обоих
физических интерфейсах, а интерфейс wlan должен быть поднят и запущен:
rum0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
ether 00:24:1d:9a:bf:67
media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <hostap>
status: running
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
ether 00:24:1d:9a:bf:67
inet 10.50.90.1 netmask 0xffffff00 broadcast 10.50.90.255
media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <hostap>
status: running
ssid unwiredbsd channel 6 (2437 Mhz 11g) bssid 00:24:1d:9a:bf:67
country US authmode OPEN privacy ON deftxkey UNDEF wepkey 1:40-bit
txpower 0 scanvalid 60 protmode CTS dtimperiod 1 -dfs
Строка status: running означает, что ваш интерфейс поднят и запущен, по крайней мере
на канальном уровне.
Замечание
Вам необходимо ознакомиться с актуальным содержимым man-страницы команды ifconfig чтобы больше узнать о опциях которые
могут быть вам полезны при конфигурировании.
Точка доступа на OpenBSD
Поддержка WPA введена в OpenBSD 4.4 с расширением драйверов беспроводных сетей и
новой утилитой wpa-psk(8) для конфигурирования ключевых операций c WPA.
Заметка
Всё ещё могут существовать драйвера беспроводных устройств не имеющих поддержки WPA, т.ч. следует обратится к
соответствующим man-страницам, что позволит убедиться в наличии поддержки WPA, прежде, чем пытаться настроить сеть с его
использованием. Вы можете объединить управление ключами 802.1x на внешнем сервере аутенцификации для режима
"enterprise", однако, для наших целей, мы будем придерживаться простой установки с предварительным ключом (preshared key).
Процедуры для установки точки доступа с WPA во многом аналогичны ранее
рассмотренным для WEP. Для генерации ключа WPA, вам необходимо запустить утилиту
wpa-psk. Если мы используем ключ WEP из придыдущего примера как простой текст, для
WPA мы генерируем парольную фразу примерно так:
$ wpa-psk unwiredbsd 0x1deadbeef9
0x31db31f2291f1ddf3ded3ca463a7dd5c0cd77a814f1d8e6c64990bfcb287b202
Вы можете скопировать это значение в команду ifconfig или в файл hostname.if, или
непосредственно
передать
ifconfig
вывод
wpa-psk.
Ввод
чистого
текста
в
конфигурационный файл может сделать его более читабельным. Для установки WPA с
предварительным ключом (который иногда называют сетевым паролем), вы можете
записать файл hostmane.if в следующем виде:
up media autoselect mediaopt hostap mode 11g chan 1 nwid unwiredbsd \
wpa wpapsk `wpa-psk unwiredbsd 0x1deadbeef9`
inet 10.50.90.1
Если вы уже запустили установку WEP описаную ранее, отключите эти установки
следующим образом:
$ sudo ifconfig ral0 -nwid -nwkey
Затем включите новые установки следующей командой:
$ sudo sh /etc/netstart ral0
Вы можете проверить что точка доступа поднята и запущена используя команду ifconfig:
$ ifconfig ral0
ral0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:25:9c:72:cf:60
priority: 4
groups: wlan
media: IEEE802.11 autoselect mode 11g hostap
status: active
ieee80211: nwid unwiredbsd chan 1 bssid 00:25:9c:72:cf:60 wpapsk <not displayed>
wpaprotos wpa1,wpa2 wpaakms psk wpaciphers tkip,ccmp wpagroupcipher tkip 100dBm
inet6 fe80::225:9cff:fe72:cf60%ral0 prefixlen 64 scopeid 0x2
inet 10.50.90.1 netmask 0xff000000 broadcast 10.255.255.255
Обратите внимание, что строка находится в состоянии status: active и что опции WPA
мы не задавали явно, но указаны их разумные значения по умолчанию.
Точка доступа с WPA на FreeBSD
Переход с точки доступа WEP которую мы построили ранее, на более безопасную с WPA,
достаточно прост. Поддержка WPA в FreeBSD осуществляется в виде hostapd (программа
которая несколько похожа на hostapd OpenBSD, но не является той же самой). Мы начнём
с редактирования файла /etc/start_if.rum0 чтобы удалить информацию аутентификации.
Отредактированный файл должен выглядеть примерно так:
wlans_rum0="wlan0"
create_args_wlan0="wlandev rum0 wlanmode hostap"
ifconfig_wlan0="inet 10.50.90.1 netmask 255.255.255.0 ssid unwiredbsd mode 11g"
Далее, мы добавим строку включения hostapd в файл /etc/rc.conf:
hostapd_enable="YES"
И, наконец, сконфигурируем сам hostapd в /etc/hostapd.conf:
interface=wlan0
debug=1
ctrl_interface=/var/run/hostapd
ctrl_interface_group=wheel
ssid=unwiredbsd
wpa=1
wpa_passphrase=0x1deadbeef9
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP TKIP
Определения интерфейса (interface) в этом файле вполне очевидны, а значения отладки
(debug) имеет значение для установки генерации минимального числа сообщений.
Диапазон отладки может быть от 0 до 4, где 0 - отключение всех отладочных сообщений.
Вы не должны изменять параметры ctrl_interface, если вы конечно не разработчик
hostapd. Первая из последующих пяти строк (ssid) указывает идентификатор сети.
Последующие строки включают WPA (wpa) и задают ключевую фразу (wpa_passphrase).
Последние две строки указывают алгоритм управления ключами (wpa_key_mgmt) и схемы
шифрования (wpa_pairwise). (Для понимания тонкостей настройки обратитесь к manстраницам hostapd(8) и hostapd.conf(5)).
После завершения конфигурации (и соотвествующего выполнения sudo /etc/rc.d/hostapd
forcestart), вывод команды ifconfig для двух интерфейсов должен соответствовать
следующему:
rum0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
ether 00:24:1d:9a:bf:67
media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <hostap>
status: running
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
ether 00:24:1d:9a:bf:67
inet 10.50.90.1 netmask 0xffffff00 broadcast 10.50.90.255
media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <hostap>
status: running
ssid unwiredbsd channel 6 (2437 Mhz 11g) bssid 00:24:1d:9a:bf:67
country US authmode WPA privacy MIXED deftxkey 2 TKIP 2:128-bit
txpower 0 scanvalid 60 protmode CTS dtimperiod 1 -dfs
Строка status: running говорит о том, что интерфейс поднят и запущен, по крайней мере
на канальном уровне.
Набор правил PF для точки доступа
Когда интерфейсы настроены, пришло время приступить к настройке пакетного фильтра
шлюза точки доступа. Вы можете начать с копирования базовой конфигурации сделаной
для шлюза в Главе 3. Включите шлюз посредством внесения записей в файлы sysctl.conf
или rc.conf, а затем скопируйте файл pf.conf. Некоторые части, зависимые от предыдущей
главы, могут быть весьма полезны, и ваш файл pf.conf может выглядеть примерно так:
ext_if = "re0" # macro for external interface - use tun0 or pppoe0 for PPPoE
int_if = "re1" # macro for internal interface
localnet = $int_if:network
client_out = "{ ssh, domain, pop3, auth, nntp, http,\
https, cvspserver, 2628, 5999, 8000, 8080 }"
udp_services = "{ domain, ntp }"
icmp_types = "{ echoreq, unreach }"
# ext_if IP address could be dynamic, hence ($ext_if)
match out on $ext_if from $localnet nat-to ($ext_if)
block all
pass quick inet proto { tcp, udp } from $localnet to port $udp_services
pass log inet proto icmp icmp-type $icmp_types
pass inet proto tcp from $localnet port $client_out
Если вы запускаете версию PF эквивалентную OpenBSD 4.6 или ранее, правило
соответствующее nat-to становится таким:
nat on $ext_if from $localnet to any -> ($ext_if)
Различие заключается в том, что для работы точки доступа необходимо изменение
определение int_if, для его соответствия беспроводному интерфейсу. В нашем случае,
макрос должен выглядеть так:
int_if = "ral0" # macro for internal interface
С большой долей вероятности, вы захотите настроить dhcpd для обслуживания адресов и
другой связанной сетевой информации для клиентов точки доступа. Настройка dhcpd операция достаточно простая, если вы ознакомитесь с соответствующей страницей
руководства.
Собственно, это всё, что необходимо сделать. Данная конфигурация предоставит вам
функциональную точку доступа, с некоторой безопасностью WEP, или чуть более
надёжной WPA. Если вам требуется поддержка FTP, скопируйте конфигурацию ftp-proxy
созданную в главе 3 и произведите соответствующие изменения, аналогичные тем,
которые вы сделали для остального набора правил.
Точка доступа с тремя и более интерфейсами
Если дизайн вашей сети требует, чтобы ваша точка доступа являлась. кроме всего
прочего, шлюзом для проводной сети, или нескольких беспроводных сетей, вам
необходимо произвести незначительные изменения набора правил. Вместо того, чтобы
просто изменить макрос int_if, вы можете добавить ещё одно (описательное) определение
для беспроводного интерфейса, например:
air_if = "ral0"
Ваши беспроводные интерфейсы подобны отдельным подсетям, поэтому полезно иметь
отдельное правило управления NAT для каждого из них. Вот пример для OpenBSD 4.7 и
более новых систем:
match out on $ext_if from $air_if:network nat-to ($ext_if)
А для версии pre-OpenBSD 4.7 PF:
nat on $ext_if from $air_if:network to any -> ($ext_if) static-port
В зависимости от вашей политики, вы можете настроить определение localnet, или, по
крайней мере, включить $air_if, по мере необходимости, в правила пропуска. И опять,
если вам необходима поддержка FTP, нормой будет отдельное правило пропуска с
перенаправлением для беспроводной сети на ftp-proxy.
Управление IPSec VPN
Вы можете устанвить виртуальную частную сеть (VPN), используя встроенные
инструменты IPsec, OpenSSH и некоторые другие. Однако, с учётом относительно низкого
уровня безопасности беспроводных сетей в целом, вы, вероятно, захотите настроить
некоторые дополнительные возможности безопасности.
SSH - если ваш VPN основан на SSH тунелях, базовый набор правил уже содержит всё
что вам нужно. Для пакетного фильтра, ваш туннелированный трафик не будет
отличаться от всего остального трафика SSH.
IPsec с UDP ключами обмена (IKE/ISAKMP) - несколько вариантов IPsec зависят от
обмена ключами на порту 500 протокола UPD и используют порт 4500 протокола UDP для
NAT траверса (NAT-T). Вам необходимо разрешить прохождение этого трафика, для того,
чтобы установить потоки. Практически во всех реализациях есть критическая зависимость
от разрешения трафика протокола ESP (протокол номер 50) между хостами:
pass proto esp from $source to $target
Фильтрация на интерфейсах инкапсуляции IPsec - при правильной настройке IPsec,
вы можете настроить фильтрацию PF для интерфейса инкапсуляции enc0 следующим
образом4:
pass on enc0 proto ipencap from $source to $target keep state (if-bound)
Смотрите Приложение А для получения большей информации о данном вопросе.
На стороне клиента
Для BSD клиентов настройка очень простая. Этапы подключения BSD машины к
беспроводной сети очень похожи на те, которые мы делали для настройки беспроводной
точки доступа. На OpenBSD конфигурация центрируется на файле hostname.if
беспроводного интерфейса. В FreeBSD в основном работают с rc.conf, но придётся
работать и с некоторыми другим файлами, в зависимости от конкретной конфигурации.
Установка клиента на OpenBSD
Начнём со случае OpenBSD. Для того, чтобы подключиться к созданной нами WEP точке
доступа,
ваши
клиенты
должны
использовать
файл
hostname.if
(например
/etc/hostname.ral0) со следующим содержимым:
up media autoselect mode 11g chan 1 nwid unwiredbsd nwkey 0x1deadbeef9
dhcp
Первая строка устанавливает параметры канального уровня с рядом требуемых опций.
Вообще обязательны только параметры up, nwid и nwkey. В большинстве случаев, драйвер
будет ассоциировать с точкой доступа соответствующий канал и лучший из доступных
режимов. Вторая строка вызывает конфигурирование DHCP, и на практике приводит к
запуску команды dhclient для получания команды о конфигурации TCP/IP.
Если вы решили использовать конфигурацию WPA, файл должен выглядеть так:
up media autoselect mode 11g chan 1 nwid unwiredbsd wpa wpapsk `wpa-psk unwiredbsd 0x1deadbeef9`
dhcp
И снова, первая строка устанавливает параметры канального уровня, где обязательными
являются выбор сети и параметры шифрования nwid, wpa и wpapsk. Вы можете
попробовать опустить параметры mode и chan; в большинстве случаев они будут
ассоциированы
автоматически.
Если
вы
хотите
попробовать
произвести
конфигурирование
из
командной
строки
до
создания
файла
конфигурации
/etc/hostname.if, команды для установки клиента WEP сети должны выглядеть так:
$ sudo ifconfig ral0 up mode 11b chan 1 nwid unwiredbsd nwkey 0x1deadbeef9
Команда должна завершиться без какого либо вывода. Затем, вы можете использовать
ifconfig для проверки настройки интерфейса. Вывод должен выглядеть примерно так:
$ ifconfig ral0
ral0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:25:9c:72:cf:60
priority: 4
groups: wlan
media: IEEE802.11 autoselect (OFDM54 mode 11g)
status: active
ieee80211: nwid unwiredbsd chan 1 bssid 00:25:9c:72:cf:60 nwkey <not displayed> 100dBm
inet6 fe80::225:9cff:fe72:cf60%ral0 prefixlen 64 scopeid 0x2
Обратите внимание, что строка ieee80211 отображает имя сети и канал, а так же
некотрые дополнительные параметры. Информация отображённая здесь должна
соответствовать той которую вы ввели в предыдущей команде ifconfig.
Теперь рассмотрим команду для конфигурирования OpenBSD клиента на работу с сетью
WPA:
$ sudo ifconfig ral0 nwid unwiredbsd wpa wpapsk `wpa-psk unwiredbsd 0x1deadbeef9`
4. В OpenBSD 4.8 интерфейс инкапсуляции стал клонируемым интерфейсом, и вы можете настроить несколько отдельных
интерфейсов enc. Все интерфейсы enc становятся членами группы интерфейсов enc
Команда, так же должна завершиться без вывода. Если вы снова используете ifconfig для
проверки статуса интерфейсов, вывод должен быть похож на следующий:
$ ifconfig ral0
ral0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:25:9c:72:cf:60
priority: 4
groups: wlan
media: IEEE802.11 autoselect (OFDM54 mode 11g)
status: active
ieee80211: nwid unwiredbsd chan 1 bssid 00:25:9c:72:cf:60 wpapsk <not displayed>
wpaprotos wpa1,wpa2 wpaakms psk wpaciphers tkip,ccmp wpagroupcipher tkip 100dBm
inet6 fe80::225:9cff:fe72:cf60%ral0 prefixlen 64 scopeid 0x2
Проверьте, что строка ieee80211 отображает корректное имя сети и параметры WPA.
Когда ваши интерфейсы удовлетворительно сконфигурированы на канальном уровне,
используйте команду dhclient для конфигурирования TCP/IP, примерно так:
$ sudo dhclient ral0
Команда dhclient должна вывести итоговый диалог с DHCP сервером примерно
следующего вида:
DHCPREQUEST on ral0 to 255.255.255.255 port 67
DHCPREQUEST on ral0 to 255.255.255.255 port 67
DHCPACK from 10.50.90.1 (00:25:9c:72:cf:60)
bound to 10.50.90.11 -- renewal in 1800 seconds.
Настройка FreeBSD
На FreeBSD, вам может понадобиться сделать немного больше работы чем на OpenBSD. В
зависимости от конфигурации ядра, вам может быть необходимо добавить
соответствующие строки в /boot/loader.conf. На одной из моих тестовых систем
/boot/loader.conf выглядел так:
if_rum_load="YES"
wlan_scan_ap_load="YES"
wlan_scan_sta_load="YES"
wlan_wep_load="YES"
wlan_ccmp_load="YES"
wlan_tkip_load="YES"
После загрузки необходимых модулей, вы можете подключиться
сконфигурированной ранее используя следующую команду:
к
WEP
сети
$ sudo ifconfig wlan create wlandev rum0 ssid unwiredbsd wepmode on wepkey 0x1deadbeef9 up
Затем выполнить:
$ sudo dhclient wlan0
Для более удобной конфигурации создайте файл start_if.rum0 (замените rum0 на
соответствующее имя физического интерфейса) с примерно следующим содержимым:
wlans_rum0="wlan0"
create_args_wlan0="wlandev rum0 ssid unwiredbsd wepmode on wepkey 0x1deadbeef9 up"
ifconfig_wlan0="DHCP"
Если вы подключаетесь к WPA сети, вам необходимо установить wpa_supplicant и
соответственно изменить настройки вашего интерфейса. Для соединения с точкой доступа
WPA используйте следующую конфигурацию файла start_if.rum0:
wlans_rum0="wlan0"
create_args_wlan0="wlandev rum0"
ifconfig_wlan0="WPA"
Вам так же необходим файл /etc/wpa_supplicant.conf следующего содержимого:
network={
ssid="unwiredbsd"
psk="0x1deadbeef9"
}
Наконец, добавьте строку ifconfig_wlan0 в rc.conf для корректного запуска dgclient.
ifconfig_wlan0="DHCP"
Другие сети WPA могут потребовать дополнительных опций.
конфигурации вывод ifconfig должен выглядеть примерно так:
После
завершения
rum0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
ether 00:24:1d:9a:bf:67
media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
status: associated
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
ether 00:24:1d:9a:bf:67
inet 10.50.90.16 netmask 0xffffff00 broadcast 10.50.90.255
media: IEEE 802.11 Wireless Ethernet OFDM/36Mbps mode 11g
status: associated
ssid unwiredbsd channel 1 (2412 Mhz 11g) bssid 00:25:9c:72:cf:60
country US authmode WPA2/802.11i privacy ON deftxkey UNDEF
TKIP 2:128-bit txpower 0 bmiss 7 scanvalid 450 bgscan bgscanintvl 300
bgscanidle 250 roam:rssi 7 roam:rate 5 protmode CTS roaming MANUAL
Защита вашей беспроводной сети с помощью authpf
Специалисты в области безопасности сходятся во мнении, что даже если WEP и
предлагает слабую защиту, этого вполне достаточно, чтобы предупредить атакующих, что
вы не намерены отдавать кому бы то нибыло свои сетевые ресурсы. Использование
стандарта WPA в некоторой степени повышает уровень безопасности, за счёт
незначительного усложнения конфигурации. Конфигурации которые мы построили ранее
являются вполне функциональными. Обе конфигурации WEP и WPA, позволяют
подключать любых разумно сконфигурированных клиентов, что может стать проблемой,
поскольку конфигурация не имеет возможности контролировать разрешения на
использования вашей сети.
Как упоминалось ранее, фильтрация MAC адресов, на самом деле, не даёт требуемого
уровня защиты, поскольку можно, достаточно просто, изменить MAC адрес. Разработчики
OpenBSD решили использовать радикально иной подход к этой проблеме, введя authpf в
OpenBSD 3.1. Вместо того, чтобы привязать идентификацию к оборудованию сетевого
адаптера, например к MAC адресу карты, они решили расположить надёжные и гибкие
механизмы аутентификации пользователя в месте, более подходящем для этой цели.
Пользовательская оболочка authpf позволяет привязать загружаемые правила PF
базируясь на пользователе, эффективно решая задачу раздачи прав пользователям.
Для использования authpf, вы создаёте пользователя с оболочкой authpf. В процессе
получения доступа к сети, пользователи регистрируются на шлюзе с использованием SSH.
Как только пользователь успешно завершает SSH аутентификацию, загружаются которые
вы определили для пользователя или соответствующего класса пользователей. Эти
правила, которые применяются к IP адресу пользователя, действуют до тех пор пока
пользователь остаёстя связанным с системой через SSH соединение. После завершения
SSH сессии, правила выгружаются, и в большинстве случаев, весь не SSH трафик от IP
адреса пользователя запрещается. При разумных настройках, будет проходить только
трафик авторизованных пользователей.
Примечание
В OpenBSD, authpf - один из классов логинов предлагаемых по умолчанию, и вы можете это заметить когда будеде создавать
пользователя используя команду adduser.
Для систем, в которых класс authpf не доступен по умолчанию, может быть необходимым
добавление некоторых строк в файл /etc/login.conf:
authpf:\
:welcome=/etc/motd.authpf:\
:shell=/usr/sbin/authpf:\
:tc=default:
Несколько следующих разделов содержат примеры, которые могут (или не могут)
соответствовать вашей ситуации, но я надеюсь, что они дадут вам некоторые идеи
которые вы сможете использовать.
Базовая аутентификация шлюза
Настройка аутентификации шлюза с authpf включает в себя создание и поддержку
нескольких дополнительных файлов, помимо вашего основного файла конфигурации
pf.conf. Основное дополниние - файл authpf.rules. Все прочие файлы имеют достаточно
статичные записи, и вам не придётся тратить на них много времени в дальнейшем.
Начните с создания пустого файла /etc/authpf/authpf.conf. Этот файл необходим для
работы authpf, однако содержимое его может быть разнообразным, т.ч. создание пустого
файла будет разумным.
Далее следуем в /etc/pf.conf. Сначала, создаём макросы интерфейса:
ext_if = "re0"
int_if = "ath0"
Дополнительно, если вы определите таблицу названную <authpf_users>, authpf будет
добавлять IP адреса аутентифицируемых пользователей в эту таблицу:
table <authpf_users> persist
Если вам необходимо запустить NAT, правила которые занимаются трансляцией, проще
определить в authpf.rules, а не хранить их в файле pf.conf:
pass out on $ext_if from $localnet nat-to ($ext_if)
Синтаксис для pre-OpenBSD 4.7:
nat on $ext_if from $localnet to any -> ($ext_if)
Далее, мы создадим якорь authpf, который позволит загружать правила из authpf.rules
при аутентификации пользователя:
anchor "authpf/*"
Для версии authpf pre-OpenBSD 4.7, требуется несколько якорей, т.ч. соответствующая
секция должна выглядеть так:
nat-anchor "authpf/*"
rdr-anchor "authpf/*"
binat-anchor "authpf/*"
anchor "authpf/*"
Этим мы завершим конфигурирование pf.conf связанное с authpf.
В части фильтрации, мы начнём block all по умолчанию, и будем добалять разрешающие
правила (pass) по необходимости. Здесь для нас важно, чтобы SSH трафик проходил во
внутреннюю сеть:
pass quick on $int_if inet proto { tcp, udp } to $int_if port ssh
С этого момента всё зависит от вас. Вы хотите, чтобы ваши клиенты получили
разрешение мён прежде чем аутентифицировались? Если это так, вставьте правило
пропуска для TCP и UDP сервиса разрешения имён в ваш файл pf.conf. Для относительно
простых установок, вы можете включить остальную часть нашего базового набора правил,
изменив пропускающие правила для позволения трафика адресов в таблице
<authpf_users>, вместо любого адреса вашей локальной сети:
pass quick inet proto { tcp, udp } from <authpf_users> to port $udp_services
pass inet proto tcp from <authpf_users> to port $client_out
Для более дифференцированной установки, вы можете поместить остальную часть
вашего набора правил в /etc/authpf/authpf.rules или разместить отдельные правила
пользователя в пользовательских файлах authpf.rules в поддиректории каждого
пользователя в /etc/uathpf/users/. Если вашим пользователям нужна защита, ваш общий
файл /etc/authpf/authpf.rule может выглядеть например так:
client_out = "{ ssh, domain, pop3, auth, nntp, http, https }"
udp_services = "{ domain, ntp }"
pass quick inet proto { tcp, udp } from $user_ip to port $udp_services
pass inet proto tcp from $user_ip to port $client_out
Макрос user_ip встроен в authpf и расширяется в IP адрес пользователя который прошёл
аутентификацию. Эти правила будут применяться к любому пользователю, который
проходит проверку подлинности на шлюзе. Если файл authpf.rules существует в каталоге
пользователя /etc/authpf/users, правила из этого файла будут загружаться для
пользователя. Это значит, что ваш наивный пользователь Пётр (пусть будет Пётр - п.п.)
котору необходимо только просматривать странички в интернет и иметь доступ к службе
работающей на верхнем порту специфичной машины может получить только то, что ему
нужно при наличии файла /etc/authpf/users/peter/authpf.rules подобного следующему:
client_out = "{ domain, http, https }"
pass inet from $user_ip to 192.168.103.84 port 9000
pass quick inet proto { tcp, udp } from $user_ip to port $client_out
С другой стороны, коллега Петра, Кристина, запускает OpenBSD и вообще не знает, что
она делает, даже если она создаёт трафик. Вы могли бы дать ей волю, создав примерно
такой файл /etc/authpf/users/cristina/authpf.rules:
pass from $user_ip os = "OpenBSD" to any
Это означает, что Кристина может
аутентифицирована на своей OpenBSD.
делать
всё
что
ей
захочется,
пока
она
Широко открытая закрытая сеть
В некоторых случаях, имеет смысл настроить сеть таким образом, чтобы она была
открытой и не зашифрованной на канальном уровне, в то же время соблюдая некоторые
ограничения по authpf. Следующий пример - Wi-Fi зона которая может создаваться в
аэропортах или других общественных местах, где любой желающий может связаться с
точками доступа и получить IP адрес, однако любая попытка выхода в Интернет будет
перенаправлена на специальную страницу, до тех пор, пока пользователь не получит
аутентификации5.
Следующий файл pf.conf построен на нашей предыдущей базе, с двумя важными
дополнениями в базовой настройке authpf: макросами и перенаправлениями.
ext_if = "re0"
int_if = "ath0"
auth_web="192.168.27.20"
dhcp_services = "{ bootps, bootpc }" # DHCP server + client
table <authpf_users> persist
pass in quick on $int_if proto tcp from ! <authpf_users> to port http rdr-to $auth_web
match out on $ext_if from $int_if:network nat-to ($ext_if)
anchor "authpf/*"
block all
pass quick on $int_if inet proto { tcp, udp } to $int_if port $dhcp_services
pass quick inet proto { tcp, udp } from $int_if:network to any port domain
pass quick on $int_if inet proto { tcp, udp } to $int_if port ssh
5. Благодарю Вегарда Энгена (Vegard Engen) за идею и его конфигурацию, которая сохранена здесь если не во всех деталях, то
хотя бы в целом.
Для старой версии authpf, используйте такой файл:
ext_if = "re0"
int_if = "ath0"
auth_web="192.168.27.20"
dhcp_services = "{ bootps, bootpc }" # DHCP server + client
table <authpf_users> persist
rdr pass on $int_if proto tcp from ! <authpf_users> to any port http -> $auth_web
nat on $ext_if from $localnet to any -> ($ext_if)
nat-anchor "authpf/*"
rdr-anchor "authpf/*"
binat-anchor "authpf/*"
anchor "authpf/*"
block all
pass quick on $int_if inet proto { tcp, udp } to $int_if port $dhcp_services
pass quick inet proto { tcp, udp } from $int_if:network to port domain
pass quick on $int_if inet proto { tcp, udp } to $int_if port ssh
Макрос auth_web и перенаправление позволяет перенаправлять весь web трафик от
адресов, которые не попадают в таблицу <authpf_users> аутентифицированных
пользователей на специальный адрес. На этом адресе вы создаёте web-сервер, который
обеспечивает информационные службы для клиентов. Это могут быть страницы с
инструкциями, информирующими к кому следует обратиться за получением доступа или
подсистема обработки данных кредитных карточек для получения платного доступа.
Следует отметить, что в этом случае будет работать сервис разрешения имён, однако все
попытки web сёрфинга будут перенаправлены на адрес auth_web. Как только
пользователи пройдут аутентификацию, вы можете добавить для них общие правила или
специфические правила пользователя в файлах authpf.rules, в зависимости от вашей
ситуации.
Глава 5
СЕТИ БОЛЬШЕ ИЛИ СЛОЖНЕЙ
В этой главе мы будем опираться на материал из предыдущих глав, чтобы встретиться в
реальной жизни с проблемами больших и малых сетей относительно требовательных
приложений и пользователей. Пример кофигурации в этой главе основан на
предположении, что для вашей пакетной фильтрации необходим учет служб, которые
запущены в вашей локальной сети. Мы будем главным образом, смотреть на эту проблему
с точки зрения Unix, сосредоточив внимание на SSH, электронной почте и веб сервисах (с
некоторыми указаниями о том, как позаботиться о других сервисах).
Эта глава о том, что делать когда вам нужно комбинировать пакетную фильтрацию с
ссервисами которые должны быть доступными извне вашей локальной сети. Насколько это
усложнит ваши наборы правил будет зависеть от вашей сети и, в определенной степени,
от количества маршрутизируемых адресов, которые у вас имеются, а затем мы перейдем к
ситуациям с всего лишь одним маршрутизируемым адресом и основанных на PF обходных
путях, которые делают сервисы используемыми даже при этих ограничениях.
Веб сервер и почтовый сервер внутри –
маршрутизируемые адреса
Насколько сложна ваша сеть? Насколько сложной она должна быть? Мы начнем с
базового сценария и клиентов из главы 3, того что мы создали за базовым брандмауэром
PF, имеющих доступ к ряду сервисов, размещенных в других местах, а не сервисов,
работающих в локальной сети.
Эти клиенты получают трех новых соседей: почтовый сервер, веб-сервер и файловый
сервер. В этом сценарии мы используем официальные, маршрутизируемые адреса, так как
это делает жизнь немного легче. Другим преимуществом такого подхода является то, что с
маршрутизируемыми адресами мы можем позволить двум новым машинам работать в роли
DNS серверов для нашего домена example.com: один в качестве master, а другой в
качестве авторитатрного slave1.
Замечание:
Для DNS, всегда имеет смысл иметь, по крайней мере, один авторитарный slave сервер где-то за пределами вашей сети
(фактически, некоторые домены верхнего уровня не позволяют зарегистрироваться без него). Вы тоже самое можете
организовать для резервного почтового сервера, который будет в другом месте. Имейте это ввиду, когда строите свою сеть.
На этом этапе, имеется довольно простое физическое расположение сети. Мы ставим
новые серверы в той же локальной сети, что и клиенты, возможно, в отдельной комнате,
но, безусловно, в том же сегменте сети или на том же коммутаторе, где подключены
клиенты. Концептуально новая сеть выглядит примерно как на рисунке 5-1.
1. Фактически, example.com находится в блоке 192.0.2.0/24, которые определяется в RFC 3330 используемый как
зарезервированный для использования примера и документации. Мы используем этот диапазон адресов в основном, чтобы
отличать от NAT примеров в этой книге, которые используют адреса в частном адресном пространстве RFC 1918.
Рисунок 5-1. Базовая сеть с серверами и клиентами внутри одной сети
С базовыми параметрами сети мы можем приступить к настройке разумных наборов
правил для обработки сервисов, которые нам нужны. Еще раз, мы начинаем от базового
набора правил и добавляем несколько макросов для удобства чтения. Макросы, которые
нам нужны, естественно, возьмем из спецификации:
•
Web server:
webserver = "192.0.2.227"
•
Web server services:
webports = "{ http, https }"
•
Mail server:
emailserver = "192.0.2.225"
•
Mail server services:
email = "{ smtp, pop3, imap, imap3, imaps, pop3s }"
•
Name servers:
nameservers = "{ 192.0.2.221, 192.0.2.223 }"
Будем считать, что файловый сервер недоступен для внешнего мира, если мы хотим
установить его, как сервис за пределами локальной сети, например, авторитетный slave
сервер имен для нашего домена. С помощью макросов мы добавим правила для
прохождения. Начнем с веб-сервера, и сделаем его доступным для мира со следующим
правилом:
pass proto tcp to $webserver port $webports
С похожим правилом, мы разрешаем миру общаться с почтовым сервером:
pass proto tcp to $emailserver port $email
Это позволит клиентам откуда угодно иметь такой же доступ как и у тех, что находятся в
нашей локальной сети, включая несколько почтовых протоколов, которые работают без
шифрования. Это обычная вещь в реальном мире, но вы можете принять во внимание
ваши опции, если настраиваете новую сеть.
Почтовый сервер, чтобы быть полезным, должен иметь возможность отправлять почту для
хостов также за пределами локальной сети:
pass log proto tcp from $emailserver to port smtp
Имейте в виду, что набор правил начинается с блокирования всех правил, а это означает,
что только почтовый сервер имеет право инициировать SMTP-трафик из локальной сети в
остальной мир. Если каким-либо другим хостам в сети нужно будет послать почту во
внешний мир или получить почту, им нужно использовать назначенный почтовый сервер.
Это может быть хорошим способом для обеспечения, например, того, что вы делаете это
так сложно, насколько возможно для какой-либо спам рассылки, которые могут появиться
в вашей сети, что фактически повысит нагрузку на них.
Стоит ли свечь SYN-прокси?
За эти годы, вариант опции syn-прокси получило большое внимание как возможный оплот против злонамеренного
трафика извне. В частности, опция syn-прокси предназначена для защиты от syn-флудных атак, которые могут привести
к истощению ресурсов на бэкэнде(back end). Вот как это работает: когда новое соединение создано, PF нормально
позволяет соединению установиться, просто пропускает пакеты, если они совпадают с набором правил позволяющих их.
С включенным syn-прокси PF во время первоначального соединенеия позволяет соединиться с партнерами только один
раз, подтверждая, что он правильно установлен, по существу создавая буфер между соединением с партнером. Syn
проксирование немного затратнее, чем состояние по умолчанию, но не всегда заметно, насколько разумно дальше
масштабировать оборудование.
Потенциальные недостатки проявляются в настройках балансировки нагрузки где SYN-проксирование PF может
принимать соединения на бэкэнд не готовый к приему, в некоторых случаях короткого замыкания резервирование путем
создания соединения с другими хостами, чем выбранная логика балансировки нагрузки. Это особенно очевидно в таких
протоколах как SMTP, где встроенное резервирование подсказывает, что если основной почтовый сервер не принимает
соединения, вы должны попробовать вместо него вторичный.
При рассмотрении вопроса установки, где syn-прокси кажется привлекательным, имейте эти вопросы ввиду и
анализируйте потенциальное влияние на вашу установку, которая может поступать от syn-прокси добавляя мешанины.
Если вы решили, что SYN проксирование нужно, просто лавируйте на состояния syn-прокси в конце правил, в нужных
опциях.
Наконец, серевера имен должны быть доступны для клиентов за пределами нашей сети,
которые смотрят на информацию о example.com и любых других доменов для которых мы
являемся авторитетным:
pass inet proto { tcp, udp } to $nameservers port domain
Имея, интегрированными все сервисы, которые должны быть доступны из вне, наш набор
правил закончится примерно так:
ext_if = "ep0" # macro for external interface - use tun0 or pppoe0 for PPPoE
int_if = "ep1" # macro for internal interface
localnet = $int_if:network
webserver = "192.0.2.227"
webports = "{ http, https }"
emailserver = "192.0.2.225"
email = "{ smtp, pop3, imap, imap3, imaps, pop3s }"
nameservers = "{ 192.0.2.221, 192.0.2.223 }"
client_out = "{ ssh, domain, pop3, auth, nntp, http,\
https, cvspserver, 2628, 5999, 8000, 8080 }"
udp_services = "{ domain, ntp }"
icmp_types = "{ echoreq, unreach }"
block all
pass quick inet proto { tcp, udp } from $localnet to port $udp_services
pass log inet proto icmp all icmp-type $icmp_types
pass inet proto tcp from $localnet to port $client_out
pass inet proto { tcp, udp } to $nameservers port domain
pass proto tcp to $webserver port $webports
pass log proto tcp to $emailserver port $email
pass log proto tcp from $emailserver to port smtp
Это по-прежнему довольно простая настройка, но, к сожалению, она имеет один
потенциально тревожный недостаток безопасности. Серверы, которые предлагают
сервисы в мире в целом все в той же локальной сети, что и клиенты, и вам нужно будет
ограничивать любые внутренние сервисы только для локального доступа.
В принципе, это означает, что злоумышленник должен получить доступ только к одному
хосту в локальной сети, чтобы получить доступ к любым ресурсам там, установив злодею
равные права с любым пользователем в вашей локальной сети. В зависимости, от того,
насколько хорошо каждая машина и ресурс защищены от несанкционированного доступа,
это может быть что угодно, начиная от незначительного раздражения на головную боль. В
следующем разделе, мы рассмотрим некоторые варианты для разделения сервисов,
которые должны взаимодействовать с миром в целом из локальной сети.
Степень разделения: введение в DMZ
В предыдущем разделе, вы увидели как настроить сервисы в вашей локальной сети и
сделать их выборочно доступными из внешнего мира посредством разумного набора
правил PF. Для более точного контроля над доступом к вашей внутренней сети, а также
сервисам, которые вам нужно сделать видимым для остального мира, добавить степень
физического разделения. Даже отдельные виртуальные локальные сети (VLAN) будут
делать это красиво.
Достижение физического и логического разделения довольно легко: просто преместить
машины, что работают с публичными сервисами отделить в свою сеть, прикрепленной к
отдельному интерефейсу на шлюзе. Конечным результатом является отдельная сеть,
которая не является частью вашей локальной сети, и не является частью сети интернет.
Концептуально, отделённая сеть выглядит как на рисунке 5-2.
Рисунок 5-2. Сеть с серверами в DMZ
Замечание:
Думайте об этой маленькой сети как о зоне относительного затишься между территориями враждебных фракций. Нет ничего
удивительного, что несколько лет назад, кто-то придумал фразу демилитаризованной зоны, или кратко DMZ, чтобы описать этот
тип конфигурации.
Для распределения адресов, вы можете отщипнуть кусочек от вашего официального
адресного пространства для новой сети DMZ. Кроме того, вы можете переместить те части
вашей сети, которые не имеют особой необходимости запускаться с публичным доступом
и маршрутизируемыми адресами внутри NAT окружения. В любом случае, вам в конечном
итоге понадобится еще один интерфейс, трафик которого необходимо будет фильтровать.
Как вы увидите позже, можно запустить установку DMZ во всех NAT средах, а также если
вам действительно не хватает официальных адресов.
Корректировка набора правил ставит перед собой задачу не быть обширной. Если
необходимо, вы можете изменить конфигурацию для каждого интерфейса. Базовая логика
набора правил остается, но вам может понадобится для настройки пределения макросов
(веб-сервер, почтовый сервер, сервер имен, и возможно другие), чтобы отразить новую
схему сети.
В нашем примере, мы могли бы выбрать часть сегмента нашего диапазона адресов, где
мы уже разместили наши серверы. Если мы оставим некоторое пространство для роста, мы
можем настроить новый dmz_if на /25 маске с сетевым адресом и маской подсети
192.0.2.128/255.255.255.128. Это оставит нас с диапазоном от 192.0.2.129 по 192.0.2.254
как используемый диапазон адресов для хостов в DMZ. С этой конфигурацией и без
изменений в IP адреса, назначенных серверам, вам действительно не нужно трогать набор
правил для всех для фильтрации пакетов для работы после создания физически
отдельного DMZ.
То есть приятный побочный эффект, который может быть связан либо с ленью, либо с
отличным долгосрочным планированием. В любом случае, он подчеркивает важность
наличия разумного распределения адресной политики на месте. Это может быть полезно
для того, чтобы подтянуть ваш набор правил, отредактировав ваши правила для
проходящего трафика таким образом, чтобы разрешить передавать трафик только на те
интерфейсы, которые имеют отношение к вашим сервисам.
pass in on $ext_if proto { tcp, udp } to $nameservers port domain
pass in on $int_if proto { tcp, udp } from $localnet to $nameservers \
port domain
pass out on $dmz_if proto { tcp, udp } to $nameservers port domain
pass in on $ext_if proto tcp to $webserver port $webports
pass in on $int_if proto tcp from $localnet to $webserver port $webports
pass out on $dmz_if proto tcp to $webserver port $webports
pass in log on $ext_if proto tcp to $mailserver port smtp
pass in log on $int_if proto tcp from $localnet to $mailserver port $email
pass out log on $dmz_if proto tcp to $mailserver port smtp
pass in on $dmz_if from $mailserver to port smtp
pass out log on $ext_if proto tcp from $mailserver to port smtp
Вы могли бы написать другие разрешающие правила, которые характеризуют
специфичные интерфейсы вашей локальную сеть, но если вы оставите всё как есть они
будут продолжать работать.
Распределение нагрузки: перенаправление на пул
адресов
После того, как вы создали сервисы, которые будут доступны для всего мира, вероятно
один из возможных сценариев, то, что ваши сервисы будут расти и станут более
сложными и ресурсоемкими, или просто привлекут больше трафика чем тогда, когда вы
чувствовали себя комфортно при обслуживании одного сервера. Есть несколько способов,
чтобы распределить нагрузку между несколькими машинами, в том числе способы тонкой
настройки сервиса. Для уровня сетевой нагрузки, PF предлагает базовые функции,
которые осуществляются через таблицы перенаправления или пулы адресов. На самом
деле, вы можете реализовать форму распределения назгрузки даже без того, чтобы
изменять набор разрешенных правил.
Для примера возьмем наш веб-сервер. Мы уже имеем макрос для публичного IP адреса
(webserver=”192.0.2.227”), который, в свою очередь связан с именем хоста, который ваши
пользователи имеют помеченным, например www.example.com. Когда настанет время
распределять нагрузку, нужно установить необходимое количество идентичных или по
крайней мере эквивалентных, серверов, а затем немного изменить наш набор правил для
введения перенаправления. Во-первых, определить содержит ли таблица адресов для
вашего веб сервера пул:
table <webpool> persist { 192.0.2.214, 192.0.2.215, 192.0.2.216, 192.0.2.217 }
Затем выполнить перенаправление:
match in on $ext_if protp tcp to $webserver port $webports \
rdr-to <webpool> round-robin
Не похожий на перенаправление в ранних примерах, таких как FTP прокси в главе 3, этот
набор правил устанавливает всех членов талицы веб пула, как потенциальные цели для
перенаправления для входящих соединений, предназначенных для веб портов адресов
веб сервера. Каждое входящее соединение которое подпадает под правило
перенаправится на один из адресов в таблице, распределяя нагрузку между несколькими
хостами. Вы можете выбрать на последок оригинальный веб-сервер, однажды
переключившись перенаправление завершиться или будет захвачен в новый пул вебсервера.
В более ранних версиях PF чем OpenBSD 4.7 эквивалентное правило будет выглядеть:
rdr on $ext_if proto tcp to $webserver port $webports -> <webpool> round-robin
В обоих случаях, round-robin опция значит, что PF распределяет нагрузку между
машинами в пуле циклично через таблицу перенаправления адресов последовательно.
Когда это необходимо для доступа с каждого отдельного адреса всегда переходит на тот
же хост в бэкэнде (например, если сервис зависит от клиент или сессий-специфических
параметров, то будет потеряно, если несколько новых соединений произойдет с
различных хостов на бэкэнде), вы может добавить опцию «липкого» адреса, чтобы
убедиться, что новые соединения с клиентом всегда перенаправляются на ту же машину
по ту сторону перенаправления в качестве начального соединения. Недостатком этой
опции то, что PF нужно обслуживать источник отслеживания данных для каждого клиента
и по умолчанию значение для максимального количества узлов установлено на 10000,
которые могут быть ограничивающим фатором. (смотрите главу 9 советы по настройке
этого и подобных предельных значений)
Даже когда равномерное распределение нагрузки не является абсолютным требованием,
выбрав перенаправление адресов в случайном порядке может быть целесообразным.
match in on $ext_if proto tcp to $webserver port $webports rdr-to <webpool> random
Замечание:
В версиях PF перед OpenBSD 4.7, опция случайного порядка не поддерживается для таблицы перенаправления или списка
адресов.
Даже организация с большим пулом официальных, маршрутизируемых адресов решает
ввести NAT между балансировкой нагрузки пулов сервера и интернета в целом. Эта
техника работает одинаково хорошо в различных основанных на NAT установках, но
переход к NAT предлагает некоторые дополнительные возможности и вызовы.
Получение права балансировки нагрузки посредством
relayd
После того, как вы запустили распределение нагрузки посредством round-robin
перенаправления, вы могли заметить, что перенаправление присходит не автоматически,
а адаптируется к внешним условиям. Для примера, если не приняты специальные меры,
если хост в списке целей перенаправления «упал», трафик все еще будет
перенаправляться на IP адрес в список возможных.
Очевидно, что требуется решение мониторинга. К счастью, базовая система OpenBSD
предоставляет это. Relay демон relayd2 взаимодествует с вашей PF конфигурацией,
предоставляя возможность отсеять нефункционирующие хосты из вашего пула.
При введении relayd в вашу настройку, однако, могут потребоваться некоторые
незначительные изменения в наборе ваших правил.
Realyd демон работает в двух основных классах сервисов, которые называются
редиректы(redirects) и релеи(relays). Он ожидает, до тех пор пока у него не появится
возможность включить или исключить хосты с IP адресами в/из таблицу(ы) PF которыми
он управляет. Демон взаимодействует с набором правил через специального назначения
2. Первоначально введен в OpenBSD 4.1 под названием hoststated, демон развивался(в основном Рейк Флетери и Пьер-Ив
Ришардом) активно в течение нескольких лет, в том числе несколько важных изменений в синтаксисе конфигурации и был
переименован в relayd в релизе OpenBSD 4.3.
якорями называемыми relayd (и в версиях предшествующих OpenBSD 4.7, также
перенаправление якорем, RDR-якорь, назывался также).
Увидеть как мы можем сделать наш пример конфигурации работающей немного лучше
используя relayd, мы взглянем назад в правила распределения нагрузки. Начнем с
вершины вашего pf.conf файла, добавим якорь для relayd написав:
anchor “relayd/*”
В версиях предшествующих OpenBSD 4.7, вам также нужен якорь перенаправления как
этот:
rdr-anchor "relayd/*"
anchor "relayd/*"
В наборе правил распределения нагрузки мы имеем следующее определение для нашего
пул веб-сервера:
table webpool persist { 192.0.2.214, 192.0.2.215, 192.0.2.216, 192.0.2.217 }
В этом наборе правил создается перенаправление:
match in on $ext_if proto tcp to $webserver port $webports rdr-to <webpool> round-robin
Или в версиях предшествующих OpenBSD 4.7 вы должны использовать следующее:
rdr on $ext_if proto tcp to $webserver port $webports -> <webpool> round-robin
Это сделает конфигурацию работающей более лучше, мы удалим пренаправление и
таблицу, и позволим relayd обрабатывать перенаправление путем создания своих
собственных версий внутри якоря. (не удаляйте разрешающие правила, тем не менее,
потому что ваш набор правил будет все еще нужен, чтобы иметь разрешющий набор
правил, позволяющий трафику проходить через таблицы IP адресов relayd).
После части pf.conf, которыми мы занимались, мы обращаемся к собственной
конфигурации файла relayd.conf. синтаксис этого конфигурационного файла достаточно
похож на pf.conf, что делает его довольно легко читаемым и понятным. Во-первых, мы
добавим определение макроса, который будем использовать позже:
web1="192.0.2.214"
web2="192.0.2.215"
web3="192.0.2.216"
web4="192.0.2.217"
webserver="192.0.2.227"
sorry_server="192.0.2.200"
Все они соответсвуют опредлениям, которые мы могли бы поместить в pf.conf файл. По
умолчанию проверочный интервал relayd 10 секунд, что означает, что хост может быть
недоступен в течение 10 секунд, пока не будет определено, что он находится в
оффлайне. Будьте осторожны, мы установим интервал в 5 секунда, чтобы минимизировать
время простоя, следующей строкой:
interval 5 # проверка хоста каждые 5 секунд
Теперь мы сделаем вызов таблицы webpool, которая использует многие из наших
макросов:
table <webpool> { $web1, $web2, $web3, $web4 }
По причинам, к которым мы вернемся в ближайшее время, мы определим еще одну
таблицу:
table <sorry> { $sorry_server }
В этой части, мы готовы установить перенаправление:
redirect www {
listen on $webserver port 80 sticky-address
tag relayd
forward to <webpool> check http "/status.html" code 200 timeout 300
forward to <sorry> timeout 300 check icmp
}
Это говорит, что соединения на 80 порт должны быть перенаправлены на других членов
таблицы webpool. Опция «липкий» адрес имеет тот же эффект здесь, что и с rdr в PF
правилах: новое соединение с того же самого источника IP адреса (с временным
интервлом определенным в значении timeout) перенаправиться на тот же хост в пуле
бэкэнде как и в предыдущем случае.
Relayd демон должен проверять видимость, если хост доступен, опрашивать его в
соответствии с файлом /status.html, используя протокол HTTP, и ожидая возвращения
кода равным 200. Это ожидаемый результат для клиента которого опрашивают на предмет
работы веб сервера, его файл доступен.
Без больших сюрпризов до сих пор, не так ли?! Relayd демон позаботиться об
исключении хостов из таблица, если они «упадут». Но что если все хосты в webpool
таблице упадут? К счастью разработчики предусмотрели и это также, и ввели концепцию
резервирования таблицы для сервисов. Это последняя часть определения веб сервиса, с
таблицей sorry как таблицей резервного копирования: хосты в sorry таблице берут на
себя все обслуживание, если таблица webpool становится пустой. Это означает, что вам
нужно сконфигурировать сервис, чтобы была доступно предложение “Извините, у нас
проблемы” сообщение в случае, если хосты в вашем веб пуле «упадут». Со всеми
элементами дествующей relayd конфигурации вы можете включить вашу новую
конфигурацию. Перезапустите ваш набор правил PF, а затем запустите relayd. Если вы
хотите проверить вашу конфигурацию до того как запустить relayd вы можете
использовать опцию –n в командной строке с relayd:
$ sudo relayd -n
Если ваша конфигурация корректна, relayd отобразит сообщение конфигурация ОК и
выйдет.
Чтобы действительно запустить демона, мы нам не нужен какой-либо флаг в командной
строке, поэтому следующий последовательность перезагрузит вашу отредактированную
конфигурацию PF и включит relayd.
$ sudo pfctl -f /etc/pf.conf
$ sudo relayd
Если конфигурация верна, обе команды спокойно запустятся, без отображения какихлибо сообщений. Вы можете проверить, что relayd запущен командами top или ps. Во
обоих случаях, вы найдете три relayd процесса, приблизительно как это:
$ ps waux | grep relayd
_relayd 9153 0.0 0.1 776 1424 ?? S 7:28PM 0:00.01 relayd: pf update engine
(relayd)
_relayd 6144 0.0 0.1 776 1440 ?? S 7:28PM 0:00.02 relayd: host check engine
(relayd)
root 3217 0.0 0.1 776 1416 ?? Is 7:28PM 0:00.01 relayd: parent (relayd)
Практически во всех случаях, вы захотите, чтобы relayd стартовал при загрузке системы.
Вы должны добавить вот эту строку в свой rc.conf.local файл:
relayd_flags="" # for normal use: ""
Однако, как только конфигурация включена, то большая часть взаимодействия с relayd
произойдет через программу администрирования relayctl . Кроме контроля статуса, relayctl
позволит вам загружать relayd конфигурацию и выборочно отключать или включать
хосты, таблицы и сервисы. Вы всегда можете посмотреть статус сервиса в интерактивном
режиме, примерно как здесь:
$ sudo relayctl show summary
Id Type Name Avlblty Status
1 redirect www active
1 table webpool:80 active (2 hosts)
1 host 192.0.2.214 100.00% up
2 host 192.0.2.215 0.00% down
3 host 192.0.2.216 100.00% up
4 host 192.0.2.217 0.00% down
2 table sorry:80 active (1 hosts)
5 host 127.0.0.1 100.00% up
В качестве примера, веб пул серьезно упадет, только с двумя из четырех работающих
хостов. К счастью, таблица бэкапа все еще функционирует. Все таблицы активны с по
крайней мере одним работающим хостом. Для таблиц, которые уже не имеют членов,
столбец статуса изменится на пустой. Запрашиваемая relayctl для хостов информация
отображает информацию о статусе в центральной части отображения:
$ sudo relayctl show hosts
Id Type Name Avlblty Status
1 table webpool:80 active (3 hosts)
1 host 192.0.2.214 100.00% up
total: 11340/11340 checks
2 host 192.0.2.215 0.00% down
total: 0/11340 checks, error: tcp connect failed
3 host 192.0.2.216 100.00% up
total: 11340/11340 checks
4 host 192.0.2.217 0.00% down
total: 0/11340 checks, error: tcp connect failed
2 table sorry:80 active (1 hosts)
5 host 127.0.0.1 100.00% up
total: 11340/11340 checks
Если вам нужно взять хост из пула на обслуживание (или любую другую временную
операцию), вы можете использовать relayctl, чтобы исключить их:
$ sudo relayctl host disable 192.0.2.217
В большинстве случаев, операция отобразит команду succeeded, что показывает, что
операция завершена успешно. После завершения обслуживания и после того, как вы
поставите машину в онлайн, вы можете снова включить его в качестве части вашего
relayd пула этой командой:
$ sudo relayctl host enable 192.0.2.217
Снова вы должны были увидеть сообщение команды succeeded почти сразу отобразит,
что операция была завершена успешно.
В дополнение к базовому распределению нагрузки, продемонстрированного здесь, relayd
имеет расширенную версию в недавней OpenBSD, и предлагает несколько характеристик,
которые сделают его привлекательным в более сложных настройках. Для примера, он
может теперь обрабатыватьс седьмой уровень проксирования или ретранслировать
функции HTTP и HTTPS, включая обработку протокола с добавлением заголовка и
перезаписи, добавлением URL пути и перезаписи, и даже обработку сессий и куки.
Обработка протокола должна быть адаптирована для вашего приложения. Например,
ниже приведен просто HTTPS relay для распределения нагрузки зашифрованного веб
трафика от клиентов на веб-серверах:
http protocol "httpssl" {
header append "$REMOTE_ADDR" to "X-Forwarded-For"
header append "$SERVER_ADDR:$SERVER_PORT" to "X-Forwarded-By"
header change "Keep-Alive" to "$TIMEOUT"
query hash "sessid"
cookie hash "sessid"
path filter "*command=*" from "/cgi-bin/index.cgi"
ssl { sslv2, ciphers "MEDIUM:HIGH" }
tcp { nodelay, sack, socket buffer 65536, backlog 128 }
}
Это определение обработчика протокола демонстрирует ряд простых операций над
заголовками HTTP, а также устанавливает и SSL параметры и специфичные TCP
параметры для оптимизации обработки соединений. Параметры заголовка влияют на
заголовки протокола, включая значения переменных, либо присоединение к
существующим заголовкам (добавить) или изменение содержания нового значения
(изменение).
URL и хэш куки используется для балансировки нагрузки, чтобы выбрать те хосты,
которые в пуле целевого запроса перенаправляется. Специфика фильтрации пути такова,
что любой может получить запрос, включая первое квотированное ограничение как
ограничение второго отброшенного. Опция SSL указывает, что только для SSL версии 2
шфиры будут приняты, с длиной ключа в средне-высоком диапазоне; другими словами,
128 битный или более3. И наконец, в-третьих, tcp опции nodelay задают минимизацию
задержек, указывающих на использование селективных методов (RFC 2018), и
устанавливают размер буфера сокета и максимально допустимое число отложенных
соединений, которые балансировщик нагрузки отслеживает. Эти опции являются только
примерами, в большинстве случаев, ваше приложение будет хорошо работать с этими
настройками со значениями по умолчанию.
Определение relay c помощью обработчика протокола означает, что шаблон должен
определяться в раннем определении веб-службы:
relay wwwssl {
# Run as a SSL accelerator
listen on $webserver port 443 ssl
protocol "httpssl"
table <webhosts> loadbalance check ssl
}
Тем не менее вашим веб приложениям с поддержкой SSL, скорее всего, будет выгодно
иметь немного другой набор параметров:
Замечание:
Мы добавили проверку SSL, предполагаю, что каждый член таблицы вебхостингов правильно сконфигурирован для полной
поддержки SSL. В зависимости от приложения, это может быть полезно взглянуть на состояние всех SSL обработок в relayd, тем
самым, снимая нагрузку с задач шифрования на бэкэнде.
Наконец, для отказоустойчивости хостов основанной на CARP relayd в сети (смотрите
«Избыточность и отказоустойчивость: CARP и pfsync» на странице 119) должен быть
сконфигурирован для поддержки CARP взаимодействуя с установками понижения
счетчика CARP для указанной группы интерфейсов при выключении или запуске. Похоже
все части системы OpenBSD идут с информативными страницами мануалов. Для угловатых
вариантов не освещенных здесь (есть несколько), изучайте страницы мануалов для
relayd, relayd.conf и relayctl, и начинайте экспериментировать для поиска той
конфигурации, что вам нужна.
Веб сервер и почтовый сервер внутри – случай NAT
Давайте немного вернемся и начнем снова с базовым сценарием, где пример клиентов из
главы 3 получающих трех новых соседей: почтовый сервер, веб-сервер и файловый
сервер. На этот раз адреса внешне видимые либо отсутствуют, либо слишком дороги и
запускать ряд других служб на машине, которая в первую очередь является брандмауэром
нежелательно. Это означает, что мы вернулись назад, к ситуации где мы делаем наш NAT
шлюзом. К счастью, механизмы перенаправления в PF делют его относительно простым в
поддержке на внутренней строне шлюза, который выполняет роль NAT.
Характеристики сети такие же, как для установки example.com: мы должны запустить
веб-сервер, который подает данные в открытом виде (http) и зашифрованном (https), а
также почтовый сервер, который посылает и получает почту пока резрешено клиентам
внутри и вне локальной сети использовать ряд хорошо известных протоколов. Короче
говоря, нам нужны такие же функции, что и в установке из предыдущего раздела, но
только с одним маршрутизируемым адресом.
3. Смотрите страницу man для OpenSSL для дальнейшего объяснения параметров связанных с шифром.
Из трех серверов, только веб-сервер и почтовый сервер должны быть видимыми из
внешнего мира, так мы добавим макросы для их IP адресов и сервисов в набор правил из
главы 3:
webserver = "192.168.2.7"
webports = "{ http, https }"
emailserver = "192.168.2.5"
email = "{ smtp, pop3, imap, imap3, imaps, pop3s }"
С одним единственным маршрутизируемым адресом и серверами скрытыми за NAT
адресным пространством, нам нужно установить правила на шлюзе, которые
перенаправят трафик, который нам нужен на наши сервера. Мы могли бы определить
набор правил соответствия, чтобы настроить перенаправление, а затем адрес блокировать
или пропустить вынести в отдельный набор правил примерно так:
match in on $ext_if proto tcp to $ext_if port $webports rdr-to $webserver
match in on $ext_if proto tcp to $ext_if port $email rdr-to $emailserver
pass proto tcp to $webserver port $webports
pass proto tcp to $emailserver port $email
pass proto tcp from $emailserver to port smtp
Эта комбинация правил match и pass очень похожим путем все эти вещи могут быть
сделаны в pre-OpenBSD 4.7 PF версиях, и если вы модернизируете из предыдущих версий,
этот тип быстрой правки мог бы быть мостом через небольшой разрыв в синтаксисе. Но вы
также можете выбрать новый стиль, и написать это более копактно:
pass
pass
pass
pass
in on $ext_if inet proto tcp to $ext_if port $webports rdr-to $webserver
in on $ext_if inet proto tcp to $ext_if port $email rdr-to $mailserver
on $int_if inet proto tcp to $webserver port $webports
on $int_if inet proto tcp to $mailserver port $email
Обратите внимание на разрешающие правила с rdr-to. Эта комбинация фильтрации и
перенаправления поможет сделать вещи легче и меньше пока, так как в этой комбинации.
В pre-OpenBSD 4.7 PF, набор правил будет совершенно похожим, исключая то, что мы
сделали с перенаправлениями
webserver = "192.168.2.7"
webports = "{ http, https }"
emailserver = "192.168.2.5"
email = "{ smtp, pop3, imap, imap3, imaps, pop3s }"
rdr on $ext_if proto tcp to $ext_if port $webports -> $webserver
rdr on $ext_if proto tcp to $ext_if port $email -> $emailserver
pass proto tcp to $webserver port $webports
pass proto tcp to $emailserver port $email
pass proto tcp from $emailserver to any port smtp
DMZ с NAT
Во всех установках, где есть NAT пул доступных адресов выделяемый для DMZ, вероятно,
будет больше, чем в нашем предыдущем примере, но применяются те же принципы. Когда
вы перемещаете серверы в физически отдельную сеть, вы должны будете проверить в
наборе ваших правил, что
макро определения являются по определению
здравомыслящими и отрегулировать значения, если это необходимо.
Как и в случае с маршрутизируемыми адресами, полезно было бы ужесточить набор
ваших правил, отредактировав разрешенные правила для входящего и исходящего
трафика вашего сервера и разрешить передавать только на те интерфейсы, которые на
самом деле имеют отношения к сервису:
pass in on $ext_if inet proto tcp to $ext_if port $webports rdr-to $webserver
pass in on $int_if inet proto tcp from $localnet to $webserver port $webports
pass out on $dmz_if proto tcp to $webserver port $webports
pass in log on $ext_if inet proto tcp to $ext_if port $email \
rdr-to $mailserver
pass in log on $int_if proto tcp from $localnet to $mailserver port $email
pass out log on $dmz_if proto tcp to $mailserver port smtp
pass in on $dmz_if from $mailserver to port smtp
pass out log on $ext_if proto tcp from $mailserver to port smtp
Для версий ранее OpenBSD 4.7 есть различия в некоторых деталях, с перенаправлением
в отдельных правилах:
pass
pass
pass
pass
pass
pass
pass
pass
in on $ext_if proto tcp to $webserver port $webports
in on $int_if proto tcp from $localnet to $webserver port $webports
out on $dmz_if proto tcp to $webserver port $webports
in log on $ext_if proto tcp to $mailserver port smtp
in log on $int_if proto tcp from $localnet to $mailserver port $email
out log on $dmz_if proto tcp to $mailserver port smtp
in on $dmz_if from $mailserver to port smtp
out log on $ext_if proto tcp from $mailserver to port smtp
Вы можете создать конкретные разрешающие правила, которые ссылаются на интерфейс
вашей локальной сети, но если вы оставите существующие разрешенные правила
нетронутыми, они будут продолжать работать.
Перенаправление для балансировки нагрузки
Перенаправление основанное на балансировке нагрузки из предыдущего примера
работает равно хорошо в режиме NAT, где публичный адрес это внешний интерфейс
шлюза и перенаправление адресов происходит в частном диапазоне.
Это опредление для webpool:
table <webpool> persist { 192.168.2.7, 192.168.2.8, 192.168.2.9, 192.168.2.10 }
Главное различие между случаем маршрутизируемых адресов и NAT версией это то, что
после того, как вы добавили определение для webpool, вы редактируете существующие
правила проходят с перенаправлением, которое затем становится этим:
pass in on $ext_if inet proto tcp to $ext_if port $webports rdr-to <webpool> round-robin
Или для версий ранее OpenBSD 4.7 используйте это:
rdr on $ext_if proto tcp to $ext_if port $webports -> <webpool> round-robin
С этого момента ваш NATированный DMZ ведет себя так же, как один с официальными,
маршрутизируемыми адресами.
Назад к единой NATированной сети
Это может удивить вас, если вы услышите, что есть случаи, где настройки маленькой
сети гораздо сложней чем в большой. Например, вернемся в ситуацию где серверы
находятся в той же физической сети, что и клиенты, основываясь на NATированной
конфигурации, работает очень хорошо до определенного момента. Фактически, все
работает прекрасно до тех пор, пока все в чем вы заинтересованы это получение трафика
от хостов вне вашей локальной сети для достижения ваших серверов.
Вот полная конфигурация:
ext_if = "re0" # macro for external interface - use tun0 or pppoe0 for PPPoE
int_if = "re1" # macro for internal interface
localnet = $int_if:network
# for ftp-proxy
proxy = "127.0.0.1"
icmp_types = "{ echoreq, unreach }"
client_out = "{ ssh, domain, pop3, auth, nntp, http, https, \
446, cvspserver, 2628, 5999, 8000, 8080 }"
udp_services = "{ domain, ntp }"
webserver = "192.168.2.7"
webports = "{ http, https }"
emailserver = "192.168.2.5"
email = "{ smtp, pop3, imap, imap3, imaps, pop3s }"
# NAT: ext_if IP address could be dynamic, hence ($ext_if)
match out on $ext_if from $localnet nat-to ($ext_if)
block all
# for ftp-proxy: Remember to put the following line, uncommented, in your
# /etc/rc.conf.local to enable ftp-proxy:
# ftpproxy_flags=""
anchor "ftp-proxy/*"
pass in quick proto tcp to port ftp rdr-to $proxy port 8021
pass out proto tcp from $proxy to port ftp
pass quick inet proto { tcp, udp } to port $udp_services
pass proto tcp to port $client_out
# allow out the default range for traceroute(8):
# "base+nhops*nqueries-1" (33434+64*3-1)
pass out on $ext_if inet proto udp to port 33433 >< 33626 keep state
# make sure icmp passes unfettered
pass inet proto icmp icmp-type $icmp_types from $localnet
pass inet proto icmp icmp-type $icmp_types to $ext_if
pass in on $ext_if inet proto tcp to $ext_if port $webports rdr-to $webserver
pass in on $ext_if inet proto tcp to $ext_if port $email rdr-to $mailserver
pass on $int_if inet proto tcp to $webserver port $webports
pass on $int_if inet proto tcp to $mailserver port $email
Последние четыре правила здесь интересуют нас больше всего. Если вы пытаетесь
достичь сервиса на официальном адресе с хостов в вашей сети, вы вскоре увидите, что
запросы для перенаправленных сервисов с машин в вашей локальной сети скорей всего
не доходят на внешний интерфейс. Это потому, что все перенаправление и перевод
происходят на внешнем интерфейсе. Шлюз получает пакты из вашей локальной сети на
внутренний интерфейс, с адресом назначения для внешнего интерфейса. Шлюз
распознает адрес как один из своих и попытается обработать запрос как если бы он был
направлен к локальному сервису, и как следствие, перенаправления совсем не работают с
внутренней стороны.
Эквивалентная часть тех последних четырех строк из предыдущего набора правил для
версий предшествующих OpenBSD 4.7 систем выглядят так:
rdr on $ext_if proto tcp to $ext_if port $webports -> $webserver
rdr on $ext_if proto tcp to $ext_if port $email -> $emailserver
pass proto tcp to $webserver port $webports
pass proto tcp to $emailserver port $email
pass proto tcp from $emailserver to any port smtp
К счастью, возможны несколько способов решения данной проблемы. Проблема
достаточно распространена, в руководстве пользователя PF перечисляется четыре
различных решения проблемы4, в том числе 4 перемещением ваших серверов в DMZ как
описано ранее. Так как это книга о PF, мы сосредоточимся на решении основанном на PF
(на самом деле довольно ужасный обход), который заключается в лечении локальной сети
как частный случай для нашего перенаправления и NAT правил. Нам нужно
перехватывать сетевые пакеты, проходящие в локальную сеть и управлять этими
соединениями правильно, убедившись, что любой обратный трафик направлен к партнеру
по соединению и в том, что действительно возникла связь. Это означает, что для того,
чтобы перенаправить для работы как ожидается из локальной сети, нам нужно добавить
правила особого перенаправления, которые отражают то, что предназначено для
обработки
запросов
снаружи.
Во-первых,
вот
разрешающие
правила
с
перенаправлениями для OpenBSD 4.7 и более новых версий:
pass in on $ext_if inet proto tcp to $ext_if port $webports rdr-to $webserver
pass in on $ext_if inet proto tcp to $ext_if port $email rdr-to $mailserver
pass in log on $int_if inet proto tcp from $int_if:network to $ext_if \
port $webports rdr-to $webserver
pass in log on $int_if inet proto tcp from $int_if:network to $ext_if \
port $email rdr-to $mailserver
match out log on $int_if proto tcp from $int_if:network to $webserver \
port $webports nat-to $int_if
pass on $int_if inet proto tcp to $webserver port $webports
match out log on $int_if proto tcp from $int_if:network to $mailserver \
port $email nat-to $int_if
pass on $int_if inet proto tcp to $mailserver port $email
Первые два правила идентичны оригинальным. Следующие два перехвата трафика из
локальной сети и rdr – к действиям в обоих перезаписать адрес назначения, так же как
это сделано для соответствующих правил, которые берут свое начало в другом месте.
Разрешающие правила для $int_if служат той же цели, что и в предыдущей версии.
Совпадают правила с nat как вокруг работающая маршрутизация. Без них, веб-сервер и
почтовый сервер маршрутизировали бы обратный трафик, который нужно перенаправлять
напрямую к хостам в локальной сети, где трафик мог бы не соответствует исходящим
соединениям. В месте, где nat, серверы рассматривают шлюз в качестве источника
4.Смотрите
«Перенаправление
faq/pf/rdr.html#reflect)
и
Отражение»
раздел
в
руководстве
пользователя
PF
(http://www.openbsd.org/
трафика и направят его обратно тем же путем, что она пришел изначально. Шлюз
совпадающий обратный трафик для состояний созданных соединений от клиентов в
локальной сети и применяет соответствующие меры для возвращения трафика
корректным клиентам. Эквивалентные правила для версий предшествующих OpenBSD 4.7,
на первый взгляд немного более запутанный, но конечный результат тот же:
rdr on $int_if proto tcp from $localnet to $ext_if port $webports -> $webserver
rdr on $int_if proto tcp from $localnet to $ext_if port $email -> $emailserver
no nat on $int_if proto tcp from $int_if to $localnet
nat on $int_if proto tcp from $localnet to $webserver port $webports -> $int_if
nat on $int_if proto tcp from $localnet to $emailserver port $email -> $int_if
Таким образом, мы прикручиваем перенаправление и трансляцию адресов, чтобы делать
то, что нам нужно, и нам не нужно трогать разрешенный правила вообще. (Я имел счастье
наблюдать через электронную почту или IRC реакции нескольких администраторов сети в
момент, когда правда около 5 строк реконфигурации затонули.)
Фильтрация по группам интерфейсов
Ваша сеть должно быть имеет несколько подсетей, которые могут никогда не
взаимодействовать с вашей локальной сетью за исключением нескольких общих сервисов,
таких как почта, веб, файловый и печать. Как вы справляетесь с трафиком из таких
подсетей зависит от того, для чего ваша сеть предназначена. Одним из полезных
подходов относится к каждой менее привилегированной сети как к отдельной локальной
сети, к которой привязан свой отдельный интерфейс на общем фильтрующем шлюзе, а
затем дать ему набор правил, который позволяет только нужные направления
взаимодействия с соседними сетями прилагаемыми к основному шлюзу.
Вы можете сделать вашу PF конфигурацию более управляемой и читабельной
сгруппировав логически похожие интерфейсы в группы интерфейсов и применить правила
фильтрации к группам более предпочтительно чем к отдельным интерфейсам. Группы
интерфейсов, как это реализовано с помощью опции группы ifconfig, первоначально
появились в OpenBSD 3.6 и были приняты в дальнейшем в FreeBSD 7.0.
Все сконфигурированные сетевые интерфейсы могут быть сконфигурированы
принадлежащими одной или больше группам. Некоторые интерфейсы автоматически
принадлежат к одной из групп по умолчанию. Для примера, все IEEE 802.11 беспроводные
сетевые интерфейсы принадлежат к wlan группе, пока интерфейсы не ассоциируются с
маршрутом по умолчанию принадлежащему egress группе. К счастью, интерфейс может
быть членом нескольких групп, и вы можете добавить интерфейсы к группе интерфейсов
через соответствующую команду ifconfig, как в этом примере:
# ifconfig sis2 group untrusted
Эквивалентно под OpenBSD могло бы в hostname.sis2 файле или ifconfig_sis2= строке в
rc.conf файле на FreeBSD 7.0 или более поздних версиях.
Там, где это имеет смысл, вы можете относиться к группе интерфейсов так же, как если
бы вы обрабатывали единственный интерфейс в правилах фильтрации:
pass in on untrusted to any port $webports
pass out on egress to any port $webports
Если теперь вы думаете, что в большинстве, если не все, наборы правил до этого
момента можно будет фильтровать по группе gress вместо макроса $ext_if, вы ухватили
важный момент. Это должно быть полезное упражнение для прохождения через
существующие наборы правил, которые у вас есть, чтобы увидеть как использование
группы интерфейсов может помочь сделать еще более читабельным. Помните, что группа
интерфейсов может иметь одного или больше членов.
Заметьте, что фильтрация на группах интерфейсов позволяет писать по существу
аппаратно-независимые наборы правил. Пока ваш hostname.if файлы или ifconfig_if=
вставлены строки с интерфейсами в правильные группы, набор правил для постоянной
фильтрации на группах интерфейсов будут полностью переносимыми между машинами,
которые могут или не могут иметь одинаковые аппаратные конфигурации. На системах где
функция группа интерфейсов недоступна, вы можете быть в состоянии достичь некоторых
из тех же эффектов через создание использования макросов, вот так:
untrusted = "{ ath0 ath1 wi0 ep0 }"
egress = "sk0"
Сила тегов
В некоторых сетях, решение о том, где пакету должен быть разрешен проход не может
быть сделано легко картой критериев, таких как подсети и сервисы. Мелкозернистые
политики контроля сайта требуют создание сложных наборов правил и потенциально
трудно поддерживаемых.
К счастью, PF предлагает еще один механизм для классификации и фильтрации в виде
тегирования пакета. Полезный способ представления тегирования пакета это тегировать
входящие пакеты для соответствия конкретным разрешающим правила, а затем разрешать
пакетам проходить где-то еще на основе конкретного идентификатора тегированного
пакета. В OpenBSD 4.6 и более поздних версиях, это даже возможно иметь отдельные
соответствующие правила для соответствующих тегов с соответствующим критерием,
оставляющим решения о прохождении, перенаправлении, или принятии другого действия
в правилах далее в наборе правил.
Одним из примеров может быть беспроводные точки доступа, которые мы создали в главе
4, которые мы могли бы ожидать, чтобы передать трафик в локальную сеть с очевидным
адресом источника равным точке доступа $ext_if. При таком сценарии, полезным
дополнением к набру правил шлюза с несколькими из этих точек доступа может быть
следующее (при условии, конечно, что определения макросов wifi_allowed и wifi_ports
соответствуют требованиям сайта)
wifi = "{ 10.0.0.115, 10.0.0.125, 10.0.0.135, 10.0.0.145 }"
pass in on $int_if from $wifi to $wifi_allowed port $wifi_ports tag wifigood
pass out on $ext_if tagged wifigood
Так как сложность набора правил растет, рассмотрите использование тегов в
соответствующем входящем и проходящих правилах, чтобы сделать набор правил
читабельным и легким в обслуживании. Теги «липки», и как только пакет был помечен
соответствующим правилом, тег остается, это означает, что пакет может иметь тег, даже
если не было применено последнее соответствующее правило. Однако, пакет может иметь
только один тег в любое время. Если пакет соответствует нескольким правилам, к которым
применяется тегирование, тег будет перезаписан с каждым новым правилом в
соответствии с тегом для правила.
Для примера, вы могли бы установить несколько тегов на входящий трафик через
установку соответствующих или проходящих правил, дополненные набором прохождения
правил, которые определяют, где пакеты обрабатываются на основании тегов,
установленных на входящий трафик.
Брандмауэр в случае моста
Ethernet мост состоит из двух или более интерфейсов сконфигурированных в
соответствии Ethernet фреймами прозрачно, и которые видимы не напрямую, а через
несколько верхних слоев, таких как TCP/IP стек. В контексте фильтрации, конфигурация
моста часто считают привлекательной, поскольку это означает, что фильтрация может
быть выполнена на машине, которая не имеет своего собственного IP адреса. Если на
машине, о которой идет речь, запущена OpenBSD или столь же способная операционная
система, она все еще может фильтровать и перенаправлять трафик.
Главное преимущество такой установки это то, что атака брандмауэра сама по себе более
сложна5. Недостатком является то, что все административные задачи должны выполняться
на консоли брандмауэра, если вы не настроили сетевой интерфейс доступный через
какую-то защищенную сеть, или даже последовательную консоль. Это также следует, что
мосты без настроенных IP адресов не могут быть установлены в качестве шлюза для сети
и не может запускать любые другие службы на интерфейсе моста. Скорее, вы можете
подумать о мосте как интеллектуальной выпуклосте на сетевом кабеле, которая может
фильтровать и перенаправлять. Несколько основных предостережений распространяется
на использование брандмауэров реализованных в виде мостов:
•
•
•
Интерфейсы находятся в неразборчивом режиме, а это значит, что они получат (и в
некоторой степени обработают) каждый пакет в сети.
Мосты работают на уровне Ethernet, и по умолчанию, пропускают все типы
пакетов, а не только TCP/IP.
Отсутствие IP адреса на интерфейсах делает некоторые из более эффективных
функций, таких как CARP, недоступными.
Способы конфигурирования мостов различаются в некоторых деталях среди
операционных систем. Следующие примеры весьма поверхностны и не освещаются все
возможные недостатки, но должны быть достаточными для начала.
Базовая настройка моста на OpenBSD
GENERIC ядро OpenBSD содержит весь необходимый код для конфигурирования моста и
фильтрации на нем. Если вы собрали ядро без кода моста, установка довольно проста.
Замечание:
На OpenBSD 4.7и более подних версиях, beconfig команда больше не существует. Вся конфигурация моста и связанные с ними
функции были объединены в ifconfig для релиза OpenBSD 4.7.
Для установки моста с двумя интерфейсами в командной строке, необходимо сначала
создать устройство моста. Первому устройству принято давать порядковый номер 0,
поэтому мы создаем bridge0 устройство с помощью следующей команды:
$ sudo ifconfig bridge0 create
Перед следующей командой ifconfig (brconfig на OpenBSD 4.6 и более ранних версиях)
используется ifconfig для проверки что перспективный интерфейсы (в нашем случае, ep0
и ep1) поднялись, но не назначены IP адреса. Затем настройте мост, введя следующее:
$ sudo ifconfig bridge0 add ep0 add ep1 blocknonip ep0 blocknonip ep1 up
На OpenBSD 4.6 и более ранних версиях введите это:
$ sudo brconfig bridge0 add ep0 add ep1 blocknonip ep0 blocknonip ep1 up
OpenBSD команда ifconfig (brconfig на OpenBSD 4.6 и более ранних версиях) содержит
бит фильтрации в самом коде. В этом примере мы используем blocknonip опцию для
каждого интерфейса, чтобы блокировать весь не IP трафик.
Замечание:
OpenBSD ifconfig команда предлагает свои собственные опции фильтрации в дополнение к другим опциям конфигурации.
Bridge(4) и ifconfig(8) man страницы предоставляют больше информации. Так как они действуют на уровене Ethernet, можно
использовать ifconfig, чтобы указать правила фильтрации, которые разрешают мосту фильтровать по МАС адресам. Используя
эти возможности фильтрации, также возможно, тегировать пакеты моста для дальнейшей обработки в ваших PF правилах через
ключевое слово tagged. Для тегирования целей, мост должен быть с одним из членов интерфейсов. Эта функциональность и
ключевые слова были также представлены в brconfig(4) в OpenBSD 4.6 и более ранних версиях.
Чтобы сделать конфигурацию постоянной,
hostname.ep0 и введите следующую строку:
создайте
или
отредактируйте
/etc/
up
Для других интерфейсов, /etc/hostname.ep1 должны содержать ту же строку:
up
Наконец, введите настройки моста в /etc/hostname.bridge0 (/etc/bridgename.bridge0 на
OpenBSD 4.6 и более ранних версиях):
5. Насколько безопасно это на самом деле напоминает о случайных горячих спорах в списках рассылки, таких как OpenBSD-misc
и других ориентированных на сеть списках. Чтение о плюсах и минусах в восприятии основных разработчиков OpenBSD может
быть как увлекательным, так и полезным.
add ep0 add ep1 blocknonip ep0 blocknonip ep1 up
Ваш мост должен сейчас быть поднят, и вы может продолжать создавать правила
фильтрации PF.
Базовая настройка моста на FreeBSD
Для FreBSD процедура немного более сложная чем на OpenBSD. Для того, чтоб было
возможно использовать мост, ваше работающее ядро должно включать в себя модуль
if_bridge. Конфигурация ядра по умолчанию собрана с этим модулем, так при обычных
обстоятельствах, вы можете перейти непосредственно к создания интерфейса. Для
компиляции устройства моста в ядре, добавьте следующую строку в файл конфигурации
ядра:
device if_bridge
Вы также можете загрузить устройство во время загрузки добавив следующую строку
в /etc/loader.conf файл.
if_bridge_load="YES"
Создайте мост введя это:
$ sudo ifconfig bridge0 create
Создание bridge0 интерфейса также создается установкой связанной с мостом sysctl
значения:
$ sudo sysctl net.link.bridge
net.link.bridge.ipfw: 0
net.link.bridge.pfil_member: 1
net.link.bridge.pfil_bridge: 1
net.link.bridge.ipfw_arp: 0
net.link.bridge.pfil_onlyip: 1
Следует проверить, чтобы эти sysctl значения были доступны. Если они есть, это
подтверждение того, что мост был включен. Если это не так вернитесь назад и
посмотрите, что пошло не так и почему.
Замечание:
Эти значения применяются для фильтрации на мосту самого интерфейса. Вам не нужно прикасаться к ним, так как IP
фильтрация на уровне члена интерфейсов (концы труб) включена по умолчанию.
Перед следующей командой ifconfig, убедитесь, что перспективные интерфейсы (в нашем
случае, ep0 и ep1) работают, но не были назначены IP адреса, а затем настройте мост,
введя следующее:
$ sudo ifconfig bridge0 addm ep0 addm ep1 up
Сделайте конфигурацию постоянной, добавив следующие строки в /etc/rc.conf:
ifconfig_ep0="up"
ifconfig_ep1="up"
cloned_interfaces="bridge0"
ifconfig_bridge0="addm ep0 addm ep1 up"
Это означает, что ваш мост работает, и вы можете продолжать создание правил
фильтрации PF. Посмотрите if_bridge(4) man страницу для дальнейшее конкретной
информации о мосте в FreeBSD.
Базовая настройка моста на NetBSD
В NetBSD, в конфигурации по умолчанию нет поддержки фильтрации моста. Вы должны
скомпилировать ядро со следующей опцией добавленной в файл конфигурации ядра. Если
у вас есть новое ядро вставьте код моста в место, установка довольно проста.
options
BRIDGE_IPF
# bridge uses IP/IPv6 pfil hooks too
Создать мост с двумя интерфейсами в командной строке, первым создается устройство
bridge0:
$ sudo ifconfig bridge0 create
Перед следующей командой brconfig используйте ifconfig, чтобы проверить каким
интерфейсам являются работающими (в нашем случае, ep0 и ep1), но которым не
назначены IP адреса. Затем сконфигурируйте мост, введя это:
$ sudo brconfig bridge0 add ep0 add ep1 up
Затем, включите фильтрацию на устройстве bridge0:
$ sudo brconfig bridge0 ipf
Сделайте конфигурацию постоянной, создав или отредактировав /etc/ifconfig.ep0 и введя
следующую строку.
up
Для другого интерфейса, /etc/ifconfig.ep1 должен содержать такую же строку:
up
Наконец, введите установку моста в /etc/ifconfig.bridge():
create
!add ep0 add ep1 up
Ваш мост должен сейчас работать, и вы можете продолжить создавать правила
фильтрации PF. Для дополнительной информации смотрите документацию о PF в NetBSD
по ссылке: http://www.netbsd.org/Documentation/network/pf.html.
Набор правил моста
Здесь есть pf.conf файл для версии выпуклости-в-проводе базовый набор правил,
который мы начали в этой главе. Сеть немного изменена, как показано на рисунке 5-3.
Рисунок 5-3. Сеть с мостом бранмауэром
Машина в локальной сети общий шлюз по умолчанию, который не мост, но могут быть
размещены внутри или за пределами моста.
ext_if = ep0
int_if = ep1
localnet= "192.0.2.0/24"
webserver = "192.0.2.227"
webports = "{ http, https }"
emailserver = "192.0.2.225"
email = "{ smtp, pop3, imap, imap3, imaps, pop3s }"
nameservers = "{ 192.0.2.221, 192.0.2.223 }"
client_out = "{ ssh, domain, pop3, auth, nntp, http, https, \
446, cvspserver, 2628, 5999, 8000, 8080 }"
udp_services = "{ domain, ntp }"
icmp_types = "{ echoreq, unreach }"
set skip on $int_if
block all
pass quick on $ext_if inet proto { tcp, udp } from $localnet \
to port $udp_services
pass log on $ext_if inet proto icmp all icmp-type $icmp_types
pass on $ext_if inet proto tcp from $localnet to port $client_out
pass on $ext_if inet proto { tcp, udp } to $nameservers port domain
pass on $ext_if proto tcp to $webserver port $webports
pass log on $ext_if proto tcp to $emailserver port $email
pass log on $ext_if proto tcp from $emailserver to port smtp
Возможны значительно более сложные настройки. Но помните, что в то время как
перенаправление будет работать, вы не сможете запускать службы на любом из
интерфейсов без IP адресов.
Обработка немаршрутизируемых адресов где-то в другом
месте
Даже при правильной настройке шлюза для обработки фильтрации и, возможно, NAT для
вашей собственной сети, вы можете оказаться незавидном положении, нуждающемся в
компенсировании
неправильной
настройки
других
людей.
Один
удручающе
распространенный вид неправильной настройки, который позволяет трафику с
немаршрутизируемых адресов выходить в Интернет. Трафик от немаршрутизируемых
адресов также принимает участие в нескольких методах атаки отказах в обслуживании
(DoS), так что стоит учесть явную блокировку трафика от немаршрутизируемых адресов в
сеть. Одно из возможных решений обозначено здесь. На всякий случай, он также
блокирует любую попытку инициировать контакт с немаршрутизируемых адресов через
внешний интерфейс шлюза.
martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \
0.0.0.0/8, 240.0.0.0/4 }"
block in quick on $ext_if from $martians to any
block out quick on $ext_if from any to $martians
Здесь макрос martians обозначает RFC 1918 адреса и несколько других диапазонов
рекомендуемых различными RFC, не находящимися в обращении в открытом Интернете.
Входящий и исходящий трафик таких адресов тихо отбросится на внешнем интерфейсе
шлюза.
Замечание:
Макрос martians может быть легче реализован в виде таблицы, а не со всеми преимуществами таблицы в качестве
дополнительного бонуса в ваш набор правил.
Конкретные детали как реализовать этот вид защиты будет варьироваться в зависимости
от конфигурации сети и может быть частью более широкого комплекса мер безопасности
сети. Дизайн вашей сети также может диктовать, какие вы включите, а какие исключите
другие диапазоны адресов, помимо этих.
Глава 6
Использование таблиц для проактивной защиты
Как было показано в предыдущей главе, вам потребуется значительное время и
дополнительные затраты энергии, чтобы убедиться, что сервисы, которые вы хотите
предложить будут доступны даже тогда, когда установлены строгие правила фильтрации
пакетов. В скором времени после проведения установки, вы можете заметить, что
некоторые сервисы, в отличии от других, привлекают немного больше нежелательного
внимания.
Сценарий таков: У вас есть сеть с реализованной фильтрацией пакетов в соответствии с
вашими требованиями, включающая сервисы, которые должны быть доступны для
удалённых пользователей. К сожалению, когда сервисы доступны, существует риск того,
что кто-то захочет использовать их вне установленных целей. Почти наверняка, вы
обнаружите несанкционированные попытки удалённого входа посредством SSH, или
использования SMTP.
В этой главе, мы рассмотрим несколько способов усложнить получение
несанкционированного входа посредством SSH, а затем обратимся к некоторым наиболее
эффективным способам противостояния спамерам.
Борьба с брутфорсом
Сервис безопасной оболочки, обычно называемый SSH, является весьма важным
сервисом для администраторов Unix. Часто он является основным интерфейсом машины и
наиболее излюбленной мишенью для атак.
Атака на SSH методом подбора паролей (SSH Brute-Force)
Если вы запустили сервис SSH, доступ к которому возможен из Интернет (обычное дело),
вы наверняка наблюдали подобные записи в своих журналах аутентификации:
Sep 26 03:12:34
Sep 26 03:12:34
Sep 26 03:12:35
Sep 26 03:12:44
Sep 26 03:12:44
Sep 26 03:12:44
41484 ssh2
Sep 26 03:12:44
41484 ssh2
Sep 26 03:12:45
Sep 26 03:13:10
Sep 26 03:13:10
Sep 26 03:13:10
Sep 26 03:13:15
Sep 26 03:13:15
Sep 26 03:13:15
43811 ssh2
Sep 26 03:13:15
43811 ssh2
Sep 26 03:13:15
Sep 26 03:13:25
skapet
skapet
skapet
skapet
skapet
skapet
sshd[25771]: Failed password for root from 200.72.41.31 port 40992 ssh2
sshd[5279]: Failed password for root from 200.72.41.31 port 40992 ssh2
sshd[5279]: Received disconnect from 200.72.41.31: 11: Bye Bye
sshd[29635]: Invalid user admin from 200.72.41.31
sshd[24703]: input_userauth_request: invalid user admin
sshd[24703]: Failed password for invalid user admin from 200.72.41.31 port
skapet sshd[29635]: Failed password for invalid user admin from 200.72.41.31 port
skapet
skapet
skapet
skapet
skapet
skapet
skapet
sshd[24703]: Connection closed by 200.72.41.31
sshd[11459]: Failed password for root from 200.72.41.31 port 43344 ssh2
sshd[7635]: Failed password for root from 200.72.41.31 port 43344 ssh2
sshd[11459]: Received disconnect from 200.72.41.31: 11: Bye Bye
sshd[31357]: Invalid user admin from 200.72.41.31
sshd[10543]: input_userauth_request: invalid user admin
sshd[10543]: Failed password for invalid user admin from 200.72.41.31 port
skapet sshd[31357]: Failed password for invalid user admin from 200.72.41.31 port
skapet sshd[10543]: Received disconnect from 200.72.41.31: 11: Bye Bye
skapet sshd[6526]: Connection closed by 200.72.41.31
Именно так выглядит атака перебором паролей, более известная как brute-force. Кто-то
или что-то, пытается с помощью грубой силы подобрать имя пользователя и пароль для
входа в вашу систему. Простейшей реакцией станет написание правила в pf.conf, которое
будет блокировать весь доступ. Однако, это приведёт к ряду проблем, первой из которых
станет вопрос - как предоставить доступ к сервису легитимным пользователям. Настройка
sshd принимает только аутентификацию основанную на ключе, однако это скорее всего не
остановит попыток получения доступа. Вы можете рассмотреть вопрос о переводе сервиса
на другой порт, но существует вероятность, что те кто сканировал порт 22, с таким же
упехом обнаружат и порт 22222.
(Практика показывает, что смена порта SSH на порт из верхнего диапазона, в значительной мере сокращает число попыток
несанкционированого доступа, хотя, конечно не исключает их. Применяя этот способ в качество одной из мер предосторожности
можно добиться некоторых успехов - п.п.).
Начиная с OpenBSD 3.7, PF предлагает несколько более элегантное решение данной
проблемы.
Настройка адаптивного брандмауэра
Для предотвращения атак подбором паролей, вы можете написать правила пропуска
таким образом, чтобы они поддерживали определённые ограничения на возможности
подключающихся хостов. На всякий случай, вам следует направлять нарушителей в
таблицу адресов, для которой запрещён весь доступ или некоторые виды доступа. Можно
даже указать блокирование всех подключений от машин перекрывших свои лимиты. Для
включения этой функции, создайте таблицу добавив следующую строку в файл
конфигурации перед правилами фильтрации:
table <bruteforce> persist
Затем, в начале набора правил блокируем брутфорс, как показано ниже:
block quick from <bruteforce>
Наконец добавим пропускающее правило:
pass inet proto tcp to $localnet port $tcp_services keep state (max-src-conn 100, max-src-conn-rate 15/5, overload
<bruteforce> flush global)
Это правило очень похоже на те которые мы видели в более ранних примерах.
Интересная часть его контекста, заключённая в скобки, называется опциями
отслеживания состояний:
•
•
•
•
max-src-conn - число одновременных соединений позволенных от одного хоста. В
данном примере установлено в 100. Вы можете установить значение больше или
меньше в зависимости от параметров вашей сети.
max-src-conn-rate - число новых подключений позволеных от одного любого
хоста. Зесь установлено в 15 соединений за 5 секунд, записанное как 15/5.
Выберите значение соответствующее вашей установке.
overload <bruteforce> - означает, что адрес любого хоста, который превысил
текущие лимиты будет добавлен в таблицу bruteforce. Соответственно, наш набор
правил блокирует весь трафик с адресов попадающих в эту таблицу. Как только
хост превышает любой из этих лимитов и попадает в таблицу перегрузки, правило
перестаёт сопоставлять трафик с этим хостом. Убедитесь, что перегрузка
обрабатывается только правилом блокировки по умолчанию или аналогичным.
flush global - сообщает, что когда хост достигает лимита, все состояния для его
соединений уничтожаются (сбрасываются). Опция global означает, что мера
применяется и для состояний созданных для трафика этого хоста которые так же
соответствовали другим правилам пропуска.
Как вы понимаете, эффект от этого небольшого дополнения набора правил весьма
драматичен. После нескольких попыток подбора пароля, адрес хоста производившего
брутфорс попадает в таблицу bruteforce. А это, в свою очередь, означает, что все его
существующие соединения уничтожаются (сбрасываются), а любые новые попытки
соединения будут заблокированы, скорее всего постоянно. Таким образом вы только что
создали адаптивный брандмауэр, который автоматически настраивается на условия вашей
среды и самостоятельно воздействует на нежелательную активность.
Замечание
Наши адаптивные правила действуют только для защиты от традиционных и простых попыток подбора паролей. Рапределённые
попытки подбора производящиеся с низкой интенсивностью, факт применения которых был впервые зафиксирован в 2008 году
(известные среди прочих под названием The Hail Mary Cloud) не проявляют аналогичной активности и не будут соответствовать
параметрам данных правил.
Вполне вероятно, что вы можете создать некоторую гибкость в наборе правил и
допустить большее число соединений к некоторым сервисам, но стоит быть более
экономным, особенно когда речь идёт о SSH. В этом случае, вы можете основное правило
пропуска содержимым похожим на следующее, добавив его в начало набора правил:
pass quick proto { tcp, udp } to port ssh \
keep state (max-src-conn 15, max-src-conn-rate 5/3, \
overload <bruteforce> flush global)
Вам придётся самостоятельно найти необходимые параметры подходящие к вашей
ситуации, обратившись к соответствующим man-страницам и руководству PF (смотрите
приложение А).
Замечание
Помните, что данные примеры правил предназначены для иллюстрирования работы, а в поддержка сервисов вашей сети может
потребовать значительной переработки правил. Установка слишком низкого уровня количества одновременных соединений или
скорости соединий может привести к блокированию законного трафика и созданию внутреннего источника отказа обслуживания,
в случае, если конфигурация включает множество узлов находящихся за общим шлюзом NAT.
Опции отслеживания состояний и механизм перегрузки не следует применять
исключительно к сервису SSH, а блокирование всего трафика атакующего не всегда
полезно. Например можно использовать следующее правило:
pass proto { tcp, udp } to port $mail_services keep state (max 1500, max-src-conn 100)
Здесь, max определяет максимальное число состояний, которые могут быть созданы для
каждого правила (или ряда правил, в зависимости от того как расширяется макрос
$mail_services) без перегрузки для защиты почтового или web сервиса с приёмом
большего числа соединений чем то которое он может обработать. С таким правилом,
значение max определяет максимальное число состояний, которые будут созданы для
каждого результирующего правила. Как только будет достигнут предел, новые
соединения не будут разрешаться вплоть до завершения существующих.
Альтернативно, можно удалить ограничение max и добавить в правила часть overload, и
назначить атакующим очередь с минимальным выделением полосы пропускания (смотрите
обсуждение настройке очередей ALTQ в главе 7).
Некоторые сайты используют overload для реализации многоуровневой системы, где
хосты попадающие под правило overload направляются на одну или несколько
промежуточных "испытательных" таблиц для специальной обработки. Это может быть
полезно при работе с web содержимым, и позволит не блокировать трафик от хостов в
таблице перегрузки непосредственно, а направлять все HTTP запросы от этих узлов на
определённые web-страницы (как мы видели в примере authpf в конце Главы 4).
Очистка таблиц с помощью pfctl
Используя правила overload описаные в предыдущем разделе, вы получили адаптивный
брандмауэр, который автоматически определает нежелательное поведение и добаляет IP
адреса нарушителей в таблицы. Просмотр журналов и таблиц может быть весёлым
занятием, однако, поскольку правила только добавляют данные в таблицы мы
сталкиваемся со следующей задачей: поддержание актуальности таблиц.
Когда вы запускаете конфигурацию с адаптивным набором правил, через некоторое
время вы обнаруживаете, что одни IP адреса, недавно заблокированные из-за брутфорса,
в настоящее являются вполне легальными для работы с вашей сетью 1. Если ваши
адаптивные правила собираю много трафика, вы можете обнаружить, что таблицы
перегрузки быстро разрастаются и занимают много места. Решение данной проблемы
заключается в создание записей срока истечения таблиц (expire) - необходимых для
удаления записей на которые небыло ссылок за определённое время. В OpenBSD 4.1
инструмент pfctl приобрёл способность создавать в таблице записи expire основываясь на
статистических параметрах времени, таких как последний сброс 2. (Практически во всех
случаях, время сброса равно времени добавления записи в таблицу). Используется
ключевое слово expire и возраст записи таблицы, указываемый в секундах. Например:
$ sudo pfctl -t bruteforce -T expire 86400
Эта команда удалит записи таблицы bruteforce для которых статистика сброса превысила
86400 секунд (24 часа).
Замечание
Выбор значения 24 часа в качестве времени истечения - величина довольно произвольная. Вы должны выбирать значение
которое вам наиболее подходит, величину соответствующую разумному времени обнаружения и устранения проблемы. Если у
вас присутствуют адаптивные правила, будет хорошей мыслью создать запись cron, для периодического выполнения очистки
таблиц используя команду указанную выше. Это позволит содержать таблицы в актуальном состоянии.
Усложним жинь спамеров используя spamd
Электронная почта является весьма важным сервисом и требует особого внимания из-за
большого объёма нежелательных сообщений и спама. Большой объём спама стал весьма
болезненной проблемой, когда вирусописатели начали писать почтовых червей и
перегружать почтовые сервисы. В начале 2000-х годов совокупный объём спама и
вредоносных программ распространяемых через почту дошло до уровня, когда запуск
почтового сервиса SMTP без мер защиты от спама стал просто немыслимым.
Меры борьбы со спамом практически на столько стары, как и сама проблема его
существования. Ранние усилия были направлены на анализ содержания почтовых
сообщений (более известный как фильтрация контекста) и в некоторой степени на
интерпретацию сообщений путём тривиального вытягивания данных заголовков, таких
как предполагаемый адрес отправителя (From:) или заголовков Recieved.
Когда команда OpenBSD разрабатывала свой инструмент борьбы со спамом названый
spamd, впервые появившийся в OpenBSD 3.3 в 2003 году, они сосредоточились на работе
сетевого уровня и немедленном взаимодействии с партнёром SMTP, в сочетании с любой
имеющейся информацией о хостах которые имели дело с доставкой сообщения.
Разработчики задались целью создать небольшую, весьма простую и безопасную
программу. Последующая реализация была практически исключительно основана на
творческом использовании таблиц PF в сочетании с данными из надёжных внешних
источников.
Примечание
В дополнение к демону блокировки спама OpenBSD, пакету SpamAssassin основанному на фильтрации контента
(http://spamassassin.apache.org) существует программа названная spamd. Обе программы разработаны для оказания помощи в
борьбе со спамом, но они имеют весьма различные подходы к решению одной проблемы и не имеют прямого взаимодействия.
Следует отметить, что когда обе программы правильно настроены и запущены, они прекрасно дополняют друг друга.
Анализ поведения сетевого уровня и черные списки
Оригинальный дизайн spamd основан на том наблюдении, что спамеры отправляют много
почты и вероятность того, что вы первый человек узнавший об этом невероятно малая.
Кроме того, спам рассылается посредством нескольких спам-сетей и множества угнанных
(хайджек - в классическом понимании) машин. Сообщения и машины которые их
передают достаточно быстро попадают в соответствующие чёрные списки, и эти данные
чёрных списков содержащих IP адреса отправляющие спам формируют основу для работы
spamd.
При взаимодействии с блокированными хостами spamd использует метод называемый
tarpitting. Когда демон получает SMTP соединение, он выставляет баннер и мгновенно
переключается на режим, в котором отвечает SMTP трафиком со скоростью 1 байт в
секунду, используя маленький набор SMTP команд разработанный таким образом, чтобы
почта никогда не была доставлена, а возвращалась обратно в очередь отправителя
поскольку заголовки сообщения были переданы.
1. В более долгосрочной перспективе, вполне вероятно, что целые сети и большие диапазоны IP адресов будут
переассоциированы с новыми владельцами в ответ на события внешнего мира.
2. Прежде чем pfctl приобрёл возможность работать с истечением табличных записей, для управления истечением
использовалась специальная утилита expitrtable. Если ваш pfctl ещё не поддерживает режим истечения записей, найдите
expiretable в вашей системе пакетов.
Эта реализация tarpitting'а c однобайтовым ответом часто упоминается как заикание.
Черный список основанный на тарпиттинге с заиканием является режимом по умолчанию
для spamd до версии OpenBSD 4.0 включительно.
Замечание
На FreeBSD и NetBSD, spamd не является частью базовой системы, однако доступен через систему портов и пакетов как
mail/spamd. Если вы запускаете PF на базе релиза FreeBSD 5.x или NetBSD 4.0 или более новом, вам следует произвести
установку порта или пакета.
Настройка spamd в режиме черного списка
Для настройке spamd в традиционном режиме чёрного списка, сначала создайте
специальные таблицы и соответствующие перенаправления в pf.conf, а уже затем
переключите внимание на spamd.conf. spamd цепляется к набору правил PF через таблицу
и перенаправления. Вам необходимо добавить следующие строки в файл pf.conf:
table <spamd> persist
pass in on $ext_if inet proto tcp from <spamd> to { $ext_if, $localnet } port smtp rdr-to 127.0.0.1 port 8025
Для pre-OpenBSD 4.7 следующий синтаксис:
table <spamd> persist
rdr pass on $ext_if inet proto tcp from <spamd> to { $ext_if, $localnet } port smtp -> 127.0.0.1 port 8025
Таблица <spamd> - место для хранения IP адресов, которые вы импортируете из
доверенных источников черных списков. Перенаправление берёт на себя заботу о всех
попытках установления SMTP соединений с хостов находящихся в чёрных списках. spamd
слушает порт 8025 и м-е-д-л-е-н-н-о отвечает (со скоростью 1 байт в секунду) на все
переадресуемые SMTP соединения. Позже, вы добавите в набор правил соотвествующее
правило, обеспечивающее пропуск лигитимного SMTP трафика к почтовому серверу.
В файле spamd.conf вы указываете источники данных черных списков и любые
исключения или локальные переопределения.
Замечание
На OpenBSD 4.0. и более ранних релизах (и соответственно в базе портов основаных на версиях до OpenBSD 4.1), spamd.conf
находился в директории /etc. Начиная с OpenBSD 4.1, spamd.conf можно найти в /etc/mail. Пример файла конфигурации spamd
при установке из системы портов FreeBSD можно найти в /usr/local/etc/spamd/spamd.conf.sample.
В начале spamd.conf вы можете заметить строку без знака комментария #, которая
выглядит как all:\. Эта строка указывает черные списки которые вы будете использовать.
Например:
all:\
:uatraps:whitelist:
Добавьте все черные списки которые вы хотитет использовать ниже строки all:\,
разделяя их двоеточием (:). Для использования белых списков адресов, с вычитанием их
из чёрных списков, добавьте имя белого списка сразу после названия каждого чёрного
списка, например как :blacklist:whitelist:. Далее идёт определение черного списка:
uatraps:\
:black:\
:msg="SPAM. Your address %A has sent spam within the last 24 hours":\
:method=http:\
:file=www.openbsd.org/spamd/traplist.gz
Примечание
Используя чёрные списки по умолчанию, spamd может исключать большие блоки Интернет, в том числе некоторые диапазоны
адресов, которые охватывают записи целых стран. Если ваш сайт предполагает обмен лигитимной почтой с любой из стран, о
которой идёт речь, эти списки могут быть не оптимальны для вашей установки. Другие популярные черные списки с диапазоном
источников спама /16 должны быть так же подробно рассмотрены до их использования в рабочих политиках.
Введите строки для spamd и параметров запуска в ваш /etc/rc.conf.local на OpenBSD, или
в /etc/rc.conf на FreeBSD или NetBSD. Вот пример:
spamd_flags="-v -b" # for normal use: "" and see spamd-setup(8)
Здесь мы включаем spamd и устанавливаем запуск режима чёрных списков используя
флаг -b. Кроме того, флаг -v включает раширенное журналирование, которое полезно для
отслеживания активности spamd при отладке.
В FreeBSD, установка obspamd_enable в /etc/rc.conf позволяущая контролировать
поведение spamd должна быть установлена в "YES" для включения spamd, а параметр
obspamd_flags можно заполнить любыми параметрами командной строки spamd:
obspamd_enable="YES"
obspamd_flags="-v -b" # for normal use: "" and see spamd-setup(8)
Примечание
Для запуска spamd в родном режиме черного списка на OpenBSD 4.1 и более новых релизах, вы можете получить тот же эффект
путём установки переменной spamd_black в значение "YES", а затем перезапустить spamd.
После того, как вы закончите редактирование конфигурации, запустите spamd с
требуемыми опциями, и завершите конфигурирование установки. Наконец, создайте
задание cron которое вызывает spamd-setup для обновления чёрных списков через
разумные интервалы времени. В родном режиме черных списков, вы можете проматривать
и манипулировать собержимым таблиц используя команду pfctl.
Журналирование spamd
По умолчанию, журналы spamd включаются в общие системные журналы. Для того,
чтобы отправить сообщения журналирования spamd в отдельный журнал, следует
добавить следующую запись в syslog.conf:
!!spamd
daemon.err;daemon.warn;daemon.info;daemon.debug
/var/log/spamd
Как только spamd запущен и делает именно то что вы пытались от него добиться, вы
можете добавить файл журналирования spamd в систему ротатации журналов. После
запуска spamd-setup и заполнения таблиц, вы можете просматривать содержимое таблиц
используя pfctl.
Примечание
Образец pf.conf в начале данного раздела содержит правило перенаправления (rdr-to) как часть правила pass. Если вы
планируете использовать вместо него другие соответствующие правила (или, если вы используете старую версию PF и решили
написать правило rdr, не включающее часть pass), вам следует убедиться, что вы создали правило pass, позволяющее
прохождение трафика к вашему перенаправлению. Так же может понадобиться установить правила для пропуска лигитимной
почты. Однако, если сервис электронной почты в вашей сети уже работает, с большой вероятностью вы можете продолжить
использовать старые правила пропуска SMTP.
Имея набор надёжных и упорядоченных чёрных списков, spamd в родном режиме чёрного
списка производит видимую работу по сокращению спама. Тем не менее, только в режиме
чёрных списков, вы ловите трафик только от хостов которые уже пытались отправлять
спам (и это было кем то зафиксировано - п.п.), и опираетесь на внешние доверенные
источники на основании данных которых решаете, для каких хостов можете применять
тарпитт. Для создания установки обеспечивающей непосредственную реакцию на
поведение сетевого уровня и предлагающую превентивные меры в борьбе со спамом,
следует рассмотреть использование серых списков (graylists), которые являются важной
частью современной работы spamd.
Серые списки: Мой администратор
разговарить с незнакомцами
сказал
мне
не
Серые списки в основном состоят из интерпретации текущих стандартов SMTP и
добавляют немного белой лжи чтобы облегчить вам жизнь. Как правило, спамеры
используют чужое оборудование для отправки своих сообщений и незаконно
устанавливают соответствующее программное обеспечение работаующее в фоновом
режиме. В отличии от легитимных отправителей почты, спамеры не считают важным
любое индивидуальное сообщение которое они отправляют. В целом, это означает, что
типовое ПО отправляющее спам, или соответствующее вредоносное ПО не занимаются
корректной обработкой статусных кодов SMTP. И это мы можем использовать в своих
целях, как было предложено Эваном Харрисом в его докладе названом "Следующий шаг в
войне со спамом: Серые списки", опубликованым в 2003 году 3.
Харрис отметил, что когда взломаный компьютер используется для отправки спама,
приложение отправитель производит только отправку, без проверки результов или кодов
возврата. Реальная реализация SMTP интерпретирует коды возврата и прозводит
соответствующие действия, а реальный почтовый сервер повторит попытку отправки,
если первая попытка не увенчалась успехом из-за ошибки. В своей статье, Харрис
изложил практические подходы:
• при первом контакте с SMTP ранее неизвестного партнёра не принимать
электронную почту с первой попытки доставки, а вместо этого ответить статусным
кодом информирующим о временно локальной проблеме, и сохранить IP адрес
отправителя для дальнейшего использования.
• если отправка повторяется немедленно, вернуть, как и прежде, статусный код
временной проблемы.
• если отправитель, повторяет отправку после некоторого установленного минимума
времени
(например 1 час), но не более максимального периода ожидания
(например 4-х часов), принять сообщение, и записать IP адрес отправителя в
белый список.
Такова сущность серых списков. И к счастью, вы можете настроить и сохранить серые
списки spamd на шлюзе оборудованном PF.
(Вот такая паранойя в самой жестокой форме, и заметьте вполне актуальная - п.п.).
Установка spamd в режим серых списков
Возможность использования серых списков появилась в OpenBSD 3.5. Начиная с
OpenBSD 4.1, spamd использует режим серых списков по умолчанию. В режиме серых
списков по умолчанию, таблица spamd используемая для черных списков, описанных в
предыдущем разделе, становится избыточной. Вы всё ещё можете использовать серые
списки, но spamd будет использовать сочетание частных структур данных для данных
чёрных списков и базу данных spamdb для хранения данных связанных с серыми
списками. Типовой набор правил для spamd в режиме по умолчанию выглядит примерно
так:
table <spamd-white> persist
table <nospamd> persist file "/etc/mail/nospamd"
pass in log on egress proto tcp to port smtp \
rdr-to 127.0.0.1 port spamd
pass in log on egress proto tcp from <nospamd> to port smtp
pass in log on egress proto tcp from <spamd-white> to port smtp
pass out log on egress proto tcp to port smtp
Сюда включены необходимые правила pass, позволяющие поток легитимной почты из
вашей сети в пункт назначения. Таблица <spamd-white> является белым списком,
который ведётся spamd. Хосты в таблице <spamd-white> предварительно прошли серые
списки, а почте с этих машин позволено проходить к реальным почтовым серверам или
интерфейсам фильтрации контента. Кроме того, таблица <nospamd> используется для
загрузки адресов хостов, которые вы не желаете подвергать обработке spamd, а
соответствующие правила pass гарантируют прохождение SMTP трафика от этих хостов.
В вашей сети, вы можете ужесточить эти правила для передачи трафика SMTP только к
или с хостов, которым разрешено отправлять и получать почту через SMTP. Мы вернёмся к
таблице <nospamd> в разделе "Обработка узлов которые плохо рабтают с серыми
списками", на странице 102.
3. Оригинал работы Харриса и ряд других полезных статей и ресурсов можно найти по адресу http://www.greylisting.org/.
Эквивалент правил для синтаксиса pre-OpenBSD 4.7:
table <spamd-white> persist
table <nospamd> persist file "/etc/mail/nospamd"
rdr pass in log on egress proto tcp to port smtp \
-> 127.0.0.1 port spamd
pass in log on egress proto tcp from <nospamd> to port smtp
pass in log on egress proto tcp from <spamd-white> to port smtp
pass out log on egress proto tcp to port smtp
ВРЕЗКА КАК РАБОТАЮТ СЕРЫЕ СПИСКИ
Большое число разработок было направлено на улучшение работы основных сервисов, например таких как SMTP. С
практической точки зрения, это означает что мы можем получить полные данные о всём процессе доставки сообщений SMTP.
Именно по этой причине, мы, в конечном счёте, можем полагаться на серые списки получая почту от определённых почтовых
серверов. Текущий стандарт передачи электронной почты в сети Интернет определяется RFC 5321.* Вот несколько отрывков
из раздела 4.5.4.1 "Стратегия отправки":
[В типовых системах, программа компоновки сообщения имеет иной способ запроса немедленной обработки исходящей
почты, а почта, которая не может быть отправлена немедленно, должна помещаться в очередь и периодически пытаться
отправиться. Отправитель обязан делать паузу перед повторной попыткой оправки сообщения адресату, если предыдущая
попытка не удалась. в целом, интервалы повтора ДОЛЖНЫ быть не менее 30 минут, однако будет полезна и более сложная
стратегия периодичности, в случае если клиент SMTP может определить причину невозможности доставки. Попытки будут
продолжаться вплоть до передачи сообщения или отказа отправителя: отказ оправителя обычно составляет период 4-5 дней.
Доставка электронной почты является процессом совместных усисилий и RFC чётко регламентирует, что, ели сайт, на который
вы пытаетесь отправить почту, информирует о том, что не может принять сообщение в данный момент, ваша обязанность
(установленая требованием) повторить отправку несколько позже, дав возможность принимающему серверу устранить
возможные проблемы. Серые списки - ложь во спасение. Когда мы говорим что имеются временные локальные проблемы, эти
проблемы эквивалентны выражению - "Мой администратор сказал мне не разговаривать с незнакомцами". Действительные
отправители повторят отправку, однако спамеры не будут ждать шанса попробовать ещё раз отправить сообщение, поскольку
при этом увеличивается его совокупная стоимость. Именно по этому серые списки работают на основе строгого соблюдения
стандартов и ложные срабатывания весьма редки. ]
* Соответствующие части RFC 5321 идентичны частям устаревшего документа RFC 2821. Некоторые из нас были сильно
разочарованы тем, что IETF не уточнил эти фрагменты в соответствии с текущими стандартами. Моя реакция (хотя наверное
это слишком напыщенная фраза) отмечена на
http://bsdly.blogspot.com/2008/10/ietf-failed-to-account-for-greylisting.html.
Соответствующие RFC, в основном RFC 1123 и RFC 5321 (заменивший RFC 2821). Запомните, что временный отказ является
функцией отказоустойчивости SMTP.
В FreeBSD, для того чтобы использовать режим серых списков spamd, вам необходим
файл дескриптора файловой системы (смотрите man 5 fdescfs) смонтированный в /dev/fd/.
Для этого, добавьте следующую строку в /etc/fstab и убедитесь, что код fdescfs
присутствует в вашем ядре или загрузите соответствующий модуль с помощью команды
kldload.
fdescfs /dev/fd fdescfs rw 0 0
Для начала конфигурирования spamd, разместите строки для spamd и параметров
загрузки в /etc/rc.conf.local. Например:
spamd_flags="-v -G 2:4:864" # for normal use: "" and see spamd-setup(8)
На FreeBSD, эквивалентные строки должны быть в /etc/rc.conf:
obspamd_flags="-v -G 2:4:864" # for normal use: "" and see spamd-setup(8)
Вы можете более тонко настроить несколько параметров связанных с серыми списками
используя параметры командной строки spamd с опцией -G.
Список разделённый двоеточиями 2:4:864 представляет значения passtime, greyexp и
whiteexp:
•
•
•
passtime указывает минимальное число минут, которые spamd считает разумным
временем прежде чем повторить отправку. По умолчанию, значение составляет 25
минут, но мы уменьшили его до 2 минут.
greyexp указывает количество часов, в течение которых запись остаётся в серых
списках до удаления из базы данных
whiteexp указывает в часах, как долго хранятся записи в белом списке.
Значения по умолчанию для greyexp и whiteexp составляют 4 и 864 часа (чуть
более одного месяца) соответственно.
Использование серых списков на практике
Пользователи и администраторы сайтов, которые реализуют практику использования
серых списков, сходятся во мнении, что серые списки позволяют избавиться от большой
части спама и приводят к значительному падению нагрузки на любую фильтрацию
контента. Для начала, мы рассмотрим, как выглядят файлы журналов spamd при
использовании серых списков, а затем вернёмся к некоторым данным.
Если вы выполните в командной строке spamd -v, что обеспечит высокую детализацию
ведения файлов журналов, они будут включать некоторую дополнительную информацию
кроме IP адресов. Типичный отрывок такого журнала выглядит примерно так:
Oct 2 19:53:21 delilah spamd[26905]:65.210.185.131: connected (1/1), lists: spews1
Oct 2 19:55:04 delilah spamd[26905]:83.23.213.115: connected (2/1)
Oct 2 19:55:05 delilah spamd[26905]:(GREY) 83.23.213.115: <gilbert@keyholes.net> ->
<wkitp98zpu.fsf@datadok.no>
Oct 2 19:55:05 delilah spamd[26905]:83.23.213.115: disconnected after 0 seconds.
Oct 2 19:55:05 delilah spamd[26905]:83.23.213.115: connected (2/1)
Oct 2 19:55:06 delilah spamd[26905]:(GREY) 83.23.213.115: <gilbert@keyholes.net> ->
<wkitp98zpu.fsf@datadok.no>
Oct 2 19:55:06 delilah spamd[26905]: 83.23.213.115: disconnected after 1 seconds.
Oct 2 19:57:07 delilah spamd[26905]: (BLACK) 65.210.185.131: <bounce-3C7E40A4B3@branch15.summerbargainz.com> -> <adm@dataped.no>
Oct 2 19:58:50 delilah spamd[26905]: 65.210.185.131: From: Auto lnsurance Savings
<noreply@branch15.summer-bargainz.com>
Oct 2 19:58:50 delilah spamd[26905]: 65.210.185.131: Subject: Start SAVlNG M0NEY on Auto lnsurance
Oct 2 19:58:50 delilah spamd[26905]: 65.210.185.131: To: adm@dataped.no
Oct 2 20:00:05 delilah spamd[26905]: 65.210.185.131: disconnected after 404 seconds. lists: spews1
Oct 2 20:03:48 delilah spamd[26905]: 222.240.6.118: connected (1/0)
Oct 2 20:03:48 delilah spamd[26905]: 222.240.6.118: disconnected after 0 seconds.
Oct 2 20:06:51 delilah spamd[26905]: 24.71.110.10: connected (1/1), lists: spews1
Oct 2 20:07:00 delilah spamd[26905]: 221.196.37.249: connected (2/1)
Oct 2 20:07:00 delilah spamd[26905]: 221.196.37.249: disconnected after 0 seconds.
Oct 2 20:07:12 delilah spamd[26905]: 24.71.110.10: disconnected after 21 seconds. lists: spews1
Первая строка - начало соединения с машиной находящейся в чёрном списке spews1.
Следующие шесть строк отображают полные записи из двух попыток соединения с другой
машины, которая каждый раз подключается как вторичное активное соединение. Эта
вторая машина ещё не попала в чёрный список, поскольку она находится в сером списке.
Обратите внимание на любопытный адрес доставки в сообщении (wkitp98zpu.
fsf@datadok.no), которое пытается доставить машина из серого списка. Существует
полезный трюк, который мы рассмотрим в разделе "Graytrapping" на странице 98. (GRAY)
и (BLACK) перед адресом, указывают статус серых или черных списков. Сейчас
существует большая активность от блокированного хоста, а несколько позже мы увидим,
что после 404 секунд (6 минут 44 секунды), блокированный хост сбрасывается без
завершения доставки.
Остальные строки показывают несколько очень коротких соединений, в том числе и от
машины находящейся в чёрном списке. Правда на этот раз разыв соединения происходит
слишком быстро для того чтобы увидеть флаг (BLACK) в начале диалога SMTP, однако в
конце мы видим ссылку на список имён (spews1). Около 400 секунд (по данным
различных сайтов) наивные спамеры торчат в чёрном списке и примерно столько же
времени требуется (из расчёта 1 байт в секунду) на завершение диалога EHLO пока spamd
отклоняет сообщение. Однако, если заглядывать в журнал почаще, вы можете заметить,
что некоторые спамеры висят значительно больше. Например, по данным шлюза нашего
офиса, можно выделить одну запись журнала:
Dec 11 23:57:24 delilah spamd[32048]: 69.6.40.26: connected (1/1), lists:
spamhaus spews1 spews2
Dec 12 00:30:08
seconds. lists: delilah spamd[32048]: 69.6.40.26: disconnected after 1964
spamhaus spews1 spews2
Данная машина уже находилась в нескольких чёрных списках, когда она сделала 13
попыток доставки с 9 по 12 декабря. Последняя попытка длилась 32 минуты 44 секунды,
так и не завершив доставки. Умные спамеры разрывают соединение в течение первых
пяти секунд, как было показано в первом фрагменте журнала. Другие, после 400 секунд.
Некоторые повисают на несколько часов. (Самый крайний зарегистрированный случай 42673 секунды, почто 12 часов).
Отслеживание ваших реальных почтовых соединений:
spamlogd
За сценой, о чём редко упоминается и, что слабо документировано, находится одна из
наиболее важных вспомогательных программ spamd: система обновления белых списков
spamlogd. Как следует из названия, spamlogd работает в фоновом режиме, ведёт
протоколирование соединений от ваших почтовых серверов с целью обновления ваших
белых списков. Идея заключается в уверенности, что действующая почта, отправляемая
между регулярно общающимися хостами проходит с мимнимум суеты.
Примечание
Если вы следовали всем действия до этого момента, ваш spamlogd скорее всего уже работает. Если ваша первоначальная
конфигурация spamd не включала режим серых списков, spamlogd может быть не запущен, и вы можете столкнуться со
странными симптомами, подобными тому, что серые и белые списки не обновляются должным образом. Перезапуск spamd после
включения режима серых списков должен так же запустить spamlogd.
Для того, чтобы функционировать должным образом, spamlogd нуждается
журналировании ваших SMTP соединений с и к вашим почтовым серверам, таким же
образом, как мы уже делали в главе 5:
emailserver = "192.0.2.225"
pass log proto tcp to $emailserver port $email
pass log proto tcp from $emailserver to port smtp
На OpenBSD 4.1 и выше (и эквивалентных системах), вы можете создать несколько
интерфейсов pflog и указать какие правила должны журналироваться. Вот как отделить
данные которые должен читать spamlogd от прочих журналов PF:
1. Создайте отдельный интерфейс pflog1 используя ifconfig pflog1 create, или создайте
файл hostname.pflog1 со строкой up.
2. Измените соответствующие правила к следующему виду:
pass log (to pflog1) proto tcp to $emailserver port $email
pass log (to pflog1) proto tcp from $emailserver to port smtp
3. Добавьте -l pflog1 к параметрам начальной загрузки spamlogd.
Таким образом, вы отделите данные регистрации spamd от всех прочих (смотрите главу 8
подробно обсуждающую журналирование). При наличии соответствующих правил,
spamlogd будет добавлять IP адреса, получившие ваши электронные письма в белый
список. Это не железная гарантия того, что ответ будет проходить немедленно, но в
большинстве конфигураций, некоторые вещи значительно ускоряются.
Greytrapping
Как мы уже знаем, спамеры редко используют полное соответствие реализации SMTP при
отправке своих сообщений, и именно по этой причине работают серые списики. Так же,
мы знаем, что спамеры редко проверяют адреса скармливаемые угнанным машинам.
Объединяя эти факты, мы увидим, что, если машина находящаяся в сером списке
пытается отправить сообщение на неправильный адрес в вашем домене, существует шанс,
что письмо является спамом или вирусом. Осознание этого факта привело к следующему
эволюционному шагу в развитии spamd - техники называемой greytrapping. Когда хост из
серого списка пытается доставить почту к неизвестному адресу в нашем домене, этот хост
будет добавлен в локальный чёрный список, называемый spamd-greytrap. Члены spamdgreytrap так же получают траппинг со скоростью 1 байт в секунду как и участники чёрных
списков. Greytrapping реализован в spamd весьма просто и элегантно. Всё что вам нужно чтобы spamd работал в режиме серых списков. Другие важные компоненты - список
адресов в домене обслуживаемом сервером электронной почты домена, тех, которые
никогда не получают лигитимную почту. Количество адресов в списке не имеет значения,
должен быть по крайней мере один адрес, а верхний предел определяется только вашими
требованиями.
Далее, вы скармливаете список функции greytrapping и просто ждёте. Во-первых,
отправитель пытается отправить письмо на адрес в списке greytrap, и при этом просто
работают серые списки, как и в случае с любым отправителем, с которым вы ещё не
обменивались электронной почтой. Если хост повторяет отправку, на тот же самый,
неверный адрес или другой адрес вашего серого списка, срабатывает greytrap, и
нарушитель вводится в spamd-greytrap на 24 часа. В течение последующих 24 часов
любой SMTP трафик от хоста попавшего под greytrapping будет "заикаться" со скоростью
ответов 1 байт в секунду.
Этот 24 часовой период является достаточно коротким чтобы не вызывать серьёзных
нарушений легитимного трафика, поскольку полноценная реализация SMTP будет
пытаться осуществить доставку по крайней мере несколько дней. Опыт крупномаштабных
реализаций данной технологии показывает, что она редко вызывает ложные
срабатывания. Машины которые продолжат рассылку спама после 24 часового интервала
достаточно скоро снова попадут в тарпит.
Установка траплиста
Для установки вашего траплиста (списка трапов), используйте spamdb с опцией -T. В
моём случае, странные адреса 4 о которых я упоминал на странице 96 "Практика
использования серых списков", стали естественными кандидатами для включения:
$ sudo spamdb -T -a wkitp98zpu.fsf@datadok.no
Команда, которую я ввёл, фактически выглядит как $ sudo spamdb -T -a
"<wkitp98zpu.fsf@datadok.no>". В OpenBSD 4.1 и более новых релизах, spamdb не
требует ввод угловых скобок или кавычек, но так же будет их принимать. Вы можете
добавить столько адресов сколько захотите. Я всегда стараюсь найти новые дополнения
для своего локального списка spamtrap-адресов, просматривая серые списки серверов и
почтовые журналы на предмет неудачных попыток доставки или попыток доставки на
несуществующие адреса в моём домене (да я знаю что это звучит как сумашествие).
ПРЕДУПРЕЖДЕНИЕ
Убедитесь, что адреса, которые вы добавляете в свои списки spamtrap являются недействительными и будут таковыми
оставаться. Через некоторое время, могут возникнуть затруднения вспомнить, что вы занесли адрес в spamtrap.
Следующий фрагмент журнала показывает, как пытается впервые соединиться машина
спамера находящаяся в сером списке, а затем возвращается снова и грубо пытается
доставить сообщения на любые адреса, которые я добавил в траплист, только для того
чтобы попасть через несколько минут в черный список spamd-greytrap. Мы точно знаем,
что эта машина будет делать следующие 20 с лишним часов.
Nov 6 09:50:25 delilah spamd[23576]:210.214.12.57: connected (1/0)
Nov 6 09:50:32 delilah spamd[23576]:210.214.12.57: connected (2/0)
Nov 6 09:50:40 delilah spamd[23576]:(GREY) 210.214.12.57: <gilbert@keyholes.net> ->
<wkitp98zpu.fsf@datadok.no>
Nov 6 09:50:40 delilah spamd[23576]:210.214.12.57: disconnected after 15 seconds.
Nov 6 09:50:42 delilah spamd[23576]:210.214.12.57: connected (2/0)
Nov 6 09:50:45 delilah spamd[23576]:(GREY) 210.214.12.57: <bounce-3C7E40A4B3@branch15.summerbargainz.com> -> <adm@dataped.no>
Nov 6 09:50:45 delilah spamd[23576]:210.214.12.57: disconnected after 13 seconds.
Nov 6 09:50:50 delilah spamd[23576]:210.214.12.57: connected (2/0)
Nov 6 09:51:00 delilah spamd[23576]:(GREY) 210.214.12.57: <gilbert@keyholes.net> ->
<wkitp98zpu.fsf@datadok.no>
Nov 6 09:51:00 delilah spamd[23576]:210.214.12.57: disconnected after 18 seconds.
Nov 6 09:51:02 delilah spamd[23576]:210.214.12.57: connected (2/0)
Nov 6 09:51:02 delilah spamd[23576]:210.214.12.57: disconnected after 12 seconds.
Nov 6 09:51:02 delilah spamd[23576]:210.214.12.57: connected (2/0)
Nov 6 09:51:18 delilah spamd[23576]:(GREY) 210.214.12.57: <gilbert@keyholes.net> ->
<wkitp98zpu.fsf@datadok.no>
Nov 6 09:51:18 delilah spamd[23576]:210.214.12.57: disconnected after 16 seconds.
Nov 6 09:51:18 delilah spamd[23576]:(GREY) 210.214.12.57: <bounce-3C7E40A4B3@branch15.summerbargainz.com> -> <adm@dataped.no>
Nov 6 09:51:18 delilah spamd[23576]:210.214.12.57: disconnected after 16 seconds.
4. Конечно, этот адрес явлетс поддельным. Эта идея использовалась почтовыми генераторами ID и GNUS, и генерируется
новостным клиентом. Вероятней всего он взят из спула новостей или почтового ящика какой нибудь жертвы.
Nov 6 09:51:20 delilah spamd[23576]:210.214.12.57: connected (1/1), lists: spamd-greytrap
Nov 6 09:51:23 delilah spamd[23576]:210.214.12.57: connected (2/2), lists: spamd-greytrap
Nov 6 09:55:33 delilah spamd[23576]:(BLACK) 210.214.12.57: <gilbert@keyholes.net> ->
<wkitp98zpu.fsf@datadok.no>
Nov 6 09:55:34 delilah spamd[23576]:(BLACK) 210.214.12.57: <bounce-3C7E40A4B3@branch15.summerbargainz.com> -> <adm@dataped.no>
К сведению, даже если спамер сменил отправляющую машину, оба адреса From: и To:
остались прежними. То, что он всё ещё пытается отправить на адрес которого небыло в
доставке, является показателем того, что спамер не слишком часто проверяет свой список
адресов.
Управление списками с использованием spamdb
Могут возникнуть ситуации, когда вам необходимо просмотреть или измениь содержимое
черного, белого или серого списков. Эти записи находятся в базе данных /var/db/spamdb,
и основным инструментом для их администрирования является spamdb.
Ранние версии spamdb просто предлагали варианты добавления записи в базу данных
белого списка или обновление существующей записи (spamdb -a nn.mm.nn.mm). Вы
можете удалить записи белого списка (spamdb -d nn.mm.nn.mm) для компенсации
недостатков в чёрных списках либо повышения эффективности алгоритма серых списков.
Новые версии spamdb, кроме того, предлагают несколько интересных функций для
поддержки greytrapping.
Обновление списков
Если вы запустите spamdb без параметров, будет выведен список содержимого базы
данных, и вы сможете добавлять или удалять адреса spamtrap и записи траплистов. Кроме
того, вы можете, на лету добавлять записи белого списка. Если вы хотите добавить хост в
белый список, не добавляя его на постоянной основе в файл nospamd и перезагрузить
ваш небор прпавил или таблицу, вы можете сделать это из командной строки примерно
так:
$ sudo spamdb -a 213.187.179.198
Если спамеру всё таки удалось произвести доставку сообщения, несмотря на все ваши
усилия, вы можете попытаться исправить ситуацию, добавив спамера в список spamdgreytrap, например так:
$ sudo spamdb -a -t 192.168.2.128
Добавить новую ловушку адреса так же просто:
$ sudo spamdb -a -T _-medvetsky@ehtrib.org
Если вы хотите отменить любое из этих решений, вам следует заметь ключ -а на -b в
обеих командах.
Сохранение синхронизации серых списков spamd
Начиная с OpenBSD 4.1, spamd может сохранять синхронизацию баз данных серых
списков с любым числом взаимодействующих шлюзов использующих серые списки.
Реализация основана на наборе параметров командной строки spamd:
•
•
Опция -Y указывает цель синхронизации (sync target) - т.е. IP адрес(а) других
spamd-шлюзов которые вы хотите проинформировать о обновлении информации
вашего серого списка.
На принимающем конце, опция -y используется для указания слушателя
синхронизации, адреса или интерфейса, на котором экземпляр spamd готов
получить обновления серых списков с других хостов.
Например, наш основной spamd-шлюз mainoffice-gw.example.com может использовать
следующие параметры командной строки
синхронизации слушателя, соответственно:
для
создания
цели
синхронизации
и
-Y minorbranch-gw.example.com -y mainoffice-gw.example.com
И наоборот, minorbranch-gw.example.com, в филиале нашего офиса использует:
-Y mainoffice-gw.example.com -y minorbranch-gw.example.com
Демон spamd поддерживает аутентификацию между партнёрами синхронизации. В
частности, если вы создаёте файл /etc/mail/spam.key и передаёте его копии всем
партнёрам синхронизации, он будет использоваться для расчёта контрольной суммы
аутентификации. Файл spamd.key может содержать любые данные, например такие как
случайные наборы данных собранные из /dev/arandom, как предлогается на его manстранице.
Примечание
В ситуациях, когда непосредственная синхронизация данных spamd невозможна, или вы просто хотите поделиться своими
траплистами с другими людьми, возможен прямой экспорт содержимого в текстовый файл. Формат списка spamd-setup ожидает
обнаружить один адрес на строку, возможно с коментариями, начинающимися с одного или нескольких знаков #. Экспорт
вашего списка текущих трапов в пригодном формате, может быть легко использован в spamdb, grep или ещё где нибудь.
Обнаружение внепорядкового использования MX
В OpenBSD 4.1 spamd получил возможность обнаруживать использование внепорядковых
MX. Связаться со вторичным MX'ом вместо главного - известный спамерский трюк, именно
тот, который мы и ожидаем от рядовых агентов передачи спамерской почты. Другими
словами, если кто-то пытается использовать почтовые обменники не в установленном
порядке, можно утвердительно сказать что это спамеры.
Для нашего домена example.com, главный почтовый сервер имеет адрес 192.0.2.225, а
резервный 192.0.2.224. Добавление параметра запуска -M 192.0.2.224 к spamd будет
означать, что любой хост, пытающийся связаться с 192.0.2.224 посредством SMTP прежде
чем обратиться на основной сервер 192.0.2.225, будет добавлен в локальный список
spamd-greytrap на ближайшие 24 часа.
Работа с сайтами которые не дружат с серыми списками
К сожалению, бывают случаи, когда вам необходимо компенсировать особенности
настроек других сайтов электронной почты. Первое сообщение отосланное вам сайтом,
который ранее с вами не взаимодействовал, при работе серых списков будет отложено на
некоторый случайный промежуток времени, который зависит в основном от интервала
повтора отправителя.
Существуют ситуации, когда даже минимальные задержки могут быть нежелательны.
Например, если у вас имеются редкие клиенты, которые требуют быстрой реакции на их
сообщения, и задержка их сообщений на несколько часов может быть невозможна. Кроме
того, вы можете сталкнуться с неправильно сконфигурированными почтовыми серверами,
которые не повторяют попытку или повторяют её слишком быстро, или прекращают
попытки всего после одного повтора.
Кроме того, некоторые сайты являются достаточно большими и имеют множество SMTP
серверов, что не очень хорошо при использовании серых списков, поскольку не
гарантируется доставка сообщения с того же IP адреса, используемого при ранних
попытках доставки. И хотя эти сайты соответствуют требования повтора, очевидно, это
демонстрирует один из немногих недостатков серых списков.
Одним из способов компенсации данных ситуаций является определение таблиц
локальных белых списков заполняемых из файла в случае перезагрузки. Чтобы
убедиться, что трафик SMTP с адресов находящихся в таблице обрабатывается spamd,
добавьте пропускающее правило позволяющее проход трафика:
table <nospamd> persist file "/etc/mail/nospamd"
pass in log on egress proto tcp from <nospamd> to port smtp
В синтаксисе pre-OpenBSD 4.7, добавьте правило no rdr в верхней части блока
перенаправления и соответствующее правило пропуска позволяющее SMTP трафик с
хостов вашей таблицы nospamd:
no rdr proto tcp from <nospamd> to $mailservers port smtp
pass in log on egress proto tcp from <nospamd> to port smtp
После внесения данных изменений в ваш набор правил, введите адреса, которые
необходимо защитить от перенаправления в файл /etc/mail/nospamd, а затем
перезагрузите набор правил с использованием команды pfctl -f /etc/pf.conf. Затем вы
можете использовать все возможные трюки таблицы <nospamd>, включая замену её
содержимого после редактирования файла nospamd. На самом деле, на такой подход
намекают страницы руководства и примеры файлов конфигурации поставляемые с
последними версиями spamd.
По крайней мере, некоторые сайты с большим количеством исходящих SMTP серверов
публикуют информацию о том, каким хостам позволено передавать почту для их домена
через записи Sender Policy Framework (SPF - структура политики отправителя), как часть
информации DNS5. Для получения записи SPF нашего домена example.com, можно
использовать команду host с опциями -ttxt, подобно следующей:
$ host -ttxt example.com
Команда должна сформировать ответ подобный следующему:
example.com descriptive text "v=spf1 ip4:192.0.2.128/25 -all"
Здесь текст в кавычках - запись SPF для домена example.com. Если вы хотите, чтобы
почта от домена example.com приходила быстро, и вы уверены, что от туда не отправляют
спам и это не спам-релей, выберите диапазон адресов из записи SPF, и добавьте его в
свой файл nospamd. Затем перезагрузите содержимое таблицы <nospamd> из
обновлённого файла.
Советы по борьбе со спамом
При правильном использовании, чёрные списки в совокупности со spamd являются
мощным, точным и эффективным средством борьбы со спамом. Нагрузка на машины
использующие spamd - минимальна. С другой стороны, spamd никогда не будет работать
лучше, чем его самый слабый источник данных, а значит, вы должны строго
контролировать свои журналы и использование белых списков.
Существует возможность запуска spamd в режиме нативного серого списка, без
использования чёрных списков. Более того, некоторые пользователи сообщают, что
режим серого списка является более мощным инструментом, чем конфигурации с чёрными
списками, а иногда и более эффективным чем использование фильтрации контента. Один
из таких отчётов размещённый в списке рассылки openbsd-misc (доступен через
http://marc.info/; ищите на предмет "Followup - spamd greylisting results") утверждал, что
чистая конфигурация серых списков избавила компанию от 95% спама.
Я рекомендую два очень хороших чёрных списка. Один из них, Боба Бека "ghosts of
usenet postings past", список автоматически сгенерированный на компьютерах spamd в
Альбертском университете (University of Alberta, Edmonton, Alberta, Canada).
Установленные Бобом системы spamd, автоматически удаляют ловушку адреса после 24
часов, а это означает, что вы получите весьма низкое число ложных срабатываний.
Количество хостов колеблется в широких пределах и превышает 670000. До сих пор
находясь в официальном тестировании, список был обнародован в январе 2006 года. Он
доступен на http://www.openbsd.org/spamd/traplist.gz. Данный список является частью
последних образцов файлов spamd.conf как черный список uatraps.
5. Записи SPF хранятся
http://www.openspf.org/.
в
зонах
DNS
как
TXT
записи.
Для
получения
детальной
информации
обратитесь
к
Другой список, который я рекомендую - heise.de’s nixspam, который имеет 12 часовой
период истечения и весьма высокую точность. Он так же присутствует в образцах файла
spamd.conf.
Подробную
информацию
о
списке
можно
получить
по
адресу
http://www.heise.de/ix/nixspam/dnsbl_en/.
Как только вы будете удовлетворены своей установкой, попробуйте использовать
местный greytrapping. Это позволит отловить ещё несколько спамеров. Некоторые
ограниченные эксперименты, проведённые в процессе написания этой главы (смотрите
http://bsdly.blogspot.com/, записи начинающиеся с http://bsdly.blogspot.com/2007/07/heyspammer-heres-list-for-you.html), позволяют предположить, что сбор используемых
спамерами адресов из журнала почтового сервера и журналов spamd, или даже
непосредственно из ваших серых списков, для их отправки в тарплист может быть весьма
эффективным. Публикация списка на ограниченных web-страницах используется для того,
чтобы адреса которые вы создали были бы записаны снова и снова роботами сборщиками
адресов, и предоставили вам лучший материал для graytrapping'а, поскольку адреса
спамеров будут всегда в актуальном состоянии.
Глава 7
Очереди, формирование трафика и избыточность
В этой главе рассматриваются две основные темы, каждая из которых или обе вместе,
потенциально, могут радикально изменить работу вашей сети. Общая тема главы сводится
к управлению доступностью ресурсов. В первой части этой главы, мы рассмотрим, как
эффективно использовать подсистему формирования трафика ALTQ для рапределения
полосы пропускания и необходимые для этого политики. Во второй части главы
рассматривается, как добиться, что бы ваши ресурсы были постоянно доступны благодаря
использованию функций избыточности, предлагаемой протоколами CARP и pfsync.
Управление трафиком с помощью ALTQ
ALTQ - это сокращение понятия альтернативного обслуживания, весьма гибкого
механизма управления сетевым трафиком, который существовал в самостоятельном виде
до того, как был включён в PF на OpenBSD1. В OpenBSD ALTQ был интегрирован
Хеннингом Брауэром в код PF начиная с релиза OpenBSD 3.3, включая его конфигурацию
в pf.conf, поскольку имело смысл объединить его именно с пакетным фильтром. Порты PF
для других BSD систем последовали этому примеру, внеся ряд некоторых дополнительных
интеграций ALTQ.
Базовые концепции ALTQ
Управление пропускной способностью имеет много общего с контролем баланса вашей
чековой книжки или обработкой других ресурсов, которые являются дефицитными или
доступны в ограниченных количествах. Обычно, ресурсы доступны с жёстким
ограничением верхних пределов, и вам необходимо выделять ресурсы с максимальной
эффективностью, в соответствии с некоторыми приоритетами, установленными вашими
политиками или спецификациями.
Ядро управления пропускной способностью ALTQ основано на концепции очередей.
Очереди явлются одной из форм буферов для сетевых пакетов. Пакеты будут находиться
в очереди до тех пор, пока они де будут либо удалены, либо отправлены по пути их
следования, в зависимости от критериев относящихся к очереди и с учётом доступной
пропускной способности очереди. Очереди прикреплются к конкретным интерфейсам и
управление пропускной способностью осуществлется на базе интерфейса, с разделением
доступной пропускной способности в определённых вами очередях.
Очереди выделяют определённую часть из полосы пропускания, а иногда и
иерархический приоритет. В данном контексте, приоритет является показателем
предпочтений того, какую очередь необходимо обслуживать в кратчайшие сроки.
Некоторые очереди могут настраиваться в сочетании выделения полосы пропускания и
приоритета. В дальнейшем уточнении, мы рассмотрим некоторые типы очередей, в
которых вы сможете выделить часть пропускной способности очереди в подочереди или
создать очереди в очередях, которые будут претендовать на долю ресурсов родительских
очередей.
После определения очереди вы интегрируете формирование трафиком в ваш набор
правил, переписав свои правила пропуска или правила соответствия для назначения
трафика на указанные очереди.
Примечание
В установках ALTQ, любой трафик который вы явно не назначали в спецфичную очередь, ставится в очередь по умолчанию.
Планировщики очереди или дисциплины очереди
В сети настроенной по умолчанию, без использования очередей в стиле ALTQ, стек TCP/IP
и его подсистема фильтрации обрабатывают пакеты в порядке их поступления на
интерфейс. Это то, что обычно называется дисциплиной первым вошёл-первым вышел
(FIFO). Очереди ALTQ могут быть настроены на совершенно различное поведение, иногда
привнося поразительный эффект. Каждый из трёх алгоритмов расписания (планировщика)
или дисциплины предлагает свои собственные уникальные наборы опций. Эти типы
известны как priq, cbq и hfsc.
•
•
•
•
priq - очереди основанные на приоритетах определяются исключительно с точки
зрения установленных приоритетов в общей полосе пропускани. Для очередей типа
priq допускается диапазон установки приорита от 0 до 15, где большее значение
имеет более приоритетный режим. Пакеты которые соответствуют критериям
высшего приоритета обслуживаются быстрее чем пакеты соответствующие низкому
приоритету.
cbq - очереди основанные на классах определяют постоянную аренду пропускной
способности, как процент от общедоступной или в единицах килобит, мегабит или
гигабит в секунду. Очереди cbq могут разделяться на очереди, которым
назначается приоритет в диапазане от 0 до 7, с тем же условием, что высокий
приоритет обслуживается в первую очередь. Пакеты находтся в очереди пока
доступна полоса пропускания. Для очередей, которые подразделяются на очереди
с приоритетом и ассигнованием пропускной способности, пакеты соответствующие
критериям более высокого приоритета обслуживаются быстрее.
hfsc - дисциплина hfsc использует алгоритм Hierarchical Fair Service Curve
обеспечивающий "справедливое" распределение полосы пропускания для очередей
в иерархии. hfsc позволяет создавать режим очереди с гарантированным
минимальным выделением полосы и жесткими верхними лимитами. Вы можете
ассигнование полосы пропускания, которое может изменяться с течением времени
и приоритет в диапазоне от 0 до 7.
Оба алгоритма и соответствующие установки достаточно сложные и имеют
множество
настраиваемых
параметров.
По
этой
причине,
большинство
практических использований ALTQ придерживается простых типов очередей.
Однако те кто понимает hfsc практически молятся им.
Примечание переводчика
(немного сумбурно получилось, а может так и написано изначально, поэтому приведу более простое описание типов очередей
которое имеется в Википедии:
•
•
•
CBQ Class Based Queueing. Очереди, присоединенные к интерфейсу, создают дерево. Таким образом, у каждой очереди
могут быть дальнейшие дочерние очереди. У каждой очереди могут быть приоритет и присвоенная пропускная
способность. Приоритет, главным образом, управляет временем, за которое пакеты будут отосланы, в то время как
другие будут ждать своей очереди. За счёт этого регулируется пропускная способность.
PRIQ Priority Queueing. У этих очередей не может быть дочерних очередей. Каждой очереди присваивается уникальный
приоритет, в пределах от 0 до 15. Пакеты с высшим номером имеют высший приоритет.
HFSC Hierarchical Fair Service Curve. В родительской очереди определяется суммарная пропускная способность для всех
очередей интерфейса. Указывается общая пропускная способность, предоставляемая провайдером и не зависящая от
скорости сетевого интерфейса. В дочерней очереди эта директива определяет максимальную скорость передачи
информации в битах, которая будет обработана очередью в любой момент. )
Установка ALTQ
Включение ALTQ для использования логики очередей в вашем наборе правил, вам могут
понадобиться дополнительные шаги, зависящие от того какую операционную систему вы
используете.
ALTQ на OpenBSD
На OpenBSD, все поддерживаемые дисциплины очередей собраны в ядра GENERIC и
GENERIC.MP. Для конфигурирования вам необходимо только отредактировать ваш pf.conf.
ALTQ на FreeBSD
На FreeBSD вам необходимо проверить что ваше ядро скомпилировано с поддержкой
опций дисциплин очередей. По умолчанию, ядро FreeBSD GENERIC на включает опцию
ALTQ, и вы можете заметить это просматривая сообщения выведенные при запуске
скрипта /etc/rc.d/pf при включении PF. Соответствующие опции пречислены ниже:
options
options
options
options
options
options
options
ALTQ
ALTQ_CBQ # Class Bases Queuing (CBQ)
ALTQ_RED # Random Early Detection (RED)
ALTQ_RIO # RED In/Out
ALTQ_HFSC # Hierarchical Packet Scheduler (HFSC)
ALTQ_PRIQ # Priority Queuing (PRIQ)
ALTQ_NOPCC # Required for SMP build
Опции ALTQ необходимы для включения ALTQ в ядре. На SMP системах, вам также
необходима опция ALTQ_NOPCC. В зависимости от типа очереди который вы планируете
использовать, вам необходимо включить по меньшей мере один из типов ALTQ_CBQ,
ALTQ_PRIQ, или ALTQ_HFSC. Наконец, вы можете включить технологию уклонения от
перегрузки (congestion-avoidance techniques) Random Early Detection (RED) и RED In/Out
совместно с опциями ALTQ_RED и ALTQ_RIO, соответственно. Обратитесь к хендбуку
FreeBSD для получения информации о компиляции и установки собственного ядра с
данными опциями.
ALTQ на NetBSD
ALTQ был интегрирован в реализацию PF NETBSD 4.0 и поддерживается в NetBSD 4.0 и
более поздних релизах. Ядро NetBSD GENERIC используемое по умолчанию не включает
поддержки опций связанных с ALTQ. Однако, файл конфигурации GENERIC поставляется
со всеми соответствующими вариантами требуемых опций, закомментированными для
простоты включения. Ниже приведены основные параметры ядра:
options
options
options
options
options
ALTQ # Manipulate network interfaces' output queues
ALTQ_CBQ # Class-Based Queueing
ALTQ_HFSC # Hierarchical Fair Service Curve
ALTQ_PRIQ # Priority Queueing
ALTQ_RED # Random Early Detection
Опции ALTQ необходимы для включения ALTQ в ядре. В зависимости от типа очереди
который вы планируете использовать, вам необходимо включить по меньшей мере один из
типов ALTQ_CBQ, ALTQ_PRIQ, или ALTQ_HFSC.
Использование ALTQ требует компиляции PF в ядро. Загружаемые модули ядра связанные
с PF не поддерживают функционал ALTQ. Для получения более актуальной информации
следует обратиться к документации PF для NetBSD по адресу http://www.netbsd.org/
Documentation/network/pf.html.
Установка очередей
Сейчас мы будем рассматривать примеры установки трёх различных типов очередей
ALTQ: основанных на приоритете, основанных на классах и HFSC.
Основной синтаксис PF для очередей ALTQ похож на следующий:
altq on interface type [options ... ] main_queue { sub_q1, sub_q2 ..}
queue sub_q1 [ options ... ]
queue sub_q2 [ options ... ] { subA, subB, ... }
[...]
pass [ ... ] queue sub_q1
pass [ ... ] queue sub_q2
Обратите внимание, что очереди cbq и hfsc могут иметь несколько уровней подочередей.
Очереди priq можно назвать плоскими, поскольку они имеют только очередь одного
уровня. Мы будем рассматривать специфику синтаксиса для каждого типа в следующих
разделах.
ВРЕЗКА: ЧТО ТАКОЕ ВАША ОБЩАЯ ПРОПУСКНАЯ СПОСОБНОСТЬ?
Фактически, для очередей может быть трудно определить полезную пропускную способность конкретного интерфейса. Если
вы не укажете общую пропускную способность, она будет использована при расчёте ассигнований. Однако, некоторые типы
интерфейсов не гарантируют предоставления верной информации о фактическом значении полосы пропускания. Одним из
распространённых примеров такого расхождения явлется 100 Мбит Ethernet-интерфейс, в приложении к линии DSL, которая,
фактически позволяет только 8Мбит дл скачивания и 1 МБит для загрузки.* Ethernet-интерфейс может сообщить вам о
100Мбитах пропускной способности, без учёта значений DSL.
Поэтому, и как правило, имеет смысл установить общую пропускную способность для фиксированного значения. К
сожалению, используемое значение не будет именно тем, о котором вам говорит поставщик канала. всегда присутствуют
некоторые накладные расходы, меняющиеся в небольших пределах в зависимости от технологий и реализации канала. В
типовых каналах TCP/IP Ethernet, накладные расходы достаточно низкие. TCP/IP через ATM накладные расходы будут гораздо
выше и могут составлять почти 20%. Если информация о пропускной способности не предоставлена поставщиком канала, вам
придётся сделать обоснованное предположение её начального значения. В любом случае, вы должны остро осознавать, что
доступная общая пропускная способность никогда не превышает пропускную способность самого слабого линка (канала) в
вашем сетевом маршруте.
Очереди поддерживаются только для исходящих соединений системы. При планировании управления полосой пропускания,
вы должны рассматривать фактическую полезную пропускную способность соответствующую самому узкому линку на пути
соединения, даже если ваши очереди настроены на различных интерфейсах.
* Эти цифры реальны сейчас. через несколько лет они могут показаться странными, если не смешными.
Очереди основанные на приоритете
Базовые концепции очереди основанной на приоритете (priq) довольно просты, и
возможно даже, являются самыми простыми для понимания. Общая полоса пропускания
распределяется в основную очередь, и главное значение имеет приоритет трафика. Вы
определяете значение приоритета в диапазоне от 0 до 15, где наиболее высокое значение
соответствует более приоритетному трафику.
Практический пример
В целях практического примера обратимся к Даниэлю Хартмееру. Он обнаружил простой,
но весьма эффективный способ улучшения пропускной способности для собственной сети
используя ALTQ. Как и многие другие, Даниэль использовал домашнее соединение по
ассиметричной линии с достаточно низкой пропускной способностью, и чувствовал
сильное желание улучшить использование доступной полосы пропускания. Кроме того,
когда линия практически полностью загружена, начинают появляться некоторые
странности. Одна из особенностей указывающая на возможности улучшения - входящий
трафик (скачивание, входящая почта и пр.) замедляется диспропорционально всякий раз,
когда возникает исходящий трафик - более чем можно было бы объяснить передачей
сырых данных. Это возвращает нас к базовым особенностям TCP.
Когда отсылается пакет, отправитель ожидает подтверждения (в виде пакета ACK) от
принимающей стороны, и ждёт его прибытия некоторое, определённое время. Если ACK не
прибывает в течение заданного интервала времени, отправитель полагает, что пакет не
был получен и отправляет пакет повторно. Проблема состоит в том, что в настройках по
умолчанию, пакеты обслуживаются последовательно, по мере их поступления на
интерфейс. Это неизбежно означает, что пакеты ACK, практически не имеющие полезной
нагрузки, будут ожидать в очереди, в то время как передаются большие пакеты данных.
Формируется гипотеза: если маленьким пакетам ACK, практически не содержащим
данных, удастся проскользнуть между большими пакетами данных, это приведёт к более
эффективному использованию доступной пропускной способности. Самый простой способ
практической реализации и проверкии теории состоял в том, чтобы создать две очереди с
разными приоритетами и и интегрировать их в набор правил. Следующие строки
показывают пример соответствующей части набора правил.
ext_if="kue0"
altq on $ext_if priq bandwidth 100Kb queue { q_pri, q_def }
queue q_pri priority 7
queue q_def priority 1 priq(default)
pass out on $ext_if proto tcp from $ext_if queue (q_def, q_pri)
pass in on $ext_if proto tcp to $ext_if queue (q_def, q_pri)
Здесь, очередь основанная на приоритете устанавливается на внешнем интерфейсе с
двумя подчинёнными очередями. Первая подочередь, q_pri, имеет большее значение
приоритета - значение 7; другая подочередь (q_def) имеет значительно более низкий
приоритет - значение 1. Этот, казалось бы весьма простой набор правил работающий за
счёт использования ALTQ обрабатывает очереди с различными приоритетами. Как только
соединение назначается в основную очередь, ALTQ проверяет тип каждого пакета по полю
типа сервиса (ToS). Пакеты ACK содержат бит задержки ToS установленный в низкое
значение (low), который говорит о том, что отправитель хотел скорейшей доставки
пакета. Когда ALTQ видит пакет с низкой задержкой (low-delay), и доступны очереди с
различными приоритетами, он назначает пакет в высокоприоритетную очередь. Это
означает, что пакеты ACK сразу передаются в очередь с более низким приоритетом и
доставляются быстрее, а это, в свою очередь означает, что пакеты данных обслуживаются
быстрее.
Конечным результатом является то, что такая конфигурация обеспечивает лучшую
производительность чем чистая конфигурация FIFO на том же оборудовании и с той же
полосой пропускания2.
Использование правила match для назначения очереди
В предыдущем примере, набор правил был построен традиционным образом, с
назначением очереди как части пропускающего правила. Тем не менее это не
единственный способ назначения очереди. Использование правил соответствия (match)
(доступных в OpenBSD 4.6 и старше) позволяет легко модифицировать этот простой
режим приоритетных очередей в существующем наборе правил.
Если вы работаете основываясь на примерах глав 3 и 4, вероятно, что ваш набор правил
уже включает правило match, которое используется для nat-to исходящего трафика. Если
вы хотите использовать очереди основанные на приоритетах в своем наборе правил, вы
можете начать с добавления определения очереди и внесения некоторох незначительных
корректировок в исходящие правила match.
Начните с определения очереди из предыдущего примера, и настройки общей
пропускной способности в соответствии с локальными условиями как в следующем
примере:
altq on $ext_if priq bandwidth $ext_bw queue { q_pri, q_def }
queue q_pri priority 7
queue q_def priority 1 priq(default)
Это позволяет определить макрос ext_bw для распределения полосы пропускания на все
очереди. Самый простой и быстрый способ интеграции очередей в набор правил
заключается в редактировании исходящего правила match примерно в следующем виде:
match out on $ext_if from $int_if:network nat-to ($ext_if) queue (q_def, q_pri)
Перезагрузите ваш набор правил, и приоритетные очереди будут применены ко всему
трафику инициированному в локальной сети. вы можете использовать команду systat для
получения живого обзора назначения трафика очередям.
$ sudo systat queues
Результат выглядит примерно так:
2 users Load 0.39 0.27 0.30 Fri Apr 1 16:33:44 2011
QUEUE
q_pri
q_def
BW SCH
priq
priq
PR PKTS BYTES DROP_P DROP_B QLEN BORROW SUSPE P/S B/S
7 21705 1392K
0
0
0
12 803
12138 6759K
0
0
0
9 4620
Рассматривая цифры в колонках PKTS (пакеты) и BYTES, вы чётко видите, что очереди
работают именно так, как было задумано. Очередь q_pri обрабатывает довольно
значительное количество пакетов в объёме данных, как собственно и ожидалось. Пакеты
ACK не занимают много места. С другой стороны, трафик назначенный в очередь q_def
содержит больше данных в каждом пакете, а цифры, по существу, показывают обратное
соотношение числа пакетов к размеру данных по сравнению с очередью q_pri.
Примечание
systat является программой присущей всем BSD системам, а версия используемая в OpenBSD предлагает несколько вариантов
представления информации, имеющей отношение к PF, которые отсутствуют в systat прочих систем. Мы вернёмся к
использованию systat в следующей главе. В тоже время, вам следует изучить руководство по работе с этой программой и
попробовать её. Это весьма полезный инструмент для знакомства с вашей системой.
Распределение полосы пропускания для небольших сетей
на основе классов
Максимально производительная сеть в основном работает хорошо. Однако, вы можете
обнаружить, что у вашей сети существуют другие потребности. Например, для некоторых
видов трафика -почты в частности и других необходимых сервисов, может быть важно
достичь базовой пропускной способности в любой момент времени, в то время как для
других сервисов, типа P2P, должны быть установлены определённые ограничения на
потребление пропускной способности.
Для решения такого рода требований или концепций, дисциплина очереди на основе
классов (CBQ) предлагает намного больше возможностей. Чтобы проиллюстрировать, как
используется CBQ, мы перейдём к следующему примеру, который описрается на набор
правил из предыдущих глав. Это небольшая локальная сеть, и нам необходимо, чтобы
пользователи в локальной сети подключали к заранее установленному набору сервисов за
пределами своей сети, и кроме того, имели доступ к локальному web-серверу локальной
сети.
Определение очереди
Здесь, все очереди устанавливаются на внешнем интерфейсе выхода в Интернет.
Главным образом, этот подход имеет смысл, поскольку пропускная способность будет
более ограничена на внешнем интерфейсе, чем на локальной сети. Однако, в принципе,
распределение очередей и балансировки трафика могут быть сделаны на любом
интерфейсе.
Следующий пример настройки включает очереди CBQ для общей пропускной способности
2Мбит с шестью подочередями.
altq on $ext_if cbq bandwidth 2Mb queue { main, ftp, udp, web, ssh, icmp }
queue main bandwidth 18% cbq(default borrow red)
queue ftp bandwidth 10% cbq(borrow red)
queue udp bandwidth 30% cbq(borrow red)
queue web bandwidth 20% cbq(borrow red)
queue ssh bandwidth 20% cbq(borrow red) { ssh_interactive, ssh_bulk }
queue ssh_interactive priority 7 bandwidth 20%
queue ssh_bulk priority 0 bandwidth 80%
queue icmp bandwidth 2% cbq
Подочередь main имеет 18% пропускной способности и определяется как очередь по
умолчанию. Это означает, что любой трафик, который соответствует правилу pass, но
явно не назначенный в остальные очереди, попадает сюда. Ключевые слова borrow и red
означают, что очередь может "позаимствовать" пропускную способность от своей
родительской очереди, в то время когда система будет пытаться избежать перегрузки,
используя алгоритм RED. Другие очереди, более или менее следуют той же схеме до
подочереди ssh, которая сама имеет две подочереди с отдельными приоритетами. Здесь
мы наблюдаем вариации на примере приоритетов ACK. Массовые передачи SSH, типичные
для передачи файлов SCP, передаются с ToS указывающим пропускную способность, в то
время, как интерактивный трафик SSH имеет флаг ToS установленный в указание низкой
задержки (low delay), и пропускается прежде массовых передач. Интерактивный трафик,
по всей вероятности, будет иметь меньшие затраты полосы пропускания и получит
меньшую долю пропускной способности, но, одновременно с этим и большие льготы,
поскольку он имеет более высокий приоритет. Кроме того данная схема позволяет
повысить скорость передачи файлов SCP, поскольку пакеты ACK для передачи SCP будут
поставлены в подочередь с более высоким приоритетом.
Наконец, мы используем icmp очередь, которая резервирует 2% полосы пропускания от
верхнего уровня. Это гарантирует минимальную пропускную способность для ICMP
трафика, который соответствует правилу pass, но не соответствует критериям для
назначения в другие очереди.
Набор правил
Для того, чтобы достич желаемого результата, мы используем правила pass, которые
указывают какой трафик назначается в очереди и их критерии:
set skip on { lo, $int_if }
pass log quick on $ext_if proto tcp to port ssh queue (ssh_bulk, ssh_interactive)
pass in quick on $ext_if proto tcp to port ftp queue ftp
pass in quick on $ext_if proto tcp to port www queue http
pass out on $ext_if proto udp queue udp
pass out on $ext_if proto icmp queue icmp
pass out on $ext_if proto tcp from $localnet to port $client_out
Правила для ssh, ftp, www, udp и icmp назначают трафик на соответствующие очереди.
Последнее правило пропускает весь прочий трафик из локальной сети направляя его в
очередь main используемую по умолчанию.
Формирование трафика на основе HFSC
Простые планировщики, которые мы рассматривали до сих пор, могут быть достаточно
эффективными в некоторых установках, однако сетевые администраторы с высокими
требования к формированию трафика склонны искать большей гибкости чем та, которую
позволяют очереди основанные на приоритетах или на классах. После только что
описанного введения в очереди, как бы это не звучало, я могу сказать, что есть режим с
гибким распределением пропускной способности, гарантированными нижними и верхними
границами полосы пропускания доступной для каждой очереди и переменным
ассигнованием полосы в течение длительного времени - и только это позволит начать
формирование трафика когда это реально необходимо.
Алгоритм очередей HFSC (hfsc в терминологии pf.conf) предлагает все эти возможности,
но за дополнительную гибкость придётся заплатить: установка будет чуть более сложной,
в отличии от прочих типов, а настройки вашей установки (в дальнейшем я буду
использовать слово "развёртывание" - п.п.) для достижения оптимального результата
могут превратится в занимательный процесс.
Определение очереди
Работая с той же конфигурацией, которую
определение этой очереди в начало файла pf.conf:
мы
использовали
раньше,
вставим
altq on $ext_if bandwidth $ext_bw hfsc queue { main, spamd }
queue main bandwidth 99% priority 7 qlimit 100 hfsc (realtime 20%, linkshare 99%) \
{ q_pri, q_def, q_web, q_dns }
queue q_pri bandwidth 3% priority 7 hfsc (realtime 0, linkshare 3% red )
queue q_def bandwidth 47% priority 1 hfsc (default realtime 30% linkshare 47% red)
queue q_web bandwidth 47% priority 1 hfsc (realtime 30% linkshare 47% red)
queue q_dns bandwidth 3% priority 7 qlimit 100 hfsc (realtime (30Kb 3000 12Kb), \
linkshare 3%)
queue spamd bandwidth 0% priority 0 qlimit 300 hfsc (realtime 0, upperlimit 1%, \
linkshare 1%)
Как вы можете видеть, определение очереди HFSC принимает несколько другие
параметры, в отличии от простых дисциплин. Мы начнём с этой, сравнительно небольшой
иерархии, путём разделения очереди верхнего уровня на две части. На следующем
уровне разобъём основную очередь на несколько подочередей, каждая из которых имеет
определённый приоритет. Все подочереди имеют заданное значение realtime; это
минимальная гарантированная полоса пропускания выделенная очереди. Опциональная
установка upperlimit определяет набор жёстких верхних пределов распределения полосы
пропускания очереди. Параметр linkshare устанавливает распределение для очереди,
которое будет доступно при её перегрузке; то есть, это начало её распределения в qlimit.
В случае возникновения заторов, каждая очередь по умолчанию имеет пул из 50 слотов,
лимит очереди (qlimit), для сохранения пакетов в период когда они не могут быть
немедленно переданы. В нашем примере очереди верхнего уровня main и spamd имеют
большие, чем заданные по умолчанию, пулы установленные их qlimit; 100 для main и 300
для spamd. Значительное повышение размеров очередей означает, что мы немного
понизим потерю пакетов при достижение трафиком установленных лимитов, но это так же
означает, что когда формирование трафика отваливается, увеличивается время ожидания
соединения, что в конечном счёте связано с большими размерами пулов.
Иерархия очереди использует два знакомых приёма для эффективного использования
доступной полосы пропускания:
•
•
Используются вариации высокого и низкого приоритетов показанные в ранних
примерах с читым приоритетом
Мы повысили скорость практически всего остального трафика (и, безусловно, webтрафика, имеющего в нашем случае основной приоритет) путём выделения
небольшой, но гарантированной чести полосы пропускания для сервиса обзора
имён. Для очереди q_dns мы установили значение realtime c лимитом времени после 3000 миллисекунд значение realtime снижается до 12Кб. Это может быть
полезно для повышения скорости соединений которые передают большую часть
полезной нагрузки в начальной фазе.
Набор правил
Следующий шаг заключается в увязывании вновь созданной очереди в набор правил.
Если предположить, что у вас уже существует фильтрующий режим, привязка будет на
удивление простой и включает только добавление нескольких простых правил match:
match
match
match
match
match
out
out
out
out
out
on
on
on
on
on
$ext_if
$ext_if
$ext_if
$ext_if
$ext_if
from $air_if:network nat-to ($ext_if) queue (q_def, q_pri)
from $int_if:network nat-to ($ext_if) queue (q_def, q_pri)
proto tcp to port { www https } queue (q_web, q_pri)
proto { tcp udp } to port domain queue (q_dns, q_pri)
proto icmp queue (q_dns, q_pri)
Здесь, правила match ещё раз используют трюк с ускорением пакетов ACK за счёт
назначения очередей с высоким и низким приоритетом, аналогично ранним примерам
использующим чистые приоритеты. Единственное исключение - когда мы назначаем
трафик на очередь с самым низким приоритетом, мы реально не заботимся о каком бы то
ни было ускорении:
pass in log on egress proto tcp to port smtp rdr-to 127.0.0.1 port spamd queue spamd
Это намеренное замедление спамеров на их пути к spamd. При использовании
иерархической системы очередей, systat так же показывает очереди и их трафик в виде
иерархии:
2 users Load 0.22 0.25 0.25 Fri Apr 1 16:43:37 2011
QUEUE
root_nfe0
main
q_pri
q_def
q_web
q_dns
spamd
BW
20M
19M
594K
9306K
9306K
594K
0
SCH
hfsc
hfsc
hfsc
hfsc
hfsc
hfsc
hfsc
PRIO
0
7
7
7
0
PKTS
0
0
1360
158
914
196
431
BYTES
0
0
82284
15816
709845
17494
24159
DROP_P DROP_B QLEN BORROW SUSPEN P/S
0
0
0
0
0
0
0
0
0
0
0
11
0
0
0
0.2
0
0
0
50
0
0
0
3
0
0
0
2
B/S
0
0
770
11
61010
277
174
Корневая очередь (root) указывает присоединение к физическому интерфейсу - nfe0 и
root_nfe0 в данном случае. main и её подочереди q_pri, q_def, q_web и q_dns
отображаются с их назначенной пропускной способностью, количеством байт и числом
прошедших пакетов. Колонки DROP_P и DROP_B показывают, соответственно,
количество сброшенных пакетов и байт, если мы будем вынуждены сбрасывать пакеты на
данном этапе. Последние две колонки показывают живое обновление пакетов в секунду и
байт в секунду, соответственно.
Очереди для серверов в зоне DMZ
Возвращаясь к главе 5, вспомним, что, мы установили сеть с одним шлюзом, а все
сервисы, видимые из вне сконфигурировали на отдельной сети DMZ. Таким образом, весь
трафик на сервера, как из Интернет так и из внутренней сети должен проходить через
шлюз. Схема сети показана на рисунке 7-1, и идентична рисунку 5-2.
Используя в качестве отправной точки набор правил созданный в главе 5, мы будем
добавлять некоторые очереди для оптимизации наших сетевых ресурсов. Физическая и
топологическая схема сети при это не изменится.
Скорее всего, узким местом в данной сети станет пропускная способность в соединении
между внешним интерфейсом шлюза и Интернетом в целом. Конечно, пропускная
способность в прочих местах нашей сети не бесконечна, однако доступная полоса
пропускания на любом интерфейсе локальной сети будет меньшим ограничивающим
фактором чем пропускная способность доступная для общения с внешним миром. Для
сервисов, которые будут доступны с наиллучшей производительностью мы должны
настроить очереди с требуемой шириной полосы пропускания предоставляемые
желательному трафику.
В нашем примере, что вполне вероятно, пропускная способность интерфейса DMZ
составляет 100Мбит или 1Гбит, в то время как фактическая пропускная способность для
соединений со стороны локальной сети значительно меньше. Это соображение
отображено в наших определениях очереди, где можно ясно видеть, что фактическая
пропускная способность доступная для внешнего трафика является основным
ограничением в установке очереди.
Рисунок 7-1: Сеть с DMZ
total_ext = 2Mb
total_dmz = 100Mb
altq on $ext_if cbq bandwidth $total_ext queue { ext_main, ext_web, ext_udp, \
ext_mail, ext_ssh }
queue ext_main bandwidth 25% cbq(default borrow red) { ext_hi, ext_lo }
queue ext_hi priority 7 bandwidth 20%
queue ext_lo priority 0 bandwidth 80%
queue ext_web bandwidth 25% cbq(borrow red)
queue ext_udp bandwidth 20% cbq(borrow red)
queue ext_mail bandwidth 30% cbq(borrow red)
altq on $dmz_if cbq bandwidth $total_dmz queue { ext_dmz, dmz_main, dmz_web, \
dmz_udp, dmz_mail }
queue ext_dmz bandwidth $total_ext cbq(borrow red) queue { ext_dmz_web, \
ext_dmz_udp, ext_dmz_mail }
queue ext_dmz_web bandwidth 40% priority 5
queue ext_dmz_udp bandwidth 10% priority 7
queue ext_dmz_mail bandwidth 50% priority 3
queue dmz_main bandwidth 25Mb cbq(default borrow red) queue { dmz_main_hi, \
dmz_main_lo }
queue dmz_main_hi priority 7 bandwidth 20%
queue dmz_main_lo priority 0 bandwidth 80%
queue dmz_web bandwidth 25Mb cbq(borrow red)
queue dmz_udp bandwidth 20Mb cbq(borrow red)
queue dmz_mail bandwidth 20Mb cbq(borrow red)
Обратите внимание, что total_ext определяет распределение ограничения пропускной
способности для всех очередей которым доступна пропускная способность для внешних
соединений. Для использования новой инфраструктуры очередей, нам необходимо внести
некоторые изменения в правила фильтрации. Имейте в виду, что любой трафик, который
вы явно не назначаете в определённую очередь, попдает в очереди по умолчанию для
интерфейса. Следовательно, это важно учитывать при настройке ваших правил
фильтрации и определении очереди актуального трафика в вашей сети.
Основная часть правил фильтрации, после добавления очередей, может выглядеть
примерно так:
pass in on $ext_if proto { tcp, udp } to $nameservers port domain \
queue ext_udp
pass in on $int_if proto { tcp, udp } from $localnet to $nameservers \
port domain
pass out on $dmz_if proto { tcp, udp } to $nameservers port domain \
queue ext_dmz_udp
pass out on $dmz_if proto { tcp, udp } from $localnet to $nameservers \
port domain queue dmz_udp
pass in on $ext_if proto tcp to $webserver port $webports queue ext_web
pass in on $int_if proto tcp from $localnet to $webserver port $webports
pass out on $dmz_if proto tcp to $webserver port $webports queue ext_dmz_web
pass out on $dmz_if proto tcp from $localnet to $webserver port $webports \
queue dmz_web
pass in log on $ext_if proto tcp to $mailserver port smtp
pass in log on $ext_if proto tcp from $localnet to $mailserver port smtp
pass in log on $int_if proto tcp from $localnet to $mailserver port $email
pass out log on $dmz_if proto tcp to $mailserver port smtp queue ext_mail
pass in on $dmz_if from $mailserver to port smtp queue dmz_mail
pass out log on $ext_if proto tcp from $mailserver to port smtp \
queue ext_dmz_mail
Обратите внимание, что, в очереди будет назначаться только трафик, который будет
проходить либо через интерфейс DMZ или внешний интерфейс. В данной конфигурации,
без внешнего доступа к внутренним сервисам локальной сети, очереди на внутреннем
интерфейсе не имеют большого смысла, поскольку вероятно, что часть нашей сети имеет
меньшие ограничения на пропускную способность.
Использование ALTQ для управления нежелательным
трафиком
До сих пор мы фокусировались на очередях, как способе позволяющем убедиться, что
конкретные виды трафика обрабатываются настолько эффективно, насколько это
возможно с учётом условий вашей сетевой среды и вне её. Теперь мы рассмотрим два
примера которые представляют несколько другой подход к выявлению и обработке
нежелательного трафика. Эти примеры демонстрируют некоторые трюки связанные с
использованием очередей, которые можно использовать создать оборону от
злоумышленников.
Перегрузка на крошечные очереди
Вспомните раздел "Отбиваемся от громил" (стр. 86), где мы использовали сочетание
опций отслеживания состояний и прегррузку правил для заполнения таблицы адресов
подлежащих специальной обработке. Специальная обработка которую мы рассматривали
в главе 6 состояла в отключении всех соединений, однако, вместо этого, существует
возможность назначить трафик перегрузки на конкретные очереди.
Рассмотрим правило из предыдущих примеров рапредения полосы пропускания на основе
классов:
pass log quick on $ext_if proto tcp to port ssh flags S/SA \
keep state queue (ssh_bulk, ssh_interactive)
Мы можем добавить опцию отслеживания состояния подобную следующей:
pass log quick on $ext_if proto tcp to port ssh flags S/SA \
keep state (max-src-conn 15, max-src-conn-rate 5/3, \
overload <bruteforce> flush global) queue (ssh_bulk, ssh_interactive)
Теперь мы можем немного уменьшить одну из очередей:
queue smallpipe bandwidth 1kb cbq
Затем назначим трафик злоумышленников на очередь с малой пропускной способностью
используя следующие правила:
pass inet proto tcp from <bruteforce> to port $tcp_services queue smallpipe
Кроме того, будет полезно дополнить эти правила таблицей истечения записей, как было
описано в разделе "Чистка таблиц с помощью pfctl" на странице 89.
Задание очереди на основе отпечатка операционной
системы
Глава 6 охватывала несколько способов использования spamd, позволяющих сократить
спам. Если запуск spamd не подходит для вашей среды, вы можете использовать очереди
и набор правил основанный на общих знаниях о том, что машины используемые для
рассылки спама, скорее всего, работают на той или иной операционной системе.
PF имеет довольно надёжный механизм снятия отпечатка (fingerprinting) операционной
системы, который позволяет определить операционную систему на другом конце
соединения, базируясь на характеристиках SYN пакетов передаваемых на начальной
стадии установки соединения. Это может стать простой заменой spamd, при условии, что
вы определили, что легитимная почта от систем работающих на данной ОС крайне
маловероятна:
pass quick proto tcp from any os "Windows" to $ext_if port smtp queue smallpipe
В соответствии с данным правилом, трафик электронной почты исходящий от хостов
использующих тип указанной операционной системы получит ширину полосы пропускания
не более 1кбит, без возможности заимствования.
Избыточность и отказоустойчивость: CARP и pfsync
Высокая надёжность и непрерывность обслуживания - одновременно маркетинговые
словечки и желанная цель для IT специалистов и сетевых администраторов. Для
достижения этой осоннаной необходимости и решения связанных с ними проблем были
созданы CARP и pfsync, добавленные в функционал OpenBSD 3.5.
Common Address Redundancy Protocol (CARP) был разработан в качестве не связанной
патентами альтернативы Virtual Router Redundancy Protocol (VRRP), который
просуществовал достаточно долго, чтобы стать санкционированным IETF стандартом, хотя
его патентные проблемы так и не были разрешены 3. Одна из главных целей CARP
является обеспечение поддержки нормального функционирования сети, даже при
нарушении работы брандмауэра или другого сервиса, либо в период сервисного
обслуживания оборудования (например обновления). В дополнение к CARP, был создан
протокол pfsync предназначенный для управления синхронизацией состояний PF между
резервными узлами пакетных фильтров или шлюзами. Оба протокола предназначены для
создания резервной сети с возможностью автоматической отказоустойчивости.
CARP основан на создании группы машин включающей одну главную и одну или более
резервных, работающих с общим IP адресом. Если главная машина падает, одна из
резервных машин наследует её IP адрес. Передача управления одной машины CARP к
другой осуществляется с проверкой подлинности, по существу используя общий пароль. В
случае брандмауэров PF, протокол pfsync может использоваться для синхронизации, и
если настройки pfsync были проведены корректно, активные соединения будут переданы
без заметных перерывов.
В сущности pfsync является виртуальным сетевым интерфейсом, специально
разработанным для синхронизации сведений о состояниях между брандмауэрами PF. Его
интерфейсы назначаются на физические интерфейсы с использованием ifconfig.
настоятельно рекомендуется устанавливать pfsync на отдельные сети (или даже VLAN),
даже если технически возможно одновременно передавать трафик pfsync с прочим
трафиком на регулярном интерфейсе. Основная причина этой рекомендации связана с
тем, что сам pfsync не производит никакой проверки подлинности для партнёров
синхронизации, и гарантировать корректную синхронизацию вы можете только
использованием специальных интерфейсов для трафика pfsync.
Спецификация проекта: Резервированная пара шлюзов
Для иллюстрации реализации отказоустойчивости с CARP и pfsync, мы начнём с примера
сети имеющей один шлюз для связи с внешним миром. Переконфигурирование сети будет
преследовать следующие цели:
•
•
•
Сеть должна работать так же как и прежде.
Необходимо достичь лучшую доступность сервисов без заметных простоев.
Сеть должна обеспечивать изящный переход на резервный ресурс без прерывания
активных соединений.
Начнём с относительно простой сети описанной в главе 3, которая изображена на
рисунке 7-2.
Рисунок 7-2. Сеть с единственным шлюзом
Заменим единственный шлюз резервированной парой шлюзов, соединённых общей
частной сетью для обмена информацией о состояниях путём использования pfsync.
Должно получиться нечто похожее на рисунок 7-3.
Рисунок 7-3 Сеть с избыточным шлюзом.
Обратите внимание, что адреса CARP - виртуальные адреса. Если у вас есть доступ к
консоли всех машин в группе CARP, вы захотите назначить IP адреса физического
интерфейса. С помощью уникального IP-адреса для каждого физического интерфейса, вы
получите возможность взаимодействия с хостами и будете абсолютно уверены с какой
машиной взаимодействуете. Без IP адреса, назначенного физическому интерфейсу, вы не
смогли б связаться с резервными шлюзами (кроме как с хостов в сети которым назначены
адреса на физические интерфейсы), до тех пор, пока они не станут главными в грруппе
резервирования и не примут на себя виртуальные IP адреса.
По соглашению, IP адрес присвоенный физическому интерфейсу будет принадлежать той
же подсети, что и виртуальный общий IP адрес. По умолчанию, ядро будет пытаться
присвоить CARP адрес физического интерфейса который уже сконфигурирован с адресом
в той же подсети что и CARP адрес. Вы можете явно выбрать отличный интерфейс
используя опцию carpdev в команде ifconfig для настройки интерфейса CARP.
ПРЕДУПРЕЖДЕНИЕ
Когда вы переконфигурируете вашу сеть и адрес шлюза по умолчанию изменяется с закреплённого на определённом интерфейсе
и хосте на виртуальный адрес, практически невозможно избежать временной потери связи.
Установка CARP
Большая часть установки CARP заключается в установке кабельного соединения (в
соответствии со схемой вашей сети), установке значений sysctl и использовании команды
ifconfig. Кроме того, на некоторых системах, вам необходимо проверить, что ваше ядро
скомпилировано с поддержкой необходимых устройств.
Проверка параметров ядра
На OpenBSD, устройства CARP и pfsync присутствуют в конфигурации ядер GENERIC и
GENERIC.MP. Если вы работаете с ядром, в котором вы отключили эти опции, потребуется
переконфигурировать ядро. Пользователи FreeBSD должны проверить, что ядро
скомпилировано с устройствами CARP и pfsync, поскольку используемое по умолчанию,
ядро GENERIC не поддерживает эти параметры. Обратитесь к руководству по FreeBSD для
получения информации по сборке и установке ядра. Пользователи NetBSD, так же должны
проверить, что ядро скомпилировано с поддержкой псевдо-устройства CARP. Ядро
GENERIC используемое по умолчанию не включает поддержку CARP. Однако, вы
обнаружите соответствующую закоментированную строку в конфигурационном файле
GENERIC, добавленную, для простоты подключения данной опции. В данное время NetBSD
ещё не поддерживает pfsync, что связано с неразрешённым вопросами в протоколе
нумерации, по крайней мере на момент написания этой главы.
Настройка значений sysctl
На всех CARP-совместимых системах, основные функции регулируются кучкой
переменных sysctl. Одна из главных, net.inet.carp.allow, включена по умолчанию. На
типовой системе OpenBSD, вы увидите следующий вывод:
$ sysctl net.inet.carp.allow
net.inet.carp.allow=1
Это говорит о том, что ваша система подготовлена к использованию CARP.
Если ваше ядро не сконфигурировано с CARP, данная команда предоставит вывод типа:
sysctl: unknown oid 'net.inet.carp.allow' на FreeBSD или sysctl: third level name
'carp' in 'net.inet.carp.allow' is invalid на NetBSD.
Используйте следующую команду sysctl для просмотра всех переменных связанных с
CARP:
$ sysctl net.inet.carp
net.inet.carp.allow=1
net.inet.carp.preempt=0
net.inet.carp.log=2
Примечание
В FreeBSD вы столкнётесь с переменной net.inet.carp.suppress_preempt, которая имеет статус 'только чтение' и показывает
существование возможности упреждения. В системах с кодовой базой CARP основанной на OpenBSD 4.2 или более ранней, вы
можете обнаружить переменную net.inet.carp.arpbalance, которая используется для включения балансировки CARP ARP
предлагающей несколько ограниченные возможности балансировки нагрузки для хостов локальной сети.
Для включения отказоустойчивости между шлюзами в планируемой установке, нам
необходимо установить переменную net.inet.carp.preempt:
$ sudo sysctl net.inet.carp.preempt=1
Установка переменной net.inet.carp.preempt означает, что на хостах имеющих более
одного сетевого интерфейса, например таких, как наш шлюз, все интерфейсы CARP будут
находиться между основным и резервным. Эта установка должна быть одинаковой на всех
хостах в группе CARP. Данную настройку необходимо повторить на всех хостах.
Переменная net.inet.carp.log устанавливает уровень отладки для журналирования CARP.
Диапазон возможных значений - от 0 до 7. По умолчанию используется уровень 2, что
означает внесение в журнал только изменения состояний CARP.
Настройка сетевого интерфейса с использованием ifconfig
Рассматривая схему сети, вы можете заметить, что локальная сеть использует адреса
диапазона 192.168.12.0, в то время как интерфейс выхода в Интернет находится в сети
192.0.2.0. С помощью этих диапазонов адресов и имея в виду интерфейс CARP по
умолчанию, можно сообразить, какие команды необходимы для создания виртуальных
интерфесов. Кроме обычных сетевых параметров, интерфейсы CARP требуют один
дополнительный параметр: идентификатор виртуального хоста (vhid), который
однозначно идентифицирует интерфейсы для общих виртуальных IP адресов.
Предупреждение
vhid представляет собой 8-битную величину, которая должна быть установлена в значение уникальное в пределах
широковещательного домена. Неверная настройка значения vhidможет привести к ряду различных сетевых проблем, которые
трудно поддаются отладке. Существует неподтверждённая информация, что системы избыточности и балансировки нагрузки
основанные на VRRP используют идентификационную схему похожую на схему CARP, таким образом, могут возникать коллизии
ID с некоторыми связанными системами, что приведёт к нарушению работы.
На машине, которую вы планируете установить в качестве начальной основной для
группы, следует использовать следующие команды:
$ sudo ifconfig carp0 192.0.2.19 vhid 1
$ sudo ifconfig carp1 192.168.1.1 vhid 2
Обратите внимание, что нет необходимости явно указывать физический интерфейс.
Виртуальные интерфейсы carp0 и carp1 связаны с физическими интерфейсами,
настроеными с адресами в той же подсети, что и CARP адреса.
Примечание
В тех ситуациях, когда выбор фзического сетевого устройства для интерфейса CARP, в существующей конфигурации сети, не
очевиден, вы можете добавить интерфейс carpdev в строке команды ifconfig. Это бывает полезно в некоторых не интуитивных
конфигурациях, когда число свободных IP-адресов в соответствующей сети сильно ограничено. Во время написания данной
главы CARP порт FreeBSD не предлагал варианта использования carpdev.
Используя ifconfig вы можете проверить корректность настройки каждого интерфейса
CARP:
$ ifconfig carp0
carp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:00:5e:00:01:01
carp: MASTER carpdev ep0 vhid 1 advbase 1 advskew 0
groups: carp
Обратите внимание, строка carp: отображает статус MASTER.
На резервной машине все настройки идентичны, за исключением добавления параметра
advskew:
$ sudo ifconfig carp0 192.0.2.19 vhid 1 advskew 100
$ sudo ifconfig carp1 192.168.1.1 vhid 2 advskew 100
Параметр advskew указывает, насколько предпочтительна данная машина при передаче
функций основной. Значение advskew в паре с величиной advbase используется хостом
для расчёта интервала между объявлениями статуса главного хоста, функции которого он
на себя принимает. По умолчанию, значение advbase равно 1, а advskew равно 0. В
нашем примере, основной хост будет формировать объявления каждую секунду
(1+0/256), в то время как резервный будет ожидать (1+100/256) секунды. При
net.inet.carp.preempt=1, когда основной хост (master) прекращает объявления или его
объявления не доступны, резервный (backup) принимает его функции на себя и
становится новым основным (новым master'ом) начиная формировать объявления с
заданной скоростью. Задание меньших значений интервалов для advskew позволяет
повысить вероятность хоста стать новым master'ом. Если несколько хостов имеют
одинаковое значение advskew, только один из них получит статус мастера.
В OpenBSD 4.1 и далее, существует ещё один фактор, определяющий, какой хост примет
на себя обязанности мастера CARP. Счётчик понижения (demotion counter) - значение,
объявляемое интерфейсу для каждого хоста CARP в качестве указания меры готовности
интерфейса CARP. Когда значение данного счётчика 0, узел находится в полной
готовности; более высокие значения указывают степень его деградации. Вы можете
установить счётчик понижения непосредственно из командной строки, используя команду
ifconfig -g, но обычно, значение устанавливается самой системой в более высокие
значения в процессе загрузки системы. При прочих равных условиях, хост с самым низким
значением счётчика будет преобладать при выборе мастера CARP.
Примечание
Во время написания этой главы, порт CARP FreeBSD не поддерживал установку счётчика понижения.
На резервном хосте, снова используем ifconfig, чтобы убедиться, что каждый CARP
интерфейс правильно сконфигурирован:
$ ifconfig carp0
carp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:00:5e:00:01:01
carp: BACKUP carpdev ep0 vhid 1 advbase 1 advskew 100
groups: carp
inet 192.0.2.19 netmask 0xffffff00 broadcast 192.0.2.255
inet6 fe80::200:5eff:fe00:101%carp0 prefixlen 64 scopeid 0x5
Результирующий вывод несколько отличается. Обратите внимание, что строка carp:
отображает статус BACKUP, наряду с параметрами advbase и advskew. Для актуального
использования, вам необходимо добавить меры безопасности защищающие CARP от
несанкционированной активности, настроив членов группы CARP с общим, секретным
паролем, например так4:
$ sudo ifconfig carp0 pass mekmitasdigoat 192.0.2.19 vhid 1
$ sudo ifconfig carp1 pass mekmitasdigoat 192.168.1.1 vhid 2
Предупреждение
Как и любой пароль, данный пароль становится неотъемлемой частью CARP трафика вашей установки. Позаботьтесь о
соответствующей настройке всех интерфейсов группы CARP с тем же паролем (или без него).
После того как вы выяснили соответствующие настройки, вам необходимо сохранить их в
соответствующих файлах директории /etc, чтобы использовать после перезагрузки:
•
•
На OpenBSD, установите параметры в hostname.carp0 и hostname.carp1
На FreeBSD и NetBSD добавьте соответствующие строки в файл rc.conf, содержащие
значения переменных ifconfig_carp0= и ifconfig_carp1=.
Храним состояния синхронизироваными: добавление
pfsync
Последняя часть конфигурирования - настройка синхронизации таблиц состояний между
хостами отказоустойчивой группы. Синхронизация таблиц состояний на резервных
брандмауэрах позволит избежать очевидных перерывов в трафике во время отказов. Это
достигается с помощью группы верно настроенных интерфейсов pfsync. (Как уже
отмечалось ранее, на момент написания главы, NetBSD не поддерживала pfsync).
Настройка интерфейсов pfsync является предметом некоторого планирования и
использования команды ifconfig. Можно настроить pfsync на сконфигурированном сетевом
интерфейсе, однако, лучшей идееё будет установка отдельной сети для синхронизации. В
нашем примере конфигурации (рисунок 7-3), мы выделили для этой цели маленькую сеть.
В нашем случае, кроссоверный кабель соединяет два Ethernet интерфейса, но в
конфигурациях с большим числом узлов отказоустойчивой группы, вы можете
использовать отдельный коммутатор, концентратор или VLAN.
В данном примере мы планируем использовать для синхронизации IP адреса 10.0.12.16 и
10.0.12.17. С основной конфигурацией TCP/IP, полная установка pfsync для каждого из
двух интерфейсов партнёров синхронизации выглядит следующим образом:
$ sudo ifconfig pfsync0 syncdev ep2
Здесь проиллюстрировано преймущество использования идентичного оборудования, а так
же поддержка трафика pfsync на отдельной физической сети. Сам протокол pfsync
практически не предоставляет средств обеспечения безопасности. Он не имеет
механизмов проверки подлинности и, по умолчанию, общается используя многоадресный
IP трафик. Однако, для случаев, когда использование физически отдельной сети
невозможно, вы можете поднять безопасность pfsync путём создания специфичного узла
синхронизации (syncpeer):
$ sudo ifconfig pfsync0 syncpeer 10.0.12.16 syncdev ep2
Команда приведёт к созданию интерфейса параметры которого можно просмотреть
используя ifconfig:
pfsync0: flags=41<UP,RUNNING> mtu 1500
priority: 0
pfsync: syncdev: ep2 syncpeer: 10.0.12.16 maxupd: 128 defer: off
groups: carp pfsync
Ещё один вариант повышения безопасности - создать туннель IPsec и использовать его
для защиты трафика синхронизации. Тогда команда ifconfig будет следующая:
$ sudo ifconfig pfsync0 syncpeer 10.0.12.16 syncdev enc0
Это означает, что используется устройство инкапсуляции syncdev enc0, а не физический
интерфейс.
Примечание
Если это возможно, настройте вашу синхронизацию путём физического разделения, используя отдельную сеть. Любая потеря
обновлений pfsync может привести к менее чистой обработке отказов.
Весьма полезный способ для проверки того, что синхронизация состояний PF работает
должным образом
- отслеживать таблицы состояний на обеих (или на всех)
синхронизируемых хостах используя systat states на каждой машине. Эта команда даёт
возможность живого отображения состояний, и вы можете видеть все обновления на
целях синхронизации. В промежутках между синхронизацией, состояния должны
отображаться одинаково на всех машинах, за исключением счётчиков трафика (например
количества прошедших пакетов и байт), которые будут отображаться только для хоста
обрабатывающего фактическое подключение.
Таким образом, мы подошли к завершению базовой конфигурации отказоустойчивой сети
основанной на CARP. В следующем разделе мы рассмотрим, что необходимо иметь в виду
при написании набора правил для конфигураций с избыточностью.
Составление набора правил
Завершив различные выкрутасы по установке базовых сетевых настроек, вам, наверняка
станет интересно, как изменить правила текущего pf.conf для новой установки. Вы будете
рады узнать, что это не займёт много времени. Основные изменения которые вы
произвели, по сути не видны из внешнего мира, а хорошо продуманный набор правил для
конфигурации с одним шлюзом, обычно хорошо работает и в системе с избыточностью.
Однако, мы ввели два новых протокола: CARP и pfsync. По всей вероятности вам
придётся внести некоторые небольшие изменения в набор правил, необходимые для того,
чтобы переход на резервный ресур работал как требуется. В принципе, вам необходимо
направить трафик CARP и pfsync на соответствующие интерфейсы.
Наиболее приемлемым способом управления трафиком CARP является введение макросов
для ваших carpdevs и соответствующих правил pass, например:
pass on $carpdevs proto carp
Вам необходимо передать трафик pfsync на соответствующие интерфейсы. Аналогично,
для трафика pfsync, можно ввести макрос для syncdev и соответствующее правило pass:
pass on $syncdev proto pfsync
Если вы хотите вывести устройство pfsync из системы фильтрации используйте следующее
правило:
set skip on $syncdev
Исключить pfsync интерфейсы из фильтрации обходится дешевле фильтровать и
пропускать.
Кроме того, вам следует рассмотреть роли виртуальных интерфейсов CARP и их адреса в
сравнении с физическим интерфейсом.
Возможно, в вашей конфигурации присутствуют правила, которые вы не хотите
нагружать синхронизацией в случае перехода на другой ресурс, например соединения для
сервисов работающих на самом шлюзе. Один из ярких примеров является типичное
правило разрешающее SSH для администрирования:
pass in on $int_if from $ssh_allowed to self
Для этих правил вы можете использовать опцию no-sync для предотвращения
синхронизации изменения состояния для соединений, которые не имеют отношения к
отказоустойчивости:
pass in on $int_if from $ssh_allowed to self keep state (no-sync)
При наличии такой конфигурации, вы можете запланировать операции обновления
системы и аналогичные процедуры приводящие к простою участников вашей CARP группы
на периоды времени удобные для системных администраторов, без заметной отсановки
пользовательских сервисов.
IFSTATE, ДЕМОН СОСТОЯНИЯ ИНТЕРФЕЙСА
При корректной установке CARP, базовая функциональность сети не нарушается. Однако, вне базовой, ваша установка может
может включать в себя элементы, которые нуждаются в особом внимании при изменении конфигурации на хостах. Для
примера, некоторые службы могут быть запущены и остановлены когда конкретный интерфейс останавливается или
запускается, или вы можете запускать определённые сценарии в ответ на изменение состояния интерфейса. Если это звучит
знакомо, то ifstated будет вам полезен.
ifstated был введён в OpenBSD 3.5 в качестве инструмента для запуска действий основанных на изменении состояния
сетевого интерфейса. вы можете думать о ifstated как о "маленьком помощнике CARP". ifstated включён в базовую систему
OpenBSD и доступен посредством портов net/ifstated на FreeBSD. В OpenBSD, файл /etc/ifstated.conf (или
/usr/local/etc/ifstated.conf если вы установили порт на FreeBSD) содержит практически готовую к работе конфигурацию,
которая даёт вам множество ответов по настройке ifstated в окружающей среде.
основные контролируемые объекты - интерфейсы и их состояния, где carp0.link.up - состояние, в котором интерфейс carp0
имеет связь и вы выполняете действия в ответ на изменение состояния. Они определяются простым языком сценариев с
основными особенностями подобными переменным, макросам и простым логическим условиям. Обратитесь к man-странице
ifstated и ifstated.conf если хотите разобраться подробнее.
CARP для балансировки нагрузки
Резервирование в целях отказоустойчивости, это конечно хорошо, но в некоторых
случаях бывает мало привлекательно, когда ваше оборудование простаивает ожидая
сбоя. Вы можете предпочесть создать конфигурацию, которая позволить распределеить
сетевую нагрузку на несколько хостов.
Дополняя балансировку ARP, которая работает путём вычисления хешей, основываясь на
MAC адресе источника входящего соединения, CARP в OpenBSD 4.3 и выше поддерживает
несколько разновидностей балансировки IP нагрузки, где трафик распределяется на
основе вычисления хешей IP адресов источника и назначения соединения. Поскольку
балансировка ARP основана на MAC адресе источника, она будет работать только для
хостов в непосредственно подключенном сетевом сегменте. Метод основанные на IP более
подходящи для балансировки нагрузки соединений в сетью Интернет.
Какой выбрать режим зависит от вашего приложения и точных спецификаций сетевого
оборудования используемого в работе. Основной режим IP балансировки использует
групповой MAC адрес для создания непосредственно подключенногокоммутатора
направляющего трафик всем хостам кластера балансировки нагрузки. Сочетание
индивидуального IP адреса и группового MAC адреса может не поддерживаться
некоторыми системами. В таком случае, вам может потребоваться настройка балансировки
нагрузки в режиме одноадресного IP (ip-unicast mode) (который использует
индивидуальный MAC адрес) и сконфигурировать ваш коммутатор для направления
трафика соответствующим хостам, или в режиме невидимого IP (ip-stealth mode), который
не использует групповой MAC. Как обычно, проблемы скрываются в деталях, а ответы
можно найти в руководстве и прочей документации, при условии проведения ряда
экспериментов.
Замечание
Традиционно, relayd использовался для интеллектуальной балансировки нагрузки в качестве фронтенда для серверов которые
предлагали свои сервисы. В OpenBSD 4.7, relayd приобрёл возможность отслеживать доступные каналы и изменять таблицы
маршрутизации основываясь на состоянии линков, используя обертку с ключевым словом router. Для установки с несколькими
возможными каналами или вариантами таблиц маршрутизации, вы можете настроить relayd для выбора вашего канала, или с
некоторой помощью переменных sysctl net.inet.ip.multipath и net.inet6.ip6.multipath, выполнять балансировку нагрузки между
доступными маршрутами и каналами. Конкретная специфика будет изменяться в зависимости от сетевого окружения. manстраница relayd.conf включает полный пример для начала работы.
В режиме балансировки нагрузки концепция CARP расширяется, позволяя каждому
интерфейсу CARP являться участником не только одной группы отказоустойчивости, но и
участником множества групп балансировки нагрузки, физические хосты которых будут
использовать виртуальный адрес. В отличии от отказоустойчивости, когда может
существовать только один master, каждый узел кластера балансировки нагрузки должен
быть master'ом своей собственной группы, чтобы получать трафик.
Какая группа и каким физическим хостом заканчивается обработка данного соединения определяется CARP, посредством значения хеша, вычисляемого на основании MAC адреса
источника соединения в случае выбора ARP балансировки, или IP адресе источника и
назначения при выборе IP балансировки. Обратной стороной этого, является то, что
каждая из этих групп потребляет один виртуальный идентификатор хоста, так что
нехватка идентификаторов при использовании конфигурации балансировки нагрузки,
будет ощущаться быстрее чем при конфигурации отказоустойчивости. На самом деле,
существует жесткий верхний предел числа кластеров балансировки нагрузки основаных
на CARP, установленный в 32 виртуальных идентификаторов хостов.
Параметр advskew играет аналогичную роль при балансировке нагрузки, однако
синтаксис ifconfig (и соответственно hostname.carp№) несколько отличается от режима
отказоустойчивости. Изменение группы отказоустойчивости CARP созданной нами в
предыдущих разделах к кластеру балансировки нагрузки заключается в редактировании
конфигурационных файлов и перезагрузке. В этом примере мы пойдём по схеме IP
балансировки. Если вы выбираете отличную схему, конфигурации будут различаться
только ключевым словом выбора режима.
На первом хосте мы изменим файл /etc/hostname.carp0 следующим образом:
pass mekmitasdigoat 192.0.2.19 balancing ip carpnodes 5:100,6:0
Это значит, что на данном хосте, интерфейс carp0 является членом группы с vhid 5, где
advskew = 100, а так же vhid 6, где он является главным кандидатом на получение
master'а, с avdskew = 0.
Теперь изменим /etc/hostname.carp1:
pass mekmitasdigoat 192.168.12.1 balancing ip carpnodes 3:100,4:0
Для carp1, участника vhid 3 и 4, значения advskew 100 и 0 соответственно.
Для другого хоста значения advskew соответственно меняются местами, а конфигурации
похожи. Здесь /etc/hostname.carp0 выглядит так:
pass mekmitasdigoat 192.0.2.19 balancing ip carpnodes 5:0,6:100
Соответственно, он является участником vhid 5 с advskew = 0 и участником vhid 6
advskew = 100. Файл /etc/hostname.carp1 выглядит следующим образом:
pass mekmitasdigoat 192.168.12.1 balancing ip carpnodes 3:0,4:100
И снова, carp1 является участником vhid3 и 4, с advskew 0 и 100 соответственно.
Вывод ifconfig для группы интерфейсов CARP на первом хосте выглядит так:
$ ifconfig carp
carp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 01:00:5e:00:01:05
priority: 0
carp: carpdev vr0 advbase 1 balancing ip
state MASTER vhid 5 advskew 0
state BACKUP vhid 6 advskew 100
groups: carp
inet 192.0.2.19 netmask 0xffffff00 broadcast 192.0.2.255
inet6 fe80::200:24ff:fecb:1c10%carp0 prefixlen 64 scopeid 0x7
carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 01:00:5e:00:01:03
priority: 0
carp: carpdev vr1 advbase 1 balancing ip
state MASTER vhid 3 advskew 0
state BACKUP vhid 4 advskew 100
groups: carp
inet 192.168.12.1 netmask 0xffffff00 broadcast 192.168.12.255
inet6 fe80::200:24ff:fecb:1c10%carp1 prefixlen 64 scopeid 0x8
pfsync0: flags=41<UP,RUNNING> mtu 1500
priority: 0
pfsync: syncdev: vr2 syncpeer: 10.0.12.17 maxupd: 128 defer: off
groups: carp pfsync
А на втором хосте так:
$ ifconfig carp
carp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 01:00:5e:00:01:05
priority: 0
carp: carpdev vr0 advbase 1 balancing ip
state BACKUP vhid 5 advskew 100
state MASTER vhid 6 advskew 0
groups: carp
inet 192.0.2.19 netmask 0xffffff00 broadcast 192.0.2.255
inet6 fe80::200:24ff:fecb:1c18%carp0 prefixlen 64 scopeid 0x7
carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 01:00:5e:00:01:03
priority: 0
carp: carpdev vr1 advbase 1 balancing ip
state BACKUP vhid 3 advskew 100
state MASTER vhid 4 advskew 0
groups: carp
inet 192.168.12.1 netmask 0xffffff00 broadcast 192.168.12.255
inet6 fe80::200:24ff:fecb:1c18%carp1 prefixlen 64 scopeid 0x8
pfsync0: flags=41<UP,RUNNING> mtu 1500
с
priority: 0
pfsync: syncdev: vr2 syncpeer: 10.0.12.16 maxupd: 128 defer: off
groups: carp pfsync
Если бы мы имели три узла в нашей схеме балансировки нагрузки, каждый интерфейс
CARP должен быть членом дополнительных групп, в общей сложности трёх. Короче
говоря, для каждого физического узла вы вводите группу балансировки нагрузки, и
каждый интерфейс CARP становится членом дополнительной группы.
После того, как вы создали кластер балансировки нагрузки, можно проверить актуальный
поток соединений выполнив systat states на каждом из хостов в вашем кластере. Я
рекомендую провести проверку в течение нескольких минут, чтобы быть уверенным, что
система работает так, как ожидалось и ваши усилия были потрачены не зря.
Журналирование,
мониторинг и статистика
Постоянный контроль над сетью, основная задача читателя этой книги независимо от того, домашняя ли это сеть или сеть вашего предприятия.
Необходимым элементом контроля является доступ ко всей информации о
событиях в вашей сети. К счастью, PF (подобно большинству компонентов UNIXподобных систем) способен генерировать журнал данных регистрации сетевой
активности.
PF предлагает множество опций для настройки уровня детализации журнала, обработки
файлов журнала и извлечения определённых видов данных. Многие операции доступны
благодаря инструментам (утилитам) входящим в базовую систему. Кроме того существует
большое количество прочих инструментов, которые могут быть установлены из системы
пакетов для сбора, изучения и просмотра данных журналов множеством различных
способов.
В этой главе, мы подробно рассмотрим журналы PF в целом, а так же некоторые
инструменты, которые можно использовать для извлечения и представления полезной
информации.
Журналы PF: Основы
Информация попадающая в журналы PF и уровень детализации ведения журнала
определяется вашим набором правил. Основы журналирования просты: для каждого
правила, которое должно добавлять данные в журнал, добавляется ключевое слово log.
Когда вы загружаете набор правил с добавлением log к одному или более правилам,
любые пакеты начинающие соединение в соотвествии с правилом (bloked, passed, или
matched) копируются на устройство pflog. Кроме того, PF будет хранить некоторые
дополнительные данные, такие как штамп времени (временную метку), интерфейс, на
котором пакет был пропущен или заблокирован, и связанный номер правила из
загруженного набора правил.
Данные журнала PF собираются демоном журналирования pflogd, который запускается по
умолчанию, при запуске PF в процессе начальной загрузки системы. По умолчанию,
данные журнала хранятся в /var/log/pflog. Журналы пишутся в бинарном формате
предназначенном для чтения с использованием tcpdump. Дополнительные инструменты
для извлечения и отображения информации из вашего журнала, мы обсудим несколько
позже. Формат файла журнала хорошо документирован и широко поддерживаются.
Для начала приведём простой пример журнала. Начнём с добавления ключевого слова
log в необходимые правила:
block log
pass log quick proto { tcp, udp } to port ssh
Перезагрузив набор правил, вы должны увидеть изменение метки времени файла
/var/log/pflog и возростание его размера. Чтобы разобрать, что в данный момент
находится в файле, используйте tcpdump с опцией -r для чтения содержимого файла.
Если журналирование продолжается некоторое время, используйте следующую команду,
чтобы получить больший результат вывода:
$ sudo tcpdump -n -ttt -r /var/log/pflog
Например, далее приводятся только первые строки файла занимающего несколько
экранов:
$ sudo tcpdump -n -ttt -r /var/log/pflog
tcpdump: WARNING: snaplen raised from 96 to 116
Sep 13 13:00:30.556038 rule 10/(match) pass in on epic0: 194.54.107.19.34834 > 194.54.103.66.113:
3097635127:3097635127(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 0,[|tcp]> (DF)
Sep 13 13:00:30.556063 rule 10/(match) pass out on fxp0: 194.54.107.19.34834 > 194.54.103.66.113:
3097635127:3097635127(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 0,[|tcp]> (DF)
Sep 13 13:01:07.796096 rule 10/(match) pass in on epic0: 194.54.107.19.29572 > 194.54.103.66.113:
2345499144:2345499144(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 0,[|tcp]> (DF)
Sep 13 13:01:07.796120 rule 10/(match) pass out on fxp0: 194.54.107.19.29572 > 194.54.103.66.113:
2345499144:2345499144(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 0,[|tcp]> (DF)
Sep 13 13:01:15.096643 rule 10/(match) pass in on epic0: 194.54.107.19.29774 > 194.54.103.65.53:
49442 [1au][|domain]
Sep 13 13:01:15.607619 rule 12/(match) pass in on epic0: 194.54.107.19.29774 > 194.54.107.18.53:
34932 [1au][|domain]
Программа tcpdump весьма гибкая, особенно в отношение вывода результата, предлагая
несколько вариантов вывода. Формат данного примера следует опциям указанным для
tcpdump. Программа практически всегда отображает дату и время поступления пакета
(длинный формат данных определяется опцией -ttt). Далее, tcpdump перечисляет номер
правила в загруженном наборе правил, интерфейс с которого появился пакет, исходный и
целевой адрес и порт (опция -n сообщает tcpdump отображать IP адреса а не имена
хостов), и различные свойства пакетов.
Примечание
Номера правил в файлах журнала относятся к загруженнабору правил. В процессе загрузки, ваш набор правил проходит через
некоторые автоматизированные шаги, например расширение макросов и оптимизации, которые с некоторой вероятностью
приведут к тому, что номера правил хранимых в журнале, не всегда соответствуют порядковым номерам правил в самом файле
pf.conf. Если возникает неочевидность того какое правило соответствует, используйте pfctl -vvs rules и изучите полученный
вывод.
В нашем примере вывода tcpdump мы видим, что правило 10 (rule 10) загруженного
набора правил кажется всеобъемлющим и соответствует запросам IDENT и обзору
доменных имён. Этот тип вывода вы найдёте весьма полезным в процессе отладки и очень
важно, чтобы данные такого рода были постоянно доступны, что позволит контролировать
вашу сеть. Приложив немного усилий и внимательно изучив страницы руководства
tcpdump, вы должны быть в состоянии извлечь полезную информацию из вашего журнала
данных.
Для живого отображения движения данных журнала, используйте tcpdump для чтения
информации журнала непосредственно с устройства журналирования. Чтобы сделать это,
используйте опцию -i для указания интерфейса с которого читает tcpdump:
$ sudo tcpdump -nettti pflog0
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: listening on pflog0, link-type PFLOG
Sep 13 15:26:52.122002 rule 17/(match) pass in on epic0:
194.54.103.65.22: [|tcp] (DF)
Sep 13 15:28:02.771442 rule 12/(match) pass in on epic0:
194.54.107.18.8025: udp 50
Sep 13 15:28:02.773958 rule 10/(match) pass in on epic0:
194.54.103.65.8025: udp 50
Sep 13 15:29:27.882888 rule 10/(match) pass in on epic0:
194.54.103.65.53:[|domain]
Sep 13 15:29:28.394320 rule 12/(match) pass in on epic0:
194.54.107.18.53:[|domain]
91.143.126.48.46618 >
194.54.107.19.8025 >
194.54.107.19.8025 >
194.54.107.19.29774 >
194.54.107.19.29774 >
Данная последовательность начинается с соединений SSH. Далее следуют два
соединения синхронизации spamd, затем следуют два обзора доменных имён. Если вы
оставите эту команду запущенной, будет производится прокрутка отображаемых строк,
однако, вы можете перенаправить вывод данных в файл или в отдельную программу для
дальнейшей обработки.
Примечание
В некоторых случаях, вас будет интересовать трафик между двумя конкретными хостами, или трафик соответствующий
определённым критериям. Для этих случаев возможности фильтрации tcpdump могут быть весьма полезны. Для подробного
изучения обратитесь к странице руководства tcpdump.
Журналирование всех пакетов: log (all)
Для общей
предоставит
потребность
того, чтобы
опцию (all).
следующее:
отладки и простоты мониторинга, регистрация первого пакета соединения
достаточное количество информации. Однако, иногда может возникнуть
в регистрации всех пакетов, соответствующих определённым правилам. Для
это сделать, используйте в правилах которые необходимо контролировать
Сделав это изменение в наших правилах мы должны получить примерно
block log (all)
pass log (all) quick proto tcp to port ssh keep state
Использование этой опции делает журналы более многословными. Для иллюстрации того,
насколько больше данных генерируется в журналах при использовании опции all, мы
возьмём следующий фрагмент набора правил, который пропускает пакеты поиска
доменных имён и синхронизации времени:
udp_services = "{ domain, ntp }"
pass log (all) inet proto udp to port $udp_services
Имея эти правила, мы рассмотрим пример когда русский сервер имён посылает запрос
доменного имени на сервер нашей сети:
$ sudo tcpdump -n -ttt -i pflog0 port domain
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: listening on pflog0, link-type PFLOG
Sep 30 14:27:41.260190 212.5.66.14.53 > 194.54.107.19.53:[|domain]
Sep 30 14:27:41.260253 212.5.66.14.53 > 194.54.107.19.53:[|domain]
Sep 30 14:27:41.260267 212.5.66.14.53 > 194.54.107.19.53:[|domain]
Sep 30 14:27:41.260638 194.54.107.19.53 > 212.5.66.14.53:[|domain]
Sep 30 14:27:41.260798 194.54.107.19.53 > 212.5.66.14.53:[|domain]
Sep 30 14:27:41.260923 194.54.107.19.53 > 212.5.66.14.53:[|domain]
Теперь мы имеем в журнале шесть записей вместо одной.
Ответственное журналирование!
Создание журналов любого рода может привести к неожиданным последствиям, в том числе и юридическим. Как только вы
начинаете хранить данные журналов сетевого трафика, вы создаёте хранилище информации о пользователях. Могут
существовать хорошие причины для длительного хранения журналов технической информации или данных о бизнес-процессах,
однако регистрация только данных достаточных для отображения состояния в течение определённого времени может быть
вполне достаточной. Вы должны иметь некоторое представление о практических вопросах связанных с генерацией данных
журналов, например таких как организация достаточного места для хранения журнала в периоде его актуальности.
Юридические аспекты могут изменяться в зависимости от ваше местоположения. В некоторых странах и регионах имеются
особые требования к обработке данных журналов, наряду с ограничениями того, как эти данные должны сохраняться. Иногда
от ISP требуется сохранять журналы трафика за определённый период времени, и при необходимости предоставлять эти
данные по запросу правоохранительных органов. Убедитесь, что вы разобрались с правовыми вопросами, прежде чем строить
инфраструктуру системы журналирования.
Даже при использовании фильтрации port domain в tcpdump, добавление log(all) к одному
или нескольким правилам значительно увеличивает объём данных в ваших журналах.
Если вам необходимо журналировать весь трафик, но ёмкость хранилища шлюза
ограничена, может потребоваться добавление дисковой памяти. Кроме того, запись и
хранение журналов трафика с таким уровнем детализации, с большой вероятностью будет
иметь юридические последствия.
Журналирование нескольких интерфейсов pflog
PF в версиях OpenBSD старее 4.1 позволял только один интерфейс pflog. Это изменилось
с OpenBSD 4.1, когда интерфейс pflog стал клонируемым устройством, а это,
соответственно, означает, что вы можете использовать команды ifconfig для создания
нескольких интерфейсов pflog в дополнение к стандартному pflog0. Это позволяет вести
журнал данных для различных частей вашего набора правил с помощью отдельных
интерфейсов pflog и проще обрабатывать полученные данные. Необходимые изменения
настройки являются небольшими, но эффективными. Для журнала с несколькими
интерфейсами,
следует
убедиться,
что
все
интерфейсы
используемые
для
журналирования набора правил, созданы. Вам не нужно создавать устройства перед
загрузкой набора правил, поскольку, при журналировании на несуществующие
устройства, данные журнала просто отбрасываются. При настройке вашей установки
использующей несколько интерфейсов pflog, скорее всего вам потребуется добавить
необходимые интерфейсы с помощью командной строки, например так:
$ sudo ifconfig create pflog1
Для создания постоянной конфигурации в OpenBSD, создайте файл hostname.pflog1,
содержащий только up и аналогичные файлы hostname.pflogN для любых дополнительных
интерфейсов журналирования.
На FreeBSD, конфигурирование клонированых интерфейсов pflog производится в файле
rc.conf, в следующем виде:
ifconfig_pflog1="up"
На NetBSD, клонирование pflog не поддерживалось на момент написания главы.
Как вы видели в Главе 6, направление информации журнала для различных частей
набора правил на отдельные интерфейсы, позволяет передавать данные журнала PF
различным приложениям. Это облегчает передачу требуемой информации специальным
программам, таким как spamlogd, в то время, как другие части журнала PF будут
передаваться другим программам обработки.
Журналирование с Syslog, локально или удалённо
Один из способов избежать хранения данных журналов PF на шлюзе - настроить ваш
шлюз для журналирования на другую машину. Если у вас уже существует
централизованая инфраструктура журналирования, вполне логично, что это необходимо
сделать, даже если обыкновенные механизмы журналирования PF не были разработаны в
традиционном стиде syslog.
Длительное использование BSD подскажет вам, что традиционная система
журналирования syslog - основана на несколько наивном управлении данными, через
передачу UDP с других хостов, и частым упоминанием о возможности DoS атак. Кроме
того, существует риск того, что информация журналов будет потеряна при высокой
нагрузке на любой из отдельных систем или сетей. Таким образом, следует рассматривать
вопрос о создании удалённого журналирования только если все участвующие хосты
находятся в хорошо защищённой сети. На большинстве BSD систем, syslogd не
настраивается по умолчанию для приёма данных с других хостов. (Смотрите manстраницу syslogd для получения информации о подключении демона к приёму
информации с других хостов, если вы планируете использовать удалённое
журналирование).
Если вы всё таки планируете проводить журналирование PF посредством syslog, далее
следует короткий рецепт того, как это сделать. В стандартных установках PF, pflogd
копирует журналируемые данные в файл журнала. Если вам необходимо сначала
сохранять данные журнала на удалённой системе, необходимо отключить накопление
данных pflog изменив его файл журнала на /dev/null, через параметры запуска демона в
rc.conf.local (для OpenBSD), следующим образом:
pflogd_flags="-f /dev/null"
На FreeBSD и NetBSD измените строку pflog_logfile= в файле rc.conf, затем убейте и
перезапустите процесс pflogd с новыми параметрами:
pflog_logfile="/dev/null"
Далее, убедитесь, что данные журнала, более не собираемые pflogd, передаются
требуемым образом для вашей системы обработки журналов. Этот шаг состоит из двух
частей: первое - настройте ваш системный журнал для передачи данных в журнал
системы обработки, а затем используйте tcpdump для преобразования данных и
внедрения их в системный журнал системы.
Чтобы настроить syslogd для обработки данных, выберите объект журнала (log facility),
уровень журналирования (log level) и действие (action) и введите результирующую строку
в /etc/syslog.conf. Этот пункт хорошо объясняется в man-странице syslog.conf, которую
обязательно следует изучить, если вы хотитет понять системные журналы. Часть action это обычно файл в локальной файловой системе. Для примера, если вы уже создали
системный журнал на loghost.example.com для получения ваших данных, выберите объект
журнала local2 с уровнем журналирования info введя следующую строку:
local2.info
@loghost.example.com
После внесения этих изменений, перезагрузите syslogd чтобы он прочитал новые
настройки.
Далее, установите tcpdump для преобразования данных журнала с устройства pflog и
передаче их логгеру, который будет отправлять данные в системный журнал. Здесь мы
повторим команду tcpdump из основных примеров использованных ранее в этой главе, с
рядом полезных дополнений:
$ sudo nohup tcpdump -lnettti pflog0 | logger -t pf -p local2.info &
Команда nohup гарантирует, что процесс продолжит работать даже если не имеет
управляющего терминала или помещается в фоновый режим (как мы делаем добавляя &).
Опция -l с командой tcpdump указывает буферизацию строк вывода, что полезно при
перенаправлении на другие программы. Опция logger добавляет теги pf для
идентификации данных PF в потоке и указывает приоритет журнала с опцией -p как
local2.info. Результат записывается в файл указанный вами на хосте журналирования, с
записями выглядящими следующим образом:
pf: Sep 21 14:05:11.492590 rule
82.117.50.17.80: [|tcp] (DF)
pf: Sep 21 14:05:11.492648 rule
82.117.50.17.80: [|tcp] (DF)
pf: Sep 21 14:05:11.506289 rule
82.117.50.17.80: [|tcp] (DF)
pf: Sep 21 14:05:11.506330 rule
82.117.50.17.80: [|tcp] (DF)
pf: Sep 21 14:05:11.573561 rule
10.168.103.1.53:[|domain]
pf: Sep 21 14:05:11.574276 rule
> 209.62.178.21.53:[|domain]
93/(match) pass in on ath0: 10.168.103.11.15842 >
93/(match) pass out on xl0: 194.54.107.19.15842 >
93/(match) pass in on ath0: 10.168.103.11.27984 >
93/(match) pass out on xl0: 194.54.107.19.27984 >
136/(match) pass in on ath0: 10.168.103.11.6430 >
136/(match) pass out on xl0: 194.54.107.19.26281
Этот фрагмент журнала показывает в основном активность web-обозревателя с клиента в
локальной сети за NAT, с точки зрения шлюза, с сопутствующим поиском доменных имён.
Отслеживание статистики
помощью меток (Labels)
для
каждого
правила
с
Последовательную информацию вы получаете из соответствующих данных журнала
основанных на отслеживании движения пакета во времени. В других контекстах,
последовательность или история соединений менее важна, чем агрегация, так как
количество пакетов или байтов, соответствующих правилу, в дальнейшем очищаются. В
конце главы 2, вы видели, как использовать pfctl -s info для просмотра глобальных
счётчиков, наряду с прочими данными. Для подробной разбивки данных, отслеживание
глобального трафика основывается на правиле с несколько иной формой команды pfctl,
такой как pfctl -vs rules, для отображения статистики правила, как показано далее:
$ pfctl -vs rules
pass inet proto tcp from any to 192.0.2.225 port = smtp flags S/SA keep state label "mail-in"
[ Evaluations: 1664158 Packets: 1601986 Bytes: 763762591 States: 0 ]
[ Inserted: uid 0 pid 24490 ]
pass inet proto tcp from 192.0.2.225 to any port = smtp flags S/SA keep state label "mail-out"
[ Evaluations: 2814933 Packets: 2711211 Bytes: 492510664 States: 0 ]
[ Inserted: uid 0 pid 24490 ]
Такой формат вывода легко читаем, и, очевидно, предназначен для контекста в котором
вы хотите получить представление о том, что происходит на первый взгляд. Если указать
ещё более подробный вывод с pfctl -vvc rules, вы увидите тот же вывод, с добавленными
номерами правил. С другой стороны, вывод этой команды не очень подходит для
передачи в сценарий или программы для дальнейшей обработки Для извлечения данных в
формате более удобном для обработки используйте правило labels.
labels делают больше, чем просто определяют правила обработки отдельных видов
трафика, они облегчают извлечение статистики трафика. Добавив labels к правилам, вы
можете сохранить некоторые дополнительные данные о части вашего набора правил.
Например, вы можете использовать маркировку (labeling) для измерения пропускной
способности в целях учёта. В следующем примере мы присоединим labels mail-in и mailout на ваши правила pass для входящего и исходящего почтового трафика,
соответственно.
pass log proto { tcp, udp } to $emailserver port smtp label "mail-in"
pass log proto { tcp, udp } from $emailserver to port smtp label "mail-out"
После загрузки набора правил с метками, можно проверить данные используя команду
pfctl -vsl:
$ sudo pfctl -vsl
1
2
3
4
5
6
7
mail-in 1664158 1601986 763762591 887895
682427415 714091
mail-out 2814933 2711211 492510664 1407278 239776267 1303933
8
81335176
252734397
Этот вывод содержит следующую информацию:
1.
2.
3.
4.
5.
6.
7.
8.
метка
Сколько раз оценивались правила
Общее количество прошедших пакетов
Общее число прошедших байт
Количество пакетов пропущенных в (in)
Количество байт пропущенных в (in)
Количество пакетов пропущенных из (out)
Количество байт пропущенных из (out)
Формат весьма хорошо подходит для разбора скриптами и приложениями.
labels накапливает данные с момента загрузки набора правил до момента сброса
счётчиков. Во многих контекстах, имеет смысл создать задание cron'а которое будет
читать значение меток через фиксированные промежутки времени, а затем помещать их в
постоянное хранилище.
Если вы решили запустить сбор данных через определённые промежутки времени, для
подсчёта собранных данных используйте команду pfctl -vszl. Опция z сбрасывает счётчики
после их подсчёта pfctl, в результате чего ваш сборщик данных будет иметь
периодические выборки данных, накопленные последней запущенной командой или
сценарием.
Замечание
Правила с макросами и списки расширяются до нескольких правил. Если ваш набор правил содержит списки или макросы,
имеющие метки, результатом в памяти будет ряд правил, разделяемых одинаковыми именами меток прикреплённых к ним. Хотя
это может привести к неожиданным выводам sudo pfctl -vsl, это не должно стать проблемой до тех пор, пока приложение или
скрипт получающий данные может их правильно интерпритировать путём суммирования итогов для идентичных меток.
Дополнительные
статистики PF
инструменты
для
журналирования
и
Ещё одна важная составляющая постоянного контроля вашей сети - наличие возможности
хранить актуальный статус системы. В этом разделе мы рассмотрим, как выбрать
инструменты мониторинга которые могут оказаться весьма полезными. Все инструменты
представленные здесь доступны либо в базовой системе, либо в системе пакетов OpenBSD
и FreeBSD (за исключение NetBSD).
Взгляд на вещи посредством systat
Если вы заинтересованы в том, чтобы получить мгновенный снимок трафика (снапшот),
проходящего через вашу систему в текущий момент времени, программа systat в OpenBSD
предлагает несколько полезных возможностей. В главе 7, мы в кратце рассматривали
очереди systat для просмотра трафика назначенного очередям в нашем наборе правил
ALTQ. Здесь мы рассмотрим декоторые дополнительные полезные опции.
Программа systat доступна на всех операционных системах BSD, в нескольких различных
вариантах. На всех системах, systat позволяет работать со статистикой системы,
незначительно различаясь в синтаксисе и результирующем выводе. Например, на момент
написания книги, несколько видов просмотра queues доступно в systat на OpenBSD, но не
на FreeBSD или NetBSD.
Для более общего взгляда на таблицу состояний, отличного от того, который
предоставляет queues, попробуйте использовать systat states, которая даёт список очень
похожий на список процессов top(1). Далее представлен типовой вывод systat states:
2 users
PR
D
udp O
tcp I
tcp I
tcp I
tcp O
Load 0.24 0.28 0.27 (1-16 of 895) Fri Apr 1 14:00:04 2011
SRC
DEST
STATE AGE
EXP
PKTS
192.168.103.1:56729
192.168.103.9:12345 1:0
8340m 25
372K
10.168.103.15:47185
213.187.179.198:22 4:4
62377 86398 2954
10.168.103.15:2796
213.187.179.198:22 4:4
62368 86219 4014
10.168.103.15:15599
129.240.64.10:6667 4:4
61998 86375 9266
213.187.179.198:1559 129.240.64.10:6667 4:4
61998 86375 9266
BYTES RATE
542M 1492
613K 13264
679K 0
849K 0
849K 0
PEAK
4774
23654
0
58
58
AVG
1137
10
11
14
14
RU G
*
18
18
*
* 1
Если состояния не умещаются на одном экране, можно пролистать изображение.
Аналогично, systat rules отображает живой вид пакетов, байтов и другую статистику для
загруженного набора правил, например так:
2 users
Load 1.25 0.87 0.52 (1-16 of 239) Fri Apr 1 14:01:59 2011
RUL ANCHOR A
0
M
1
M
2
M
3
M
4
M
5
M
6
M
7
M
8
B
9
B
10
P
11
P
12
P
13
P
14
P
15
P
DIR
In
Out
Out
Out
Out
Out
Out
Out
Any
Any
Any
In
Out
Any
In
In
L Q IF
nfe0
nfe0
nfe0
nfe0
nfe0
nfe0
nfe0
PR
K
tcp
tcp
tcp
udp
icmp
L
Q
Q
L
L
L
egres
egres
tcp
tcp
K
K
tcp
tcp
K
K
PKTS
26M
4853K
3318K
6404K
84298
502
512K
11
14638
95
1139K
18538
0
1421
1830K
31
BYTES
12G
3162M
2430M
4341M
43M
34677
64M
1008
1346K
5628
1005M
1350K
0
128K
87M
5240
STATE
4946K
94858
61672
134K
1594
63
257K
3
0
0
757
708
0
134
18933
2
MAX
INFO
all max-mss 1440
inet from 10.0.0.0/8 to any queue(q_def
inet from 192.168.103.0/24 to any queue
from any to any port = www queue(q_web,
from any to any port = https queue(q_we
from any to any port = domain queue(q_d
from any to any port = domain queue(q_d
all queue(q_dns, q_pri)
return all
return from <bruteforce> to any
all flags any
inet from any to any port = ftp
inet from 127.0.0.1/32 to any port = ftp
all flags any
inet from any to any port = smtp queue
from <nospamd> to any port = smtp
Обзор правил systat особенно полезен, поскольку он предлагает живое представление
полностью развёрнутого загруженного набора правил. Например, если ваш набор правил
ведёт себя несколько несколько странно, данный вид может направить вас в правильном
направлении поиска и показать фактический поток пакетов. Программа systat так же
предлагает вид представления данных которые вы можете получить посредством команды
pfctl -s status. Следующий пример показывает часть вывода systat pf. Вид systat pf
предлагает больше информации чем может поместиться на экран, но её можно видеть
вживую.
2 users Load 0.34 0.64 0.47 (1-16 of 51) Fri Apr 1 14:04:04 2011
TYPE
pf
pf
pf
pf
NAME
Status
Since
Debug
Hostid
VALUE
Enabled
139:05:08
err
0x82aea702
nfe0
nfe0
nfe0
nfe0
nfe0
nfe0
nfe0
nfe0
nfe0
nfe0
nfe0
Bytes In
Bytes In
Bytes Out
Bytes Out
Packets In
Packets In
Packets In
Packets In
Packets Out
Packets Out
Packets Out
6217042900
0
5993394114
64
12782504
0
11096
0
12551463
1
167
RATE
NOTES
IPv4
IPv6
IPv4
IPv6
IPv4,
IPv6,
IPv4,
IPv6,
IPv4,
IPv6,
IPv4,
Passed
Passed
Blocked
Blocked
Passed
Passed
Blocked
Программа systat предлагает несколько прочих видов, в том числе связанных с сетью,
таких как NetStat, vmstat для статистики виртуальной памяти, iostat для статистики
устройств ввода/вывода Вы можете циклически переключаться между всеми видами systat
используя левую и правую клавиши управления курсором. (Смортите man systat для
получения подробной информации).
Взгляд на вещи с помощью pftop
Если ваша система не имеет версии systat с поддержкой вида PF, вы можете отслеживать
активность вашей сети в режиме реального времени используя pftop. Эта команда
отображает снимки вашего трафика. pftop не включена в базовую систему, но доступна в
качестве пакета, и в системе портов OpenBSD и FreeBSD как /sysutils/pftop, а так же в
NetBSD посредством pkgsrc как sysutils/pftop. Вот пример её вывода:
pfTop: Up State 1-17/771, View: default, Order: none, Cache: 10000
PR
udp
tcp
tcp
tcp
tcp
tcp
tcp
...
DIR
Out
In
In
In
Out
In
Out
SRC
DEST
192.168.103.1:56729
192.168.103.9:12345
10.168.103.15:47185
213.187.179.198:22
10.168.103.15:2796
213.187.179.198:22
10.168.103.15:15599
129.240.64.10:6667
213.187.179.198:15599 129.240.64.10:6667
10.168.103.15:8923
140.211.166.4:6667
213.187.179.198:8923 140.211.166.4:6667
14:05:42
STATE
SINGLE:NO_TRAFFIC
ESTABLISHED:ESTABLISHED
ESTABLISHED:ESTABLISHED
ESTABLISHED:ESTABLISHED
ESTABLISHED:ESTABLISHED
ESTABLISHED:ESTABLISHED
ESTABLISHED:ESTABLISHED
AGE
8346m
62715
62706
62336
62336
62181
62181
EXP
22
86395
86369
86379
86379
86380
86380
PKTS
373K
3232
4071
9318
9318
15755
15755
BYTES
543M
667K
686K
854K
854K
4821K
4821K
Вы можете использовать pftop для сортировки ваших подключений по различным
критериям, в том числе правилам PF, объёму, возрасту и адресам источника и назначения.
Визуализация вашего трафика с помощью pfstat
Если ваша система поднята, работает и обрабатывает данные, графическое
представление данных о потоках информации станет полезной возможностью для
просмотра и анализа данных. Один из способов графического отображения данных PF программа pfstat, разработанная Даниэлем Хартмеером с целью извлечения и
представления статистических данных, автоматически генерируемых PF. Инструмент pfstat
доступен через систему пакетов OpenBSD или в качестве порта net/pfstat, через систему
портов FreeBSD как sysutils/pfstat, и через pkgsrc в NetBSD, как sysutils/pfstat.
Программа pfstat собирает данные, которые вы определяете в файле конфигурации и
представляет эти данные как файлы формата JPG или PNG. источником данных может
быть либо PF работающий на локальной системе, через устройство /dev/pf, либо данные
собранные с удалённого компьютера под управлением демона pfstatd.
Для настройки pfstat, в должны решить, какие части данных PF требуется
визуализировать и каким образом, а затем написать конфигурационный файл и запустить
задание cron для сбора данных и генерации ваших графиков. Программа поставляется с
подробно комментированным файлом конфигурации и полезной man-страницей. Пример
конфигурации может быть полезной отправной точкой для написания собственного
конфигурационного файла. Например, следующий фрагмент pfstat.conf весьма близок к
первоначальному примеру конфигурации{1}:
collect 8 = global states inserts diff
collect 9 = global states removals diff
collect 10 = global states searches diff
image "/var/www/users/peter/bsdly.net/pfstat-states.jpg" {
from 1 days to now
width 980 height 300
left
graph 8 "inserts" "states/s" color 0 192 0 filled,
graph 9 "removals" "states/s" color 0 0 255
right
graph 10 "searches" "states/s" color 255 0 0
}
Конфигурация начинается с тремя объявлениями collect, где каждому из рядов данных
присваивается уникальный цифровой идентификатор. В данном случае, мы захватываем
число вставок (insertions), удалений (removals) и поисков (searches) в таблице состояний.
Далее определяются параметры изображения, которое отображает указанные данные. В
строке указывается период отображения (from 1 days to now, означает, что будут
отображаться только данные собранные в течение последних 24 часов). width (ширина) и
height (высота) указывают на размер изображения измеряемый в пикселях для каждого
направления. Объявление graph указывает, как отображаются ряды данных и легенды
графиков. Сбор состояний вставки, удаления и поиска производится один раз в минуту, а
затем данные графика собираются в суточное отображение примерно так, как показано на
рисунке 8-1.
Рисунок 8-1 Статистика таблицы состояний по 24-часовой шкале времени.
График может быть изменён, в целях более детального представления одних и тех же
данных. Например, чтобы увидеть данные за последний час с большим разрешением,
измените период на from 1 hours to now и размерность на width 600 height 300.
Примерный результат должен быть подобен рисунку 8-2.
Рисунок 8-2. Статистика таблицы состояний, 1-часовая шкала времени.
Домашняя страница pfstat http://www.benzedrine.cx/pfstat.html содержит несколько
примеров, с демонстрациями в виде живых графических данных с доменного шлюза
benzedrine.cx. Читая примеры и используя знания своего трафика, вы должны суметь
создать конфигурацию pfstat, которая хорошо подойдёт к потребностям вашего сайта
(развёртывания).
Сбор данных NetFlow с помощью pflow(4)
NetFlow - метод сбора и анализа сетевых данных, который породил множество
вспомогательных инструментов для записи и анализа данных о TCP/IP соединениях.
NetFlow изначально появился в Cisco, и с течением времени стал важной особенностью
различного сетевого оборудования, как инструмент управления и анализа сети.
Модель данных NetFlow определяет сетевой поток как однонаправленную
последовательность пакетов с одними и теми же IP адресами источника и назначения и
протоколами. Например, TCP соединения определяются в данных NetFlow в виде двух
потоков: по одному в каждом направлении.
Данные PF могут быть доступны для инструментов NetFlow посредством
псевдоинтерфейса pflow(4), который впервые появился в OpenBSD 4.5 с опцией pflow
state. По существу, всю информацию которую вы ожидаете найти в записи потока NetFlow
стиля легко выводится из данных PF хранимых в таблице состояний, а интерфейс pflow
предоставляет простой способ экспорта данных таблицы состояний PF в очищенном и
хорошо документированном формате. Как и при прочем журналировании, вы должны
обеспечить получение данных NetFlow из набора правил PF базируясь на основе правил.
Система сетевого мониторинга основанная на NetFlow состоит из нескольких отдельных
частей. Данные NetFlow получаются от одного или нескольких сенсоров генерирующих
данные о сетевом трафике. Сенсоры передают данные о потоках в коллектор который
хранит получаемые данные. Наконец система анализа и отчётности извлекает и
обрабатывает данные. {2}
Установка сенсора NetFlow
Для установки сенсора NetFlow требуется два компонента: одно или несколько
настроеных устройств pflow(4), и, по крайней мере, одно правило passв наборе правил с
включённой опцией pflow state. Интерфейсы pflow создаются с двумя обязательными
параметрами: IP адресом источника и IP адресом назначения потока и номером порта. Вот
пример команды ifconfig для файла /etc/hostname.pflow0:
flowsrc 192.0.2.1 flowdst 192.0.2.105:3001
Из командной строки можете сделать так:
$ sudo ifconfig pflow0 create flowsrc 192.0.2.1 flowdst 192.0.2.105:3001
В обоих случаях, эта команда устанавливает хоств для отправки данных NetFlow с адреса
источника 192.0.2.1 на коллектор, который слушает данные NetFlow на адресе
192.0.2.105, на порту UDP 3001.
Примечание
Можно настроить несколько устройств pflow с отдельными направлениями потока. Тем не менее, в настоящее время невозможно
указать, основываясь на правилах, какое устройство pflow должно получать генерируемые данные.
После включения устройства pflow, укажите в /etc/pf.conf правила pass которые должны
предоставлять данные NetFlow сенсору. Например, если ваша основная задача
заключается в сборе данных о почтовом трафике клиентов хостов IPv4, следующее
правило установит необходимый сенсор:
pass out log inet proto tcp from <client> to port $email \
label client-email keep state (pflow)
Когда pflow впервые появился в PF, немедленной реакцией ранних пользователей стало
то, что они хотели добавить pflow ко всем правилам pass из ранних наборов правил. Это
привело разработчика PF, Брауэра Хеннинга, к введению ещё одной полезной
возможности PF - установке состояния по умолчанию которое применяется для всех
правил, если не указано иное. Например, если вы добавите следующую строку в начале
вашего набора правил, все правила pass в конфигурации будут генерировать данные
NetFlow, которые будут экспортироваться через устройства pflow:
set state-defaults pflow
Создав по крайней мере одно устройство pflow и одно правило в pf.conf, генерирующее
данные для экспорта через устройство pflow, вы практически закончите настройку
сенсора. Однако, возможно, вам понадобится добавить правило, которое позволит
передачу UDP данных в поток с IP адреса который вы указали как источник потока
данных в IP адрес коллектора и целевой порт для назначения потока. После того, как вы
завершите этот последний шаг, вам следует переключить внимание на сбор данных для
последующей обработки.
Сбор, отчётность и анализ данных NetFlow
Если ваша система имеет инфраструктуру сбора и анализа данных основанную на
NetFlow, возможно, вы уже добавили все необходимые настройки конфигурации для
системы сбора и анализа данных PF. Если среда анализа данных потока у вас ещё не
настроена, вам доступны несколько вариантов.
Система пакетов OpenBSD предлает три коллектора и анализатора пакетов NetFlow: flowtools, flowd и nfdump3. Все три системы разработаны преданными ии компетентными
разработчиками и сообществами, и имеют множество дополнений, в том числе
графических web-интерфейсов. flow-tools - является основнм инструментом анализа
потока во многих развёртываниях. Фанаты nfdump указывают на анализатор пакетов
nfsen который объединяет инструменты nfdump в мощный и гибкий фронтенд с web
интерфейсом.
Выбор коллектора
Выбор коллектора, в какой-то мере, привязан к выбору пакета анализатора. Возможно по той причине, что коллектор, как
правило хранит поток данных в собственном уникальном формате, большинство бакендов отчётности и анализа
разрабатываются в зависимости от различий коллекторов.
Независимо от вашего выбора коллектора NetFlow, журналирование должно выполняться со следующей оговоркой: подробная
информация журналирования трафика требует хранения. В случае NetFlow, каждый поток будет генерировать запись
фиксированного размера, и по неофициальным данным, даже скромный набор профилей на загруженных системах может
генерировать гигабайт данных NetFlow в день. Объём памяти, необходимый вам, прямо пропорционален количеству
соединений и тому как долго вы храните исходные данные NetFlow. Наконец следует помнить о правовых аспектах.
Коллекторы обычно предлагают некоторые возможности фильтрации, позволяющие отбросить данные о специфических хостах
или сетях, или даже отбросить некоторые части записей NetFlow, глобально или для указанных хостов и сетей.
Чтобы проиллюстрировать некоторые основы сбора данных NetFlow и то, как извлекать
подмножество собранных данных для дальнейшего анализа, мы будем использовать flowd,
достаточно длительное время разрабатываемого Дамьеном Миллером (Damien Miller),
одним из разработчивков OpenBSD и доступном посредством системы пакетов (на
OpenBSD в качестве net/flowd, а на FreeBSD как net-mgmt/flowd). Я решил использовать
flowd в основном потому, что она была разработана как маленькая, простая и безопасная
система. Как вы увидите далее, flowd по прежнему удаётся быть весьма полезным и
гибким инструментом. Оперирование с потоком данных посредством других инструментов
будут оличаться только в некоторых деталях, однако основные принципы остаются теми
же.
В сравнении с другими пакетами коллекторов NetFlow, flowd очень компактен и состоит
только из двух исполняемых программ (демона коллектора flowd и программы фильтрации
и представления потока flowd-reader), библиотеки поддержки и файла конфигурации.
Документация программы весьма краткая но адекватная, образец файла /etc/flowd.conf
содержит большое количество подробных комментариев. Основываясь на странице
руководства и комментариях в образце конфигурационного файла вы потратите совсем
немного времени на создание полезной конфигурации коллектора.
После удаления строк комментариев (используем команду grep -v \# /etc/flowd.conf или
аналогичную), базовый файл конфигурации flowd может выглядеть следующим образом:
logfile "/var/log/flowd"
listen on 192.0.2.105:3001
flow source 192.0.2.1
store ALL
Хотя эта конфигурация содержит не больше информации чем конфигурация интерфейса
pflow при настройке сенсора, она включает два важных пункта:
•
•
Строка logfile сообщает нам, где будут храниться собранные данные (и показывает,
что flowd стремится хранить все данные в одном файле).
Последняя строка говорит нам, что flowd будет сохранять все поля в данных
полученных от назначенного потока источника.
Запустив демон flowd с этой конфигурацией, практически сразу вы увидите рост файла
/var/log/flowd, показывающий, что сетевой трафик проходит через шлюз и записи потоков
собираются коллектором. Через некоторое время вы сможете посмотреть на данные
используя программу flowd-reader. Для примера с сохранением всех полей, данные для
одного поиска имени с хоста в NAT локальной сети выглядят в flowd-reader примерно так:
$ sudo flowd-reader /var/log/flowd
FLOW recv_time 2011-04-01T21:15:53.607179 proto 17 tcpflags 00 tos 00 agent
[213.187.179.198] src [192.168.103.254]:55108 dst [192.168.103.1]:53 packets 1
octets 62
FLOW recv_time 2011-04-01T21:15:53.607179 proto 17 tcpflags 00 tos 00 agent
[213.187.179.198] src [192.168.103.1]:53 dst [192.168.103.254]:55108 packets 1
octets 129
Обратите внимание, что поиск генерирует два потока: по одному в каждом направлении.
Первый поток определяется главным образом по времени получения, далее следует
используемый протокол (протокол 17 это UDP, как вам может подсказать /etc/protocols).
Оба флага соединения TCP и TOS сняты, и коллектор получает данные от нашего шлюза
192.0.2.1. Адрес источника потока 192.168.103.254, порт источника 55108, адрес
назначения 192.168.103.1 и порт 53, т.е. порт DNS. Поток состоял из одного пакета с
полезной нагрузкой в 62 октета. В то же время коллектором был получен обратный поток,
и мы видим, что этот поток имеет обратные значения источника и назначения, с чуть
большей полезной загрузкой в 129 октетов. Выходной формат flowd-reader поддаётся
разбору с помощью регулярных выражений для последующей обработки инструментами
отчётности или графопостроителями.
Вы можете подумать, что эти данные - всё что можно узнать о наборе сетевых потоков,
однако реально можно извлечь и более подробную информацию. Например, с помощью
опции -v программы flowd-reader можно получить более подробный вывод, который
выглядит примерно так:
FLOW recv_time 2011-04-01T21:15:53.607179 proto 17 tcpflags 00 tos 00 agent
[213.187.179.198] src [192.168.103.254]:55108 dst [192.168.103.1]:53 gateway
[0.0.0.0] packets 1 octets 62 in_if 0 out_if 0 sys_uptime_ms 1w5d19m59s.000
time_sec 2011-04-01T21:15:53 time_nanosec 103798508 netflow ver 5 flow_start
1w5d19m24s.000 flow_finish 1w5d19m29s.000 src_AS 0 src_masklen 0 dst_AS 0
dst_masklen 0 engine_type 10752 engine_id 10752 seq 5184351 source 0 crc32
759adcbd
FLOW recv_time 2011-04-01T21:15:53.607179 proto 17 tcpflags 00 tos 00 agent
[213.187.179.198] src [192.168.103.1]:53 dst [192.168.103.254]:55108 gateway
[0.0.0.0] packets 1 octets 129 in_if 0 out_if 0 sys_uptime_ms 1w5d19m59s.000
time_sec 2011-04-01T21:15:53 time_nanosec 103798508 netflow ver 5 flow_start
1w5d19m24s.000 flow_finish 1w5d19m29s.000 src_AS 0 src_masklen 0 dst_AS 0
dst_masklen 0 engine_type 10752 engine_id 10752 seq 5184351 source 0 crc32
f43cbb22
Поле gateway указывает, что сенсор сам служит шлюзом для этого соединения. Вы
увидите список учавствующих интерфейсов (in_if и out_if), время непрерывной работы
сенсора (sys_uptime_ms), а так же множество других параметров, таких как AS номера
(src_as и dst_as - как я понимаю речь идёт о номерах автономных систем источника и
назначения п.п.), которые могут быть полезны для статистики или фильтрации целей в
различных контекстах. И снова следует отметить, что вывод очень подходит для
фильтрации с помощью регулярных выражений.
Вам не следует полагаться на внешние программы для начальной фильтрации данных
собранных с вашего датчика pflow. flowd предлагает широкий спектр фильтров, которые
позволяют хранить только необходимые данные. Один из подходов - ввести выражения
фильтрации в flowd.conf, как показано в следующем примере:
logfile "/var/log/flowd.compact"
listen on 192.0.2.105:3001
flow source 192.0.2.1
store SRC_ADDR
store DST_ADDR
store SRCDST_PORT
store PACKETS
store OCTETS
internalnet = "192.168.103.0/24"
unwired = "10.168.103.0/24"
discard src $internalnet
discard dst $internalnet
discard src $unwired
discard dst $unwired
Вы можете хранить только некоторые поля в записях потока. Для примера, в
конфигурации которая содержит только один коллектор или агент, поле agent не
содержит никакой полезной информации и сохраняться не должно. В этой конфигурации
мы будем хранить только адрес источника, получателя, порт, число пакетов и число
октетов.
Вы можете ограничить хранимые данные ещё больше. Макросы internaknet и unwired
расширяются для двух натированных локальных сетей, а четыре строки discard
следующие за определением макросов означают, что flowd отбрасывает все данные,
получаемые о потоках с любых источников и назначений в любой из этих сетей.
Результатом станет более компактный набор данных, учитывающий ваши конкретные
потребности, и вы будете видеть только маршрутизируемые адреса и адреса сенсоров
внешнего интерфейса шлюза:
$ sudo flowd-reader /var/log/flowd.compact | head
FLOW src [193.213.112.71]:38468 dst [192.0.2.1]:53 packets 1 octets 79
FLOW src [192.0.2.1]:53 dst [193.213.112.71]:38468 packets 1 octets 126
FLOW src [200.91.75.5]:33773 dst [192.0.2.1]:53 packets 1 octets 66
FLOW src [192.0.2.1]:53 dst [200.91.75.5]:33773 packets 1 octets 245
FLOW src [200.91.75.5]:3310 dst [192.0.2.1]:53 packets 1 octets 75
FLOW src [192.0.2.1]:53 dst [200.91.75.5]:3310 packets 1 octets 199
FLOW src [200.91.75.5]:2874 dst [192.0.2.1]:53 packets 1 octets 75
FLOW src [192.0.2.1]:53 dst [200.91.75.5]:2874 packets 1 octets 122
FLOW src [192.0.2.1]:15393 dst [158.37.91.134]:123 packets 1 octets 76
FLOW src [158.37.91.134]:123 dst [192.0.2.1]:15393 packets 1 octets 76
Даже с опцией -v, вывод flowd-reader показывает только то, что явно указано в настройке
фильтрации:
$ sudo flowd-reader -v /var/log/flowd.compact | head
LOGFILE /var/log/flowd.compact
FLOW src [193.213.112.71]:38468 dst [192.0.2.1]:53 packets 1 octets 79
FLOW src [192.0.2.1]:53 dst [193.213.112.71]:38468 packets 1 octets 126
FLOW src [200.91.75.5]:33773 dst [192.0.2.1]:53 packets 1 octets 66
FLOW src [192.0.2.1]:53 dst [200.91.75.5]:33773 packets 1 octets 245
FLOW src [200.91.75.5]:3310 dst [192.0.2.1]:53 packets 1 octets 75
FLOW src [192.0.2.1]:53 dst [200.91.75.5]:3310 packets 1 octets 199
FLOW src [200.91.75.5]:2874 dst [192.0.2.1]:53 packets 1 octets 75
FLOW src [192.0.2.1]:53 dst [200.91.75.5]:2874 packets 1 octets 122
FLOW src [192.0.2.1]:15393 dst [158.37.91.134]:123 packets 1 octets 76
К счастью, flowd не заставляет вас делать применять все ваши решения фильтрации в тот
момент когда коллектор получает поток данных от сенсоров. Использование флага -f
позволит указать отдельный файл с заявлениями фильтрации на извлечение
определённых данных из большого набора собранных данных потока. Например, чтобы
увидеть HTTP трафик нашего web-сервера, вы можете написать фильтр, который хранит
только потоки с адреса вашего web-сервера и TCP порта назначения с номером 80, или
адреса web-сервера и TCP порта 80 как источника:
webserver = 192.0.2.227
discard all
accept dst $webserver port 80 proto tcp
accept src $webserver port 80 proto tcp
store RECV_TIME
store SRC_ADDR
store DST_ADDR
store PACKETS
store OCTETS
Предположив, что вы храните фильтр в towebserver.flowdfilter, вы можете извлечь трафик,
соответствующий вашим критериям фильтрации из /var/log/flowd:
$ sudo flowd-reader -v -f towebserver.flowdfilter /var/log/flowd | tail
FLOW recv_time 2011-04-01T21:13:15.505524 src [89.250.115.174] dst
[192.0.2.227] packets 6 octets 414
FLOW recv_time 2011-04-01T21:13:15.505524 src [192.0.2.227] dst
[89.250.115.174] packets 4 octets 725
FLOW recv_time 2011-04-01T21:13:49.605833 src [216.99.96.53] dst [192.0.2.227]
packets 141 octets 7481
FLOW recv_time 2011-04-01T21:13:49.605833 src [192.0.2.227] dst [216.99.96.53]
packets 212 octets 308264
FLOW recv_time 2011-04-01T21:14:04.606002 src [91.121.94.14] dst [192.0.2.227]
packets 125 octets 6634
FLOW recv_time 2011-04-01T21:14:04.606002 src [192.0.2.227] dst [91.121.94.14]
packets 213 octets 308316
FLOW recv_time 2011-04-01T21:14:38.606384 src [207.46.199.44] dst
[192.0.2.227] packets 10 octets 642
FLOW recv_time 2011-04-01T21:14:38.606384 src [192.0.2.227] dst
[207.46.199.44] packets 13 octets 16438
FLOW recv_time 2011-04-01T21:15:14.606768 src [213.187.176.94] dst
[192.0.2.227] packets 141 octets 7469
FLOW recv_time 2011-04-01T21:15:14.606768 src [192.0.2.227] dst
[213.187.176.94] packets 213 octets 308278
В дополнение к фильтрации продемонстрированной здесь, функции фильтрации flowd
имеют несколько других вариантов. некоторе из этих вариантов покажутся знакомыми из
других контекстов фильтрации, таких как PF, включая диапазон сетевых параметров, а
прочие больше ориентированы на извлечение данных о потоках происходящих в
определённое время или периоды времени. Полное описание можно найти в man
flowd.conf.
После извлечения требуемых данных, вы можете использовать некоторые инструменты,
доступные для обработки и представления данных.
Сбор данных NetFlow с помощью pfflowd
Для систем которые не поддерживают экспорт данных NetFlow через pflow, NetFlow
поддерживает порт доступный посредством пакета pfflowd. Модель данных NetFlow
определяет сетевой поток, как однонаправленную последовательность пакетов с одного IP
адреса источника и нзанчения и протокола. Это хорошо отображает информацию
состояния PF, а pfflowd предназначен для записи изменений состояний с локальных
устройств системы pfsync. После включения, pfflowd действует как сенсор NetFlow
который преобразует данные pfsync в формат NetFlow для передачи в сетевой коллектор
NetFlow.
Инструмент pfflowd написан и поддерживается Дамьеном Миллером (Damien Miller), и
доступен через http://www.mindrot.org/projects/pfflowd/ и систему пакетов OpenBSD или
систему портов FreeBSD как net/pfflowd. Отсутствие поддержки pfsync в NetBSD означает,
что pfflowd не доступен на этой платформе, по крайней мере на момент написания статьи.
Инструменты SNMP и связанные с PF SNMP MIBs
SNMP был разработан для сбора и отслеживания ключевых данных работы систем и
изменения конфигураций на множестве сетевых узлов централизованной системы. 4
Протокол SNMP поставляется с четко определённым интерфейсом и методом расширения
информационной базы управления (MIB), которая определяет управления устройствами и
объектами.
Как для проприетарных, так и для открытых систем мониторинга и управления сетью,
SNMP поддерживается в той или в иной форме. На BSD системах, поддержка SNMP, как
правило, осуществляется в виде Net-SNMP пакета, который предоставляет инструменты
необходимые для получения и сбора данных SNMP. Пакет доступен на OpenBSD как
net/net-snmp, на FreeBSD как net-mgmt/net-snmp, и на NetBSD как net/net-snmp.
OpenBSD snmpd (большей частью написаный Reyk Floeter) дебютировал как часть базовой
системы в OpenBSD 4.3, и выполняет все требования функциональности SNMP.
(Обратитесь к man snmpd и man snmpd.conf для получения детальной информации).
Существует MIB позволяющая сделать доступными данные PF для мониторинга SNMP.
Джоел Кнайт (Joel Knight) поддерживает MIB для получения данных PF, CARP и сенсоров
ядра OpenBSD, и вы можете загрузить её на http://www.packetmischief.ca/openbsd/snmp/.
Кроме того, сайт предлагает патчи для пакета net-snmp для интеграции OpenBSD MIB.
После установки пакета и расширений, ваша система SNMP мониторинга позволит
получать данные PF в любой детализации. (В FreeBSD bsnmpd включён в модуль PF.
Обратитесь к странице man bsnmpd для изучения деталей).
Данные журналов как основа для эффективной отладки
В этой главе мы рассмотрели основы сбора, отображения и интерпретации данных о
системе с включённым PF. Знание того, как находить и использовать информацию о
поведении системы может быть полезна в нескольких целях.
Отслеживание статуса работающей системы полезно само по себе, но умение читать и
интерпретировать данные журнала имеют важное значение при тестировании установки.
Другой пример использования данных журнала - отслеживание влияния изменений
вносимых в конфигурацию, например при настройке вашей системы на оптимальную
производительность. В следующей главе мы сосредоточимся на проверке вашей
конфигурации и настройке оптимальной производительности, основываясь на журналах и
других наблюдениях.
ДОСТИЖЕНИЕ
ПРАВИЛЬНОГО
РАЗВЕРТЫВАНИЯ
К настоящему времени, вы потратили много времени проектированию сети и
реализации спроектированной конфигурации PF. Для достижения правильного
развертывания – то есть удаления всех оставшихся ошибок настройки и
неэффективности может быть довольно сложным в разы.
Эта глава описывает некоторые опции и методы, которые помогут вам получить
необходимую для вас настройку. Во-первых, мы взглянем на глобальные опции
и некоторые настройки, которые мы имеем, оказывают глубокое влияние на
поведение вашей конфигурации.
Вещи которые вы можете изменить и те, которые
вероятно следует оставить в покое
Сетевые конфигурации по своей природе весьма настраиваемы. При просмотре страницы
man pf.conf или другой документации, легко быть ошеломленным количеством опций и
настроек, которые вы, вероятно, можете настроить, для того чтобы получить прекрасно
оптимизированных настроек.
Помните, что для PF в целом, настройки по умолчанию являются нормальными для
большинства случаев. Некоторые параметры и переменные поддаются настройке, другие
должны настраиваться с большой осторожностью, потому, что они должны быть
скорректированы только в очень необычных обстоятельствах. Здесь мы будем
рассматривать некоторые глобальные настройки, которые вы должны знать, хотя вам в
большинстве случаев не придется их менять. Эти параметры записываются в виде набора
параметров и переходят после любого макроопределения в файл pf.conf, но до перевода
или фильтрации правил.
Замечание:
Если вы читаете страницу man pf.conf, вы откроете, что доступны несколько разных параметров. Однако, большинство из них не
относятся к тестированию сети в контексте оптимизации производительности.
Запрещающие политики
Запрещающие политики определяют, какую обратную связь, если таковая имеется, PF
даст хостам, которые пытаются создать соединение, которые затем оказываются
заблокированы. Опция имеет два возможных значения:
•
•
drop отбросывает заблокированный пакет без обратной связи
return возвращает код статуса такой как Отказ в соединении (Connection refused)
или что-то похожее
Правильная стратегия для блокирующих политик была предметом серьезного обсуждения
на протяжении многих лет. Значение по умолчанию для блокирующих политик это
отбросить, что означает, что пакет молча будет отброшен без какой-либо обратной связи.
Тем не менее, молча отбрасывая пакеты делает это похожим на то, что отправитель
повторно отправляет неподтвержденные пакеты, а не разрывает соединение. Таким
образом, усилие соединиться сохраняется пока не истечет счетчик соответствующего
тайм-аута. Если вам не приходит в голову веская причина для установки блокирующих
политик, установите значение return:
set block-policy return
Это значит, что сетевой стэк отправителя получит недвусмысленный сигнал о том, что
соединение отклоенено.
Эта настройка определяет глобальное значение по умолчанию для ваших запрещающих
политик. При необходимости, вы может изменять тип блокировки для определенных
правил.
Например, вы могли бы изменить набор правил для защиты от брут-форса из главы 6,
чтобы запрещающие политики были настроены на возвращение, но использовали
блокировку отбрасывания quick из <bruteforce> сделать брут-форс по истечении времени,
если они пробиваются внутрь, после того как были добавлены в таблицу. Кроме того,
можно указать на отбрасывания трафика от немаршрутизируемых адресов входящих на
ваш интерфейс смотрящий в интернет.
Пропуск интерфейсов
Опция skip позволяет вам исключить определенные интерфейсы из всех обработок PF.
Конечный результат получается как правило пропустить все для интерфейса, но на самом
деле отключает все обработки PF на интерфейсе.
Одним из распространенных примеров является отключение фильтрации на группе
loopback интерфейса, где фильтрация в большинстве конфигураций добавляет немного с
точки зрения безопасности или удобства, а именно: set skip on loopback фактически,
фильтрация на loopback интерфейсе почти никогда не бывает полезна, и может привести
к некорректным результатам с рядом общих программ и служб. По умолчанию опция skip
не установлена, что означает, что все сконфигурированные интерфейсы могут принимать
участие в обработке PF. В дополнение к небольшому упрощению набора правил,
установка skip на границах, где вы не хотите выполнять фильтрацию результатов для
небольшого прироста производительности.
Политики состояний
Опция state-policy указывает, как PF сопоставляет пакеты в таблице состояний.
Существует два возможных значения:
•
•
при установке по умолчанию политика состояния является плавающей, трафик
может соответствовать состоянию на всех интерфейсах, а не только на том где
состояние было создано.
В случае связанной политике, трафик будет соответствовать только на том
интерфейсе, где состояние было создано, трафик на других интерфейсах не будет
соответствовать существующему состоянию.
Как блокирующая политика, эта опция определяет глобальное состояние сопоставления
политики. Вы можете изменить политику состояния в области за основными правилами,
если это необходимо. Например, в набор правил по умолчанию плавающей политики
состояния, вы могли бы иметь следующее правило:
pass out on egress inet proto tcp to any port $allowed modulate state (if-bound)
с этим правилом, любой обратный трафик попытается передать обратно в случае, если
нужно пропустить на тот же интерфейс, где состояние было создано в порядке
соответствующем записи в таблице состояний.
Состояние по умолчанию
Опция state-defaults была введена в OpenBSD 4.5 включить установление конкретных
опций состояния как опций по умолчанию во всех правилах наборе правил, если только
специально переопределены другие опции в отдельных правлах.
Вот общий пример:
set state-defaults pflow
Это устанавливает все проходящие правила в конфигурации для генерации NetFlow
данных, которые будут экспортироваться через pflow устройство.
В некоторых случаях имеет смысл применять опции отслеживания состояния (statetracking), такие как ограничения на подключения, как глобальное состояние по
умолчанию для всего набора правил. Вот пример:
set state-defaults max 1500, max-src-conn 100, source-track rule
Это устанавливает по умолчанию максимальное количество записей в таблице состояний
каждого правила до 1500, с максимумом до 100 одновременных соединений с любого
одного хоста, с отдельными лимитами для каждого правила в загруженном наборе правил.
Любая опция которая действует в скобках для сохранения состояния в отдельном правиле
может быть также включена в набор состояний по умлочанию. Настройка состояний по
умолчанию, таким образом, является полезным, если есть опции состояний, которые еще
не являются системой по умолчанию, которые необходимо применить для всех правил в
вашей конфигурации.
Таймауты
Опция timeout устанавливает таймауты и связанные опции для различных
взаимодействий с записями в таблице состояний. Большинство доступных параметров это
конкретный протокол значения хранящиеся в секундах и префиксах tcp., udp., icmp., и
другие. Тем не менее, adaptive.start и adaptive.end обозначает количество записей в
таблице состояний. Следующие опции таймаутов влияют на таблицу состояний,
использования памяти и некоторой степени скорости поиска:
•
•
•
•
adaptive.start
и
adaptive.end
значения
устанавливают
ограничения
для
сворачивания значения таймаута, когда число записей в таблице состояний
достигают значения adaptive.start. Когда число состояний достигает adaptive.end,
все таймауты установлены в 0, по существу, истекают все состояния немедленно.
По умолчанию есть 6000 и 12000 (в расчете как 60 и 120 процентов лимита
состояния), соответственно. Эти параметры тесно связаны с пулом памяти
предельных параметров, установленные через опцию предела.
Значение interval обозначает количество секунд между чистками просроченных
состояний и фрагментов. По умолчанию 10 секунд.
Значение frag обозначает количество секунд в течение которого фрагмент будет
хранится в разобранном состоянии, прежде чем будет отброшен. По умолчанию 30
секунд.
Если установлен, src.track обозначает количество секунд, источник отслеживания,
данные будут храниться после последнего истекшего состояния. По умолчанию 0
секунд.
Вы можете инспектировать текущие настройки для всех параметров timeout c pfctl –s
timouts. Например, следующее отображение показывает систему с запущенными
значениями по умолчанию.
$ sudo pfctl -s timeouts
tcp.first
120s
tcp.opening
30s
tcp.established
86400s
tcp.closing
900s
tcp.finwait
45s
tcp.closed
90s
Getting Your Setup Just Right
155
tcp.tsdiff
30s
udp.first
60s
udp.single
30s
udp.multiple
60s
icmp.first
20s
icmp.error
other.first
other.single
other.multiple
frag
interval
adaptive.start
adaptive.end
src.track
10s
60s
30s
60s
30s
10s
6000 states
12000 states
0s
Эти опции могут быть использованы для настройки вашей системы для повышения
производительности. Тем не менее, изменения протокола настройки отдельных значений
по умолчанию создает значительный риск, что действительно, но неактивные соединения
могут быть удалены или заблокированы преждевременно напрямую.
Лимиты
Опция limit устанавливает размер пула памяти используемого PF для таблицы состояний и
таблицы адресов. Это тяжелые пределы, так вам может понадобиться повысить или
настроить значения по различным причинам. Если ваша сеть занята с большим
количеством, чем значения по умолчанию позволяют, или если ваши настройки
нуждаются в большей таблице адресов или большем количестве таблиц, чем в этом
разделе это будет очень актуально для вас.
Помните что общее количество памяти доступное через пул памяти берется из адресного
пространства ядра, и общая доступность это функция общей доступности памяти ядра.
Ядро выделяет определенное количество памяти для собственного использования при
запуске системы. Однако, так как память ядра никогда не изменяется, количество памяти
выделенной для ядра никогда не может равняться или превышать всю физическую память
в системе. (если это случилось, то не будет пространства для запуска пользовательского
режима программы.)
Количество доступной памяти в пуле зависит от использования некоторых аппаратных
платформ, которые вы используете, а также на ряд трудно предсказываемых переменных
характерных для локальной системы. На архитектуре i386 максимальный размер памяти
ядра от 768Мб до 1Гб, в зависимости от ряда факторов, включая количество и тип
устройств в системе. Количество фактически доступного для распределения пулам памяти
выходит из этого количества, опять же в зависимости от числа системно-ориентированных
переменных.
Для просмотра текущих настроек limit используйте pfctl –sm. Обычно вывод выглядит
так:
$ sudo pfctl -sm
states
hard limit 10000
src-nodes
hard limit 10000
frags
hard limit
5000
tables
hard limit
1000
table-entries hard limit 200000
Изменить эти значения, отредактируйте pf.conf включая одну или более строк с новыми
значениями limit. Например, вы могли бы использовать следующие строки, чтобы
повысить жестко лимиты для количества состояний до 25000 и записей таблиц до 300000:
set limit states 25000
set limit table-entries 300000
Вы можете также установить несколько парметров limit в то же время в одной строке,
заключив их в квадратные скобки, например:
set limit { states 25000, src-nodes 25000, table-entries 300000 }
В конце концов, вы почти наверняка не должны изменять лимиты для всех. Если вы это
сделаете, тем не менее, важно, посмотреть логии системы на предмет любых признаков
того, что ваши изменения лимитов не имели нежелательные побочные эффекты или
вписываются в доступную память. Установка уровня отладки в более высокое значение
потенциально весьма полезно для просмотра эффектов параметров настройки предела.
Отладка
Опция debug определяет, что если таковые имеются, информация об ошибке PF будет
генерироваться на уровне журнала kern.debug. Значения по умолчанию err, означает, что
только серьезные ошибки будут журналироваться. Начиная с OpenBSD 4.7 уровень
журналирования здесь соответствует обычным уровням системного журнала, которые
варьируются с emerg (входят также сообщения о панике), alert (исправляемые, но очень
серьезные ошибки журналируются), crit (критические ошибки журналируются), err
(ошибки журналируются), warning (предупреждения журанлируются), notice (необычные
условия журналируются), info (информационные сообщения журналируются), debug
(полная отладочная информация, скорее всего, полезно только для разроботчиков).
В версиях предыдущих OpenBSD 4.7, PF использовал только свой собственных уровень
журналирования, с настройками по умолчанию urgent (эквивалентным err сообщениям в
новой системе). Другие возможные настройки были none (вообще без сообещений), misc
(отчетность чуть большая, чем urgent) и loud (сообщения о состоянии для большинства
операций). Синтаксический анализатор pfctl все еще понимает старый стиль правил для
совместимости.
После запуска на одном из моих шлюзов в debug уровне через небольшое время, это то,
что является типичным куском журнала /var/log/messages файл сообщений выглядел так:
$ tail -f /var/log/messages
Oct 4 11:41:11 skapet /bsd: pf_map_addr: selected address 194.54.107.19
Oct 4 11:41:15 skapet /bsd: pf: loose state match: TCP 194.54.107.19:25
194.54.107.19:25 158.36.191.135:62458 [lo=3178647045 high=3178664421 win=33304
modulator=0 wscale=1] [lo=3111401744 high=3111468309 win=17376 modulator=0
wscale=0] 9:9 R seq=3178647045 (3178647044) ack=3111401744 len=0 ackskew=0
pkts=9:12
Oct 4 11:41:15 skapet /bsd: pf: loose state match: TCP 194.54.107.19:25
194.54.107.19:25 158.36.191.135:62458 [lo=3178647045 high=3178664421 win=33304
modulator=0 wscale=1] [lo=3111401744 high=3111468309 win=17376 modulator=0
wscale=0] 10:10 R seq=3178647045 (3178647044) ack=3111401744 len=0 ackskew=0
pkts=10:12
Oct 4 11:42:24 skapet /bsd: pf_map_addr: selected address 194.54.107.19
Как вы может видеть, debug уровень дает детальный просмотр там, где PF неоднократно
отчитывается по обрабатываемым IP адресам на интерфейсе. В промежутках между
выбранными сообщениями адрес, PF предупреждает два раза об одном и том же пакете,
порядковый номер находится на самом краю ожидаемого диапазона. Такой уровень
детализации кажется почти захватывающим, на первый взгляд, но в некоторых
обстоятельствах, изучение этого вида вывода является лучшим способом для диагностики
проблемы, а затем проверки, действительно ли ваше решение помогло.
Замечание:
Эта опция может быть установлена из командной строки с использованием pfctl –x, следующим уровнем отладки нужным именно
вам. Команда pfctl –x debug дает вам максимум отладочной информации; pfctl –x none выключает отладочные сообщения
полностью.
Помните, что некоторые отладочные настройки могут производить огромное количество
журнальных данных, и в экстремальных случаях, могут повлиять на производительность
вплоть до уровня самоотказа в обслуживании.
Оптимизация набора правил
Опция ruleset-optimization включает или устанавливает режим для оптимизатора набора
правил. По умолчанию настройка для ruleset-optimization в OpenBSD 4.1 эквивалентна
none, что означает, что набор правил, который загружен не оптимизирован. В OpenBSD
4.2 и далее, по умолчанию является основным, а это значит, что, когда набор правил
загружен, оптимизатор делает следующие вещи:
•
•
•
Удаляет дублирующиеся правила
Удаляет правила, которые являются подмножеством других правил
Осуществляет слияние в таблицах при необходимости (типичное rule-to-table
оптимизирующие пропускающие, перенаправления или блокирующие правила
•
основанные на идентичных критериях кроме источника и/или целевых адресов)
Изменяет порядок правил повышая производительность
Например, скажем вы имеет макрос tcp_services = { ssh, www, https } комбинированный с
правилом pass proto tcp from any to self port $tcp_services. В другом месте набора правил,
у вас есть другое правило, которое говорит pass proto tcp from any to self port ssh. Второе
правило явно является подмножеством первого, а значит они могут быть объединены в
одно. Другая распространенная комбинация имеем pass rule like pass proto tcp from any to
int_if:network port $tcp_services с каким-то идентичным правлом, где целевые адреса
находятся в том же диапазоне, что и все в int_if сети.С
установленным
rulesetoptimization, оптимизатор анализирует загруженный набор правил по отношению к
фактическому сетевому трафику с целью определения оптимального порядка и быстроты
правил.
Вы также можете установить значение опции оптимизации из командной строки с pfctl:
$ sudo pfctl -o basic
Этот пример включает оптимизацию набора правил в режим basic.
С оптимизацией могут удаляться или упорядочиваться правила, что значимо для
некоторых статистических данных, - главным образом ряд оценок в правилах может
измениться таким образом, что некоторые могут быть трудно предсказуемыми. Однако в
большинстве случаев, эффект незначителен.
Оптимизация
Опция optimization определяет профили для обработки состояния тайм-аутов. Возможные
значения: normal, high-latency, satellite, aggressive, conservation. Рекомендуется иметь по
умолчанию в значении normal, если у вас очень специфические потребности. Значения
high-latency и satellite являются синонимами, где состояния истекают более медленно,
чтобы компенсировать потенциально состояние high-latency. А установка aggressive
состояния истекают раньше, чтобы сохранить память. Это может, в принципе, повышать
риск откидывания простаивающих-но-действительных соединений, если ваша система
близка к пределу нагрузки трафика, но неофициальные данные показывают, что
настройки aggressive оптимизации редко, если вообще используется, препятствует
разрешенному трафику.
Установка сonservative предназначена для того, чтобы сохранить состояния
простаивающих соединений, за счет некоторого дополнительного использования памяти.
Фрагментарная сборка
Опция fragment reassembly связаная с отменой была значительно переработана в
OpenBSD 4.6, введения нового набора сборки, возможность включить или
выключитьсборку фрагментированных пакетов. По умолчанию set reassemble on, что
означает фрагменты собраны и собранные пакеты где, нет фрагментированного бита были
установлены в отдельные фрагменты, которые будут иметь очищенный бит.
Очистка вашего трафика
Следующие две особенности, которые мы будем обсуждать, скраб и антиспуф, часть
общей темы: они обеспечивают автоматизированную защиту от потенциально опасных
помех в вашем сетевом трафике. Вместе они обычно упоминаются в качестве инструмента
для «гигиены сети», потому, что они дезинфицируют значительную часть сети.
Нормализация пакета со скрабом
В PF до версии OpenBSD 4.5 включительно, ключевое слово scrub активирует
нормализацию сетевого трафкиа. Со скрабом, фрагментированные пакеты будут собраны,
а недействительные фрагменты такие как перекрывающиеся фрагменты удаляются, так
что в результате пакет, является полным и недвусмысленным.
Включение srub предоставляет меры по защите от определенных видов атак, основанных
на неправильной обработке фрагментов пакетов1. Количество дополняющих вариантов, но
простейшая форма подходит для большинства конфигураций.
scrub in
Для того, чтобы некоторые сервисы работали со скрабом, должны быть установлены
конкретные параметры. Один из часто цитируемых примеров некоторые NFS реализации,
которые не будут работать со скрабом вообще, если вы используете не-df параметр, чтобы
очистить нефрагментированный бит в любых пакетах, которые имеют установленный бит.
Некоторые комбинации сервисов, ОС и сетевых конфигураций может нуждаться в
некоторых более экзотических опциях скраба.
В OpenBSD 4.6, скраб был понижен из материала автономных правил, чтобы сделать
действующим вы могли бы прикрепить, чтобы передавать или соответствовать правилам
(введением соответствия является одним из основных новых функций PF в OpenBSD 4.6).
Еще одним важным событием в том же переписывании кода скраба было то, что
многочисленные варианты пакетных сборок были ликвидированы в пользу вновь
собранных вариантов, которые просто включают сборку или выключают. С помощью
нового синтаксиса скраба, вам нужно поставить по крайней мере одну опцию в скобках.
Следующий вариант работает достаточно хорошо в нескольких сетях с которыми я
работаю:
match in all scrub (no-df max-mss 1440)
Это очищает нефрагментированный бит и устанавливаем максимальны размер сегмента в
1440 байт.
Другие варианты тоже возможны, и даже если список вариантов скраба несколько
сократились в версии OpenBSD 4.6, вы должны иметь возможность для удовлетворения
различных специфических потребностей, просмотрите страницы man и сделайте
несколько экспериментов. Если вам понадобится для отладки проблемы связанной тесно
со скрабом, изучите pf.conf man страницу и проконсультируйтесь с гуру по
соответствующим спискам рассылки.
Защита от спуфинга с antispoof
Существует несколько очень полезных и общих действий для пакетной обработки,
которые могут быть записаны как правила PF, но не без них становится длинным,
сложным и подвержен ошибкам шаблонного набора правил. Таким образом, антиспуф был
реализован для общего частного случая фильтрации и блокировки. Этот механизм
защищает от деятельности подделки или поддельных IP адресов, в основном, путем
блокирования пакетов, которые появляются на интерфейсах путешествующих в
направлениях, которые логически невозможны.
С antispoof вы можете указать, что вы хотите, чтобы отсеять поддельный трафик,
поступающий внутрь от остального мира и любые поддельные пакеты, которые (тем не
менее вряд ли) должны были происходить из вашей собственной сети. Рисунок 9-1
иллюстрирует эту концепцию.
Чтобы установить вид защиты изображенный на диаграмме, укажите antispoof для обоих
интерфейсов в сети, которое иллюстрирует следующие две строки:
antispoof for $ext_if
antispoof for $int_if
Эти строки расширяют комплекс правил. Первая строка блокирует входящий трафик
когда адрес источника появится как часть сети напрямую соединенный с антиспуфовым
интерфейсом, а прибудет на другой интерфейс. Второе правило выполняет те же функции
для внутреннего интерфейса, блокируя любой трафик с явного адреса локальной сети,
которые прибывают на другие интерфейсы отличные от $int_if. Однако, имейте в виду,
что антиспуф предназначен для обнаружения подложных адресов удаленно для сетей,
которые не напрямую соединены с машиной, на которой запущен PF.
Рисунок 9-1. antispoof отбрасывает пакеты, пришедшие из неверной сети
Тестирование вашей настройки
Теперь пришло время сдуть пыль с точной спецификации, описывающей, как ваши
настройки должны работать. Физическое расположение нашего примера сети
сосредоточена вокруг шлюза подключенного к Интернету через $ext_if. В приложении к
шлюзу через $int_if имеется локальная сеть с рабочими станциями и, возможно, один или
несколько серевров для местного применения. И наконец, мы имеем DMZ подключенный
через $dmz_if, населенный серверами, предлагающих услуги локальной сети и Интернета.
Рисунок 9-2 показывает логическую схему сети.
Соответствующие спецификации набора правил выглядят следующим образом:
•
•
•
Машины вне нашей сети, должны иметь доступ к сервисам наших серверов в DMZ,
и не иметь доступа к локальной сети.
Машины в нашей локальной сети, прикрепленные через $int_if, должны иметь
доступ к нашим сервисам, предлагаемых сереврами в DMZ и доступ к
определенному перечню сервисов за пределами нашей сети
Машины в DMZ должны иметь доступ к некоторым сетевым сервисам во внешнем
мире.
Задача состоит в том, чтобы убедиться что набор правил, фактически реализует
спецификацию. Мы должны проверить настройки. Полезный тест можно было бы
попробовать изображенный в таблице 9-1. Вашей конфигурации может потребоваться
другие тесты или могут отличаться в некоторых частностях. Ваш реальный тестовый
сценарий должен указать, как пакеты и соединения должны быть зарегистрированы.
Главное, что вы должны решить, это ожидаемый и желаемый результат для каждого из
ваших тестов должно быть определен перед началом тестирования. В общем, вы должны
Рисунок 9-2. сеть с серверами в DMZ
Задача состоит в том, чтобы убедиться что набор правил, фактически реализует
спецификацию. Мы должны проверить настройки. Полезный тест можно было бы
попробовать изображенный в таблице 9-1. Вашей конфигурации может потребоваться
другие тесты или могут отличаться в некоторых частностях. Ваш реальный тестовый
сценарий должен указать, как пакеты и соединения должны быть зарегистрированы.
Главное, что вы должны решить, это ожидаемый и желаемый результат для каждого из
ваших тестов должно быть определен перед началом тестирования. В общем, вы должны
проверить использование приложений, которые как вы ожидаете должен иметь
пользователь. Такие как веб браузер или почтовый клиент в различных ОС. Соединения
должны просто быть приняты или отброшены, в соответствии со спецификацией. Если
один или более из ваших основных тестов дает неожиданные результат, переходите к
отладке набора правил.
Таблица 9-1. простой набор правил, в случае проверяющей последовательности
Тестируемое действие
Попробовать соединиться из локальной сети на каждый
разрешенный порт на серверы в DMZ
Попробовать соединиться из локальной сети на каждый
разрешенный порт на серверы вне нашей сети
Попробовать соединиться на любой порт из DMZ в
локальную сеть
Попробовать из DMZ на каждый разрешенный порт на
серверы вне нашей сети
Попробовать соединиться извне нашей сети на $webserver
в DMZ на каждый порт на $webports
Попробовать соединиться извне нашей сети на $webserver
в DMZ на порт 25 (SMTP)
Попробовать соединиться из вне нашей сети на
$emailserver в DMZ на 80 порт (HTTP)
Попробовать соединиться извне нашей сети на
$emailserver в DMZ на 25 порт (SMTP)
Попробовать соединиться извне нашей сети на один или
более машин в локальной сети
Ожидаемый результат
Соединение должно пройти
Соединение должно пройти
Соединение должно быть заблокировано
Соединение должно пройти
Соединение должно пройти
Соединение должно быть заблокировано
Соединение должно быть заблокировано
Соединение должно пройти
Соединение должно быть заблокировано
Отладка вашего набора правил
Когда конфигурация не ведет себя, так как ожидалось, может быть логическая ошибка в
наборе правил, поэтому вам нужно найти ошибку и исправить ее. Отслеживание
логических ошибок в вашем наборе правил может занять много времени, и может
включать оценки вашего набора правил вручную, так как хранится все это в pf.conf файле
и загружается версия после расширения макросов и любых оптимизаций. Пользователи
часто изначально винят PF в проблемах, которые оказываются основными проблемами
сети. Сетевые интерфейсы настроены в неправильные настройки дуплекса, плохие маски,
и неисправное оборудование сети являются общими виновниками.
Прежде чем погрузиться в набора правил, вы можете легко определить является ли PF
конфигурация причиной проблемы. Сделайте так, отключите PF используя pfctl –d, чтобы
посмотреть исчезла ли проблема. Если проблема не устраняется когда PF отключен, вы
должны обратиться к отладке других частей конфигурации. С другой стороны, если
проблема исчезла после отключения PF, и вы собираетесь начать исправлять
конфигурацию PF, убедитесь, что PF включен и, что ваш набор правил загружен, этой
командой:
$ sudo pfctl -si | grep Status
Status: Enabled for 20 days 06:28:24
Debug: err
Status: Enabled говорит нам, что PF включен, нужно попытаться посмотреть загрузились
правила используя различные команды:
$ sudo pfctl -sr
match in all scrub (no-df max-mss 1440)
block return log all
block return log quick from <bruteforce> to any
anchor "ftp-proxy/*" all
Здесь, pfctl –sr эквивалентно pfctl –s правилам. Фактический вывод вероятно, будет
немного больше, чем показано здесь, но это хороший пример того, что вы должны
ожидать, чтобы увидеть, когда набор правил загружен. Для отладки, попробуйте добавить
–vv флаг в командную строку pfctl, вы увидите количество правил и некоторую
дополнительную отладочную информацию примерно как эту:
$ sudo pfctl -vvsr
@0 match in all scrub (no-df max-mss 1440)
[ Evaluations: 341770 Packets: 3417668 Bytes: 2112276585 States: 125 ]
[ Inserted: uid 0 pid 14717 State Creations: 92254 ]
@1 match out on nfe0 inet from 10.0.0.0/8 to any queue(q_def, q_pri) nat-to
(nfe0:1) round-robin static-port
[ Evaluations: 341770 Packets: 0
Bytes: 0
States: 0
]
[ Inserted: uid 0 pid 14717 State Creations: 0
]
@2 match out on nfe0 inet from 192.168.103.0/24 to any queue(q_def, q_pri) nat-to
(nfe0:1) round-robin static-port
[ Evaluations: 68623
Packets: 2138128 Bytes: 1431276138 States: 103 ]
[ Inserted: uid 0 pid 14717 State Creations: 39109 ]
@3 block return log all
[ Evaluations: 341770 Packets: 114929 Bytes: 62705138 States: 0
]
[ Inserted: uid 0 pid 14717 State Creations: 0
]
@4 block return log (all) quick from <bruteforce:0> to any
[ Evaluations: 341770 Packets: 2
Bytes: 104
States: 0
]
[ Inserted: uid 0 pid 14717 State Creations: 0
]
@5 anchor "ftp-proxy/*" all
[ Evaluations: 341768 Packets: 319954 Bytes: 263432399 States: 0
]
[ Inserted: uid 0 pid 14717 State Creations: 70 ]
Теперь вы должны выполнять структурированную пошаговую загрузку набора правил.
Найти правила, которые соответствуют расследованию пакетов. Какое последнее
соответствующее правило? Если больше чем одно соответствующее правило? (как вы,
наверное, помните из предыдущих глав, когда пакет соответствует правилу quick оценка
останавливается, и все, что quick правило определяет происходит с пакетом). Если так,
вам нужно проследить за оценкой правил до тех пор, пока вы не дойдете до конца набора
правил или пока пакет не будет соответствовать правилу quick, которое затем завершает
процесс. Если ваш набор правил проходит в конце где-то в другом, чем в ожидаемом вами
соответствующем правиле месте, вы нашли свою логическую ошибку.
Логические ошибки в наборе правил как правило, делятся на три типа:
•
•
•
Ваше правило, не соответствует, потому что оно никогда не оценивается. Имеется
quick правило ранее, и поэтому все оценки правил на этом останавливаются.
Ваше правило оценивается, но пакет не соответствует в конце концов, из-за
критериев правила.
Ваше правило оценивается, правило соответствует, но пакет также соответсвует
другом правилу позже в наборе правил. Последнее соответствие правило является
тем, которое определяет что происходит с вашим соединением.
В главе 8 введен tcpdump как ценный инструмент для чтения и интерпретации логов PF.
Программа также очень хорошо подоходит для просмотра трафика, который проходит
через определенный интерфейс. То, что вы узнали о логах PF и как использовать tcpdump
в фильтрации пригодится, когда вы хотите разыскать какие именно пакеты достигают
какого интерфейса. Вот пример использования tcpdump для просмотра TCP трафика на xl0
интерфейсе (но не показано SSH или SMTP трафик) и распечатывает результат в очень
подробном режиме (vvv):
$ sudo tcpdump -nvvvpi xl0 tcp and not port ssh and not port smtp
tcpdump: listening on xl0, link-type EN10MB
21:41:42.395178 194.54.107.19.22418 > 137.217.190.41.80: S [tcp sum ok]
3304153886:3304153886(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale
0,nop,nop,timestamp 1308370594 0> (DF) (ttl 63, id 30934, len 64)
21:41:42.424368 137.217.190.41.80 > 194.54.107.19.22418: S [tcp sum ok]
1753576798:1753576798(0) ack 3304153887 win 5792 <mss 1460,sackOK,timestamp
168899231 1308370594,nop,wscale 9> (DF) (ttl 53, id 0, len 60)
Соединения показанные здесь успешно соединяются с вебсайтом. Есть более интересные
вещи, на которые стоит взглянуть, хотя, например, соединения, которые никогда не
должны в соответствии с вашими требованиями, или соединения, которые были успешны,
когда ваше задание говорит, что они явно не должны. Тест в таких случаях включает в
себя отслеживание пути пакетов через свою конфигурацию. Еще раз, это полезно, чтобы
проверить, включен или выключен PF и проверить есть ли разница. Опираясь на
результаты от начального теста, вы затем выполните такой же анализ набора правил как
описано выше:
•
•
•
•
Если у вас есть разумные теории о том, как пакеты должны пройти ваш набор
правил и сетевых интерфейсов, используя tcpdump, вы увидите трафки на каждом
из интерфейсов, в свою очередь.
Использование tcpdump в фильтрации, чтобы извлечь только нужную информацию,
чтобы увидеть только те пакеты, которые должны соответствовать вашему
конкретному случаю, таких как порт SMTP и назначение 192.0.2.19.
Найти место, где ваши предположения не соответствуют реальности вашего
сетевого трафика.
Включите ведение журнала для правил, которые могут быть вовлечены, и
посмотрите через tcpdump на соответствующий в pflog интерфейс, чтобы увидеть
действительно соответствующие правилам пакеты.
Основной план теста процедуры довольно исправен. Если вы сузили по причине вашей
конфигурации PF, опять же, это случай выяснить, какие правила соответствуют и какое
правило заканчивается в определении того, будет пакет проходить или заблокируется.
Знайте вашу сеть и сохраняйте контроль
Повторяющаяся тема в этой книге в том, что PF и связанные с ним инструменты
позволяют относительно легко для вас, как сетевого администратора, брать под контроль
сети и заставить вести ее так как вы хотите, чтобы она себя вела. Иными словами, строить
сеть вам нужно.
Запуск сети может быть веселым, и я надеюсь, вам понравился этот тур, я считаю это
лучшим инструментом для сетевой безопасности. Представляя PF, я сделал осознанное
решение на раннем этапе, чтобы познакомить вас с методами и способами мышления с
помощью интересных и полезных конфигураций, а не предлагать полный каталог
доступных функций, или что, впрочем, делает эту книгу полным справочником. Полный
справочник PF уже существует в man страницах, которые обновляются каждый шесть
месяцов с новыми релизами OpenBSD. Вы также можете найти дополнительную
информацию на ресурсах, которые я перечислял в приложении А.
Теперь у вас есть широкие базовые знания о том, что PF может сделать, вы можете
начать строить сети в соответствии с вашими собственными представлениями о том, что
вам нужно. Это когда самое интересное начинается!
Download