UNИX, весна 2009, 08 лекция (от 15 апреля)

Материал из eSyr's wiki.

Версия от 08:11, 20 апреля 2009; 158.250.19.110 (Обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Содержание

Конспект Kda

Продолжаем разговор про межсетевые экраны. Все идет к тому, что разговор про pf будет разговором про pf из OpenBSD.

stateful firewall

Ситуация с stateful файрвол. Идея в следующем. Межсетевой экран с состояниями выглядит следующим образом: есть кусок, связанный с фильтрацией трафика и этот кусок хотелось бы обойти следующим путем. Раз уж мы допустили само подключение сервера к клиенту, то все остальные пакеты под разрешающее правило обычно попадают. Можно устроить файрвол таким образом, что все те ситуации, когда пакет считается принадлежащим уже рассмотренному TCP-трафику. Когда применяем правило с запоминанием состояний, образуется временное специфическое правило, сохраняется в специальной таблице. Соответствие состояний.

Пример

Мы пропускаем пакет.

pass out tcp from any to $www port 80 flags S/SA keep-state

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

Интересное новшество в pf

Есть в ICMP, в UDP, про TCP речь идет почему: в BSD 4.1 было переписывание pf в интересную лектору сторону. Теперь в pf все правила по умолчанию keep-state. Каждое правило pass, имеющее отношение к трафику прописываются. Первый недостаток: сжирать больше памяти. Каждое соединение откладывается. С другой стороны, память сейчас большая. Другой недостаток: мы возможно захотим странного. Захотим пропускать трафик через машину, а потом взять и не пропускать. В частности, была речь о фильтре. Придется подключаться к pf.

Важен первый недостаток. Людей, которые занимаются набиванием памяти межсетевых экранов, хватает. В pf есть целая глава.

Бонус новшества

Главный бонус в том, что это быстрее. Воспроизводится идея разработчиков pf — файрвол всегда работает примерно в одном штатном режиме. Стратегия last wins вроде бы должна давать проигрыш, а first wins при правильной организации ускорять. Но при first wins можно написать что-то, работающее если не вечно, то долго, а тут заданное время. Функционирование будет примерно одинаковым. Если идет соединение по TCP, то по умолчанию, когда вы пишете правило типа pass, у него указываются флаги. По умолчанию сразу речь идет о таблице состояний. Количество писанины уменьшается раза в полтора. Базовую задачу решаем ничуть не мене легко, чем в первом случае. Писанины меньше, оба правила делают одно и то же. Ленивый администратор будет применять первый метод. Лектор попался на это в линуксе.

Подход

pf не был разработан как межсетевой экран с подходом от инструмента. Подход от задачи. Как сделать инструмент, который решит задачи. Подход от задачи делается все более и более глубоким. Мы упрощаем вид правила, чтобы оно стало более читаемым. Умолчания увеличивают эффективность и «правильность». Усложняем поведение межсетевого экрана по структуре. Одно правило приводит к двум вещам.

Типичный более простой пример — списки и возможность разворачивания. Правило одно, а в списке произведение всех списков правила.

Modulate state

Интересно, что помимо keep-state есть еще довольно забавное modulate state. Sequential number в последовательности подменяется на действительно случайный.

Типы состояний

Состояния в pf могут быть трех видов — привязанные к интерфейсу, к группе и плавающие. Можно подкрутить гайки, сказать, что правило привязано к интерфейсу. Получив пакет с другого интерфейса, на временном правиле получим отрицательный результат.

Флуд

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

(max 200)

Больше двухсот соединений по правилу не делается. Речь не о количестве срабатываний, а о количестве откладываемых состояний.

Как иначе мы определим, что произошло то же самое? Количество соединений в секунду.

overload <badguys>
drop all from <badguys>

Как только с какого-то ip превышено ограничение, он попадает в таблицу и мы можем что-то сделать. Overload — таблица провинившихся ip.

Возможности

Мы можем другие таблички делать. Письма посылать. Еще одна забавная штука. Один из способов пересобирать трафик — synproxy. Последовательность всех слов может быть достаточно произвольной. Лишь бы нормально читалось. Еще одно подтверждение BSD — простота для пользователя увеличивается, сложность подложки увеличивается.

Synproxy

Принимается соединение, отсылается ack. Вся процедура подключения проделывается файрволом. И только после того, как процедура подключения прошла, он на другой стороне, куда идет проксирование, проигрывает процедуру после чего начинает гонять трафик. В чем смысл такой процедуры? Если происходит Synflood, чтобы не произошло, машина с другой стороны не увидит. Мы разбираемся на файрволе, что делать с человеком. А сервер ничего и не видит.

Antispoof

Есть волшебное слово

antispoof [log] for dl0

Блокировка передачи всех пакетов на ip-адрес, связанный с пакетом на другие интерфейсы. Приходит пакет с валидным адресом, но оттуда, откуда не должен приходить. Это бывает довольно часто для обхода файрволов. Блокировка пропускания пакетов через все интерфейсы не равные данному. Запрещает принимать пакеты через любой интерфейс, если отправитель задан.

block in on!fxp0 inet from 10.0.0.0/24 to any
block in inet from 10.0.0.0 to any

Эта штука блокирует попытку переслать пакет с адреса 10.0.0.1 на loopback, что бывает иногда нужно.

Skip

Фича, про которую стоит рассказать.

set skip on lo0

Интерфейс не участвует в файрволе. При желании можем исключить и живой интерфейс.

Добавление

antispoof — для упрощения конфига, делает то же, что и два block. Когда речь идет не о том, чтобы с подозрением относиться к пакету, пришедшего с другого адреса.

В pf можно по виду пакетов выяснять, какая система находится у отправителя.

Forwarding

Когда мы пропускаем пакеты, NAT или не NAT, forwarding надо включить (в sysctl). Это может работать маршрутизатором без файрвола.

Nat, dnat

nat on tl0 from 192.168.1.0/24 to any -> 24.5.0.5

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

fxp0:network

Адреса вытащатся сами. Можно сделать

(tl0)

что работает существенно медленнее. Без скобок формируется один раз, а со скобками смотрится каждый раз. Замена статического адреса функцией, вычисляющей его. Вместо слова nat пишем слово bind.

Вкусность

Предположим, есть машины, которым запрещен доступ в интернет, возможно временно. Как их обслуживать? Можно поставить фильтрующее правило. Куда ставить, если сначала nat, потом filter?

no nat tl0 from $dummy to any
pfctl -s state
rdr on tl0 proto tcp 5000:5500
from any to any port 80 -> $www port 8080

Документация

В документации есть много про проброс портов, nat и прочее.

Проброс порта на внутренний сервер

Мы хотим пробрасывать порт на веб-сервер, который находится внутри ЛВС. Внешние лезут на файрвол. Внутренние лезут по тому же имени. Первый вариант: используйте то же. Второе вариант: прокси, netcat. Он работает быстрее и памяти ест меньше. OpenBSD'шники поразили лектора: очень любят userspace программы. Например, ftp proxy. А http прокси еще проще: netcat. Зачем извращения с файрволом?

127.0.0.1:5000 stream tcp new id nobody /usr/bin/nc nc -w 2 102.168.1.10 79
rdr on $int_ip proto tcp from $int_net to $ext_if port 80 -> 127.0.0.1 port 5000

Дополнительно

Идея насчет создателей pf, думавших о приближенности к пользователю. Подтверждается наличием раздела в документации. Макросы, списки, pf-штуки, приводящие к размножению правил, можно написать

block all

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

block return

Опции

Непонятно, что говорить про опции. Одну группу составляют счетчики и ограничения. Сколько времени длится tcp-timeout и т.д. Другая группа — где живет conf, где файлик с fingerprint'ами и т.д. Отдельная группа — сколько в системе таблиц, якорей и т.д. Такая штука, как log-интерфейс, на него будет складываться вообще все. Не используется аппаратный интерфейс и т.д. Всевозможные настройки оптимизации поведения файрвола. Какие виды: просто оптимизация, для high-latency сетей (например, спутник). Есть conservative — настраивает так, чтобы сеть работала во что бы то ни стало, но памяти будет есть много. Можно написать свой профайл оптимизации.

Пересборка трафика

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

scrab in all

Что такое scrab? Это пересборка проходящего трафика. Пакеты фрагментированные собираются в целые. Random id. В ip пакете есть id, который должен быть случайным, некоторые ОС делают не совсем случайным. Делает случайным. TTL. Можно изменить TTL.

С фрагментацией можно делать много разного.

reassemble, crow

Что касается пересборки? В pf есть пересборка tcp-фреймов. Много ОС, у которых по-разному написан стек. Может быть несовместимость с Windows, например. Пакет пересобирается, хотя ничего существенного не меняется.

Якорь

Последнее — якорь. Про это уже было в прошлый раз. Набор правил, в которым может быть nat, dnat, redirect. На набор можно ссылаться из основного кода. Идея якорей в том, чтобы обеспечить хранилища файрвольных правил, которые мы часто модифицируем из userspace. Останавливаем, перехакиваем, запускаем. Это нехорошо. При использовании якорей работа не останавливается, пока якорь не задействован и пакет не матчится. Ссылок на якорь может быть много. Что-то вроде пользовательской цепочки. Он — отдельная структура данных.

block on$ext_if all
pass out on $ext_if all
Личные инструменты
Разделы