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

    Макросы и списки
    ext_if = "em0"
   int_if="le0"
   tcp_services = "{{22, 13}}"
   comp3 = "10.30.50.3"

Параметры настройки фаерволла

set block_policy return

Как мы выбасываем пакеты? Мы можем молча пожирать и никак не реагировать. Можем посылать хост анричебл. Можем закрываться тцп соединение ресетом. Клиент прислал ак, а мы ему вместо сина рст. block_policy return врубает как раз ресет. Но блокируем мы не только тцп соединения и задание такой полиси по умолчанию означает, чт всякий раз, когда у нас соединение не разрешается, мы должны чсто-нибудь посылать клиенту. короче говроя, если есть какая-то норма реакции на то, что передача данных блокируется -- эту реакцию надо будет воспроизводить.

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

 set skip o lo

На лупбэк интерфейсе мы не фильтруем ничего. Далее нормализация.

    scrub in

Нормализуем только входящий трафик.

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

nat on $ext_if inet from !(ext_if)->($ext_if:0)

Круглый скобочки при обращении к сетевому интерфейсу превращаются в айпиадрес на этом текущем интерфейсе. Второй нюанс :0. В pf есть при обращении к сетевому интерфейсу есть несколько модификаторов, позволяющих превратить айпиадрес в сеть, итд. :0 -- Если ип адресов несколько, то брать первый.

Фильтрационные правила работают по принципу ласт винс. Кто последний напишет на пакете, что с ним делать, то с ним и сделают.

Другой способ преобразования -- редирект, destination nat, проборос портов.

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

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

rdr в пфе это дестинейшн нат. Для него устанавливается чек стейт. Происзодит подмена адресов, подмена портов.

Поехали фильтрующие правила.

block in
pass out
antispoof quick for{lo init}
pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services

Нам нужно еще обслужить редирект 80 порта

    pass in on $ext_if inet proto tcp from any to $comp3 port 80 synproxy state

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

Такой вот главный эффект использования механизма состояний с параметрами син прокси.

Чего недурно пропускать через фаерволл еще?

pass inet proto icmmp all icmo-type echoreq

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

Здесь не были использованя таблицы и якоря. Что касается таблиц.

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

Таблички указываются в угловых скобочках.

table <good> 172.16.0.0/16, !172.16.1.0/24, 172.16.1.100}

block in on $int_if
pass in on $int_if from <good>

Восклицательный знак означает не "все адреса кроме", а "не те адреса".

У таблицы есть еще одно достоинство. Это тот факт, что модифицируя таблицу вы не модифицируете свод правил.

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

Таблицу можно модифицировать из юзерспейса. Когда вы модифицируете таблицу из юзерспейса.

pfctl -t good -T add 1.2.3.4

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

Раз уж мы заговорили про таблицу.

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

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

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

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

Это очень хороший пример использования таблицы, которая вживую по мере наблюдения нежелательных событий заполняется и по мере устаревания выбрасывается. Довольно типичный пример применения подобных конструкций лет 10 назад -- грей листинг. Когда у вас по каким-то причинам.. Нет. не так. Когда у вас по каким-то причинам с одного и того же сервера происходит слишком много соединений на один порт, его надо затолкать. Робот не может понять 10 соединений в секунду -- это от того, что робот чего то подбирает или пользователь судорожно пытается зайти и не помнит пароль. Ну 10 раз в секунду достаточно однозначно. Но если не в секунду, а в минуту, то все не так понятно. Поэтому такой адрес надо вносить на время в черный список, а через неокторое время выбрасывать. Такие дела.

Это был разговор про таблицы.

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

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

    all tcp 10.30.50.3:80 (10.0.2.15:80) < 10.0.2.2:...
    FIN_WAIT2:fin-wait2

Это состояние редиректа портов вот этого правила.

Состояния хранятся не только для tcp.

    all icmp 144.76.222.201:3782 <- 10.3.0.52:3782 0:0

Минуточку, а где же нат?

all icmp 10.0.2.15:25608(10.3.0.52:3782) -> 144.76.222.201:25608 0:0