Введение
- Файрвол PF в ОС FreeBSD < — Вы здесь
- Фильтрация трафика PF
- FreeBSD. Трансляции, тэги и якоря в PF
- FreeBSD. Условная маршрутизация средствами PF
- FreeBSD. Путь сетевого пакета внутри ядра
В Рунете есть множество статей о настройке FreeBSD и PF, но все они разрозненны и несистематичны. А за любыми более-менее интересными вещами, такими, как маршрутизация средствами файрвола (Policy Based Routing), приходится читать оригинальную документацию, например, OpenBSD PF FAQ. Однако, есть отличия в синтаксисе команд для FreeBSD и OpenBSD. В этом цикле статей мы пробуем систематизировать и разобрать возможности PF от простого к сложному. Наверняка, эта вводная статья будет похожа на все остальные статьи о Packet Filter. Поэтому тем, кто уже знаком с базовыми возможностями, будет не интересно. Однако, без вступления не обойтись, а мясо будет в следующих статьях.
![](https://habrastorage.org/webt/dt/ra/og/dtraoggiabz_bgw__itxb7xr4zy.png)
PF — Packet Filter — это межсетевой экран, изначально созданный в рамках проекта OpenBSD. В 2003 году был портирован во FreeBSD. В 2004 году был интегрирован в основную систему. Основные возможности:
- Фильтрация на основе адресов, портов, протоколов, интерфейсов
- NAT — Source NAT, подмена адреса отправителя. Destination nat, подмена адреса получателя, проброс порта
- Scrub — нормализация сетевого трафика. Помогает от некоторых видов dos атак, основанных на формировании специально подготовленных пакетов
- SYN-proxy — Защита от SYN-flood атак
- Балансировка соединений
- Отказоустойчивость — pfcync позволяет синхронизировать состояние файрволов на нескольних хостах, что, в сочетании с протоколом CARP, позволяет создать отказоустойчивый файрвол, который продолжит обрабатывать соединения после падения активной ноды
- Прозрачный файрвол (Без собственного IP-адреса, включая фильтр 2 уровня)
- Макросы — аналог переменных
- Таблицы — динамически изменяемые без перезагрузки конфигурации списки IP адресов
- Метки — позволяет метить пакеты, если простой фильтрации недостаточно
- Якоря (anchors) — наборы правил, похожи на таблицы IPTables в Linux
- Сбор статистики и вывод графиков с помощью утилиты pfstat
- Автоматическая оптимизация правил при загрузке
Основное отличие от того же IPTables — непривычная схема работы. Обработка пакета не заканчивается после первого совпадения с правилом. То есть, если вы поставили первым правилом «запретить всё», то пакет не будет отброшен, а пометится как запрещенный, пойдёт дальше по правилам, и, если его не разрешит никакое правило, то будет отброшен. Это важно понимать и использовать. Однако, если нужно, это поведение можно отменить параметром quick в правиле.
Управление и полезные команды
Для включения PF достаточно в файле «/etc/rc.conf» указать опции:
pf_enable="YES" # включает pf и загружает модуль
pf_flags="" # дополнительные флаги pfctl
pf_rules="/etc/pf.conf" # файл конфигурации
pflog_enable="YES" # запуск pflog
pflog_flags="" # флаги pflog
pflog_logfile="/var/log/pflog" # файл лога
Основные команды управления файрволом:
pfctl - # Включить файрвол
pfctl -d # Выключить файрвол
pfctl -nf # Проверить синтаксис файла
pfctl -f # Перечитать правила из файла
pfctl -Rf # Перечитать правила фильтрации из файла
pfctl -Nf # Перечитать правила NAT из файла
pfctl -sa # Просмотр всех состояний
pfctl -s # Просмотр правил фильтрации
pfctl -sn # Просмотр правил NAT
pfctl -s Anchors -v # Просмотр дерева якорей
pfctl -ss # Просмотр текущих соединений
Структура файла конфигурации и базовые настройки
Файл конфигурации состоит из разделов:
- Макросы
- Таблицы
- Опции
- Правила нормализации трафика (scrub)
- Очереди, приоритезация и контроль скорости
- NAT трансляции адресов
- Фильтрация пакетов
Правила в общем случае имеют следующий синтаксис:
action [direction] [log] [quick] [on interface] [af] [proto protocol]
[from src_addr [port src_port]] [to dst_addr [port dst_port]]
[flags tcp_flags] [state]
action — что следует сделать с пакетом
direction — in out, направление
log — попадёт ли пакет в pflog
quick — если пакет попал под это правило, то дальнейшей обработки не будет. Это правило будет последним для пакета
interface — название сетевого интерфейса
af — address family, inet или inet6, IPv4 или IPv6 соответственно
protocol — протокол 4 уровня, к примеру: tcp, udp, icmp
scr_addr, dst_addr — адреса источника и назначения
src_port, dst_port — порты
tcp_flags — флаги tcp
state — опции сохранения состояния. Например, keep state будет означать, что соединение сохранится в таблице состояний, и ответные пакеты могут проходить. Поведение по умолчанию.
Возьмем простейший веб-сервер в вакууме. Необходимо открыть входящие соединения по портам tcp 22, 80, 443 (ssh, http, https). Также нужно открыть исходящие соединения по портам tcp 22, 80, 443 (ssh, http, https) и udp 53, 123 (dns и ntp). Всё остальное запретить.
# ee pf.conf
#macros section
permit_tcp_ports="22,80,443"
permit_udp_ports="53,123"
#table section
# в данный момент пустая
#options section
set block-policy return # разрываем соединения с ответом, а не просто дропаем пакеты
set skip on lo0 # пропускаем проверку на локальной петле, там фильтрация не нужна
#scrub section
scrub in all # нормализация всего входящего трафика
#Queueing section
# в данный момент пустая
#nat section
# пустая, у нас нечего транслировать
#filtering section
block all # запрет всего по умолчанию, помним, что это не означает окончание обработки пакета.
pass in proto tcp to port { $permit_tcp_ports } # разрешаем входящие соединения
pass out proto tcp to port { $permit_tcp_ports } # разрешаем исходящие соединения tcp
pass out proto udp to port { $permit_udp_ports } # разрешаем исходящие соединения udp
pass out inet proto icmp # разрешаем исходящий icmp
Затем вводим команду проверки синтаксиса:
pfctl -nf pf.conf
Если сообщений об ошибках нет, вводим команду применения правил:
pfctl -f pf.conf
Для проверки посмотрим правила фильтрации:
# pfctl -sr
scrub in all fragment reassemble
block return 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 = http flags S/SA keep state
pass out proto tcp from any to any port = https flags S/SA keep state
pass out proto udp from any to any port = domain keep state
pass out proto udp from any to any port = ntp keep state
pass out inet proto icmp all keep state
pass in proto tcp from any to any port = ssh flags S/SA keep state
pass in proto tcp from any to any port = http flags S/SA keep state
pass in proto tcp from any to any port = https flags S/SA keep state
Как видно, макросы развернулись в отдельные правила по каждому порту, порядок изменен автоматически. В остальном всё так, как нужно.
Итог
Мы разобрались, что такое Packet Filter, узнали его основные возможности. Разобрались в структуре конфигурации PF и её основных секциях. Создали самую простую конфигурацию, которая, однако вполне функциональна, включает макросы, нормализацию пакетов и фильтрацию входящих и исходящих пакетов. В следующей статье разберем более подробно правила фильтрации, управление состояниями и флаги.
Наше решение, Интернет Контроль Сервер – это шлюз безопасности, построенный на базе FreeBSD. Данная система была выбрана ввиду своей стабильности, скорости сетевого стэка, встроенной в ядро поддержки ZFS и отсутствия заморочек с лицензиями. Кроме того, работа с FreeBSD достаточно приятна, хоть и не во всем проста. Но мы будем рады делиться с вами этим опытом!