В прошлых статьях мы разобрали PF, его основные возможности, и попробовали применить этот файрвол в различных ситуациях. Однако, простого знания, какие правила и в какой последовательности надо поставить в конфигурации, для достижения цели не всегда достаточно. Многое становится понятно только если взглянуть чуть глубже: на уровень ядра ОС, и того, как файрволы с ним взаимодействуют.
Мы не будем разбирать уровни драйвера сетевой карты (2 уровень модели OSI), а сразу поднимемся на 3 уровень, где работает tcp/ip стек ядра.
Для каждого входящего пакета первым делом создаётся объект mbuf. Это базовая структура данных ядра, в которой хранится как сам пакет, так и все метаданные относительно него: aдрес источника и назначения, маршрут (next hop), ttl, метки, и прочие атрибуты. В таких же объектах хранятся буферы локальных сокетов. Состоит он из заголовков и небольшого внутреннего буфера данных. Затем этот mbuf начинает путешествие по стэку ядра.
На выходе со второго уровня пакет попадает в функцию ip_input().
Надо также отметить, что мультикаст и широковещательный трафик обрабатываются в соответствии с их правилами.
Здесь происходят различные проверки на возможность отправки.
Функция подготовки и отправки пакета через сетевой интерфейс.
Таким образом, на третьем уровне пакет отправляется на обработку файрволлам дважды. Один раз на входе, один раз на выходе. При этом файрвол может как пропустить пакет, так и отбросить его. Или создать новый, например, поменяв источник, и передать его соответствующей функции ядра. Файрволы вообще могут менять любые поля mbuf.
К примеру, в предыдущих статьях мы использовали правила pf с ключевыми словами in и out.
pass in on re0 inet...
Такие правила будут обрабатываться только при вызове ip_input. Соответственно правила с out — в ip_output.
pass out quick on $ExtIf2 ...
В сочетании с anchors это позволяет добиться впечатляющей оптимизации даже при большом количестве правил.
Ключевые слова route-to или reply-to поменяют next hop для соответствующих пакетов:
pass in quick on $ExtIf2 reply-to ($ExtIf2 $ExtIf2Gw ) tagged DSTNAT
pass in quick on $IntIf1 route-to ( $Tun1 $Tun1Gw ) from ($IntIf1:network)
Или укажет необходимость обработки пакета в контексте таблицы маршрутизации опцией rtable:
pass in quick on $IntIf2 from { $IntIf2Net } rtable 1 tag PASS
Мы рассмотрели общую схему работы сетевого стэка FreeBSD, это позволит осуществить тонкую настройку и оптимизацию файрвола, избежать различных сюрпризов на этапе эксплуатации, да и просто довольно интересно, на мой взгляд.
Описанные схемы мы применяем для создания нашего ИКСа — универсального шлюза безопасности. Защита сети, прокси, встроенный антивирус, фильтрация контента по спискам Минюста, контроль доступа и учет трафика, VPN для удаленной работы, почта, ftp-, web- и jabber-сервер, IP-телефония… Тестируйте все и сразу, скачав ИКС с официального сайта. Триал 35 дней, есть бесплатная версия на 9 пользователей.
К сожалению, не доступен сервер mySQL