C.3. Управление пакетным фильтром OpenBSD при помощи утилиты pfctl(8)

Программа pfctl(8) предназначена для управления системой pf(4). Она позволяет устанавливать правила, менять значения параметров и выводить статистическую информацию. Ниже описаны опции данной команды.

-e
Включить пакетный фильтр
-d
Отключить пакетный фильтр
-h
Справка
-n
Не загружать правила, только проверить синтаксис.
-f file
Загрузить правила из файла. См. так же опцию -n
-o

Включить опимизацию правил. Оптимизатор может улучшить производительность пакетного фильтра путём удаления повторов и расположения правил в другом порядке. Вот что он делает:

  1. Удаляет дублирующиеся правила
  2. Удаляет правила, которые являются подмножеством других правил. Например, если вы в одном правиле блокируете весь трафик от хоста A, а в другом весь трафик от этого хоста на 22-й порт, то второе правило, очевидно, избыточно.
  3. Когда это возможно, объединяет несколько правил в одно, при помощи использования таблиц.
  4. Меняет порядок расположения правил для увеличения эффективности работы.

При указании второй опции -o, оптимизатор начинает вставлять ключевое слово quick в правила.

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

-z
Очистить статистику по правилам
-i interface
Ограничить действия указанным интерфейсом
-p device
Использовать устройство альтернативное /dev/pf.
-A
Загружать только очереди
-N
Загрузить только правила NAT
-O
Загрузить только опции.
-R
Загружать только правила фильтрации
-a anchor

Применять опции -f, -F и -s только к правилам соответствующим якорю anchor. Например, следующая команда позволит просмотреть правила добавленные при помощи команды authpf(8) для пользователя smith, при условии, что программа authpf имеет pid 1234:

# pfctl -a "authpf/smith(1234)" -s rules
   

Кроме того, данная опция позволяет ограничивать область видимости таблицы:

# pfctl -a foo/bar -t mytable -T add 1.2.3.4 5.6.7.8
   

Данная команда изменит таблицу созданную в якоре foo/bar но не тронет глобальную таблицу, даже в случае конфликта имён.

-k host

Сбросить все записи в таблице состояний, относящиеся к указанному хосту. Можно употребить несколько раз:

# pfctl -k host1 -k host2
   

Сбросит все записи относящиеся к соединениям между host1 и host2.

-m

Установить явно заданные опции без сброса прочих:

# echo "set loginterface fxp0" | pfctl -mf -
   
-D macro=value
Эта опция позволяет переопределять в командной строке значения макросов определённые в конфигурационном файле.
-F modifier

Сбросить параметр modifier в пакетном фильтре. Можно указать всего одной буквой:

-F natСбросить правила nat
-F queueСбросить правила queue
-F rulesСбросить правила фильтрации
-F state Сбросить таблицу состояния (для nat и фильтрации)
-F Sources Сбросить информацию о источниках пакетов (см. Раздел C.2.1.4.7, «Опции таблицы состояний»)
-F info Сбросить статистическую информацию (не привязанную к правилам фильтрации)
-F TablesСбросить содержимое всех таблиц
-F osfp Сбросить содержимое таблицы для пассивного детектирования операционной системы
-F allСбросить всё

-s modifier

Показывать параметры пакетного фильтра, указанные в modifier:

-s natПоказать загруженные правила nat
-s queue Показать загруженные очереди. При указании совместно с опцией -v показывается статистика по очередям. При указании двух флагов -v -v, пакетный фильтр входит в цикл и показывает информацию on-line обновляя её раз в 5 минут. При этом видна так же измеренная полоса пропускания по каждой очереди.
-s rules Показать загруженные правила фильтрации. При использовании совместно с ключём -v показывается статистика по каждому правилу: количество срабатываний, количество пакетов и байт прошедших через правило. Оптимизация «set step», включённая в ядре по умолчанию, отключает вычисление статистики, когда это только возможно. Пакеты соответствующие правилу учитывающему состояни (keep state) учитываются только в этом правиле.
-s Anchors Показать якоря, загруженные непосредственно из главного набора правил. Если надо просмотреть вложенные якоря, надо употребить аргумент -a anchor. При указании опции -v все якоря рекурсивно разворачиваются.
-s stateПоказать таблицу состояний
-s Sources Показать информацию о источниках пакетов (см. Раздел C.2.1.4.7, «Опции таблицы состояний»)
-s info Показать статистическую информацию и счётчики. При использовании совместно с -v показывает информацию об источниках пакетов.
-s labels Показать статистику по каждому правилу. (Метки, количество срабатываний, количество пакетов, количество байт).
-s timeoutsПоказать установленные таймауты.
-s memory Показать текущие ограничения на размеры пулов памяти.
-s TablesПоказать список загруженных таблиц.
-s osfp Показать список известных операционных систем для пассивного детектирования операцонной системы.
-s Interfaces Показать список интерфейсов и драйверов интерфейсов, доступных пакетному фильтру. Совметстно с двумя аргументами -v -v может показать статистикку на интерфейсе. Можно ограничить статистику одним интерфейсом, если использовать совместно с опцией -i interface.
-s all Паказать всю информацию, кроме списка интерфейсов и списка операционных систем.

-t table
Указание, с какой таблицей мы работаем.
-T команда [адреса ...]

Указывает действие, которое можно совершить с таблицей. Команда может быть сокращена до одной буквы. Допустимы следующие команды:

-T killУничтожить таблицу
-T flushОчистить таблицу
-T add Добавить адреса в таблицу. Если таблица не существует, она автоматически создаётся
-T deleteУдалить указанные адреса из таблицы
-T replaceЗаменить адреса в таблице. Если таблица не существует, она автоматически создаётся
-T showПоказать содержимое таблицы
-T test Проверить, принадлежит ли указанный адрес таблице
-T zero Очистить статистическую информацию по таблице
-T load Загрузить только определения таблиц. Используется совместно с опцией -f

Для опций add, delete, replace и test адреса можно задавать как в командной строке, так и в файле, с помощью опции -f. Комментарии в текстовом файле с перечнем адресов, можно начинать с символа #. Можно использовать один или два раза флаг -v для того, чтобы информация о проделанных действиях печаталась подробнее. При этом перед каждым адресом будет печататься следующий флаг:

AДобавлен адрес (сеть)
CАдрес (сеть) изменены
DАдрес (сеть) удалены
M Адрес (сеть) найдены в таблице (для операции test)
X Адрес (сеть) дублируются (уже есть в таблице), поэтому игнорированы
Y Адрес (сеть) не могут быть добавлены или удалены, так как конфликтуют с записью с знаком !
ZСтатистика по этому адресу сброшена

В каждой таблице есть счётчики, которые можно просмотреть при помощи флага -v. Например, следующая команда создаёт открытый всем ветрам брандмауэр и посылает десять пингов на сервер ftp.openbsd.org:

# printf "table <test> { ftp.openbsd.org }
 
 pass out to <test> keep state
" | pfctl -f-
$ ping -qc10 ftp.openbsd.org
   

Теперь мы можем использовать команду show для того, чтобы просмотреть статистику по адресам из таблицы:

# pfctl -t test -vTshow
 129.128.5.191
  Cleared:  Thu Feb 13 18:55:18 2003
  In/Block: [ Packets: 0  Bytes: 0  ]
  In/Pass:  [ Packets: 10  Bytes: 840  ]
  Out/Block: [ Packets: 0  Bytes: 0  ]
  Out/Pass: [ Packets: 10  Bytes: 840  ]
   

Строка Cleared показывает когда начался учёт.

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

# pfctl -vvsTables
--a-r- test
 Addresses: 1
 Cleared:  Thu Feb 13 18:55:18 2003
 References: [ Anchors: 0  Rules: 1  ]
 Evaluations: [ NoMatch: 3496  Match: 1  ]
 In/Block: [ Packets: 0  Bytes: 0  ]
 In/Pass:  [ Packets: 10  Bytes: 840  ]
 In/XPass: [ Packets: 0  Bytes: 0  ]
 Out/Block: [ Packets: 0  Bytes: 0  ]
 Out/Pass: [ Packets: 10  Bytes: 840  ]
 Out/XPass: [ Packets: 0  Bytes: 0  ]
   

Как видно из строки Evaluations, только один пакет соответствовал правилу, остальные, однако корректно учтены таблицей, так как соответствовали записи в таблице состояний. Перезагрузка правил не влияет на счётчики в таблице. Строки XPass увеличиваются в том случае, если пакет пропускается благодаря записи в таблице состояний, но при этом более не соответствует таблице. (Например, если адрес удалён из таблицы, уже открытые соединения не должны оборваться, если они соответвуют таблице состояний.)

С одним флагом -v будет выведена только первая строка, в которой приведены флаги таблицы и её названия. Вот перечень флагов:

c Константа. Содержимое таблицы не может быть изменено вне pf.conf(5)
p persist — таблица не удаляется автоматически, когда на неё не ссылается ни одно правило.
a Активная таблица. Таблицы без этого флага реально не существуют, они не могут содержать адреса и видны только если задан флаг -g.
i inactive — неактивная таблица. Этот влаг выставляется на таблице, на время, в течение которого в неё «заливаются» данные.
r На данную таблицу есть ссылки, т.е. на неё реально ссылаются какие-то правила.
h Таблица скрыта (на время), так как при помощи якоря загружена другая таблица с таким же именем.

-v
Увеличить подробность отчёта. Данный флаг можно указывать дважды (см. пояснения у других флагов).
-q
Печатать только сообщения об ошибках и предупреждения.
-g
Отладочная информация
-x level

Уровень отладки. Можно сокращать до одной буквы:

-x noneНе выводить отладочных сообщений
-x urgent Выводить отладочные сообщения только для серьёзных ошибок. По умолчанию включён он.
-x misc Выводить отладочные сообщения только для различных ошибок.
-x loudВыводить всяческую отладочную информацию

C.3.1. Примеры

Пример C.1. Просмотр статистики на интерфейсе выбранном при помощи опции loginterface

Опция loginterface в файле /etc/pf.conf может указать один (и только один) интерфейс, для которого собирается полная статистическая информация. (См. Раздел C.2.2.1, «Опции в пакетном фильтре».)

# pfctl -s info
Status: Enabled for 14 days 10:02:15   Debug: Urgent

Hostid: 0xd56f1383

Interface Stats for rl1    IPv4    IPv6
 Bytes In      193781803    0
 Bytes Out      1799932863    0
 Packets In
 Passed       1716610    0
 Blocked       7973    0
 Packets Out
 Passed       2013028    0
 Blocked        0    0

State Table       Total    Rate
 current entries      5    
 searches       3848785   3.1/s
 inserts       77192   0.1/s
 removals       77187   0.1/s
Counters
 match        206160   0.2/s
 bad-offset        0   0.0/s
 fragment        0   0.0/s
 short         0   0.0/s
 normalize        0   0.0/s
 memory         0   0.0/s
 bad-timestamp       0   0.0/s
 congestion        0   0.0/s
 ip-option        0   0.0/s
 proto-cksum       0   0.0/s
 state-mismatch      604   0.0/s
 state-insert       0   0.0/s
 state-limit       0   0.0/s
 src-limit        0   0.0/s
 synproxy        0   0.0/s
  

Пример C.2. Кто из заблокированных взломщиков пытался пройти в систему в последнее время?

# pfctl -t crackers -v -v -Ts | grep "In/Block:.*Packets: [^0]" -B2
 59.124.47.229
  Cleared:  Fri Apr 20 19:29:30 2007
  In/Block: [ Packets: 159    Bytes: 9540    ]
--
 61.109.245.208
  Cleared:  Mon Apr 23 03:13:25 2007
  In/Block: [ Packets: 159    Bytes: 9540    ]
--
 62.193.224.155
  Cleared:  Sun Apr 15 00:03:19 2007
  In/Block: [ Packets: 1     Bytes: 60     ]
--
 66.34.136.28
  Cleared:  Wed Apr 25 00:06:03 2007
  In/Block: [ Packets: 3744    Bytes: 164736    ]
--
 67.15.8.50
  Cleared:  Tue Apr 24 03:44:28 2007
  In/Block: [ Packets: 568    Bytes: 34080    ]
--
 88.2.123.116
  Cleared:  Sat Apr 21 11:31:02 2007
  In/Block: [ Packets: 48     Bytes: 2880    ]
--
 210.87.136.171
  Cleared:  Sun Apr 15 00:03:19 2007
  In/Block: [ Packets: 1     Bytes: 60     ]
--
 219.153.32.201
  Cleared:  Mon Apr 23 10:54:24 2007
  In/Block: [ Packets: 164    Bytes: 9840    ]
  

Пример C.3. Просмотр таблицы состояний

# pfctl -ss 
self tcp 172.19.0.2:22 <- 172.19.0.34:60730  ESTABLISHED:ESTABLISHED
self tcp 172.19.0.2:22 <- 172.19.0.34:43768  ESTABLISHED:ESTABLISHED
self pfsync 172.19.0.2 -> 0.0.0.0  SINGLE:NO_TRAFFIC
# pfctl -vvss 
self tcp 172.19.0.2:22 <- 172.19.0.34:60730  ESTABLISHED:ESTABLISHED
 [3302985293 + 64096] wscale 1 [3073141737 + 66608] wscale 5
 age 06:30:34, expires in 24:00:00, 16093:13420 pkts, 1181656:3943411 bytes, rule 5
 id: 4621338700019ddb creatorid: d56f1383
self tcp 172.19.0.2:22 <- 172.19.0.34:43768  ESTABLISHED:ESTABLISHED
 [2485562129 + 63136] wscale 1 [4004983129 + 66608] wscale 5
 age 05:08:21, expires in 23:59:58, 2743:2321 pkts, 184400:1056475 bytes, rule 5
 id: 4621338700019f1d creatorid: d56f1383
self pfsync 172.19.0.2 -> 0.0.0.0  SINGLE:NO_TRAFFIC
 age 02:33:08, expires in 00:00:29, 15314:14760 pkts, 6238352:826560 bytes, rule 14
 id: 462133870001ca8b creatorid: d56f1383
  

При наличии на интерфейсе NAT трансляции, она отображается в данном отчёте. Это было показано при обсуждении pf.conf(5) в Раздел C.2.1.5.7, «Проверка состояния правил NAT».

См. так же Раздел C.5.2, «pftop».

Пример C.4. Сколько пакетов на какое правило попало?

# pfctl -vvsr 
@0 scrub in all fragment reassemble
 [ Evaluations: 8292326 Packets: 3818454 Bytes: 0   States: 0  ]
@0 block return in log all
 [ Evaluations: 389809 Packets: 2153  Bytes: 935446  States: 0  ]
@1 pass quick on lo0 all
 [ Evaluations: 389809 Packets: 237302 Bytes: 62225678 States: 0  ]
@2 pass in quick on rl1 inet proto udp from any to 172.19.0.2 port = domain
 [ Evaluations: 152507 Packets: 19368  Bytes: 1286672  States: 0  ]
@3 pass in quick on rl1 inet proto tcp from <trusted_ip:8> to 172.19.0.2 port = ssh keep state
 [ Evaluations: 48415  Packets: 19371  Bytes: 2672486  States: 0  ]
@4 block return in log quick on rl1 inet proto tcp from <crackers:314> to 172.19.0.2 port = ssh
 [ Evaluations: 46532  Packets: 7310  Bytes: 371716  States: 0  ]
@5 pass in on rl1 inet proto tcp from any to 172.19.0.2 port = ssh flags S/SA keep state
 [ Evaluations: 39219  Packets: 822253 Bytes: 144372004 States: 2  ]
@6 pass in on rl1 inet proto tcp from any to 172.19.0.2 port = smtp flags S/SA keep state
 [ Evaluations: 39400  Packets: 49654  Bytes: 41860091 States: 0  ]
@7 pass in on rl1 inet proto tcp from any to 172.19.0.2 port = domain flags S/SA keep state
 [ Evaluations: 39400  Packets: 763  Bytes: 44898  States: 0  ]
@8 pass in on rl1 inet proto tcp from any to 172.19.0.2 port = http flags S/SA keep state
 [ Evaluations: 39400  Packets: 2409271 Bytes: 1888003875 States: 0  ]
@9 pass in on rl1 inet proto tcp from any to 172.19.0.2 port = imap flags S/SA keep state
 [ Evaluations: 39400  Packets: 53382  Bytes: 36933799 States: 0  ]
@10 pass in on rl1 inet proto udp from any port = domain to 172.19.0.2 keep state
 [ Evaluations: 41095  Packets: 293  Bytes: 21590  States: 0  ]
@11 pass in inet proto icmp all keep state
 [ Evaluations: 47877  Packets: 0   Bytes: 0   States: 0  ]
@12 pass in on rl1 from <internal_ip:3> to any keep state
 [ Evaluations: 47877  Packets: 23966  Bytes: 2072826  States: 0  ]
@13 pass out on rl1 from any to <internal_ip:3> keep state
 [ Evaluations: 125819 Packets: 0   Bytes: 0   States: 0  ]
@14 pass out on rl1 all keep state
 [ Evaluations: 77942  Packets: 1184788 Bytes: 239933074 States: 1  ]
  

В отчёте, там, где даны имена таблиц, указано сколько в них записей.

Все эти данные позволяют применять утилиту pfctl(8) не только для управления пакетным фильтром, но и для сбора разнообразных данных и постоения биллинговых систем. Некоторое уже готовое програмное обеспечение на эту тему предствлено в Раздел C.4, «Интеграция пакетного фильтра с програмным окружением».


Обновлено: 12.03.2015