Опции запуска
Опции используются для контроля за операциями PF. Они могут быть также указаны в pf.conf, используя следующие директивы:
set block-policy
* Устанавливает поведение по умолчанию для правил как всегда блокирующее: drop — пакеты удаляются без уведомления
* return — возвращается пакет TCP RST для блокированного TCP пакета и ICMP Unreachable для всего остального
Обратите внимание, что индивидуальные правила фильтра могут отменить заданный по умолчанию ответ.
set debug
* Установить уровень отладки pf none — отладочные сообщения не отображаются
* urgent — отображаются серьезные ошибки. Является значением по умолчанию
* misc — ошибки различной тяжести (например отображение статуса normalizer/scrubber пакета и ошибки создания правила state)
* loud — отображать события, возникающие в ходе обычной работы (например результат работы пассивной системы определения удаленной ОС)
set fingerprints file
Определить файл с сигнатурами операционных систем. Используется для пассивного определения удаленной ОС. По умолчанию /etc/pf.os.
set limit
* frags — максимальный размер памяти в строках, используемой для пересборки пакета (scrub правило). По умолчанию 5000.
* src-nodes — максимальный размер памяти в строках, используемой для хранения IP адресов источника. По умолчанию 10000.
* states — максимальный размер памяти в строках, используемой для хранения таблицы состояний (правила фильтрации keep state). По умолчанию 10000.
set loginterface int
Устанавливает интерфейс, но котором PF должен вести статистику по входящим/исходящим байтам и пропущенным/блокированным пакетам. Одновременно статистика собирается только для одного интерфейса. Обратите внимание на то, что счетчики в равилах работают независимо от того, установлен этот параметр или нет.
set optimization
* Оптимизирует работу PF руководствуясь следующими образцами: normal — подходит почти для всех сетей. Является значением по умолчанию.
* high-latency — сети с высоким временем задержки, например, спутниковые.
* aggressive — позволяет уменьшить объемы занимаемой памяти за счет малого таймаута соединений в таблице состояний.
* conservative — максимально консервативные настройки. Позволяет продлить время жизни записи в таблице состояний за счет некоторого увеличения объема занимаемой памяти и процессорного времени.
set state-policy
* Определяет манеру работы PF с таблицей состояний (см. Keeping State). if-bound — правила привязаны к интерфейсу, на котором открыты. Если трафик соответствует записи, но пересекает интерфейс указанный в ней, то соответствия не произойдет. Тогда пакет должен соответствовать фильтрующему правилу или скинут/отброшен.
* group-bound — также, как и с параметром if-bound, за исключением того, что принимаются интерфейсы одной грунны — например все ppp интерфейсы.
* floating — записи могут соответствовать пакету на любом интерфейсе. Пока пакет соответствует записи не имеет значения, через какой интерфейс он проходит и он будет пропущен. Является значением по умолчанию.
set timeout
* interval — число секунд между пакетами, соответствующих правилу. Превышение приводит к удалению правила.
* frag — время устаревания несобранного фрагмента пакета.
Пример:
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
Убирает бит «don't fragment» из заголовка IP пакета. Как уже говорилось, некоторые операционные системы генерируют фрагментированные пакеты с флагом «не фрагментировать», особенно это характерно для NFS. Такие пакеты будут отброшены, если не использовать no-df. Поскольку некоторые ОС генерируют «don't fragment» пакеты с нулевым идентификатором IP в заголовке, использование no-df лучше сочетать с опцией random-id.
random-id
Заменяет поле идентификатора в IP пакете на случайное, так как некоторые операционные системы назначают предсказуемые значения. Применяется только к исходящим пакетам, которые не фрагментируются после дополнительной сборки пакета.
min-ttl num
Устанавливает минимальное значение Time To Live (TTL) в заголовке пакета.
max-mss num
Устанавливает Maximum Segment Size (MSS) в заголовке TCP пакета.
fragment reassemble
Приходящие фрагменты накапливаются и собираются в законченный пакет, который затем передается на механизм фильтрации. Преимущество — возможность фильтрующему правилу игнорировать фрагменты. Недостаток — увеличение расхода памяти. Это опция по умолчанию, если никакая другая опция работы с фрагментами не установлена. Также это единственная опция, с которой работает NAT.
fragment crop
Все дублированные фрагменты будут отброшены и любые превышения — обрезаны. В отличие от fragment reassemble, фрагменты не буферизуются и передаются на механизм фильтрации сразу.
fragment drop-ovl
Работает подобно fragment crop, за исключением того, что все дубликаты отбрасываются.
reassemble tcp
* Постоянно нормализует TCP пакеты. При использовании scrub пересобирает пакет, может быть не определено направление (in/out). Может быть выполнена следующая нормализация: Ни одной из сторон не позволяется уменьшить IP TTL. Это сделано для того, чтобы защититься от посылок пакетов, запрашивающих соединение, но исчезающих до достижения адресата. TTL всех пакетов устанавливается в максимум.
* Модуляция временных меток RFC1323 в заголовке TCP пакета со случайным числом. Это препятствует определению uptime хоста или определению количества хостов за маршрутизатором, использующем NAT.
Пример:
Именованные (под)наборы правил и якоря
* Введение
* Именованные наборы правил
* Опции якоря
* Управление именованными наборами
Введение
В дополнению к главному набору правил, PF может работать с дополнительными наборами. С тех пор, как поднаборы могут динамически изменяться используя pfctl(8), они стали удобным инструментом изменения основного набора правил. Если таблица используется для динамического хранения адресов, поднаборы используются для динамического хранения правил фильтрации и правил nat, rdr, и binat.
Поднабор может быть добавлен в главный набор с помощью якоря. Есть четыре типа якорных правил:
* anchor name — оценивает все правила фильтра по имени якоря
* binat-anchor name — оценивает правила binat фильтра по имени якоря
* nat-anchor name — оценивает правила nat фильтра по имени якоря
* rdr-anchor name — оценивает правила rdr фильтра по имени якоря
Только главный набор правил может содержать якорные правила.
Именованные наборы правил
Именованный набор — это группа правил фильтрации группа фильтра и/или правил трансляции, которым было назначено имя. Точка привязки может содержать больше чем один такой набор. Когда 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).
Организация очередей и приоритетов
* Очереди
* Планировщики
o Очереди, базирующиеся на классах
o Приоритетные очереди
o Случайное раннее обнаружение
o Явное уведомление о перегрузке
* Конфигурирование очереди
* Назначение трафика в очередь
* Пример #1: Маленькая домашняя сеть
* Пример #2: Сеть компании
Очереди
Как известно, смысл очереди заключается в том, чтобы сохранить данные, которые еще не прошли обработку. При работе в сети, данные получаемые хостом поступают в очередь и ждут, когда они будут обработаны операционной системой, при этом она решает, какие именно пакеты и в каком порядке обрабатывать. Изменение этого порядка может оказать влияние на производительность сети. Для примера, представьте себе пользователя, работающего одновременно с приложениями по протоколам ssh и ftp. В идеальном случае, пакеты ssh должны обрабатываться в первую очередь, так как этот протокол очень чувствителен к задержкам. При нажатии клавиши в ssh-клиенте ожидается немедленный ответ, но идущая передача по ftp вызывает задержку в несколько секунд. Что может произойти в случае, когда роутер обрабатывает большое количество ftp пакетов? Пакеты ssh сохраняются в очереди, а то и просто отбрасываются в случае малого буфера и в результате ssh сессия может вообще прерваться. Модифицирование стратегии организации очередей может позволить распределить пропускную способность между различными приложениями, пользователями и хостами.
Обратите внимание, что организация очереди имеет смысл только для исходящих соединений, потому что как только пакет попал на входящий интерфейс с ним уже поздно что-либо делать, так как полоса пропускания канала была уже использована. Единственным решением этой проблемы может стать организация очереди на смежном маршрутизаторе или позволять организацию очереди на внутреннем интерфейсе, если хост сам является смежным маршрутизатором.
Планировщики
Планировщиком называется то, что организовывает очередь и определяет порядок обработки пакетов. По умолчанию в OpenBSD в качестве планировщика используется First In First Out (FIFO). Принцип его очень просто — первый вошел — первый вышел. Новоприбывший пакет добавляется в конец очереди. При превышении максимального размера очереди пакет отбрасывается. Это явление известно как tail-drop.
OpenBSD поддерживает два планировщика:
* Очереди, базирующиеся на классах (Class Based Queueing)
* Приоритетные очереди (Priority Queueing)
Очереди, базирующиеся на классах
В очередях базирующиеся на классах (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 on — определяет интерфейс, на котором будет организована очередь, планировщик и создает корневую очередь.
* queue — определяет свойства дочерних очередей
Синтаксис кдирективы altq следующий:
altq on interface scheduler bandwidth bw qlimit qlim \
tbrsize size queue { queue_list }
* interface — сетевой интерфейс, на котором активируется очередь.
* scheduler — какой планировщик будет использован. Доступные значения cbq и priq. На интерфейсе в один момент времени можно установить только один планировщик.
* bw — общая пропускная способность, доступная планировщику. Может содержать аббревиатуры b, Kb, Mb, Gb для обозначения bits, kilobits, megabits, и gigabits в секунду, конкретное значение или процент от общей пропускной способности.
* qlim — максимальное число пакетов в очереди. Необязательный параметр. По умолчанию — 50
* size — размер token bucket regulator в байтах. Если не определен, то устанавливается на основе ширины полосы пропускания.
* queue_list — список дочерних очередей, открываемых из под родительской очереди.
Например:
Эта команда запускает CBQ на интерфейсе fxp0, пропускная способность канала 2Mb и создаются три дочерние очереди std, ssh, ftp.
Синтаксис кдирективы queue следующий:
* name — имя очереди. Эта запись должна быть идентична определенной в директиве altq опцией queue_list. Для cbq это также может быть запись имени очереди в предыдущей директиве queue параметре queue_list. Имя не должно быть длиннее 15 символов.
* interface — сетевой интерфейс, на котором запущена очередь. Это значение опциональное и если не определено, то очередь будет работать применительно ко всем интерфейсам.
* bw — общая пропускная способность, доступная планировщику. Может содержать аббревиатуры b, Kb, Mb, Gb для обозначения bits, kilobits, megabits, и gigabits в секунду, конкретное значение или процент от общей пропускной способности. Указывается только при использовании планировщика cbq.
* pri — приоритет очереди. Для cbq приоритет изменяется от 0 до 7, для priq диапазон от 0 до 15. Приоритет 0 считается самым низким. Если этот параметр не определен, ему назначается 1.
* qlim — максимальное число пакетов в очереди. Необязательный параметр. По умолчанию — 50
* scheduler — используемый планировщик — cbq или priq. Должен быть таким же, как и родительская очередь.
* sched_options — дополнительные опции для управления планировщиком:
o default — определить очередью по умолчанию, куда будут включаться все пакеты не подходящие под остальные очереди. Может быть только одна.
o red — включить Random Early Detection (RED) для этой очереди.
o rio — включить RED с IN/OUT. В этом режиме RED поддерживает очереди различной длины и различные пороговые значения, по одному на каждый уровень IP Quality of Service.
o ecn — включить Explicit Congestion Notification (ECN) для этой очереди. Ecn работает совместно с red.
o borrow — эта очередь может заимствовать пропускную способность у других очереде. Может быть определено только при использовании cbq.
* queue_list — список дочерних очередей. Может быть определено только при использовании cbq.
Продолжение примера выше:
Здесь определяются дочерние очереди. Очереди std назначается 50% пропускной способности от материнской очереди и она назначается дефолтной. Очередь ssh определяет две дочерних очереди, ssh_login и ssh_bulk. Ssh_login дают более высокий приоритет чем ssh_bulk, и обе работают с ECN. Ftp назначена полоса пропускания в 500Kbps и дан приоритет 3. Эта очередь может арендовать свободную пропускную способность других очередей и используется red.
Назначение трафика в очередь
Для направления трафика в очередь используется ключевое слово queue в правилах PF. Для примера рассмотрим следующую строку:
Пакеты из этого правила могут быть направлены в очередь таким способом:
Очередь определяется на 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.
Для очередей действуют следующие правила:
* Выделяем 80Kbps для игрулек Боба, чтобы не стонал, когда Алиса и Чарли качают фильмы и музыку. Когда есть свободная полоса — пусть берет.
* SSH трафик и трафик интернет — пейджеров имеет высший приоритет.
* DNS запросы-ответы имеют приоритет чуть ниже.
* Исходящие TCP ACK имеют высший приоритет по сравнению со всем остальным исходящим трафиком.
Ниже представлены правила, реализующие эту политику. Обратите внимание, что в pf.conf не представлены правила nat, rdr, options, и т.д. непосредственно не имеющие отношения.
Пример #2: Сеть компании
В этом примере OpenBSD выступает в роли системы сетевой защиты для сети компании. В компании работает WWW сервер, установленный в DMZ. Клиенты Vill du ha en chans att vinna ett rejalt stort belopp utan krangliga regler och for en liten insats sa kan spelautomater online med en jackpott vara det basta valet for dig. обновляют свои сайты через FTP. У IT одела имеется собственная подсеть, соединенная с главной, босс использует свой компьютер для почты и серфинга по сети. Соединение с Интернетом осуществляется на скорости T1 (1.5Mbps) в обе стороны. Все прочие сетевые сегменты используют Fast Ethernet (100Mbps).
Сетевой администратор выбрал следующую политику:
* Трафик между WWW сервером и Интернетом ограничивается 500Kbps на одно соединение.
* Между WWW сервером и внутренней сетью ограничения по скорости нет.
* Трафик HTTP между WWW сервером и Интернет имеет высший приоритет по сравнению со всем остальным трафиком от WWW в Internet (таким, как доступ по FTP).
* 500Kbps резервируется для IT для того, чтобы качать последние версии программного обеспечения. Если есть лишнее — забираем.
* Трафик между начальником и Интернетом имеет высший приоритет по сравнению со сравнению со всем.
Ниже представлены правила, реализующие эту политику. Обратите внимание, что в pf.conf не представлены правила nat, rdr, options, и т.д. непосредственно не имеющие отношения.
Адресные пулы и балансировка нагрузки
* Введение
* Адресные пулы NAT
* Балансировка нагрузки входящих подключений
* Балансировка нагрузки исходящего трафика
o Пример набора правил
Введение
Адресным пулом называется адресное пространство больше двух адресов используемое группой пользователей. Адресный пул может быть указан в правилах перенаправления, трансляции и указан как адрес назначения в опциях фильтрации route-to, reply-to и dup-to.
Есть четыре метода использования пулов адресов:
* bitmask — назначает адрес из пула согласно исходному сетевому адресу (адрес источника для правил nat, адрес назначения для правил rdr). Пример: если пул адресов включает 192.0.2.1/24 и модифицируемый адрес 10.0.0.50, то результирующим адресом будет 192.0.2.50. Если пул адресов включает 192.0.2.1/25 и модифицируемый адрес 10.0.0.130, результатом будет 192.0.2.2.
* random — случайный выбор адресов из пула.
* source-hash — использование хэша адреса источника для распределения адресов из пула. Этот метод гарантирует соответствие адреса источника и адреса, взятого из пула. Ключ для алгоритма хеширования может быть определен дополнительно после ключевого слова source-hash в шестнадцетиричном формате или как строка. По умолчанию, pfctl(8) генерирует случайный ключ при каждой загрузке набора правил.
* round-robin — использование адресов пула по кругу. Это метод по умолчанию и единственный метод, когда пул адресов определен из таблицы.
За исключением метода 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 можно использовать на каждом из внешних интерфейсов:
Полный пример балансировки исходящего трафика будет выглядеть так:
Тэгирование пакетов
* Введение
* Назначение тэгов пакетам
* Проверка тэгов
* Политика фильтрации
* Тэггинг фреймов Ethernet
Введение
Тэггинг пакетов — способ пометить пакет внутренним идентификатором для дальнейшего использования в качестве критерия в правилах трансляции и фильтрации. С тэгированием становится возможным создание «доверия» между интерфейсами и определение, был ли пакет обработан правилами трансляции. Также становится возможным переход от фильтрации, основанной на правилах, к фильтрации, основанной на политиках.
Назначение тэгов пакетам
Тэг назначается пакету с использованием ключевого слова tag:
Тэг INTERNAL_NET будет назначен любому пакету, проходящему через это правило. Обратите внимание при использовании keep state; тегирование пакетов должно происходить в правилах pass.
Использование тэгов также допустимо и в макросах:
Также имеется набор предопределенных макросов, которые могут быть использованы:
* $if — интерфейс
* $srcaddr — IP адрес источника
* $dstaddr — IP адрес назначения
* $srcport — порт источника
* $dstport — порт назначения
* $proto — The protocol
* $nr — номер правила
Эти макросы определяются во время загрузки, а не во время выполнения.
Тегирование подчиняется следующим правилам:
* Тэг «приклеивается». Только один тэг может быть прикреплен к пакету и он не может быть удален. Хотя есть возможность изменить его другим тэгом.
* См. правило выше, пакет может содержать тэг, даже если последнее правило для пакета не содержало ключевое слово tag.
* Одновременно тэгу назначается только один тэг.
* Тэг — это внутренний идентификатор. Он не может быть послан во внешний мир.
Возьмем следующий набор правил для примера:
* Пакет поступает на интерфейс $int_if и ему назначается тэг INT_NET в правиле #1.
* TCP пакет направляется с $int_if на порт 80 куда то там в Интернет и будет одарен тэгом INT_NET по правилу #1. Но правилом #2 ему будет назначен тэг INT_NET_HTTP.
* Пакет, поступивший с $int_if от адреса 192.168.1.5 будет пропущен правилом #3, так как это последнее соответствующее правило. Однако, пакеты TCP port 80 будут отмечены тэгом INT_NET_HTTP, а все остальные — тэгом INT_NET.
В дополнение к применению тэгов в правилах фильтрации, nat, rdr и binat есть возможность выполнять проверку уже установленных тэгов.
Проверка тэгов
Для проверки уже установленных тэгов используется ключевое слово tagged:
Пакеты, уходящие на $ext_if должны быть помечены тэгом INT_NET, чтобы соответствовать правилу, приведенному выше. Существует возможность инверсного использования правила с помощью !:
Политика фильтрации
Фильтрация пакетов на основе политик несколько отличается от фильтрации на основе правил. В политиках устанавливаются правила, по которым определенный вид трафика должен быть пропущен, а определенный — запрещен. Пакеты классифицируются внутри политик на основе традиционных критериев — IP адрес источника/назначения, протокола и т.д.
Для примера, рассмотрим следующую политику:
* Трафик из внутренней сети в DMZ пропускается (LAN_DMZ)
* Трафик из Интернет к серверу в DMZ пропускается (INET_DMZ)
* Трафик из Интернет, переадресованный на spamd(8) пропускается (SPAMD)
* Весь прочий трафик — блокируется
Обратите внимание, что политика охватывает весь трафик, который будет проходить через систему сетевой защиты. В круглых скобках указан назначаемый для данного пункта политики тэг.
Теперь необходимо написать правила фильтрации и трансляции, реализующие данную политику:
Теперь правила, определяющие политику установлены.
Теперь, когда правила политики определены, необходимо определить и модифицировать классифицирующие правила. Для примера, если в 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