/etc/pf.conf

Конфигурационный файл фильтра пакетов

Имя

/etc/pf.conf


Описание:

Фильтр пакетов pf изменяет, сбрасывает или передает пакеты в соответствии с правилами или определениями в файле pf.conf. По умолчанию этот файл расположен по пути /etc/pf.conf.

Порядок операторов

Файл pf.conf может содержать операторы следующих типов:

Макросы

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

Таблицы

Таблицы представляют собой инструмент повышения эффективности и гибкости правил с большим количеством адресов источников и назначения.

Опции

Опции определяют поведение механизма фильтрации пакетов.

Нормализация трафика (например, очистка)

Нормализация трафика позволяет защитить машины во внутренней сети от конфликтов Интернет-протоколов и реализаций.

Формирование очередей

Формирование очередей обеспечивает управление полосой пропускания на основе правил.

Трансляция (различные формы NAT)

Правила трансляции определяют способы отображения адресов или перенаправления на другие адреса.

Фильтрация пакетов

Фильтрация пакетов с запоминанием и без запоминания состояния обеспечивает блокировку или передачу пакетов на основе правил.

За исключением макросов и таблиц, операторы следует группировать по типу и добавлять в файл pf.conf в приведенном выше порядке, поскольку он соответствует порядку выполнения операций базового механизма фильтрации пакетов. По умолчанию соблюдение этого порядка обеспечивается утилитой pfctl (см. описание set require- order далее).

Макросы

Аналогично cpp или m4, имеется возможность определения макросов и их последующего расширения в контексте. Имя макроса должно начинаться с буквы и может содержать буквы, цифры и символ подчеркивания. В качестве имен макросов не допускается использовать зарезервированные слова (например, pass, in, out). Расширение макросов, заключенных в кавычки, не выполняется.

Пример.

ext_if = "kue0"

all_ifs = "{" $ext_if lo0 "}"

pass out on $ext_if from any to any keep state

pass in on $ext_if proto tcp from any to any port 25 keep state


Таблицы

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

Таблицы используются в качестве источника или назначения правил фильтрации, правил очистки и правил трансляции, например nat или rdr (дополнительная информация о различных типах правил приведена далее). Таблицы также используются для переадресации правил nat и rdr и в опциях маршрутизации правил фильтрации, но только для циклических пулов.

Таблицы можно определить с помощью любого из перечисленных ниже механизмов pfctl. Как и для макросов, в качестве имени таблицы не допускается использовать зарезервированные слова.

Вручную

Постоянные таблицы можно создать вручную, с использованием опции добавления или опции замены pfctl, до или после загрузки набора правил.

С помощью pf.conf

Определения таблиц можно поместить непосредственно в этот файл и загрузить их одновременно с другими правилами, атомарно. В определениях таблиц в файле pf.conf используется табличный оператор; этот способ наиболее эффективен для определения временных таблиц. Содержимое предварительно созданной таблицы, для инициализации которой список адресов в определении не использовался, при загрузке файла pf.conf не изменяется. Таблица, инициализированная на основе пустого списка { }, при загрузке очищается.

Для таблиц можно определить следующие атрибуты:

persist

Менеджер io-pkt сохраняет таблицу даже при отсутствии ссылающихся на нее правил. Если этот флаг не установлен, то io-pkt автоматически удаляет таблицу после исполнения последнего ссылающегося на нее правила.

const

После создания содержимое таблицы не доступно для изменения пользователем. Если этот флаг не установлен, то с помощью утилиты pfctl можно добавлять или удалять адреса из таблицы в любой момент, даже в том случае, если securelevel = 2.

Пример.

table <private> const { 10/8, 172.16/12, 192.168/16 }

table <badhosts> persist

block on fxp0 from { <private>, <badhosts> } to any


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

Изменить содержимое таблицы private невозможно, а таблицу badhosts невозможно удалить, даже если активные ссылающиеся на нее правила фильтрации отсутствуют. В дальнейшем в таблицу badhosts можно добавлять адреса, что позволяет блокировать трафик от этих хостов, с помощью следующей команды:

# pfctl -t badhosts -Tadd 204.92.77.111

Таблицу также можно инициализировать путем ввода списка адресов в один или несколько внешних файлов, с использованием следующего синтаксиса:

table <spam> persist file "/etc/spammers" file "/etc/openrelays"

block on fxp0 from <spam> to any


Файлы /etc/spammers и /etc/openrelays содержат списки IP-адресов (по одному на строку). Строки, начинающиеся с символа #, считаются комментариями и игнорируются. Помимо определения хостов по IP-адресу, их также можно определить по именам. При вызове преобразователя адресов для добавления имени хоста в таблицу все полученные в результате адреса IPv4 и IPv6 добавляются в эту таблицу. IP-адреса также можно добавлять в таблицу путем определения действительного имени интерфейса или ключевого слова self. При этом в таблицу добавляются все адреса, присвоенные интерфейсу (интерфейсам).

Опции:

С помощью команды set можно настроить pf для различных ситуаций:

set timeout аргументы

Настроить таймаут, определенный аргументами:
Если пакет соответствует соединению с запоминанием состояния, оставшееся время соединения в секундах устанавливается равным proto.modifier, что соответствует состоянию соединения. При поступлении пакета, соответствующего этому состоянию, время существования сбрасывается. Установка этих значений позволяет повысить эффективность межсетевого экрана, однако при этом присутствует риск сброса неактивных действительных соединений.
Обработка трафика ICMP и UDP выполняется аналогично обработке TCP, однако набор состояний ограничен: Обработка трафика других протоколов выполняется аналогично UDP: Значения таймаута можно адаптивно уменьшать при увеличении количества записей в таблице состояний.
Эти значения можно установить как для всех правил, так и для каждого по отдельности. Если значения установлены для каждого правила, то они относятся к количеству состояний, созданных правилом, в противном случае к общему количеству состояний. Пример.

set timeout tcp.first 120

set timeout tcp.established 86400

set timeout { adaptive.start 6000, adaptive.end 12000 }

set limit states 10000

При наличии в таблице 9000 записей состояний значения таймаута масштабируются до 50% (tcp.first 60, tcp.established 43200).

set loginterface

Активировать сбор статистики пакетов и байтов по данному интерфейсу. Для просмотра этой статистики используется следующая команда:

pfctl -s info

В этом примере pf собирает статистику по интерфейсу с именем dc0:

set loginterface dc0

Интерфейс регистрации данных можно деактивировать с помощью следующей команды:

set loginterface none

set limit

Установить жесткие ограничения для пулов памяти, используемых фильтром пакетов. Пример.

set limit states 20000

С помощью этой команды максимальное количество записей в пуле памяти, используемых записями в таблице состояний (созданными правилами сохранения состояний), установлено на уровне 20 000.

set limit frags 20000

С помощью этой команды максимальное количество записей в пуле памяти, используемых для восстановления пакета из фрагментов (созданных правилами очистки), установлено на уровне 20 000.

set limit src-nodes 2000

С помощью этой команды максимальное количество записей в пуле памяти, используемых для отслеживания IP-адресов источника (созданных с помощью sticky-адресов иопций отслеживания источников), установлено на уровне 2000.

Эти команды можно использовать в комбинации:

set limit { states 20000, frags 20000, src-nodes 2000 }

set optimization

Оптимизировать механизм для одной из следующих сетевых сред: Пример.

set optimization aggressive

set block-policy

Определить поведение по умолчанию для действия блокировки пакетов: Пример.

set block-policy return

set state-policy


Определить поведение по умолчанию для следующих состояний:
Пример.

set state-policy if-bound

set require-order


По умолчанию pfctl обеспечивает соблюдение следующего порядка следования операторов по типам в наборе правил: опции, нормализация, формирование очередей, трансляция и фильтрация. Если для этой опции установлено значение no, этот порядок не соблюдается.

Примечание. Последствия применения противоречивого набора правил могут быть нестандартны и неочевидны. Следует убедиться, что деактивация этого порядка действительно необходима.

set fingerprints

Загрузить отпечатки известных операционных систем на основе имени файла. По умолчанию отпечатки известных операционных систем автоматически загружаются из файла /etc/pf.os; с помощью данной опции этот путь можно переопределить. Пример.

set fingerprints "/etc/pf.os.devel"

Если эта опция установлена, то в течение непродолжительного периода отпечатки, на которые ссылается активный в настоящий момент набор правил, могут конфликтовать до завершения загрузки нового набора правил.

set skip on спецификация_интерфейса

Создать список интерфейсов, для которых не требуется фильтрация пакетов. Пакеты, проходящие через такие интерфейсы в обоих направлениях, передаются так же, как и при деактивированной утилите pf, т.е. pf не выполняет их обработку. Это удобно для интерфейса обратной связи и других виртуальных интерфейсов, когда фильтрация пакетов нежелательна и может привести к неожиданным результатам. Пример.

set skip on lo0

set debug

Установить один из следующих уровней отладки:
Нормализация трафика

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

no-df

Удалить бит dont-fragment из соответствующего IP-пакета. В некоторых операционных системах при установленном бите dont-fragment все равно создаются фрагментированные пакеты. Это, в частности, справедливо для NFS. Если значение no-df не определено, то такие фрагментированные пакеты dont-fragment сбрасываются директивой scrub.

К сожалению, в некоторых операционных системах также генерируются пакеты dont-fragment, которые содержат в поле IP- идентификатора нулевое значение. При последующей фрагментации пакетов вышестоящим маршрутизатором удаление бита dont- fragment в пакетах с IP-идентификатором, равным нулю, может привести к нежелательным результатам. Для обеспечения уникальности IP- идентификаторов рекомендуется использовать модификатор random-id (см. далее) в сочетании с модификатором no-df.

min-ttl число

Установить минимальное время существования для соответствующих IP-пакетов.

max-mss число

Установить максимальный размер сегмента для соответствующих TCP-пакетов.

random-id

Заменять значение в поле IP-идентификатора произвольными значениями для компенсации предсказуемых значений, генерируемых многими хостами. Эта опция применяется только для пакетов, которые не были фрагментированы после необязательного объединения фрагментов.

fragment reassemble

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

fragment crop

Поскольку метод объединения фрагментов по умолчанию является ресурсозатратным, можно использовать специальную опцию для обрезки. В этом случае pf отслеживает фрагменты и помещает в кэш дескриптор с небольшим диапазоном. Дублирующиеся фрагменты сбрасываются, а частично совпадающие фрагменты обрезаются. Таким образом, обеспечивается только однократная передача данных. В отличие от случая применения модификатора fragment reassemble, фрагменты не помещаются в буфер, а передаются сразу после получения. Метод объединения fragment crop для подключений NAT в настоящее время не реализован.

fragment drop-ovl

Эта опция аналогична модификатору fragment crop, за исключением того, что все частично совпадающие или дублирующиеся фрагменты, а также все последующие соответствующие фрагменты сбрасываются.

reassemble tcp

Выполнять нормализацию TCP-соединений с запоминанием состояния. Для правил очистки reassemble tcp определять направление ("in/out") необязательно. Команда reassemble tcp позволяет выполнять следующие операции нормализации:
Пример.

scrub in on $ext_if all fragment reassemble

Если перед правилом очистки указана опция no, то обработка соответствующих пакетов не выполняется, аналогично быстрому сбросу в фильтре пакетов (см. далее). Этот механизм используется при необходимости исключения обработки определенных пакетов более сложными правилами очистки.

Формирование очередей

В целях управления полосой пропускания пакеты могут присваиваться очередям. Для настройки очередей необходимо выполнить, по меньшей мере, два объявления, и в дальнейшем в любое правило фильтрации пакетов можно добавить в качестве ссылок имена определенных очередей. Во время выполнения фильтрации компонентов, определенных в  pf.conf, пакеты, переданные согласно правилам передачи, помещаются в очередь, имя которой было указано в последней ссылке, а для правил блокировки он определяет очередь, в которую помещаются все итоговые пакеты ICMP и TCP RST. Диспетчер определяет алгоритм, используемый для определения пакетов, которые должны быть отложены, сброшены или немедленно переданы.

В настоящее время поддерживаются следующие диспетчеры:

cbq

Class Based Queueing, формирование очередей на основе класса. Очереди, связанные с интерфейсом, формируют дерево; таким образом, каждая очередь может иметь несколько дочерних очередей. Каждой очереди можно назначить приоритет и полосу пропускания. Приоритет задает время, необходимое для отправки пакетов, тогда как полоса пропускания определяет, прежде всего, производительность.

Диспетчер cbq обеспечивает как декомпозицию, так и разделение полосы пропускания канала между классами с иерархической структурой. Каждый класс имеет собственную очередь, и ему присваивается определенная доля полосы пропускания. При наличии избыточной полосы пропускания дочерний класс может использовать полосу пропускания родительского класса (см. описание опции borrow далее).

priq

Priority Queueing, формирование очередей на основе приоритета. Очереди имеют прямую привязку к интерфейсу, в результате чего формирование дочерних очередей невозможно. Каждой очереди присваивается уникальный приоритет от 0 до 15. Сначала обрабатываются пакеты в очереди с наиболее высоким приоритетом.

hfsc

Hierarchical Fair Service Curve, иерархическая характеристика обслуживания. Очереди, связанные с интерфейсом, формируют дерево; таким образом, каждая очередь может иметь несколько дочерних очередей. Каждой очереди можно назначить приоритет и полосу пропускания. Приоритет задает время, необходимое для отправки пакетов, тогда как полоса пропускания определяет, прежде всего, производительность.

Диспетчер hfsc поддерживает совместное использование канала и гарантированное качество обслуживания в режиме реального времени. Он основан на модели QoS, построенной на характеристике обслуживания. Уникальная функция этого диспетчера возможность разделения связи между задержками и распределением полосы пропускания.

Интерфейсы, в которых требуется активировать формирование очередей, объявляются посредством декларации altq on, для чего используются следующие ключевые слова:

интерфейс

Активировать формирование очередей в указанном интерфейсе.

диспетчер

Выбрать диспетчер для формирования очередей. Допускаются следующие значения:

bandwidth пропускная_способность

Максимальная скорость двоичной передачи в битах для всех очередей в интерфейсе. Пропускную способность интерфейса можно определить в виде абсолютного или процентного значения. При выборе абсолютного значения можно использовать индексы b, Kb, Mb и Gb, обозначающие соответственно биты, килобиты, мегабиты и гигабиты в секунду. Это значение не должно превышать пропускную способность интерфейса. Если аргумент bandwidth не указан, используется пропускная способность интерфейса.

qlimit предел

Максимальное количество пакетов в очереди. Значение по умолчанию 50.

tbrsize размер

Изменить размер регулятора наборов лексем в байтах. Если размер не задан явно, то он определяется эвристическим методом на основе пропускной способности интерфейса.

queue список

Определить список подочередей, которые требуется создать в интерфейсе.

В следующем примере интерфейс dc0 должен формировать четыре четырехсекундные очереди до 5 Мбит/с с использованием формирования очередей на основе класса. Эти четыре очереди будут описаны в примерах далее.

altq on dc0 cbq bandwidth 5Mb queue { std, http, mail, ssh }

После активации интерфейсов для формирования очереди с помощью директивы altq можно определить последовательность директив очереди. Назначенное очереди имя должно соответствовать очереди, указанной в директиве altq (например, mail), или в объявлении родительской очереди, за исключением диспетчера priq. Используются следующие ключевые слова:
В планировщик можно передавать дополнительные параметры в формате диспетчер (параметры). Доступны следующие параметры: Диспетчер CBQ поддерживает дополнительную опцию:

Диспетчер HFSC поддерживает ряд дополнительных опций (sc сокращение от "service curve", характеристика обслуживания):

Для характеристик обслуживания можно указать спецификацию в следующем формате: (m1, d, m2). Переменная m2 определяет пропускную способность, выделенную для очереди; переменные m1 и d являются необязательными и могут использоваться для управления первоначально выделенной пропускной способностью. На первые d миллисекунд очереди предоставляется пропускная способность, указанная для m1, а затем для m2.

Кроме того, в случае CBQ и HFSC можно указать дочерние очереди, как в объявлении altq, в результате чего формируется дерево очередей, занимающих часть пропускной способности соответствующих родительских очередей.

Пакеты можно присваивать очередям на основании правил фильтрации с помощью ключевого слова queue. Как правило, указывается только одна очередь; если указана вторая очередь, то в нее помещаются пакеты с типом обслуживания lowdelay и TCP-пакеты ACK без значащих данных.

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

queue std bandwidth 10% cbq(default)

queue http bandwidth 60% priority 2 cbq(borrow red) \

{ employees, developers }

queue developers bandwidth 75% cbq(borrow)

queue employees bandwidth 15%

queue mail bandwidth 10% priority 0 cbq(borrow ecn)

queue ssh bandwidth 20% cbq(borrow) { ssh_interactive, ssh_bulk }

queue ssh_interactive bandwidth 50% priority 7 cbq(borrow)

queue ssh_bulk bandwidth 50% priority 0 cbq(borrow)

block return out on dc0 inet all queue std

pass out on dc0 inet proto tcp from $developerhosts to any port 80 \

keep state queue developers

pass out on dc0 inet proto tcp from $employeehosts to any port 80 \

keep state queue employees

pass out on dc0 inet proto tcp from any to any port 22 \

keep state queue(ssh_bulk, ssh_interactive)

pass out on dc0 inet proto tcp from any to any port 25 \

keep state queue mail


Трансляция

Правила трансляции обеспечивают изменение адреса источника или получателя для пакетов, соответствующих соединению с запоминанием состояния. Соединение с запоминанием состояния автоматически создается для отслеживания пакетов, удовлетворяющих данному правилу, если они не блокируются секцией фильтрации pf.conf. Механизм трансляции модифицирует указанный адрес и/или порт пакета, выполняет перерасчет контрольных сумм IP, TCP и UDP по мере необходимости, и передает пакет в фильтр пакетов для обработки.

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

Созданная запись состояния позволяет pf отслеживать адрес источника для трафика, связанного с этим состоянием, и корректно перенаправлять обратный трафик для данного соединения.

Возможные типы трансляций в pf:

binat

Двунаправленное отображение между внешним и внутренним блоками сетевых IP-адресов.

nat

Активация изменения IP-адресов пакетов при прохождении через данный интерфейс. Этот метод обеспечивает пропуск сетевого трафика через транслятор, имеющий один или несколько IP-адресов, для передачи большому количеству узлов "внутри" сети. Теоретически во внутренней сети можно использовать любые IP-адреса, однако настоятельно рекомендуется использовать один из диапазонов адресов, определенных в стандарте RFC 1918. Сетевые блоки:

rdr

Пакет пересылается на другой адрес назначения и, возможно, на другой порт. В правилах rdr можно указать как отдельные порты, так и диапазоны портов. Пример.

rdr ... port 2000:2999 -> ... port 4000

С помощью этой команды данные с портов 20002999 (включительно) перенаправляются на порт 4000.

rdr ... port 2000:2999 -> ... port 4000:*

С помощью этой команды данные с порта 2000 перенаправляются на порт 4000, с порта 2001 на порт 4001, ..., с порта 2999 на порт 4999.

Помимо изменения адреса, некоторыми правилами трансляции могут быть изменены порты источника или назначения для соединений TCP или UDP; в случае правил nat неявно, в случае правил rdr явно. В случае правил binat трансляция номеров портов не производится.

Для каждого пакета, обрабатываемого транслятором, правила трансляции применяются последовательно, от первого к последнему. Выполняемое действие определяется первым правилом сопоставления.

Если перед правилом трансляции указана опция no, то трансляция пакетов не выполняется, аналогично опции быстрого сброса drop quick в фильтре пакетов (см. далее). Если пакету не соответствует ни одно правило, то этот пакет передается механизму фильтрации в исходном виде

Правила трансляции применяются только к тем пакетам, которые проходят через указанный интерфейс; если интерфейс не указан, то трансляция применяется к пакетам на всех интерфейсах. Например, перенаправление с порта 80 на внешнем интерфейсе на внутренний web-сервер выполняется только для соединений, инициируемых извне. Соединения на адрес внешнего интерфейса, инициируемые локальными хостами, не перенаправляются, поскольку такие пакеты не проходят через внешний интерфейс. При перенаправлении пакеты не могут быть отправлены через интерфейс, по которому они поступают; они могут быть перенаправлены только на хосты, подключенные по другим интерфейсам, или непосредственно на межсетевой экран.

Следует отметить, что перенаправление внешних входящих соединений на адрес замыкания, например:

rdr on ne3 inet proto tcp to port 8025 -> 127.0.0.1 port 25

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

См. раздел "Примеры трансляции" далее.

Фильтрация пакетов

Псевдоустройство pf осуществляет блокирование или передачу пакетов на основе атрибутов заголовков уровня 3 (см. разделы IP и IPv6 в руководстве по библиотекам Neutrino Library Reference) и заголовков уровня 4 (см. разделы ICMP, ICMP6, TCP и UDP). Кроме того, в целях управления пропускной способностью пакеты могут присваиваться очередям.

Для каждого пакета, обрабатываемого фильтром пакетов, правила фильтрации применяются последовательно, от первого к последнему. Выполняемое действие определяется последним правилом сопоставления.

В фильтре можно определить следующие действия:

block

Блокировать пакет. Блокирование пакета правилом блокирования выполняется несколькими способами. По умолчанию пакеты сбрасываются без оповещения; это поведение можно изменить, т.е. активировать оповещение о действии глобально (путем установки опции политики блокирования) или для каждого правила посредством одной из следующих опций:
В настоящее время опции возврата ICMP-пакетов не действуют, если pf функционирует на подключении типа bridge, поскольку код реализации этой функции еще не внедрен.

pass

Передача пакета.

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

block all

Она указывается в качестве первого правила фильтрации.

См. раздел "Примеры фильтрации" далее.

Параметры

Параметры правил представляют собой описание пакетов, к которым применяется правило. Любой пакет поступает или проходит через какой-либо интерфейс. Большинство параметров являются необязательными. Если задан какой-либо параметр, то данное правило применяется только к пакетам с соответствующими атрибутами. Некоторые параметры могут иметь форму списков, при этом все требуемые комбинации правил генерируются посредством pfctl.

in или out

Правило применяется к входящим или исходящим пакетам. Если параметр in или out, не указан, то правилу будут соответствовать пакеты, проходящие в обоих направлениях.

log

В дополнение к указанному действию в журнале создается сообщение. Сообщения в журнале регистрируются для всех пакетов, проходящих по данному соединению; однако если указана какая-либо из опций keep state, modulate state или synproxy state, то регистрируются только те пакеты, которые устанавливают соответствующие состояние. (См. описания опций keep state, modulate state и synproxy state далее). Зарегистрированные пакеты передаются на интерфейс pflog. Этот интерфейс отслеживается сервисом регистрации pflogd который записывает дамп регистрируемых пакетов в файл /var/log/pflog в бинарном формате pcap.

log-all

Используется совместно с правилами keep state, modulate state или synproxy state для принудительной регистрации всех пакетов, проходящих через какое-либо соединение. Как и в случае log, пакеты регистрируются в pflog.

quick

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

on интерфейс

Правило применяется только к тем пакетам, которые поступают или проходят через указанный интерфейс. Кроме того, можно указать имя драйвера интерфейса, например ppp или fxp, тогда правилу будут соответствовать пакеты, проходящие через данную группу интерфейсов.

af

Правило применяется только к тем пакетам, которые относятся к этому семейству адресов. Допустимые значения inet и inet6.

proto протокол

Правило применяется только к пакетам указанного протокола. К общепринятым протоколам относятся ICMP, ICMP6, TCP и UDP. Список всех сопоставлений имен и номеров протоколов, используемых в pfctl, содержится в файле /etc/protocols.

from источник port источник os источник to адресат port адресат

Правило применяется только к пакетам с указанными адресами и портами источника и назначения. Адреса можно указать в нотации CIDR (соответствующие блоки сетевых адресов), в виде символьных имен хостов или имен интерфейсов, либо использовать следующие ключевые слова:

К именам интерфейсов можно добавлять следующие модификаторы:


Опция :0 также может быть добавлена к именам хостов для ограничения разрешения имен только первыми из найденных адресов v4 и v6.

Разрешение имени хоста и трансляция "интерфейс-адрес" выполняются только после загрузки набора правил. При изменении адреса интерфейса (или имени хоста) (например, при использовании DHCP или PPP) набор правил необходимо загрузить повторно для учета этих изменений в io-pkt.

Если имя интерфейса (вместе с модификаторами) заключено в круглые скобки, то правило обновляется автоматически при любом изменении адреса интерфейса. Повторная загрузка набора правил в этом случае не требуется. Эту опцию удобно использовать для nat.

Порты можно указать в виде номера или имени. Например, порт 80 можно указать как www. Список всех сопоставлений имен и номеров портов, используемых в pfctl, содержится в файле /etc/services.

Для определения портов и диапазонов портов можно использовать следующие операторы:

Оператор

Значение

=

Равно

!=

Не равно

<

Меньше

<=

Меньше или равно

>

Больше

>=

Больше или равно

:

Диапазон, включая крайние значения

><

Диапазон, исключая крайние значения

<>

Кроме диапазона


Операторы ><, <> and : являются бинарными и имеют по два аргумента. Пример.

Запись

Значение

port 2000:2004

Все порты ≥ 2000 и ≤ 2004, т.е. порты 2000, 2001, 2002, 2003 и 2004

port 2000 >< 2004

Все порты > 2000 и < 2004, т.е. порты 2001, 2002 и 2003

port 2000 <> 2004

Все порты < 2000 или > 2004, т.е. порты 11999 и 200565535


Если заданы правила TCP с модификатором операционной системы, то можно указать операционную систему хоста-отправителя. Для получения дополнительной информации см. раздел "Получение отпечатка операционной системы".

Определение хоста, порта и операционной системы необязательно, см. следующие примеры:

pass in all

pass in from any to any

pass in proto tcp from any port <= 1024 to any

pass in proto tcp from any to any port 25

pass in proto tcp from 10.0.0.0/8 port > 1024 \

to ! 10.1.2.3 port != ssh

pass in proto tcp from any os "OpenBSD" flags S/SA

pass in proto tcp from route "DTAG"

all

Эквивалентно from any to any.

group группа

В данной версии NetBSD эта функция не поддерживается.

user пользователь

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

Все пакеты одного соединения, как входящие, так и исходящие, связаны с одним пользователем и одной группой. С пользователями могут быть связаны только TCP- и UDP-пакеты; для остальных протоколов эти параметры игнорируются.

Если сокет создается процессом setuid или setgid, то пользователь и группа соответствуют эффективным идентификаторам (в отличие от реальных). Идентификаторы пользователя и группы сохраняются при создании сокета; при создании прослушиваемого сокета процессом с полномочиями root (например, путем привязки к привилегированному порту) и последующей смене идентификатора пользователя (для отмены привилегий) полномочия остаются соответствующими пользователю root.

Идентификаторы пользователя и группы можно указать в виде номеров или имен. Синтаксис их записи соответствует синтаксису записи портов. Значение unknown соответствует пакетам в перенаправляемых соединениях. Опцию unknown допускается указывать только с операторами = и !=. Другие конструкции, такие как user >= unknown, являются неверными. Перенаправляемые пакеты с неизвестными идентификаторами пользователя и группы соответствуют только правилам, содержащим явное сравнение с unknown с операторами = или !=. Например, запись user >= 0 не соответствует перенаправляемым пакетам. В нижеприведенном примере открытие исходящих соединений разрешается только избранным пользователям:

block out proto { tcp, udp } all

pass out proto { tcp, udp } all \

user { < 1000, dhartmei } keep state

flags a/b | /b

Это правило применяется только к TCP-пакетам с установленными флагами для набора a в наборе b. Флаги, отсутствующие в наборе b, игнорируются. Имеются следующие флаги: (F)IN, (S)YN, (R)ST, (P)USH, (A)CK, (U)RG, (E)CE, C(W)R. Пример.

Запись

Значение

flags S/S

Установлен флаг SYN. Остальные флаги игнорируются.

flags S/SA

Из флагов SYN и ACK может быть установлен только флаг SYN. Этой записи соответствуют сочетания SYN, SYN+PSH и SYN+RST, но не соответствуют сочетания SYN+ACK, ACK и ACK+RST. По сравнению с предыдущим примером установлено больше ограничений.

flags /SFRA

Если первый набор не задан, то по умолчанию он отсутствует. Флаги SYN, FIN, RST и ACK должны быть отменены.

icmp-type тип code код
icmp6-type тип code код

Правило применяется только к ICMP- или ICMPv6-пакетам, имеющим указанный тип и код. Текстовые имена типов и кодов ICMP приведены в описаниях ICMP и ICMP6 в руководстве по библиотекам Neutrino Library Reference. Этот параметр действителен только для правил, которые применяются к протоколам ICMP и ICMP6. Протокол и индикатор типа ICMP (icmp-type или icmp6-type) должны совпадать.

tos строка | число

Правило применяется к пакетам с указанным набором битов TOS (типа обслуживания). Для типа обслуживания можно либо указать значение lowdelay (малая задержка), throughput (пропускная способность), reliability (надежность), либо число в шестнадцатеричном или десятичном формате. Например, следующие правила являются одинаковыми:

allow-opts

По умолчанию пакеты, содержащие опции IP, блокируются. Если в правиле передачи pass указана опция allow-opts, то пакеты, проходящие через фильтр согласно этому (последнему, для которого обнаружено соответствие) правилу, будут переданы даже при наличии опций IP. Для пакетов с соответствующим состоянием применяется правило, по которому было изначально создано это состояние. Неявное правило передачи pass применяемое в том случае, если пакет не соответствует ни одному правилу, не допускает наличия опций IP.

label строка

Добавить к правилу метку (имя), по которой можно идентифицировать правило. Например, команда pfctl -s labels позволяет просмотреть статистику по каждому из правил, имеющих метки.

В метках можно использовать следующие макросы:

Макрос

Значение

$if

Интерфейс

$srcaddr

IP-адрес источника

$dstaddr

IP-адрес назначения

$srcport

Спецификация порта источника

$dstport

Спецификация порта назначения

$proto

Имя протокола

$nr

Номер правила


Пример.

ips = "{ 1.2.3.4, 1.2.3.5 }"

pass in proto tcp from any to $ips \

port > 1023 label "$dstaddr:$dstport"

после расширения принимает следующий вид:

pass in inet proto tcp from any to 1.2.3.4 \

port > 1023 label "1.2.3.4:>1023"

pass in inet proto tcp from any to 1.2.3.5 \

port > 1023 label "1.2.3.5:>1023"

Расширение макроса для директивы метки осуществляется только при синтаксическом анализе конфигурационного файла (не при выполнении).

queue очередь | (очередь, очередь)

Пакеты, соответствующие этому правилу, помещаются в указанную очередь. Если указано две очереди, то в нее помещаются пакеты с типом обслуживания lowdelay, а также флаги TCP ACK без значащих данных. Для получения дополнительной информации см. раздел "Формирование очередей" выше. Пример.

pass in proto tcp to port 25 queue mail

pass in proto tcp to port 22 queue(ssh_bulk, ssh_prio)

tag строка

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

Теги имеют атрибут "sticky"; это означает, что каждый пакет отмечается тегом даже в том случае, если данное правило не является последним правилом сопоставления. При применении остальных правил сопоставления тег может быть заменен на другой, но не удаляется. Пакет может иметь только один тег. Любое правило pass, в котором присутствует ключевое слово tag, также должно содержать опцию keep state, modulate state или synproxy state.

Помимо правил фильтрации, пакеты могут отмечаться тегами при применении правил nat, rdr и binat. Теги могут содержать макросы, аналогичные макросам меток (см. выше).

tagged строка

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

probability число

В правило можно добавить атрибут вероятности, который принимает значение от 0 до 1, исключая крайние значения. В этом случае правило применяется только с учетом указанного значения вероятности. Например, при сопоставлении со следующим правилом сбрасывается 20% входящих ICMP- пакетов:

block in proto icmp probability 20%

Маршрутизация

Если пакет соответствует правилу, для которого установлена опция маршрутизации, то этот пакет отправляется фильтром пакетов в соответствии с типом опции маршрутизации. Если это правило создает состояние, то опция маршрутизации применяется ко всем пакетам, относящимся к данному соединению.

fastroute

Выполняется обычный поиск маршрута с целью определения следующего транзитного узла для данного пакета.

route-to

Пакет отправляется на указанный интерфейс, при этом указывать адрес следующего транзитного узла не обязательно. Если правило route-to создает состояние, то по данному маршруту отправляются только пакеты, передаваемые в том же направлении, которое указано в правиле фильтрации. Это не влияет на маршрутизацию пакетов, передаваемых в обратном направлении (ответов).

reply-to

Аналогично route-to, но на указанный интерфейс отправляются пакеты, передаваемые в обратном направлении (ответы). Обратное направление задается только в контексте записи состояния, т.е. reply-to используется только в правилах, создающих состояние. Эту опцию можно указать для систем, имеющих множество внешних соединений, для маршрутизации всех исходящих пакетов по определенному соединению через тот интерфейс, на который поступило входящее соединение (принудительная симметричная маршрутизация).

dup-to

Создается дубликат пакета, маршрутизация которого выполняется аналогично действию опции route-to. При этом маршрутизация исходного пакета осуществляется в обычном порядке.

Опции пула

В правилах nat и rdr (а также для опций route-to, reply-to и dup-to этих правил), для которых имеется одиночный адрес перенаправления с маской подсети меньше 32 для IPv4 или 128 для IPv6 (более одного IP-адреса), присвоение этого адреса можно выполнить несколькими способами:

bitmask

Применить сетевую часть адреса перенаправления к изменяемому адресу (адрес источника правила nat, адрес назначения правила rdr).

random

Выбирать адрес случайным образом из указанного блока адресов.

source-hash

Использовать хэш адреса источника для определения адреса перенаправления, что обеспечит постоянство адреса перенаправления для указанного источника. Кроме того, после этого ключевого слова можно указать ключ в шестнадцатеричном формате или в формате строки; по умолчанию pfctl генерирует опцию для source-hash случайным образом при каждой повторной загрузке набора правил.

round-robin

Циклический перебор адресов перенаправления.

Если задано несколько адресов перенаправления, то тип round-robin является единственным допустимым типом пула.

static-port

В случае применения правил nat запретить изменение псевдоустройством pf порта источника в TCP- и UDP-пакетах.

Кроме того, можно указать опцию sticky-address, что обеспечит сопоставление нескольких соединений от одного источника с одним и тем же адресом перенаправления. Эту опцию можно использовать совместно с опциями пула random и round-robin. Обратите внимание, что по умолчанию эти сопоставления удаляются, если ссылающиеся на них состояния больше не существуют; для сохранения сопоставлений на период, превышающий срок существования состояний следует увеличить значение соответствующей глобальной опции set timeout source-track. Другие способы отслеживания источников описаны в разделе "Опции отслеживания с запоминанием состояния".

Проверка с запоминанием состояния

Фильтр пакетов pf обеспечивает фильтрацию с запоминанием состояния (stateful); это означает, что в нем реализована поддержка отслеживания состояния соединения. Например, вместо перенаправления всего трафика на порт 25 может быть перенаправлен только первый пакет, после чего начинается поддержка состояния. Движение последующего трафика обусловлено тем, что фильтр отслеживает соединение.

Если какой-либо пакет соответствует правилу состояния pass ... keep, то для данного соединения фильтром создается новое состояние, и все последующие пакеты этого соединения передаются автоматически.

Перед применением правил фильтр проверяет пакет на соответствие какому-либо состоянию. Если соответствие найдено, то пакет передается без применения каких-либо правил.

Состояния удаляются после закрытия соединения или завершения по таймауту.

За счет этого реализуются следующие преимущества:
Пример.

block all

pass out proto tcp from any to any flags S/SA keep state

pass in proto tcp from any to any port 25 flags S/SA keep state


Данный набор правил по умолчанию создает полную блокировку. Разрешаются только исходящие соединения и входящие соединения на порт 25. Первый пакет каждого соединения содержит установленный флаг SYN, передается и создает состояние. Все последующие пакеты, проходящие по этим соединениям, передаются только в том случае, если соответствуют состоянию.

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

Политика по умолчанию определяется глобальной опцией state-policy, при этом ее можно изменить для каждого правила путем добавления ключевых слов if-bound, group-bound или floating к опции keep state. Например, определено следующее правило:

pass out on ppp from any to 10.12/16 keep state (group-bound)


В этом случае состояние, созданное на интерфейсе ppp0, будет соответствовать пакетам на всех интерфейсах PPP и не будет соответствовать пакетам, проходящим через интерфейс fxp0 или какой-либо другой.

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

При установке флагов S/SA состояние создается только для первого пакета SYN в подтверждении связи по TCP. Это ограничение можно ослабить, разрешив создание состояний на основе промежуточных пакетов (без флага SYN). При этом pf выполняет синхронизацию с существующими соединениями, например после очистки таблицы состояний.

В случае использования протокола UDP, для которого запоминание состояния не предусмотрено, опция keep state также позволяет создавать состояния. UDP-пакеты сопоставляются с состояниями только на основе адресов и портов хостов.

ICMP-сообщения делятся на две категории. ICMP-сообщения об ошибках, связанные только с TCP- или UDP-пакетами, сопоставляются с тем соединением, с которым они связаны. Если состояние TCP-соединения сохраняется и поступает сообщение подавления источника ICMP, связанное с данным TCP-соединением, то оно сопоставляется с требуемым состоянием и передается.

Для ICMP-запросов keep state создает состояние ICMP, а pf получает информацию для сопоставления ICMP-ответов с состояниями. Пример.

pass out inet proto icmp all icmp-type echoreq keep state


Эта команда разрешает исходящие запросы отклика (например, создаваемые посредством команды ping), создает состояние и корректно сопоставляет входящие запросы отклика с состояниями.

Примечание. Правила nat, binat и rdr неявно создают состояния соединений.

Модуляция состояния

Многие аспекты безопасности TCP определяются степенью правильности выбора начальных номеров последовательностей (Initial Sequence Number; ISN). Во многих случаях при реализации стека выбор ISN недостаточно усложнен, что обычно повышает риск предсказания ISN. При применении правила модуляции состояния к TCP-соединению pf создает номер последовательности высокой степени случайности для каждой конечной точки соединения.

Директива modulate state неявно сохраняет состояние в правиле и применяется только в отношении TCP-соединений. Пример.

block all

pass out proto tcp from any to any modulate state

pass in proto tcp from any to any port 25 flags S/SA modulate state

При использовании модуляции состояний следует учитывать ряд особенностей:
Прокси SYN

По умолчанию pf передает пакеты, относящиеся к подтверждению связи между конечными точками по TCP. Опция synproxy state используется для принудительного подтверждения связи между pf и активной конечной точкой с последующим подтверждением связи с пассивной точкой для передачи пакетов между ними.

До подтверждения связи с активной конечной точкой передача пакетов пассивной конечной точке невозможна, следовательно, т.н. SYN-лавина с подменными адресами источников не достигнет пассивной конечной точки, поскольку связь не подтверждена отправителем.

Этот прокси является прозрачным для обеих конечных точек, т.е. каждой из точек известно единственное соединение с другой конечной точкой. Фильтром пакетов pf выбираются случайные начальные номера последовательностей для подтверждений связи с обеих сторон. После подтверждения связи для преобразования последующих пакетов этого соединения используются модуляторы номеров последовательностей (см. предыдущий раздел). Таким образом, synproxy state включает в себя modulate state и keep state.

Правила с опцией synproxy не выполняются, если pf функционирует на подключении типа bridge.

Пример:

pass in proto tcp from any to any port www flags S/SA synproxy state


Опции отслеживания с запоминанием состояния

Каждое из правил keep state, modulate state и synproxy state поддерживает следующие опции:

max число

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

timeout секунды

Изменить значения таймаута для состояний, созданных данным правилом. Список всех допустимых имен таймаута приведен в разделе "Опции" выше.

Можно указать несколько опций, разделенных запятой:

pass in proto tcp from any to any \

port www flags S/SA keep state \

(max 100, source-track rule, max-src-nodes 75, \

max-src-states 3, tcp.established 60, tcp.closing 5)

Если указано ключевое слово source-track, то отслеживается количество состояний для каждого IP-адреса источника:

source-track rule

Максимальное количество состояний, созданных данным правилом, ограничено значениями опций max-src-nodes и max-src-state этого правила. Ограничения для данного правила распространяются только на записи состояния, созданные именно по этому правилу.

source-track global

Ограничить количество состояний, созданных всеми правилами, в которых указана эта опция. Каждое правило может содержать различные опции max-src-nodes и max-src-states, однако на записи состояния, созданные любым из этих правил, распространяются только ограничения, указанные в каждом отдельном правиле.

Можно установить следующие ограничения:

max-src-nodes число

Ограничить максимальное количество адресов источников, для которых в таблице состояния могут одновременно существовать записи.

max-src-states число

Ограничить максимальное количество записей состояния, которое может быть создано данным правилом для одного адреса источника.

Для TCP-соединений с запоминанием состояния ограничения для установленных соединений (соединений, для которых выполнено 3-стороннее подтверждение связи по TCP) также возможно определить по каждому IP-адресу источника.

max-src-conn число

Ограничить максимальное количество одновременных TCP-соединений с 3-сторонним подтверждением связи, которое допускается для отдельного хоста.

max-src-conn-rate число / секунды

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

Поскольку 3-стороннее подтверждение связи снижает риск подмены адреса источника, на основе этих ограничений возможным становится более агрессивное действие. Если задана опция переполнения таблицы состояний table, IP-адреса источников, соответствующие любому из указанных ограничений для установленного соединения, добавляются в данную таблицу. Эту таблицу можно указать в наборе правил для блокирования действий хоста-нарушителя, перенаправления их в процесс TARPIT или ограничения соответствующей пропускной способности.

Необязательное ключевое слово flush уничтожает все состояния, созданные правилом сопоставления, которые были инициированы хостом, превысившим указанные ограничения. Модификатор global команды flush уничтожает все состояния, инициированные хостом-нарушителем, вне зависимости от того, каким правилом было создано состояние.

Например, следующие правила защищают web-сервер от атак хостов, создающих более 100 соединений в течение 10 секунд. Адрес любого хоста, создающего соединения со скоростью, которая превышает указанную, добавляется в таблицу bad_hosts, и все инициируемые им состояния удаляются. Новые пакеты, поступающие от этого хоста, отбрасываются безусловно по правилу block.

block quick from bad_hosts

pass in on $ext_if proto tcp to $webserver port www flags S/SA keep state \

(max-src-conn-rate 100/10, overload bad_hosts flush global)


Получение отпечатка операционной системы

Пассивное получение отпечатков ОС это механизм, позволяющий проанализировать подробную информацию о начальном TCP-пакете SYN и определить операционную систему хоста. К сожалению, эта информация может быть имитирована злоумышленником, поэтому отпечаток не целесообразно использовать для принятия решений, связанных с безопасностью. Однако на основе отпечатков можно принимать достаточно обоснованные стратегические решения.

Отпечаток несет информацию о классе операционной системы, версии или подтипе/уровне исправлений. Класс операционной системы, как правило, определяется поставщиком или жанром; в случае межсетевого экрана pf это OpenBSD. Наиболее ранней из доступных версий OpenBSD на основном FTP является версия 2.6. Следовательно, записывается следующий отпечаток:

"OpenBSD 2.6"

Подтип операционной системы обычно используется для описания уровня исправлений, если после внедрения соответствующего исправления изменилось поведение стека TCP. В случае OpenBSD подтип существует только для отпечатка, нормализованного опцией очистки no-df, и отображается следующим образом:

"OpenBSD 3.3 no-df"

Отпечатки для наиболее популярных операционных систем содержатся в файле /etc/pf.os. После запуска pf полный список известных отпечатков операционных систем можно получить следующей командой:

# pfctl -so

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

Кроме того, в качестве отпечатка можно использовать класс unknown, соответствующий пакетам, для которых отпечаток операционной системы не известен.

Примеры:

pass out proto tcp from any os OpenBSD keep state

block out proto tcp from any os Doors

block out proto tcp from any os "Doors PT"

block out proto tcp from any os "Doors PT SP3"

block out from any os "unknown"

pass on lo0 proto tcp from any os "OpenBSD 3.3 lo0" keep state


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

Примечание. Отпечатки операционных систем в некоторых случаях могут оказаться некорректными. Существует несколько проблем:

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

Блокирование имитируемого трафика

Спуфинг это фальсификация IP-адресов, как правило, в злонамеренных целях. В результате расширения директивы antispoof возникает набор правил фильтрации, блокирующих весь трафик по IP-адресу источника из сети (сетей), непосредственно подключенной к указанному интерфейсу (интерфейсам), с целью исключения его поступления в систему через любой другой интерфейс. Например, строка

antispoof for lo0

после расширения принимает следующий вид:

block drop in on ! lo0 inet from 127.0.0.1/8 to any

block drop in on ! lo0 inet6 from ::1 to any

В отношении интерфейсов, не являющихся интерфейсами обратной связи, применяются дополнительные правила блокирования входящих пакетов с IP- адресом источника, идентичным IP-адресам интерфейса. Например, предположим, что интерфейс wi0 имеет IP-адрес 10.0.0.1 и маску сети 255.255.255.0, тогда строка

antispoof for wi0 inet

после расширения принимает следующий вид:

block drop in on ! wi0 inet from 10.0.0.0/24 to any

block drop in inet from 10.0.0.1 to any


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

Обработка фрагментов

Размер IP-дейтаграмм (пакетов) может существенно превышать максимальный размер пакета (Maximum Transmission Unit, MTU) в сети. В тех случаях, когда передача таких больших пакетов является необходимой или целесообразной, большой пакет фрагментируется на несколько пакетов меньшего размера, каждый из которых соответствует допустимым для сети пределам. С точки зрения межсетевых экранов недостатком является то, что только первый логический фрагмент содержит необходимую информацию заголовка для подпротокола, которая позволяет pf выполнять фильтрацию, например портов TCP, или трансляцию NAT.

В дополнение к использованию правил очистки, описанных в вышеприведенном разделе "Нормализация трафика", существует три опции обработки фрагментов фильтром пакетов.

Одна из них фильтрация отдельных фрагментов при помощи правил фильтрации. Если к фрагменту не применяется правило очистки, то он передается фильтру. На основе правил фильтрации с параметрами, соответствующими заголовку IP-пакета, определяется необходимость передачи или блокирования фрагмента, аналогично тому, как происходит фильтрация целых пакетов. В отсутствие объединения фрагментов возможна их фильтрация только на основе полей заголовка IP-пакета (адрес источника/назначения, протокол), поскольку поля заголовка подпротокола недоступны (номера портов TCP/UDP, код/тип ICMP). С помощью опции fragment определяется ограничение для применения правил фильтрации только к фрагментам, а не к целым пакетам. Правила фильтрации без опции fragment также применимы к фрагментам, но только в том случае, если они содержат поля заголовка IP-пакета. Например, правило

pass in proto tcp from any to any port 80


никогда не применяется к фрагменту, даже если этот фрагмент является частью TCP-пакета с портом назначения 80, поскольку без объединения эта информация доступна не всем фрагментам. Это также означает, что фрагменты не могут создавать новые состояния или соответствовать существующим записям таблицы состояний, таким образом, фильтрация с запоминанием состояния и трансляция адресов (NAT, перенаправление) для фрагментов невозможны.

Кроме того, допускается объединение только определенных фрагментов, путем определения в правилах очистки адресов либо протоколов источника или назначения в качестве параметров.

В большинстве случаев преимущества объединения более важны, чем увеличение объема потребляемой памяти. Для объединения всех фрагментов рекомендуется использовать правила очистки с модификатором fragment reassemble.

Ограничить объем памяти, выделяемый для кэширования фрагментов, можно с помощью pfctl. По достижении заданного предела фрагменты, подлежащие кэшированию, игнорируются до наступления таймаута записи. Также можно изменить значение таймаута.

В настоящее время реализована поддержка только фрагментов IPv4. Фрагменты IPv6 безусловно блокируются.

Закладки

Помимо основного набора правил, pfctl позволяет загружать наборы правил в точки присоединения закладок. Закладка это контейнер, который может содержать правила, таблицы адресов и другие закладки.

Закладка имеет имя, определяющее путь, используемый pfctl для доступа к закладке в целях выполнения, например, таких операций, как присоединение дочерних закладок или загрузка правил. Закладки могут быть вложенными, при этом компоненты разделяются символами косой чертой (/), аналогично иерархиям файловых систем. Основной набор правил по сути является закладкой по умолчанию; таким образом, в любой закладке могут содержаться, например, правила фильтрации и трансляции.

Закладка может ссылаться на другую точку присоединения закладок посредством правил следующих видов:

nat-anchor имя

Реализовать правила nat в указанной закладке.

rdr-anchor имя

Реализовать правила rdr в указанной закладке.

binat-anchor имя

Реализовать правила binat в указанной закладке.

anchor имя

Реализовать правила фильтрации в указанной закладке.

load anchor имя from файл

Загрузить правила из указанного файла в имя закладки.

Когда при реализации основного набора правил достигается правило закладки, pf реализует все правила, указанные в этой закладке.

Правила сопоставления с фильтром и трансляции в закладках с опцией quick считаются окончательными и отменяют реализацию правил в других закладках и основном наборе правил.

Правила закладки реализуются в отношении закладки, в которой они содержатся. Например, все правила закладки, указанные в основном наборе правил, ссылаются на точки присоединения закладок, являющиеся дочерними по отношению к основному набору правил, и правила закладки, указанные в файле, загруженном из правила загрузки закладки, помещаются в эту точку добавления закладок.

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

ext_if = "kue0"

block on $ext_if all

anchor spam

pass out on $ext_if all keep state

pass in on $ext_if proto tcp from any \

to $ext_if port smtp keep state


Эта команда блокирует все пакеты на внешних интерфейсах по умолчанию, затем реализует все правила в закладке с именем spam, и, наконец, передает все исходящие и входящие соединения на порт 25.

Следующая команда загружает в закладку одно правило, которое блокирует все пакеты с указанного адреса:

# echo "block in quick from 1.2.3.4 to any" | \

pfctl -a spam -f -

Закладка также может быть создана путем добавления правила load anchor после правила закладки:

anchor spam

load anchor spam from "/etc/pf-spam.conf"


При загрузке pf.conf утилитой pfctl в закладку также загружаются все правила из файла /etc/pf-spam.conf.

Кроме того, правила закладки могут определять направление, интерфейс, семейство адресов, протокол и адрес/порт источника/назначения параметра с использованием того же самого синтаксиса, что и для правил фильтрации. При использовании параметров правило закладки анализируется только в отношении соответствующих пакетов. Таким образом, обеспечивается условная реализация закладок, например:

block on $ext_if all

anchor spam proto tcp from any to any port smtp

pass out on $ext_if all keep state

pass in on $ext_if proto tcp from any to $ext_if port smtp keep state

Реализация правил, содержащихся в закладке spam, выполняется только в отношении TCP-пакетов с портом назначения 25. Следовательно, команда

# echo "block in quick from 1.2.3.4 to any" | \

pfctl -a spam -f -

блокирует соединения только с адреса 1.2.3.4 на порт 25.

Закладки могут заканчиваться символом "звездочка" (*); в этом случае все закладки, присоединенные в этой точке, подлежат реализации в алфавитном порядке, в соответствии с именами. Пример.

anchor "spam/*"

Эта команда реализует каждое правило в каждой закладке, присоединенной к закладке spam. Обратите внимание, что данная команда реализует только те закладки, которые присоединены непосредственно к закладке spam, и не реализует нижестоящие закладки.

Поскольку закладки реализуются относительно той закладки, в которой они содержатся, действует механизм доступа к родительским и прародительским закладкам данной закладки. Аналогично разрешению имен путей в файловой системе, если в пути к компоненту закладки используется последовательность .., то родительская закладка текущей закладки при реализации в данной точке становится новой текущей закладкой. Рассмотрим следующий пример:

# echo ' anchor "spam/allowed" ' | pfctl -f -

# echo -e ' anchor "../banned" \n pass' | \

pfctl -a spam/allowed -f -


Реализация основного набора правил приводит к закладке spam/allowed, которая реализует правила в закладке spam/banned, при их наличии, и только после этого реализует правило передачи pass.

Поскольку спецификацией анализатора для имен закладок является строка, для любой ссылки на имя закладки, содержащее символы косой черты (/), имя закладки следует заключить в кавычки (").

Примеры трансляции

В этом примере рассматривается сопоставление входящих запросов по порту 80 с портом 8080, который используется сервисом (например, по той причине, что он не был запущен с правами root и, таким образом, полномочия на привязку к порту 80 отсутствуют):

# Использование макроса в качестве имени интерфейса обеспечивает простоту его изменения

ext_if = "ne3"

# Сопоставление сервиса на порте 8080 с портом 80

rdr on $ext_if proto tcp from any to any port 80 -> 127.0.0.1 port 8080

При использовании модификатора pass пакеты, соответствующие правилу трансляции, передаются без выполнения проверки правил фильтрации:

rdr pass on $ext_if proto tcp from any to any port 80 -> 127.0.0.1 \

port 8080

В приведенном ниже примере для vlan12 определен адрес 192.168.168.1; выполняется автоматическая трансляция всех пакетов, поступающих с адреса 192.168.168.0/24 на 204.92.77.111, если для их передачи используется любой интерфейс, отличный от vlan12. При этом трафик с сетевого адреса 192.168.168.0/24, определяется как трафик с маршрутизируемого Интернет-адреса 204.92.77.111 к узлам за любым интерфейсом маршрутизатора, за исключением узлов в vlan12. (Таким образом, адрес 192.168.168.1 может обращаться к узлам 192.168.168.0/24.)

nat on ! vlan12 from 192.168.168.0/24 to any -> 204.92.77.111

В приведенном ниже примере компьютер расположен между ложной внутренней сетью 144.19.74.* и маршрутизируемым внешним IP- адресом 204.92.77.100. Правило no nat предотвращает трансляцию протокола AH:

# NO NAT

no nat on $ext_if proto ah from 144.19.74.0/24 to any

nat on $ext_if from 144.19.74.0/24 to any -> 204.92.77.100

В приведенном ниже примере пакеты для одного определенного сервера, а также пакеты, созданные системными администраторами, не передаются через прокси; для всех прочих соединений справедливо следующее:

# NO RDR

no rdr on $int_if proto { tcp, udp } from any to $server port 80

no rdr on $int_if proto { tcp, udp } from $sysadmins to any port 80

rdr on $int_if proto { tcp, udp } from any to any port 80 -> 127.0.0.1 \

port 80

В этом более объемном примере используется как трансляция сетевого адреса (NAT), так и перенаправление. Внешний интерфейс имеет адрес 157.161.48.183. На внутреннем интерфейсе запущен ftp-proxy, прослушивающий исходящие сеансы ftp принимаемые портом 8021:

# NAT

# Трансляция адресов источников исходящих пакетов (любой протокол).

# В этом случае отображается любой адрес, за исключением внешнего адреса шлюза.

nat on $ext_if inet from ! ($ext_if) to any -> ($ext_if)

# NAT PROXYING

# Отображение порта источника исходящих пакетов и назначенного прокси-порта вместо

# произвольного порта.

# В этом случае исходящий isakmp с портом 500 в шлюзе направляется через прокси.

nat on $ext_if inet proto udp from any port = isakmp to any -> ($ext_if) \

port 500

# BINAT

# Трансляция адреса источника исходящих пакетов (любой протокол).

# Трансляция адреса назначения входящих пакетов на узел во внутренней сети

# (двунаправленная).

binat on $ext_if from 10.1.2.150 to any -> $ext_if

# RDR

# Трансляция адресов назначения входящих пакетов.

# Пример. Перенаправление портов TCP и UDP на узел во внутренней сети.

rdr on $ext_if inet proto tcp from any to ($ext_if) port 8080 \

-> 10.1.2.151 port 22

rdr on $ext_if inet proto udp from any to ($ext_if) port 8080 \

-> 10.1.2.151 port 53

# RDR

# Трансляция исходящих управляющих соединений с ftp для их отправки на локальный хост

# в качестве прокси посредством ftp-proxy(8), работающего на порте 8021.

rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021

В этом примере на шлюзе NAT настраивается трансляция внутренних адресов посредством пула публичных адресов (192.0.2.16/28) и перенаправление входящих подключений к web-серверу на группу web-серверов во внутренней сети:

# NAT LOAD BALANCE

# Трансляция адресов источников исходящих пакетов с использованием адресного пула.

# Обязательная трансляция указанного адреса источника в адрес того же пула с

# использованием ключевого слова source-hash.

nat on $ext_if inet from any to any -> 192.0.2.16/28 source-hash

# RDR ROUND ROBIN

# Трансляция входящих соединений web-сервера с группой web-серверов во

# внутренней сети.

rdr on $ext_if proto tcp from any to any port 80 \

-> { 10.1.2.155, 10.1.2.160, 10.1.2.161 } round-robin

Примеры фильтров

# Используется внешний интерфейс kue0

# (единственный маршрутизируемый адрес 157.161.48.183),

# и частная сеть 10.0.0.0/8, для которой выполняется NAT.

# Использование макроса в качестве имени интерфейса обеспечивает простоту его изменения

ext_if = "kue0"

# Нормализация всего входящего трафика

scrub in on $ext_if all fragment reassemble

# Блокировка всего трафика по умолчанию с регистрацией в журнале

block return log on $ext_if all

# Блокировка всего трафика, поступающего из источника, для которого отсутствуют обратные маршруты

block in from no-route to any

# Блокировка и регистрация исходящих пакетов, у которых адрес источника не совпадает с нашим адресом,

# т.е. они либо имитируются, либо возникла ошибка конфигурации (например, отключена

# функция NAT), мы предпочитаем не рассылать свой мусор.

block out log quick on $ext_if from ! 157.161.48.183 to any

# Широковещательные пакеты (шум от кабельного модема) игнорируются без оповещения.

block in quick on $ext_if from any to 255.255.255.255

# Блокировка и регистрация входящих пакетов из резервного адресного пространства и недействительных

# адресов, т.е. они либо имитируются, либо возникла ошибка конфигурации. В любом случае,

# на них невозможно ответить (следовательно, отсутствует return-rst).

block in log quick on $ext_if from { 10.0.0.0/8, 172.16.0.0/12, \

192.168.0.0/16, 255.255.255.255/32 } to any

# ICMP

# Передача определенных входящих/исходящих ICMP-запросов и сохранение состояния (ping)

# Сопоставление состояний выполняется по адресам хоста и ICMP ID (не типу/коду),

# поэтому ответы (как 0/0 для 8/0) будут соответствовать запросам

# Сообщения об ошибках ICMP (которые всегда относятся к пакету TCP/UDP)

# обрабатываются состояниями TCP/UDP

pass on $ext_if inet proto icmp all icmp-type 8 code 0 keep state

# UDP

# Передача определенных исходящих UDP-соединений и сохранение состояний

pass out on $ext_if proto udp all keep state

# Передача определенных входящих UDP-соединений и сохранение состояний (DNS)

pass in on $ext_if proto udp from any to any port domain keep state

# TCP

# Передача всех исходящих TCP-подключений и модуляция состояния

pass out on $ext_if proto tcp all modulate state

# Передача определенных входящих TCP-соединений и сохранение состояния (SSH, SMTP, DNS, IDENT)

pass in on $ext_if proto tcp from any to any port { ssh, smtp, domain, \

auth } flags S/SA keep state

# Передача входящих соединений в режиме передачи данных для ftp-proxy, функционирующего на этом хосте.

# (для получения дополнительной информации см. ftp-proxy(8))

pass in on $ext_if proto tcp from any to 157.161.48.183 port >= 49152 \

flags S/SA keep state

# Запрет SMTP-соединений Windows 9x, поскольку они, как правило, являются

# вирусными червями. В качестве альтернативы для этих ОС можно установить ограничение в 1 соединение.

block in on $ext_if proto tcp from any os {"Windows 95", "Windows 98"} \

to any port smtp

# Присвоение тегов пакетам

# Три интерфейса: $int_if, $ext_if, and $wifi_if (беспроводной). NAT выполняется

# в $ext_if для всех исходящих пакетов. Теги пакетов создаются в

# $int_if, и пакеты с тегами выходят в $ext_if. Всем прочим

# исходящим пакетам (т.е. пакетам из беспроводной сети) разрешен

# доступ только через порт 80.

pass in on $int_if from any to any tag INTNET keep state

pass in on $wifi_if from any to any keep state

block out on $ext_if from any to any

pass out quick on $ext_if tagged INTNET keep state

pass out on $ext_if proto tcp from any to any port 80 keep state


Грамматика

Для pf.conf в BNF используется следующий синтаксис:

line = ( option | pf-rule | nat-rule | binat-rule | rdr-rule |

antispoof-rule | altq-rule | queue-rule | anchor-rule |

trans-anchors | load-anchors | table-rule )

option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] |

[ "optimization" [ "default" | "normal" |

"high-latency" | "satellite" |

"aggressive" | "conservative" ] ]

[ "limit" ( limit-item | "{" limit-list "}" ) ] |

[ "loginterface" ( interface-name | "none" ) ] |

[ "block-policy" ( "drop" | "return" ) ] |

[ "state-policy" ( "if-bound" | "group-bound" |

"floating" ) ]

[ "require-order" ( "yes" | "no" ) ]

[ "fingerprints" filename ] |

[ "debug" ( "none" | "urgent" | "misc" | "loud" ) ] )

pf-rule = action [ ( "in" | "out" ) ]

[ "log" | "log-all" ] [ "quick" ]

[ "on" ifspec ] [ route ] [ af ] [ protospec ]

hosts [ filteropt-list ]

filteropt-list = filteropt-list filteropt | filteropt

filteropt = user | flags | icmp-type | icmp6-type | tos |

( "keep" | "modulate" | "synproxy" ) "state"

[ "(" state-opts ")" ] |

"fragment" | "no-df" | "min-ttl" number |

"max-mss" number | "random-id" | "reassemble tcp" |

fragmentation | "allow-opts" |

"label" string | "tag" string | [ ! ] "tagged" string

"queue" ( string | "(" string [ [ "," ] string ] ")" ) |

"probability" number"%"

nat-rule = [ "no" ] "nat" [ "pass" ] [ "on" ifspec ] [ af ]

[ protospec ] hosts [ "tag" string ] [ "tagged" string ]

[ "->" ( redirhost | "{" redirhost-list "}" )

[ portspec ] [ pooltype ] [ "static-port" ] ]

binat-rule = [ "no" ] "binat" [ "pass" ] [ "on" interface-name ]

[ af ] [ "proto" ( proto-name | proto-number ) ]

"from" address [ "/" mask-bits ] "to" ipspec

[ "tag" string ] [ "tagged" string ]

[ "->" address [ "/" mask-bits ] ]

rdr-rule = [ "no" ] "rdr" [ "pass" ] [ "on" ifspec ] [ af ]

[ protospec ] hosts [ "tag" string ] [ "tagged" string ]

[ "->" ( redirhost | "{" redirhost-list "}" )

[ portspec ] [ pooltype ] ]

antispoof-rule = "antispoof" [ "log" ] [ "quick" ]

"for" ( interface-name | "{" interface-list "}" )

[ af ] [ "label" string ]

table-rule = "table" "<" string ">" [ tableopts-list ]

tableopts-list = tableopts-list tableopts | tableopts

tableopts = "persist" | "const" | "file" string |

"{" [ tableaddr-list ] "}"

tableaddr-list = tableaddr-list [ "," ] tableaddr-spec | tableaddr-spec

tableaddr-spec = [ "!" ] tableaddr [ "/" mask-bits ]

tableaddr = hostname | ipv4-dotted-quad | ipv6-coloned-hex |

interface-name | "self"

altq-rule = "altq on" interface-name queueopts-list

"queue" subqueue

queue-rule = "queue" string [ "on" interface-name ] queueopts-list

subqueue

anchor-rule = "anchor" string [ ( "in" | "out" ) ] [ "on" ifspec ]

[ af ] [ "proto" ] [ protospec ] [ hosts ]

trans-anchors = ( "nat-anchor" | "rdr-anchor" | "binat-anchor" ) string

[ "on" ifspec ] [ af ] [ "proto" ] [ protospec ] [ hosts ]

load-anchor = "load anchor" string "from" filename

queueopts-list = queueopts-list queueopts | queueopts

queueopts = [ "bandwidth" bandwidth-spec ] |

[ "qlimit" number ] | [ "tbrsize" number ] |

[ "priority" number ] | [ schedulers ]

schedulers = ( cbq-def | priq-def | hfsc-def )

bandwidth-spec = "number" ( "b" | "Kb" | "Mb" | "Gb" | "%" )

action = "pass" | "block" [ return ] | [ "no" ] "scrub"

return = "drop" | "return" | "return-rst" [ "( ttl" number ")" ] |

"return-icmp" [ "(" icmpcode [ [ "," ] icmp6code ] ")" ] |

"return-icmp6" [ "(" icmp6code ")" ]

icmpcode = ( icmp-code-name | icmp-code-number )

icmp6code = ( icmp6-code-name | icmp6-code-number )

ifspec = ( [ "!" ] interface-name ) | "{" interface-list "}"

interface-list = [ "!" ] interface-name [ [ "," ] interface-list ]

route = "fastroute" |

( "route-to" | "reply-to" | "dup-to" )

( routehost | "{" routehost-list "}" )

[ pooltype ]

af = "inet" | "inet6"

protospec = "proto" ( proto-name | proto-number |

"{" proto-list "}" )

proto-list = ( proto-name | proto-number ) [ [ "," ] proto-list ]

hosts = "all" |

"from" ( "any" | "no-route" | "self" | host |

"{" host-list "}" | "route" string ) [ port ] [ os ]

"to" ( "any" | "no-route" | "self" | host |

"{" host-list "}" | "route" string ) [ port ]

ipspec = "any" | host | "{" host-list "}"

host = [ "!" ] ( address [ "/" mask-bits ] | "<" string ">" )

redirhost = address [ "/" mask-bits ]

routehost = ( interface-name [ address [ "/" mask-bits ] ] )

address = ( interface-name | "(" interface-name ")" | hostname |

ipv4-dotted-quad | ipv6-coloned-hex )

host-list = host [ [ "," ] host-list ]

redirhost-list = redirhost [ [ "," ] redirhost-list ]

routehost-list = routehost [ [ "," ] routehost-list ]

port = "port" ( unary-op | binary-op | "{" op-list "}" )

portspec = "port" ( number | name ) [ ":" ( "*" | number | name ) ]

os = "os" ( os-name | "{" os-list "}" )

user = "user" ( unary-op | binary-op | "{" op-list "}" )

unary-op = [ "=" | "!=" | "<" | "<=" | ">" | ">=" ]

( name | number )

binary-op = number ( "<>" | "><" | ":" ) number

op-list = ( unary-op | binary-op ) [ [ "," ] op-list ]

os-name = operating-system-name

os-list = os-name [ [ "," ] os-list ]

flags = "flags" [ flag-set ] "/" flag-set

flag-set = [ "F" ] [ "S" ] [ "R" ] [ "P" ] [ "A" ] [ "U" ] [ "E" ]

[ "W" ]

icmp-type = "icmp-type" ( icmp-type-code | "{" icmp-list "}" )

icmp6-type = "icmp6-type" ( icmp-type-code | "{" icmp-list "}" )

icmp-type-code = ( icmp-type-name | icmp-type-number )

[ "code" ( icmp-code-name | icmp-code-number ) ]

icmp-list = icmp-type-code [ [ "," ] icmp-list ]

tos = "tos" ( "lowdelay" | "throughput" | "reliability" |

[ "0x" ] number )

state-opts = state-opt [ [ "," ] state-opts ]

state-opt = ( "max" number | timeout |

"source-track" [ ( "rule" | "global" ) ] |

"max-src-nodes" number | "max-src-states" number |

"max-src-conn" number |

"max-src-conn-rate" number "/" number |

"overload" "<" string ">" [ "flush" ] |

"if-bound" | "group-bound" | "floating" )

fragmentation = [ "fragment reassemble" | "fragment crop" |

"fragment drop-ovl" ]

timeout-list = timeout [ [ "," ] timeout-list ]

timeout = ( "tcp.first" | "tcp.opening" | "tcp.established" |

"tcp.closing" | "tcp.finwait" | "tcp.closed" |

"udp.first" | "udp.single" | "udp.multiple" |

"icmp.first" | "icmp.error" |

"other.first" | "other.single" | "other.multiple" |

"frag" | "interval" | "src.track" |

"adaptive.start" | "adaptive.end" ) number

limit-list = limit-item [ [ "," ] limit-list ]

limit-item = ( "states" | "frags" | "src-nodes" ) number

pooltype = ( "bitmask" | "random" |

"source-hash" [ ( hex-key | string-key ) ] |

"round-robin" ) [ sticky-address ]

subqueue = string | "{" queue-list "}"

queue-list = string [ [ "," ] string ]

cbq-def = "cbq" [ "(" cbq-opt [ [ "," ] cbq-opt ] ")" ]

priq-def = "priq" [ "(" priq-opt [ [ "," ] priq-opt ] ")" ]

hfsc-def = "hfsc" [ "(" hfsc-opt [ [ "," ] hfsc-opt ] ")" ]

cbq-opt = ( "default" | "borrow" | "red" | "ecn" | "rio" )

priq-opt = ( "default" | "red" | "ecn" | "rio" )

hfsc-opt = ( "default" | "red" | "ecn" | "rio" |

linkshare-sc | realtime-sc | upperlimit-sc )

linkshare-sc = "linkshare" sc-spec

realtime-sc = "realtime" sc-spec

upperlimit-sc = "upperlimit" sc-spec

sc-spec = ( bandwidth-spec |

"(" bandwidth-spec number bandwidth-spec ")" )

Связанные файлы

/etc/hosts

База данных имен хостов.

/etc/pf.os

Местоположение отпечатков операционных систем по умолчанию.

/etc/protocols

База данных имен протоколов.

/etc/services

База данных имен служб.

/usr/share/examples/pf

Примеры наборов правил.