The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

PF. Часть 2. Расширенная конфигурация (pf firewall bsd bridge queue filter openbsd)


<< Предыдущая ИНДЕКС Правка src / Печать Следующая >>
Ключевые слова: pf, firewall, bsd, bridge, queue, filter, openbsd,  (найти похожие документы)
From: Михаил Сгибнев <mixa(@).dreamcatcher.ru> Date: 2006-09-13 16:18:40 Subject: PF. Часть 2. Расширенная конфигурация
Перевод: Сгибнев Михаил

Оглавление

Опции запуска

Опции используются для контроля за операциями PF. Они могут быть также указаны в pf.conf, используя следующие директивы:

set block-policy set debug set fingerprints file set limit set loginterface int set optimization set state-policy set timeout Пример:

Scrub (Нормализация пакета)

Введение

"Scrubbing" - это нормализация пакета таким образом, чтобы не осталось двусмысленности в определении адресата пакета. Директива scrub также пересобирает фрагментированные пакеты, таким образом осуществляя защиту некоторых операционных систем от определенного вида атак и отбрасывает пакеты с недопустимыми флагами. Самая простая форма: Это позволит делать scrub всех пакетов на всех интерфейсах. Одной из причин не делать scrub - если вы прокидываете NFS через PF. Некоторые не-OpenBSD операционные системы посылают(и ожидают) странные пакеты - фрагментированные, но с установленным битом "do not fragment", которые будут отклоняться при использовании scrub. Это может быть решено с помощью опции no-df. Еще одной причиной могут быть некоторые игры, у которых могут возникнуть проблемы при работе через scrub.

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

Дополнительная информация может быть найдена в "Network Intrusion Detection: Evasion, Traffic Normalization, and End-to-End Protocol Semantics"

Опции

Scrub может принимать следующие опции:

no-df random-id min-ttl num max-mss num fragment reassemble fragment crop fragment drop-ovl reassemble tcp Пример:

Именованные (под)наборы правил и якоря

Введение

В дополнению к главному набору правил, PF может работать с дополнительными наборами. С тех пор, как поднаборы могут динамически изменяться используя pfctl(8), они стали удобным инструментом изменения основного набора правил. Если таблица используется для динамического хранения адресов, поднаборы используются для динамического хранения правил фильтрации и правил nat, rdr, и binat.

Поднабор может быть добавлен в главный набор с помощью якоря. Есть четыре типа якорных правил: Только главный набор правил может содержать якорные правила.

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

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

Например: Этот набор правил устанавливает по умолчанию запретительную политику на интерфейсе fxp0 для всего входящего и исходящего трафика. Stateful трафик пропускается и создается якорное правило с именем goodguys. Якоря могут быть связаны с правилами двумя методами: * Используя загрузку правил * Используя pfctl(8) Загрузка правил указывает pfctl загрузить правила из текстового файла. Например: Когда будет загружен главный набор, правила, перечисленные в файле/etc/anchor-goodguys-ssh будут загружены в именованный набор ssh, приложенный к якорю goodguys.

Для добавления правил к якорю, используя pfctl, можно использовать следующую конструкцию: Это добавит правило pass правила ssh к якорю goodguys. PF проверит эти правила (а также любые другие правила фильтрации, которые будут добавлены) когда дойдет до якоря goodguys в главном наборе правил.

Правила также могут быть сохранены и загружены из текстового файла: Эта операция загрузит правила из файла /etc/anchor-goodguys-www в именованый набор правил www якоря goodguys.

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

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

Опции якоря

Дополнительно в якорном правиле может быть определен интерфейс, протокол, адрес источника или назначения, тэг и т.д. Когда такой дополнительный параметр встречается, то пакет попадает на проверку только в случае соответствия указанному условию. Например: Правила в якоре ssh будут оцениваться только в случае, если пришел TCP пакет на 22 порт. Правила к якорю могут добавляться так: В этом случае, когда не определен ни порт, ни протокол, ни интерфейс, хосту 192.0.2.10 будет разрешена работа только по протоколу ssh.

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

Управление осуществляется с помощью pfctl. Вы можете удалять и добавлять правила из набора не перезагружая при этом главный набор.

Для примера, выведем список всех правил набора, добавленного к якорю ssh: Сброс всех правил из этого набора: Если имя набора пропущено, то действие применяется ко всем наборам якоря.

Для получения полного списка команд, пожалуйста см. pfctl(8).

Организация очередей и приоритетов

Очереди

Как известно, смысл очереди заключается в том, чтобы сохранить данные, которые еще не прошли обработку. При работе в сети, данные получаемые хостом поступают в очередь и ждут, когда они будут обработаны операционной системой, при этом она решает, какие именно пакеты и в каком порядке обрабатывать. Изменение этого порядка может оказать влияние на производительность сети. Для примера, представьте себе пользователя, работающего одновременно с приложениями по протоколам ssh и ftp. В идеальном случае, пакеты ssh должны обрабатываться в первую очередь, так как этот протокол очень чувствителен к задержкам. При нажатии клавиши в ssh-клиенте ожидается немедленный ответ, но идущая передача по ftp вызывает задержку в несколько секунд. Что может произойти в случае, когда роутер обрабатывает большое количество ftp пакетов? Пакеты ssh сохраняются в очереди, а то и просто отбрасываются в случае малого буфера и в результате ssh сессия может вообще прерваться. Модифицирование стратегии организации очередей может позволить распределить пропускную способность между различными приложениями, пользователями и хостами.

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

Планировщики

Планировщиком называется то, что организовывает очередь и определяет порядок обработки пакетов. По умолчанию в OpenBSD в качестве планировщика используется First In First Out (FIFO). Принцип его очень просто - первый вошел - первый вышел. Новоприбывший пакет добавляется в конец очереди. При превышении максимального размера очереди пакет отбрасывается. Это явление известно как tail-drop.

OpenBSD поддерживает два планировщика: Очереди, базирующиеся на классах

В очередях базирующиеся на классах (CBQ) алгоритм организации очереди построен на разделении полосы пропускания между различными очередями или классами. Трафик присоединяется к очереди на основании адреса источника или отправителя, порта, протокола и т.д. и т.п. Очередь может быть сконфигурирована на заимствование произвольной полосы пропускания от родительской очереди, если та занимает свой канал не полностью. Очереди также могут работать с системой приоритетов, например, пропуская ssh трафик в первую очередь, по сравнению с трафиком ftp/

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

В этом случае общая пропускная способность составляет 2 МБ/с и эта полоса пропускания делится между тремя дочерними очередями.

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

Очередь может быть настроена таким образом, что будет заимствовать полосу пропускания у родителя в случае неиспользования ее другими очередями. Рассмотрим такую организацию очереди: Если трафик в ftp очереди превышает 900Kbps, и трафик в очереди UserA - меньше чем 1Mbps (потому что ssh очередь использует меньше чем 100Kbps), ftp очередь заимствует дополнительную полосу пропускания от UserA. Таким образом ftp очередь способна использовать больше чем ей назначенные 900Kbps, но в случае увеличения очереди ssh заимствованая полоса освобождается.

CBQ назначает каждой группе свой приоритетный уровень. В моменты перегрузки предпочтение отдается очередям с более высоким приоритетом в случае наличия у них одного родителя. При одинаковых приоритетах очереди обслуживаются циклически. Для примера: CBQ будет обрабатывать очереди UserA и UserB циклическим способом, так как их приоритеты равны. В ходе обработки очереди UserA также обрабатываются ее дочерние очереди, где ssh имеет более высокий приоритет и будет обрабатываться в первую очередь в случае перегрузки сети. Обратите внимание, что очереди ssh и ftp е имеют приоритета по сравнению с очередями UserA и UserB так как они находятся на более низком уровне.

Для получения более детальной информации по CBQ обратитесь к References on CBQ.

Приоритетные очереди

Приоритетные очереди (PRIQ) создаются на сетевом интерфейсе, причем структура очередей является плоской - нельзя создавать дочерние очереди. Сперва определяется корневая очередь с указанием общей пропускной способности, а за ней все дочерние очереди. Рассмотрим такой пример: Корневая очередь определяется с пропускной способностью 2Mbps, следом идут дочерние.

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

Случайное раннее обнаружение

Случайное раннее обнаружение (RED) - это алгоритм определения перегрузки канала. Его целью является предотвращение переполнения очереди. Делается это путем непрерывного сравнения текущей длины очереди к минимальному и максимальному порогам. Если минимальный порог не достигнут - все пакеты пропускаются. Если достигнут максимальные порог - все пакеты отбрасываются. В промежутке пакеты отбрасываются с определенной вероятностью, зависящей от размера очереди. Чем ближе к максимальному порогу - тем выше вероятность. Пакеты для отбрасывания выбираются случайным образом из разных сессий. Чем большая полоса пропускания занимается сессией, тем более выше вероятность сброса из нее пакета.

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

RED должен использоваться только тогда, когда транспортный протокол способен реагировать на индикаторы перегрузки сети. В большинстве случаев это означает, что RED должен использоваться только к очередям TCP, а не к очередям UDP или ICMP.

Для получения дополнительной информации обратитесь к References on RED.

Явное уведомление о перегрузке

Явное уведомление о перегрузке (ECN) работает совместно с RED и применяется для уведомления двух связанных хостов о перегрузке сети. Делается это разрешением RED установить флаг в заголовке пакета, вместо его отброса. Если удаленный хост поддерживает ECN и читает этот флаг, то он начинает снижать исходящий трафик.

Для получения более подробной информации обратитесь к RFC 3168.

Конфигурирование очереди

Начиная с OpenBSD 3.0 Alternate Queueing (ALTQ) стал частью основной системы, а с версии OpenBSD 3.3 ALTQ был интегрирован в PF. Реализация ALTQ в OpenBSD поддерживает планировщики Class Based Queueing (CBQ) and Priority Queueing (PRIQ) и Random Early Detection (RED) вместе с Explicit Congestion Notification (ECN)..

Поскольку ALTQ интегрирован в PF, то PF должен быть включен для организации работы очередей. Руководство, как это сделать, можно найти в разделе документации "Getting Started".

Очереди конфигурируются в файле pf.conf. Есть два типа директив, которые используются для конфигурации очередей. Синтаксис кдирективы altq следующий: Например: Эта команда запускает CBQ на интерфейсе fxp0, пропускная способность канала 2Mb и создаются три дочерние очереди std, ssh, ftp.

Синтаксис кдирективы queue следующий: Продолжение примера выше: Здесь определяются дочерние очереди. Очереди std назначается 50% пропускной способности от материнской очереди и она назначается дефолтной. Очередь ssh определяет две дочерних очереди, ssh_login и ssh_bulk. Ssh_login дают более высокий приоритет чем ssh_bulk, и обе работают с ECN. Ftp назначена полоса пропускания в 500Kbps и дан приоритет 3. Эта очередь может арендовать свободную пропускную способность других очередей и используется red.

Назначение трафика в очередь

Для направления трафика в очередь используется ключевое слово queue в правилах PF. Для примера рассмотрим следующую строку: Пакеты из этого правила могут быть направлены в очередь таким способом: Когда используется ключевое слово queue совместно с директивой block, все пакеты TCP RST или ICMP Unreachable ставятся в указанную очередь.

Обратите внимание, что queue может приключиться для другого интерфейся, чем было определено директивой altq: Очередь определяется на fxp0, но указание на нее встречается на dc0. Если пакеты, соответствующие правилу выходит с интерфейса fxp0, то он будет поставлен в очередь ftp. Этот тип очередей может быть очень полезен на маршрутизаторах.

Обычно с ключевым словом queue используется только одно имя очереди, но если определено и второе имя, то очередь будет использоваться для пакетов с Type of Service(ToS) низкой задержки и для пакетов TCP ACK без полезного груза данных. Хороший пример может быть найден при использовании ssh: во время открытия сессии ToS устанавливается в low-delay пока не откроется сессия SCP или SFTP. PF может использовать информацию о находящихся в очереди пакетах для того. чтобы отличить пакеты на ввод логина от остальных пакетов. Возможно будет полезным разнести по приоритетам пакеты авторизации от пакетов данных: Это правило позволяет связать пакеты авторизации ssh с очередью ssh_login, а пакеты SCP и SFTP с очередью ssh_bulk, при этом ssh_login имеет приоритет выше и пакеты авторизации снуют во все стороны значительно швыдче.

Повышение приоритета пакетов TCP ACK имеет смысл на асинхронных соединениях, таких как ADSL, кде скорость входящего и исходящего потока не равны между собой. На ADSL линии при полностью занятом исходящем канале будет снижаться и полезное использование входящего канала, так как пакеты TCP ACK будут теряться и задерживаться. Тестирования показали, что для достижения наибольшей эффективности, полоса пропускания должна быть немного меньше, чем способно подключение. Например, если ADSL линия дает максимальную скорость в 640Kbps, установите значение пропускной способности для корневой линии в 600Kb. Оптимальное значение находится путем проб и ошибок.

Когда ключевое слово queue используется с правилами keep state: PF будет делать запись очереди в таблице состояний таким образом, что пакеты с fxp0 соответствующие образовавшемуся соединению будут оказываться в очереди ssh.

Обратите внимание, что ключевое слово queue применяется к правилам, обслуживающим входящий трафик.

Пример #1: Маленькая домашняя сеть В этом примере OpenBSD используется как шлюз в Интернет для маленькой домашней сети с тремя рабочими станциями. На шлюзе работает NAT и фильтрация пакетов. Выход в Интернет осуществляется по ADSL с входящей скоростью 2Mbps и исходящей 640Kbps.

Для очередей действуют следующие правила: Ниже представлены правила, реализующие эту политику. Обратите внимание, что в pf.conf не представлены правила nat, rdr, options, и т.д. непосредственно не имеющие отношения. Пример #2: Сеть компании В этом примере OpenBSD выступает в роли системы сетевой защиты для сети компании. В компании работает WWW сервер, установленный в DMZ. Клиенты обновляют свои сайты через FTP. У IT одела имеется собственная подсеть, соединенная с главной, босс использует свой компьютер для почты и серфинга по сети. Соединение с Интернетом осуществляется на скорости T1 (1.5Mbps) в обе стороны. Все прочие сетевые сегменты используют Fast Ethernet (100Mbps).

Сетевой администратор выбрал следующую политику: Ниже представлены правила, реализующие эту политику. Обратите внимание, что в pf.conf не представлены правила nat, rdr, options, и т.д. непосредственно не имеющие отношения.

Адресные пулы и балансировка нагрузки

Введение

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

Есть четыре метода использования пулов адресов: За исключением метода round-robin, пул адресов должен быть определен как блок адресов CIDR (Classless Inter-Domain Routing). В методе round-robin используется назначение адресов из таблицы.

Опция sticky-address может использоваться с пулами random и round-robin для гарантии назаначения всегда одного и того же адреса источника в адрес пула.

Адресные пулы NAT

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

В этом примере пул из двух адресов используется для трансляции исходящих пакетов. Для каждого исходящего соединения PF производит ротацию адресов методом round-robin: Единственным недостатком этого метода будет то, что не всегда будет соблюдаться соответствие между исходным адресом и адресом трансляции. Это может вызвать проблему при заходе на web - узлы, проверяющих валидность пользователя на основании IP адреса. Решением этой проблемы может стать использование метода source-hash для привязки внутреннего адреса к адресу трансляции. В этом случае адресный пул должен быть определен как сетевой блок CIDR: В этом правиле nat используется пул адресов 192.0.2.4/31 (192.0.2.4 - 192.0.2.5) как адреса трансляции для исходящих пакетов. Каждый внутренний адрес будет всегда транслироваться в свой внешний адрес, так как указано ключевое слово source-hash.

Балансировка нагрузки входящих подключений

Пулы адресов также могут использоваться для балансировки нагрузки входящих подключений. Для примера, входящие подключения на web-сервер могут быть распределены между серверной фермой: Все соединения циклически будут перенаправляться на серверы фермы используя метод round-robin. Это "sticky connection" будет существовать до тех пор, пока существуют постоянные соединения к этому адресу. Следующий пользователь будет подключен иже с следующему адресу.

Балансировка нагрузки исходящего трафика

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

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

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

Для гарантии того, что пакеты с $ext_if1 всегда направляются к $ext_gw1 (и соответственно для $ext_if2 к $ext_gw2), в правилах можно указать следующее: В заключение хочу сказать, что NAT можно использовать на каждом из внешних интерфейсов: Полный пример балансировки исходящего трафика будет выглядеть так:

Тэгирование пакетов

Введение

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

Назначение тэгов пакетам

Тэг назначается пакету с использованием ключевого слова tag: Тэг INTERNAL_NET будет назначен любому пакету, проходящему через это правило. Обратите внимание при использовании keep state; тегирование пакетов должно происходить в правилах pass.

Использование тэгов также допустимо и в макросах: Также имеется набор предопределенных макросов, которые могут быть использованы: Эти макросы определяются во время загрузки, а не во время выполнения.

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

Проверка тэгов

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

Фильтрация пакетов на основе политик несколько отличается от фильтрации на основе правил. В политиках устанавливаются правила, по которым определенный вид трафика должен быть пропущен, а определенный - запрещен. Пакеты классифицируются внутри политик на основе традиционных критериев - IP адрес источника/назначения, протокола и т.д.

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

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

Полный набор теперь будет выглядеть так: Тэггинг фреймов Ethernet

Тэгирование может быть выполнено на уровне Ethernet, если машина, осуществляющая тэггинг/фильтрацию, работает в режиме bridge(4). Для создания bridge(4) правил фильтрации используется ключевое слово tag. В PF существует возможность выполнять фильтрацию базируясь на mac адресе источника/назначения. Bridge(4) правила могут быть созданы с использованием команды brconfig(8): И затем в pf.conf указать:

Термины, используемые переводчиком.

При нахождении неточностей, ошибок или неправильном толковании терминов прошу отметить это в форуме на http://dreamcatcher.ru

Таблица состояний - таблица, образованная правилами Keep State и хранящая информацию о соединениях, образованных с помощью этого правила.
скинут/отброшен - dropped/rejected
Поднабор - Sub ruleset
Якорь - anchor

<< Предыдущая ИНДЕКС Правка src / Печать Следующая >>

 Добавить комментарий
Имя:
E-Mail:
Заголовок:
Текст:




Спонсоры:
Слёрм
Inferno Solutions
Hosting by Ihor
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2019 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру