IPFW в FreeBSD 8. Обзор, настройка, примеры

В Этой статье я коснусь важной темы в FreeBSD – настройке ipfw.
ipfw – это штатный файервол (firewall, брандмауэр) для систем FreeBSD.

Статья построена следующим образом -

1.сначала мы рассмотрим IPFW – синтаксис команд ipfw, возможности.

2.примеры ipfw для разных задач с описанием.

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

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

Итак ipfw. Это один из лучших (если не самый) firewall с которым мне приходилось работать, описать все его возможности просто нереально, он полностью отвечает идеологии UNIX и просто поражает своей гибкостью. Для его использования необходимы знания работы протоколов TCP/IP и модели OSI. IPFW состоит из семи компонентов - цепочки правил, регистратор событий, divert правила, dummynet управление трафиком, модуль моста (bridge), правила fwd (forward), модуль ipstealth.Стандартный набор правил расположен по адресу /etc/rc.firewall, конечно он не планировался для использования без изменений, в нем к примеру нету весьма полезных правил динамической фильтрации. Хотя самый простой способ использования ipfw это конечно использование стандартных правил. Рассмотрим что нужно для их запуска.
firewall_enable="YES"
firewall_type="!значение!"


!значение! может быть следующим open – просто пропускает весь трафик.

client -стандартный правила для защиты текущего компьютера.

simple – стандартные правила для защиты всей сети.

closed- закрывает весь трафик кроме петлевого (loopback )

UNKNOWN- не загружает вообще никаких правил.

путь к файлу из которого загрузить правила.

Последний способ нам вполне подходит, хотя можно просто поместить скрипт * в автозагрузку и в процессе запуска FreeBSD считает правила для ipfw из него . (*! важно ! в FreeBSD 8 нельзя чтобы этот файл имел расширение .sh – такие файлы не будут запущенны в процессе автозагрузки.) В случае запуска ipfw правил скриптом из автозагрузки можно установить
firewall_type="UNKNOWN"

Пример файла ipfw.rule помещенный /etc/rc.d/ который запрещает прохождения любого трафика
#!/bin/sh
ipfw -q flush
ipfw add deny in
ipfw add deny out
Переходим к командам и правилам ipfw.
# ipfw list
Выведет всю цепочку правил на текущий момент. Эту команду можно использовать с ключами. ipfw -a list покажет те же данные но со счетчиками, эта команда идентична ipfw show. ipfw -d list - покажет также правила которые были назначены динамически.
#ipfw zero
Обнуляет считчики входящего и исходящего трафика. ipfw zero ‘номер правила’ – тоже самое но только для конкретного правила. Цепочки правил – это правила ipfw по разрешению/запрету пакетов на основе их содержания. Когда пакет попадает в ipfw он проходит по цепочке сверху вниз от первого правила до подходящего для него. В случае достижения правила которое касается пакета, пакет уходит из цепочки правил. Если по ходу цепочки пакет не нашел соответствия он попадает под последнее правило 65535 в зависимости от настроек firewall в ядре – этот пакет или пропускается или отбрасывается. Есть также специальные указания после которых проход по цепочке продолжается не смотря на соответствие это – count ( подсчитать пакет), skipto (переводит пакет на указанное правило нарушая привычный ход пакетов.) и tee (делает копию пакета и отправляет по указанию).
Синтаксис правил выглядит следующим образом
имя команды (ipfw) цель (add) номер правила (100) действие ( allow) логирование (log) инструкция (all from any to any via lo0) инструкции состояния(in)
Разберем каждую из них -
Имя команды – ipfw – программа запускаемая из оболочки, интерфейс взаимодействия с IPFW.
Цель – add или del (добавить/удалить правило)
Номер правила – каждое правило должно обладать номером от этого зависит место нахождение в таблицы. (не рекомендуется добавлять правило без номера – хотя это и возможно в таком случае оно помещается вверх таблицы.)
Действие – правило ассоциируется с одним из действий если пакет соответствен правилу – allow, accept, pass, permit – пропускает пакет. check-state пакет проверяется по динамической таблице ipfw. deny – отбрасывает пакет и уведомляет отправителя что пакет отброшен. drop - просто отбрасывает пакет, без сообщения.
Логирование - log включает логирование событий по этому правилу, данные отправляются в syslog (по умолчанию настроек syslog данные попадают в /var/log/security). logamount – определяет количество информации которая будет передана, если logamount не указан то данные берутся из переменной ядра
net.inet.ip.fw.verbose_limit.
Инструкция – в инструкциях указывается имя протокола с которым вы хотите работать, к примеру tcp | icmp | udp – другие имена протоколов можно почитать /etc/protocols. Эти имена протоколов используются вместе с такого вида конструкциями - from ip (или имя) src to ip (или имя) dst. Вместо ip – можно использовать any (любой ip адрес) или me (ip адрес присвоенный вашему интерфейсу). Пример :
allow tcp from me to any via xl0 – разрешает любую сетевую деятельность на интерфейсе xl0.
deny udp from 10.1.1.1 to 8.8.8.8 via rl0 - запрещает сетевой трафик udp c ip 10.1.1.1 к адресу 8.8.8.8 на интерфейсе rl0. Также в инструкциях используются номера портов , они описаны в /etc/services.
Вот пример :
reset tcp from any to any dst-port 135,137,138,139,445,593,4444 – отбрасывает любую активность на перечисленных портах на всех интерфейсах.
in | out – используются для указанию правилу или только входящий трафик или исходящий – соответствует.
via ‘интерфейс’ - указывает какому интерфейсу соответствует правило, если интерфейс не указан то это общее правило для всех сетевых интерфейсов. И еще рассмотрим несколько ключевых слов которые используются в инструкциях. - keep-state – создает динамическое правило. limit - устанавливает определенное количество разрешенных пакетов ( используется для портов и ip адресов ).
Инструкции состояния - check-state если пакет соответствует то отправляется в таблицу динамических правил. Чтобы количество динамических правил не стало проблемой ( и не превратилась в DOs атаку на базе SYN-пакетов) используется опция limit которой можно установить количество разрешенных проходов пакетов.
Также примите к сведению как правильно создавать последовательность правил создания правил в ipfw ( далеко не аксиома – но может помочь ) :
1. Самыми первыми правилами – запретите все что вы планируете запретить – deny и reject.
2.Следующими правилами может идти divert ( если необходим ).
3. Далее allow ( к примеру на локальную сеть внутри )
4. Теперь разрешаем все что еще планируем разрешить.
5. И все остальное запрещаем.
Если вы детально рассмотрели все выше сказанное то вы уже способны на написание цепочек правил для ipfw любой сложности. Далее мы рассмотрим примеры работающих файерволов. Также буду рад в комментариях увидеть примеры ваших правил ipfw, который обязательно дополню в статью.
*Примечания к примеру – файл носит имя ipfw-local находиться в /etc/rc.d/ , все реальные ип адреса заменены на 1.1.1.1.
#!/bin/sh
fwcmd=”/sbin/ipfw”
natdcmd=”/sbin/natd”
int_if=”rl0″
int_if2=”rl1″
ext_if=”xl0″
${fwcmd} -f flush
${natdcmd} -s -m -u -a 1.1.1.1
${fwcmd} add 10 reset tcp from any to any 135,137,138,139,445,593,4444
#== main
${fwcmd} add 30 divert natd ip from any to any via ${ext_if}
${fwcmd} add 40 allow icmp from any to any
#== ssh
${fwcmd} add 41 allow tcp from me to 1.1.1.0/23 dst-port 22 via ${ext_if}
${fwcmd} add 42 allow tcp from 1.1.1.0/23 to me dst-port 22 via ${ext_if}
#== all
${fwcmd} add 43 deny log all from any to any dst-port 22 via ${ext_if}
${fwcmd} add 44 allow all from 192.168.30.2 to any
${fwcmd} add 45 allow all from any to 192.168.30.2
${fwcmd} add 46 allow all from 192.168.30.12 to any via ${int_if}
${fwcmd} add 47 allow all from any to 192.168.30.12 via ${int_if}
${fwcmd} add 50 allow all from any to any via lo0
${fwcmd} add 60 allow all from any to any via ${ext_if}
${fwcmd} add 65532 deny log ip from 192.168.30.0/24 to 192.168.30.1
${fwcmd} add 65322 deny log ip from 192.168.30.0/24 to 1.1.1.1
${fwcmd} add 65534 deny log ip from any to any

####################################################

Хотелось бы добавить, что ipfw еще умеет работать с
1. таблицами адресов
2. регулярными выражениями для интерфейсов
3. вешать несколько правил на один номер

ipfw table 1 add 192.168.1.2
ipfw table 1 add 192.168.1.3

ipfw add 500 allow ip from any to “table(1)” via ng*
ipfw add 500 allow ip from “table(1)” to any via ng*

####################################################
# Variables
# @dr
net=”192.168.1.0/24″
oip=”232.39.10.17″

setup_loopback () {
############
# Only in rare cases do you want to change these rules
#
${fwcmd} add pass all from any to any via lo0
${fwcmd} add deny all from any to 127.0.0.0/8
${fwcmd} add deny ip from 127.0.0.0/8 to any
}

setup_sbi()
{
sbi=”88.168.75.17″
${fwcmd} add divert natd tcp from ${net} to ${sbi} dst-port 25 out via wan
${fwcmd} add divert natd tcp from ${sbi} 25 to ${oip} in via wan
${fwcmd} add allow tcp from ${sbi} 25 to ${net}
${fwcmd} add divert natd tcp from ${net} to ${sbi} dst-port 110 out via wan
${fwcmd} add divert natd tcp from ${sbi} to ${oip} in via wan
}

####################################################
# Main programm #
fwcmd=”/sbin/ipfw -q”
${fwcmd} -f flush
setup_loopback
setup_sbi
# #
####################################################

http://ifreebsd.org/freebsd/ipfw-в-freebsd-8-обзор-настройка-примеры/

Обновлено: 12.03.2015