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

[*]C.3.1. Примеры

Программа 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 }\n \
    pass out to <test> keep state\n" | 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, «Интеграция пакетного фильтра с програмным окружением».