OpenBSD PF - Списки и макросы [FAQ PF - На главную]



Списки

Список позволяет задавать в правиле несколько похожих критериев. Например, несколько протоколов, номера портов, адресов и т.д. Таким образом, вместо написания одного правила для каждого отдельного IP-адреса, который необходимо заблокировать, можно написать одно правило, указав в списке необходимые IP-адреса. Списки определяются путем указания элементов в скобках { }.

Если pfctl(8) находит список во время загрузки набора правил, он создает несколько правил, по одному для каждого элемента в списке. Например:

block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any
будет интерпретированно как:
block out on fxp0 from 192.168.0.1 to any
block out on fxp0 from 10.5.32.6 to any
В одном правиле можно использовать несколько списков:
match in on fxp0 proto tcp to port { 22 80 } rdr-to 192.168.0.6
block out on fxp0 proto { tcp udp } from { 192.168.0.1, 10.5.32.6 } \
   to any port { ssh https }
Запятые между элементами списка необязательны.

Списки в свою очередь также могут включать в себя списки:

trusted = "{ 192.168.1.2 192.168.5.36 }"
pass in inet proto tcp from { 10.10.0.0/24 $trusted } to port 22
Остерегайтесь таких конструкций, как следующие. Они являются распространенной ошибкой и называются «списками с отрицанием»:
pass in on fxp0 from { 10.0.0.0/8, !10.1.2.3 }
Хотя предполагаемое значение должно соответствовать «любому адресу в пределах 10.0.0.0/8, кроме 10.1.2.3», правило интерпретируется как:
pass in on fxp0 from 10.0.0.0/8
pass in on fxp0 from !10.1.2.3
т.е. соответствует любому возможному адресу. Вместо этого следует использовать таблицы.

Макросы

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

Имена макросов должны начинаться с букв и могут содержать буквы, цифры и символы подчеркивания. Имена макросов не могут быть зарезервированными словами, такими как pass, out или queue.

ext_if = "fxp0"

block in on $ext_if from any to any
Это создаст макрос ext_if. Когда к макросу обращаются после того, как он был создан, к его имени должен добавляеться символ $.

В теле макросов также могут использоваться списки:

friends = "{ 192.168.1.1, 10.0.2.5, 192.168.43.53 }"
Макросы могут быть определены рекурсивно. Поскольку макросы не интерпретируются в кавычках, необходимо использовать следующий синтаксис:
host1      = "192.168.1.1"
host2      = "192.168.1.2"
all_hosts  = "{" $host1 $host2 "}"
Теперь макрос $all_hosts будет интерпретироваться как 192.168.1.1, 192.168.1.2.