Ipfw и управление трафиком в FreeBSD::Журнал СА 6.2003
www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Наука и технологии
Подписка
Где купить
Авторам
Рекламодателям
Архив номеров
Контакты
   

  Опросы
  Статьи

Электронный документооборот  

5 способов повысить безопасность электронной подписи

Область применения технологий электронной подписи с каждым годом расширяется. Все больше задач

 Читать далее...

Рынок труда  

Системные администраторы по-прежнему востребованы и незаменимы

Системные администраторы, практически, есть везде. Порой их не видно и не слышно,

 Читать далее...

Учебные центры  

Карьерные мечты нужно воплощать! А мы поможем

Школа Bell Integrator открывает свои двери для всех, кто хочет освоить перспективную

 Читать далее...

Гость номера  

Дмитрий Галов: «Нельзя сказать, что люди становятся доверчивее, скорее эволюционирует ландшафт киберугроз»

Использование мобильных устройств растет. А вместе с ними быстро растет количество мобильных

 Читать далее...

Прошу слова  

Твердая рука в бархатной перчатке: принципы soft skills

Лауреат Нобелевской премии, специалист по рынку труда, профессор Лондонской школы экономики Кристофер

 Читать далее...

1001 и 1 книга  
19.03.2018г.
Просмотров: 9893
Комментарии: 0
Потоковая обработка данных

 Читать далее...

19.03.2018г.
Просмотров: 8108
Комментарии: 0
Релевантный поиск с использованием Elasticsearch и Solr

 Читать далее...

19.03.2018г.
Просмотров: 8208
Комментарии: 0
Конкурентное программирование на SCALA

 Читать далее...

19.03.2018г.
Просмотров: 5196
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 5874
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

Друзья сайта  

 Ipfw и управление трафиком в FreeBSD

Архив номеров / 2003 / Выпуск №6 (7) / Ipfw и управление трафиком в FreeBSD

Рубрика: Администрирование /  Продукты и решения

ИГОРЬ ЧУБИН

Ipfw и управление трафиком в FreeBSD

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

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

ОС FreeBSD предлагает хороший инструментарий для решения названных вопросов. Центральным элементом этого инструментария является подсистема ядра IPFW, предназначенная для пакетной фильтрации и других родственных задач; и одноименная утилита ipfw, которая нужна для настройки этой подсистемы.

Здесь рассматривается, как пользоваться утилитой ipfw для настройки фильтрации/учета/регулировки трафика; конфигурировать демон natd для выполнения трансляции адресов, а также указывается, с какими опциями должно быть собрано ядро системы, для того чтобы все это работало. В завершение рассказывается, как IPFW и natd автоматически настраивать при загрузке системы.

Фильтрация пакетов

Что это такое, и для чего нужна фильтрация пакетов

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

Брандмауэр представляет собой программно-аппаратный комплекс, выполняющий разграничение сетей и ограничивающий доступ из одной сети в другую. Термин брандмауэр (firewall) берет свое начало в строительной отрасли, где он означает сооружение, препятствующее распространению огня при пожаре из одной части здания в другую. Аналогичным образом в компьютерных сетях брандмауэр ограничивает распространение вредного сетевого воздействия.

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

Брандмауэры обычно строятся на базе двух элементов, которые занимаются фильтрацией и контролем трафика, но делают это по-разному:

  • Фильтры пакетов выполняют анализ содержимого проходящих через него сетевых пакетов и пропускают только некоторые из них. Таким образом, нежелательные соединения отсекаются. Такой брандмауэр работает на сетевом и транспортном уровнях и абсолютно прозрачен (незаметен) для протоколов более высокого уровня. Проблема фильтрации пакетов обычно ложится на плечи ядра системы: в Linux этим занимается NetFilter, в OpenBSD – PF, а в FreeBSD – IPFW или IPF. Кстати, очень мощный функциональный фильтр пакетов PF из OpenBSD в скором времени может быть полностью портирован и в FreeBSD.
  • Брандмауэр уровня приложений также известен как прокси-сервер (сервер-посредник). Запросы на ресурсы по ту сторону сети направляются ему, а он уже самостоятельно получает доступ к этому ресурсу и передает полученную информацию запросившему ее клиенту. Брандмауэр работает на уровне приложений. Это значит, что не существует прозрачных соединений более низкого уровня, проходящих через него. Ярким примером такого рода брандмауэра может служить кэширующий прокси-сервер, который обрабатывает клиентские HTTP-запросы. Клиенты не могут соединиться напрямую с веб-сервером и отправляют запрос прокси-серверу, который, в свою очередь, обращается уже к веб-серверу.

Здесь рассматривается только первый из этих элементов – пакетный фильтр, а точнее, его реализация IPFW в FreeBSD.

Утилита ipfw

Утилита ipfw используется в FreeBSD для управления пакетным фильтром IPFW и регулировщиком трафика dummynet, встроенными в ядро.

Каждый пакет, обрабатываемый ядром, проходит через цепочку правил (ruleset). Цепочка представляет собой набор правил, на соответствие каждому из которых последовательно проверяются пакеты. Если соответствие найдено, выполняется заданное действие, иначе проверяется следующее правило. И так до тех пор, пока не будет найдено соответствие или не проверятся все правила цепочки. В последнем случае срабатывает правило по умолчанию, которое определяет, как нужно поступить с теми пакетами, о которых никто не побеспокоился.

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

# ipfw list 

00100 deny ip from 10.0.0.2 to any

65535 allow ip from any to any

Первое правило отклоняет (deny) все пакеты, которые приходят от хоста с адресом 10.0.0.2. Второе правило, которое является правилом по умолчанию, разрешает проходить всем остальным.

Цепочку правил можно модифицировать с помощью ipfw. Для этого утилите нужно указать, какое действие она должна выполнить с цепочкой:

# ipfw действие [ число ] [ правило ]

Здесь действие определяет действие, которое нужно выполнить; правило – правило, которое будет добавлено в цепочку (при условии, что его нужно добавлять). Необязательное поле число указывает, с каким именно правилом в цепочке выполняется действие. Например, команда:

# ipfw add deny ip from 10.0.0.3 to any

добавит правило deny ip from 10.0.0.3 to any в цепочку фильтрации. Номер правила будет выбран автоматически: он будет равен максимальному номеру правила (не считая правила по умолчанию) плюс шаг.

Команда:

# ipfw add 100 deny ip from 10.0.0.3 to any

будет работать точно также, но если правило с номером 100 уже существует, оно будет перезаписано.

Таблица 1. Действия с цепочками правил

Название

Смысл

add

Добавить правило

delete

Удалить правило

flush

Очистить цепочку

show или list

Показать содержимое цепочки правил

zero или resetlog

Обнулить счетчики правил

Правила ipfw

Общая структура правила такова:

[ число ] [ set число ] [ prob вероятность ] действие [ log ] тело

Обычно большинство полей в правиле не указывают, и оно имеет более простую структуру:

[ число ] действие тело

Каждое правило содержит условие (тело), при котором оно будет срабатывать, и действие (действие), которое говорит о том, как именно правило будет себя вести.

Например, правило:

allow from any to any

содержит действие allow, которое применяется ко всем пакетам (при условии, что пакет дошел до правила). Выбор пакетов определяется телом правила: from any to any.

Таблица 2. Элементы правила ipfw

Элемент

Назначение

номер

Номер правила. Если не указан, вычисляется автоматически.

set число

Номер набора. Наборы помогают управлять группами правил. Например, можно удалить множество правил одной командой, если они приналежат одному набору. Есть смысл объединять правила в наборы, если эти правила семантически как-то связаны между собой.

prob вероятность

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

log [ logamount число ]

При совпадении с правилом занести информацию о пакете

в журнал (при net.inet.ip.fw.verbose = 1). Количество записей касающихся этого правила, занесенных в журнал, не должно превышать величину logamount (или net.inet.ip.fw.verbose_limit, если logamount не указано).

Простейшими действиями ipfw являются allow и deny. Действие allow разрешает прохождение пакета, и он больше не проверяется на соответствие ни одному условию, а deny, наоборот, приводит к тому, что пакет отбрасывается. При этом отправитель не получает никакой информации о судьбе пакета – пакет считается просто потерявшимся. Если нужно, чтобы отправитель знал о том, что пакет был уничтожен, следует использовать действие unreach host.

Другие действия ipfw, такие как divert, fwd, pipe, queue, используются для организации трансляции адресов и регулирования полосы пропускания.

Таблица 3. Действия в правилах ipfw

Обозначение

Действие

allow | accept | pass | permit

Разрешить прохождение пакета, которое соответствует правилу. Прекратить поиск.

count

Посчитать пакет, который соответствует правилу, и продолжить проверку.

deny | drop

Уничтожить пакет, не извещая отправителя.

divert порт

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

unreach код

Уничтожить пакет и направить его отправителю ICMP-извещение с указанным кодом. В качестве кода может использоваться либо число от 0 до 255, либо соответствующее ему слово. Например, host означает ICMP-сообщение «Хост недоступен» (Host unreachable), а port – сообщение «Порт недоступен».

Пример фильтрации пакетов

Попробуем теперь применить наши знания на практике и немного поэкспериментировать с нашим фильтром. Для этих экспериментов необходимо, чтобы ядро было собрано с поддержкой IPFW. Как правило, ядро включает поддержку IPFW, но если нет, результатом выполнения любой команды ipfw будет сообщение об ошибке. В этом случае ядро нужно пересобрать (см. далее раздел «Настройка ядра для поддержки ipfw») или просто загрузить модуль:

# kldload ipfw

Настройка фильтра начинается с его очистки:

# ipfw -q flush

Все правила фильтрации удалены, фильтр пуст. Теперь действует только правило по умолчанию, и что произойдет с трафиком, определяет только оно: трафик будет беспрепятственно проходить, если правило по умолчанию accept (ядро собрано с опцией IPFIREWALL_DEFAULT_TO_ACCEPT), и уничтожаться в противном случае.

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

# ipfw -q flush && ipfw add 65000 allow ip from any to any

Теперь компьютер открыт всему миру, и в данном случае открытость – не самое лучшее его качество.

Нужно закрыть все лишнее. Пусть:

  • Трафик с адресами 127.0.0.0/8 разрешен только через интерфейс обратной петли;
  • Запрещается весь трафик, приходящий через внешний интерфейс (назовем его ${external}), если у него адрес отправителя или получателя относится к диапазону зарезервированных для внутреннего использования адресов;
  • Разрешаются только входящие TCP-соединения на 22, 25 и 80 порты, то есть мы принимаем соединения из Интернета, адресованные только нашему SSH, почтовому и веб-серверам;
  • Разрешены любые исходящие TCP-соединения, то есть мы можем соединяться с любым компьютером в Интернете, когда сами этого захотим;
  • Разрешается UDP-трафик на 53 и с 53 порта, то есть трафик, необходимый для работы DNS;
  • Разрешается прохождение исходящих эхо-запросов и входящих эхо-ответов, то есть мы можем пинговать внешние компьютеры, а они нас нет;
  • Весь остальной трафик должен быть заблокирован.

Запрет локального трафика не через локальный интерфейс выполняется правилами, которые уже стали традиционными при настройке фильтра пакетов:

# ipfw add 100 allow ip from any to any via lo0

# ipfw add 200 deny ip from any to 127.0.0.0/8

# ipfw add 300 deny ip from 127.0.0.0/8 to any

Первое правило разрешает любой трафик через интерфейс петли обратной связи lo0. Следующие два запрещают весь трафик, который приходит с зарезервированных адресов из сети 127.0.0.0/8. Правила 200 и 300 сработают только в том случае, если пакет прошел не через интерфейс lo0.

Трафик с адресами внутренних сетей (RFC 1918) не должен приходить через внешний интерфейс.

# ipfw add deny from any to 10.0.0.0/8 via ${external}

# ipfw add deny from any to 172.16.0.0/12 via ${external}

# ipfw add deny from any to 192.168.0.0/16 via ${external}

Такой же трафик не должен и уходить, хотя, в сущности, для нас это менее важно:

# ipfw add deny from 10.0.0.0/8 to any via ${external}

# ipfw add deny from 172.16.0.0/12 to any via ${external}

# ipfw add deny from 192.168.0.0/16 to any via ${external}

Ключевая часть фильтрации: мы хотим, чтобы из внешней сети были доступны только те сервисы, которые нужно, и не более того. Нужно, чтобы наш компьютер можно было удаленно администрировать с помщью SSH (22); он должен принимать почту по протоколу SMTP (25) и поддерживать веб-сервер (80):

# ipfw add 2000 allow tcp from any to ${external} 22,25,80 setup

# ipfw add 2100 allow tcp from any to any established

Первое правило разрешает устанавливать соединения из любой точки сети на внешний интерфейс нашего хоста ${external} по портам 22, 25 и 80. Ключевое слово setup в конце строки говорит о том, что правило относится только к пакетам, инициирующим соединение (то есть тем, которые имеют установленный флаг SYN и сброшенные ACK и RST). Второе правило относится к другим пакетам: тем, которые передаются в рамках уже установленного соединения. Такие пакеты разрешаются все. Логика правила очень простая: «Если соединение уже каким-то образом удалось установить, то значит все нормально, данные могут проходить. Если же соединение не установлено, а пакет просто делает вид, что относится к какому-то соединенеию, ну что ж, это его проблемы, он все равно никому не нужен.» Правило рассуждает так, но здесь оно немного ошибается. В определенных случаях подобный пакет, если его умело составить, может нанести вред компьютерам за брандмауэром. Для того чтобы справиться с такими пакетами, нужно использовать фильтр с поддержкой состояний (stateful), но об этом в другой раз.

Если соединение хотим установить мы, то препятствий быть не должно:

# ipfw add 3000 allow tcp from ${external} to any setup

Обратите внимание на то, что мы разрешаем соединение только с одного IP-адреса. Если же нас интересует несколько IP-адресов, то мы должны указать их либо в виде адреса сети, либо создать несколько правил – по одному для каждого из адресов.

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

# ipfw add 4000 allow udp from ${external} to any 53

# ipfw add 4100 allow udp from any 53 to ${external}

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

Последнее, что мы хотим разрешить, – это ICMP. Но мы почему-то хотим, чтобы наш компьютер нельзя было пропинговать извне, однако при этом, как свойственно человеческой природе, сами пинговать других собираемся:

# ipfw add 5000 deny icmp from any to ${external} in icmptypes 8

# ipfw add 5100 allow icmp from ${external} to any out icmtypes 8

# ipfw add 5200 allow icmp from any to ${external} in icmptypes 0

Правило 5000 запрещает входящие (in), а правило 5100 разрешает исходящие (out) ICMP эхо-запросы (ECHO REQUEST, 8). Правило 5200 разрешает эхо-ответы (ECHO REPLY, 0), приходящие на наш хост.

Последним правилом, которое подводит черту под настройкой фильтрации пакетов, является запрет всего, что не разрешено:

# ipfw add 64000 deny ip from any to any

Правило должно встать перед правилом 65000, которым мы ранее разрешили весь трафик.

Трансляция адресов

Что это такое, и зачем нужна трансляция адресов

IP-адреса (и другие параметры заголовков) пакетов, проходящих через хост, можно изменять. Измененение IP-адреса отправителя дает возможность скрывать несколько адресов хостов одним, а IP-адреса получателя, например, распределять нагрузку между несколькими хостами. Изменение порта отправителя в некоторых случаях позволяет обходить ненужные брандмауэры, а порта получателя, к примеру, организовать прозрачную работу прокси-сервера.

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

Из-за ограниченности адресного пространства IP, каждый хост, который пользуется услугами Интернета, не может получить собственного IP-адреса. В этом случае используются адреса из диапазонов 10.x.x.x, 192.168.x.x., 172.16.x.x.-172.31.x.x. Эти адреса зарезервированы для внутреннего использования и не могут встретиться в Интернете. Компьютеры, имеющие такие адреса, могут общаться друг с другом в пределах одной сети, но не могут выходить за ее пределы: пакеты, имеющие такие адреса, будут попросту уничтожаться.

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

Трансляция адресов в FreeBSD

В FreeBSD трансляцию адресов пакетов можно выполнить двумя способами:

  • natd – демон natd является процессом, то есть он работает не в пространстве ядра, а в пространстве пользователя. Поэтому для обработки демоном трафик должен копироваться из ядра в пространство пользователя и обратно. Это несколько уменьшает производительность.
  • ipnat – трансляция адресов выполняется ядром системы.

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

Настройка natd

Демон natd является процессом, работающим в пространстве пользователя (то есть не в пространстве ядра). Следовательно, пакеты, которые он обрабатывает, должны как-то к нему попасть. Действие divert пакетного фильтра может справиться с такой задачей.

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

Например, для того чтобы все пакеты, которые отправлены из сети 192.168.15.0 и проходят через интерфейс ${natd_interface}, передавались демону natd, нужно модифицировать правила таким образом:

# ipfw add divert 8868 tcp from 192.168.15.0/24 to any via ${natd_interface}

Здесь ${natd_interface} – интерфейс, через который пакеты уходят из сети во внешний мир, а 8868 – номер сокета, на котором ведет прослушивание natd. Вместо 8868 можно написать символическое имя порта: natd.

Для того чтобы трансляция адресов работала, необходимо, чтобы natd получал и все пакеты, которые возвращаются обратно. Можно пойти еще дальше и передавать демону natd вообще все пакеты, которые проходят через ${natd_interface}:

# ipfw add divert 8868 tcp from any to any via ${natd_interface}

Собственно, настройка ipfw дает только то, что пакеты будут переданы демону natd. Основная работа выполняется самим демоном, так что нужно сконфигурировать и его.

Конфигурация natd задается либо аргументами его командной строки, либо конфигурационным файлом /etc/natd.conf (имя конфигурационного файла должно быть указано при вызове natd с ключом -f). Параметры конфигурационного файла и аргументы командной строки natd в точности повторяют друг друга, с той разницей, что когда параметр указывается в командной строке, перед ним нужно поставить минус. Например, сказать:

# natd -interface xl0

значит то же самое, что и просто:

# natd -f /etc/natd.conf

когда в конфигурационном файле /etc/natd.conf находится:

interface xl0

Таблица 4. Опции natd

 -redirect_port протокол targetIP:

targetPORT[-targetPORT] [aliasIP:]aliasPORT

[-aliasPORT] [remoteIP[:remotePORT

[-remotePORT]]]

Перенавправить входящее соединение. Теперь natd отвечает за правильную передачу входящих и исходящих пакетов в рамках этого соединения.

  • протокол – протокол, пакеты которого должны перенаправляться. Допустимые значения: tcp и udp
  • targetIP и targetPORT – куда должно перенаправляться соединение;
  • aliasIP и aliasPORT – откуда должно перенаправляться соединение;
  • remoteIP и remotePORT – чье соединение будет перенаправляться.

-redirect_address localIP[,localIP,...] publicIP

Перенаправить входящие соединения, направленные на адрес publicIP на внутренний адрес localIP. Если указано несколько адресов localIP нагрузка распределяется между ними, то есть различные соединения перенаправляются на различные localIP по очереди.

-config файл или -f файл

Использовать указаный файл в качестве конфигурационного.

-dynamic

Используется в сочетании с –n или -interface. Периодически проверять адрес интерфейса и смотреть, не изменился ли он. Если адрес изменился, то нужно учесть это изменение при маскарадинге.

-a адрес или -alias_address адрес

При маскарадинге указывать заданный адрес в качестве адреса отправителя.

-interface интерфейс или -n интерфейс

Считать этот интерфейс внешним при маскарадинге. При изменение IP-адреса следует использовать вместе с опцией -dynamic.

-proxy_rule port порт server адрес:порт

Перехватывать все исходящие соединения, по указаному порту и направлять их на заданый сервер (адрес:порт). Опция используется для обеспечения работа прозрачного прокси.

-proxy-only

Не делать ничего, кроме обеспечения прозрачного прокси.

Пример настройки трансляции адресов

Итак, пусть наша сеть подключается через шлюз к Интернету. Шлюз имеет два интерфейса: ${internal} – внутренний и ${external} – внешний. Компьютеры внутри сети имеют адреса из диапазона, рекомендованного для использования внутри сетей. Необходимо:

  • обеспечить маскирование компьютеров с внутренними адресами внешним адресом интерфейса;
  • дать возможность работать прозрачному прокси-серверу ${proxy};
  • перенаправлять входящие из Интернета соединения по 25 порту на хост ${mailhub} внутри сети.

Все перечисленные задачи решаются с помощью natd. Первым делом необходимо изменить правила фильтрации пакетов так, чтобы трафик, проходящий через внешний интерфейс, обрабатывался демоном:

# ipfw add 6000 divert natd ip from any to any via ${external}

Теперь, когда natd получает весь внешний трафик, он должен правильно обработать его. Задача конфигурирования natd сводится к выбору набора директив, которые должны быть указаны в конфигурационном файле /etc/natd.conf или в качестве аргументов при запуске natd.

Конфигурация выглядит так (вместо переменной ${external} нужно указать имя интерфейса, например xl0 или en1, а вместо ${proxy} и ${mailhub} нужно подставить соответствующие IP-адреса):

interface ${external}                  

proxy_rule port 80 server ${proxy}:3128

redirect_port tcp ${mailhub}:25 25

Первый параметр указывает, что маскировка внутренних компьютеров должна проводиться адресом внешнего интерфейса ${external}.

Второй параметр заставлет natd перенаправлять все соединения по 80 порту на порт 3128 прокси-сервера ${proxy}. Для того чтобы прозрачное проксирование работало, сервер должен быть настроен соответствующим образом.

Последнее правило обеспечивает перенаправление входящих SMTP-соединений на хост ${mailhub} внутри сети. Теперь почтовый сервер и брандмауэр разнесены на разные машины. Стоит отметить, что поскольку 25-й порт хоста ${mailhub} выставлен в Интернет, хост следует размещать внутри DMZ, а на безопасности программы почтового сервера этого хоста сосредоточить усиленное внимание.

Регулировка величины трафика

Что такое регулировка трафика, и зачем она нужна

В простейшем случае задача регулировки трафика формулируется так: через наш шлюз проходит информационный поток A величной V(A). Мы хотим ограничить этот поток каким-нибудь значением Vmax. То есть, грубо говоря, сделать так, чтобы все, что выходит за пределы зачения Vmax, попросту уничтожалось.

Каждому потоку назначается специальный буфер, работающий по принципу очереди. Буфер наполняется с той скоростью, с какой в него поступают данные (Vin), а опустошается со скоростью, не превышающей заданную (Vout). В том случае, если Vin находится в допустимых пределах, поток проходит через буфер в полном объеме. Если же буфер наполняется быстрее, чем опустошается, может наступить такой момент, когда он будет полностью заполнен и вновь поступающие данные будут попросту уничтожаться.

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

Средства, которые управляют трафиком подобным образом, называют трафик-шейперами (traffic-shaper), формирователями или регулировщиками трафика.

Трафик-шейпер в FreeBSD

В состав ядра FreeBSD входит модуль dummynet, который позволяет эмулировать канал связи, обладающий

  • ограниченной полосой пропускания;
  • задержкой распространения;
  • вероятностью потери пакета;
  • очередью пакетов заданного размера.

Этот модуль можно использовать в качестве трафик-шейпера.

Настройка трафик-шейпера

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

  • создать канал;
  • указать, какой именно трафик должен быть в канал направлен;
  • настроить канал на работу с заданными параметрами.

Два первых шага совмещаются в одном и выполняются командой ipfw add pipe. Например, команда:

# ipfw add pipe 1 tcp from any to 192.168.15.1 out

создает канал 1 (pipe 1) и направляет через него весь tcp-трафик, отправленный не важно кем (from any) хосту 192.168.15.1 (to 192.168.15.1); при этом трафик должен быть исходящим (out).

Для того чтобы настроить сам канал pipe, нужно дать команду ipfw pipe. Например, команда:

# ipfw pipe 1 bw 10KB

ограничивает полосу пропускания канала pipe 1 значением 10 Кб/с. Канал мог бы иметь и другие параметры, которые в этом случае должны были быть указаны как дополнительные аргументы команды парами параметр значение.

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

В том случае, когда нужно ограничить скорость передачи информации из Интернета на хост, находящийся в локальной сети, следует изменять скорость исходящего потока. То есть скорость того потока, который уходит со шлюза на хост. Нельзя уменьшить скорость, с которой данные передаются из Интернета. Это вызывает вопрос: зачем уничтожать информацию после того, как она уже попала в нашу сеть? Ведь она уже прошла по входящему каналу и уже заняла там какое-то место? Все действительно так, но в этом случае в силу вступают механизмы регулирования потока TCP, которые не позволят в следующий раз отправлять хосту информации больше, чем он способен принять.

Таблица 5. Параметры канала dummynet

bw

Максимальная полоса пропускания канала. Может быть указана дополнительная единица измерения: MByte, KByte, Kbit, Mbit.

По умолчанию, подразумевается, что полоса пропускания указана в Кб/с.

delay

Задержка распространения в мс.

mask описание-маски

Маска для создания идентификатора. Соединения с разными идентификаторами попадают в разные каналы. Параметр описание-маски представляет собой сочетание параметров dst-ip маска, src-ip маска, dst-port маска, src-port маска, proto маска или all.

Просмотреть информацию о канале можно с помощью команды:

# ipfw pipe 1 list

00001:  80.000 Kbit/s    0 ms   50 sl. 1 queues (1 buckets) droptail

    mask: 0x00 0x00000000/0x0000 -> 0x00000000/0x0000

BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp

  0 tcp   192.168.15.199/80     192.168.15.254/52995 12365 15440683  0    0 1

Она выдает не только сведения о канале, но и о соединениях, которые проходят через этот канал.

Учет трафика

Учет трафика выполняется с помощью системы фильтрации пакетов IPFW. Собственно, подсчитывать трафик – это еще одна задача этой подсистемы.

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

# ipfw -a list

65535 4386 844198 allow ip from any to any

Ключ -a команды заставляет ее показывать не только список правил, но и счетчики каждого из них. Строка содержит три числа: номер правила (65535), количество пакетов (4386) и байт (844198), которые совпали с правилом.

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

Например, для того чтобы подсчитать весь трафик, который направляется из подсети 192.168.15.0 и который проходит через даный хост, нужно добавить правило:

# ipfw add count ip from 192.168.15.0/24 to any

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

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

Работа с ipfw

Настройка ядра для поддержки ipfw

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

Для этого необходимо поправить файл конфигурации ядра и пересобрать ядро системы. В файле /usr/src/sys/i386/conf/ВАШЕ_ЯДРО нужно добавить такие строки:

options IPFIREWALL                     

options IPFIREWALL_VERBOSE                 

options IPFIREWALL_VERBOSE_LIMIT=10    

options IPFIREWALL_DEFAULT_TO_ACCEPT

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

Для поддержки модуля dummynet нужно добавить опцию DUMMYNET в конфигурационный файл ядра:

options DUMMYNET

Дополнительные параметры, которые могут быть полезны при тонкой настройке dummynet, это NMBCLUSTERS и HZ. Первый позволяет указать объемы сетевых буферов, а второй – точность (granularity) таймера.

Если шлюз выполняет трансляцию адресов с помощью демона natd, нужно чтобы ядро могло обеспечить передачу ему пакетов с помощью так называемых divert-сокетов. Поддержка divert-советов в ядре включается с помощью опции IPDIVERT:

options IPDIVERT

Таблица 6. Опции конфигурации ядра, относящиеся к фильтру пакетов

Опция

Назначение

IPFIREWALL

Включить в ядро код, который выполняет фильтрацию пакетов

IPFIREWALL_VERBOSE

Разрешить заносить информацию о пакетах в syslog. Если эта опция не включена, опция log в правилах ipfw ничего не даст.

IPFIREWALL_VERBOSE_LIMIT=10

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

с помощью команды zero.

IPFIREWALL_DEFAULT_TO_ACCEPT

Превратить правило по умолчанию в allow. Если эта опция не указана, правило по умолчанию установлено в deny.

IPDIVERT

Поддержка divert-сокетов. Необходима для работы natd (точнее для того, чтобы natd могло работать правильно).

DUMMYNET

Встраивать в ядро модуля dummynet. Модуль используется для ограничения величины информационных потоков

HZ

Точность таймера

После того как конфигурация ядра изменена, его пересборку и инсталляцию можно выполнить командами:

# /usr/sbin/config ВАШЕ_ЯДРО

# cd ../compile/ВАШЕ_ЯДРО

# cd ../../compile/ВАШЕ_ЯДРО

# make depend

# make

# make install

Настройка ipfw и natd при загрузке

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

Напомним, что конфигурация загрузки системы определяется файлом /etc/rc.conf. В нем описываются переменные, которые сообщают загрузочным скриптам, как они должны себя вести. Для того чтобы повлиять на работу загрузочных скриптов, следует изменять значения переменных, устанавливаемых в этом файле.

При запуске машины главный загрузочный скрипт /etc/rc.conf вызывает скрипт настройки сети /etc/rc.network; он, в свою очередь, вызывает /etc/rc.firewall. Скрипт /etc/rc.firewall выполняет настройку брандмауэра.

В FreeBSD описано несколько типовых конфигураций брандмауэра. Типовая конфигурация выбирается с помощью переменной firewall_type.

  • OPEN – брандмауэр пропускает все пакеты.
  • CLIENT – брандмауэр настроен так, как должен быть настроен стандартный клиентский компьютер. Он разрешает все исходящие соединения, и запрещает все входящие соединения, кроме соединений по 25 порту.
    • пропускает пакеты, которые отправляются хостом ${ip} в локальную сеть {net}:{mask};
    • разрешает все исходящие соединения с хоста;
    • разрешает все входящие соединения на 25 порт;
    • запрещает все остальные входящие TCP-соединения;
    • разрешает прохождение UDP-пакетов по портам DNS (53) и NNTP (123);
    • все остальные пакеты рассматриваются правилом по умолчанию, которое определяется конфигурацией ядра.
  • Брандмауэр:

  • SIMPLE – простеший брандмаэур, защищающий локальную сеть от проникновения из Интернета. Правила фильтрации точно такие же, как и в CLIENT, но:
    • Есть поддержка natd. Выполняется передача IP-пакетов на divert-сокет демона natd при условии, что natd_enable=YES;
    • Выполняется защита от IP-спуфинга. Пакеты, которые имеют адреса, предназначенные для использования внутри локальных сетей 10.x.x.x, 172.16.x.x-172.31.x.x, 192.168.x.x. (RFC 1918), не пропускаются по внешнему интерфейсу. Также удаляются пакеты из внешней сети, которые имеют адрес возврата из сети внутренней.
  • Адреса внутренней {inet}:{imask} и внешней {onet}:{omask} сети, а также адреса внутреннего ${iif} и внешнего ${oif} интерфейсов указываются в файле /etc/rc.firewall. Значения ${ip}, ${net} и ${mask} следует вручную устанавливать в файле /etc/rc.firewall.

  • CLOSED – разрешается только трафик через локальный интерфейс lo0. Прохождение остального трафика определяется правилом по умолчанию. Брандмауэр в режиме CLOSED закрыт только в том случае, если правило по умолчанию установлено ядром в deny.
  • UNKNOWN – брандмауэр никак не настраивается. Будет он пропускать трафик или нет, определяется конфигурацией ядра системы. Используется по умолчанию.
  • файл – правила брандмауэра загружаются из внешнего файла. Имя файла определяется значением переменной firewall_type. Дополнительные аргументы ipfw могут быть переданы с помощью firewall_flags. Файл должен содержать команды ipfw в том виде, в каком они указываются в его командной строке. Например:

add deny icmp from any to any

add deny ip from 1.2.3.4 to any

allow tcp from any to any established

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

Если нужно, чтобы шлюз выполнял трансляцию адресов, в /etc/rc.conf следует указать natd_enable=YES. Это приведет к тому, что при загрузке автоматически будет запускаться демон natd. Нужно указать еще natd_interface, для того чтобы natd знал, какой интерфейс является внешним, и natd_flags="-f /etc/natd.conf", чтобы natd знал, откуда ему брать свою конфигурацию. Можно описать конфигурацию natd прямо в этой строке и не выносить ее во внешний файл.

natd_enable="YES"

natd_inteface="lnc0"   

natd_flags="-f /etc/natd.conf"

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

# sh /etc/rc.conf /etc/rc.firewall

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

Таблица 7. Некоторые параметры /etc/rc.conf

firewall_enable (YES|NO)

Запускать или нет скрипт настройки брандмауэра /etc/rc.firewall.

 

Скрипт, который запускается для настройки брандмауэра.

firewall_type

(OPEN| CLIENT| SIMPLE| CLOSED| UNKNOWN| файл)

Типа брандмауэра. Определяет, как будет выглядеть таблица фильтрации пакетов.

firewall_quiet (YES|NO)

Нужно ли выполнять все операции

в молчаливом режиме. При указании YES ipfw вызывается с ключом -q.

firewall_logging (YES|NO)

Разрешить журнализирование. Включает значение net.inet.ip.fw.verbose в 1.

firewall_flags

Список флагов, которые передаются ipfw при вызове

natd_program (/sbin/natd)

Программа, которая используется в качестве natd. По умолчанию: /sbin/natd

natd_enable (YES|NO)

Включить поддержку natd. Это приводит

к тому, что запускается демон natd и для брандмауэра типа SIMPLE и OPEN автоматически настраивается divert на natd для всех пакетов, проходящих через внешний интерфейс (natd_interface).

natd_interface

Интерфейс, адресом которого маскируются исходящие пакеты. Все пакеты, проходящие через этот интерфейс автоматически передаются natd если брандмауэр настроен как SIMPLE или OPEN.

natd_flags

Дополнительные флаги, которые передаются natd. Есть смысл задавать здесь -f /etc/natd.conf и описывать конфигурацию демона в файле /etc/natd.conf.

Дополнительная информация

  1. ipfw (8) – руководство пользователя программы ipfw.
  2. natd (8) – руководство пользователя программы natd.
  3. dummynet (4) – описание модуля dummynet.
  4. http://info.iet.unipi.it/~luigi/ip_dummynet – домашняя страница проекта dummynet.
  5. http://www.freebsd-howto.com/HOWTO/Ipfw-HOWTO – IPFW HOWTO: исчерпывающее руководство по использованию IPFW в FreeBSD.
  6. http://www.freebsd-howto.com/HOWTO/Ipfw-HOWTO – NAT HOWTO: руководство по трансляции адресов с помощью natd в FreeBSD.
  7. http://www.deadly.org/article.php3?sid=20030325141427 – PF for FreeBSD 5.0.

Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-41
Fax: (499) 277-12-45
E-mail: sa@samag.ru