Главная | Контакты | Настройки СМЕНИТЬ ПАЛИТРУ:

Главная > Программы > ipfw

Настраиваем фаервол во FreeBSD при помощи ipfw

Когда-то давно мы настраивали фаервол в Linux с помощью iptables. При этом отмечалось, что утилиту iptables я нахожу исключительно неудобной по сравнению с FreeBSD’шным ipfw. Сегодня мы наконец-то познакомимся с этим ipfw и постараемся ответить на вопрос, действительно ли он удобнее. Отмечу, что на момент написания этих строк FreeBSD предлагает аж три фаервола на выбор — ipfw, pf и ipf. Однако по моим представлениям из них ipfw используется чаще всего.

Описанные в этом посте действия были проверены мной на FreeBSD 10.3, но по идее не должны ничем отличаться в других версиях FreeBSD.

Итак, первое, что требуется выполнить при настройке ipfw — это команду:

# sudo kenv net.inet.ip.fw.default_to_accept=1

По умолчанию ipfw запрещает передачу вообще всех пакетов. Если вы сидите на сервере по ssh, что весьма вероятно, и просто включите ipfw, то на сервер вы больше не зайдете до следующего ребута. Приведенная команда временно меняет поведение ipfw на «разрешить всем и все», тем самым решая описанную проблему.

Теперь включаем ipfw:

# sudo kldload ipfw

При этом в /var/log/messages мы должны увидеть что-то вроде:

# ipfw2 (+ipv6) initialized, divert loadable, nat loadable,
  default to accept, logging disabled

Как видите, ipfw представляет собой обычный модуль ядра.

Давайте посмотрим на текущий список правил:

# sudo ipfw list

Должны увидеть:

# 65535 allow ip from any to any

Приведенный синтаксис довольно очевидный — номер правила, резрешить / запретить, название протокола, от кого, к кому. Тут мы видим правило с номером 65535, разрешающее передачу входящих и исходящих IP пакетов от кого угодно кому угодно на всех интерфейсах.

Также можно посмотреть время, когда правило последний раз срабатывало:

# sudo ipfw -t list

Давайте попробуем добавить парочку правил. Например, запретим пинги:

флаг -q выполняет команду в "тихом" режиме, без вывода

# sudo ipfw -q add 00100 deny icmp from any to any
# sudo ipfw list

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

Попытаемся пингануть eax.me и убедимся, что пинги больше не ходят. Теперь, когда мы осознали свою ошибку, удаляем правило:

# sudo ipfw -q delete 00100

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

# sudo ipfw -q -f flush

Перед тем, как реально добавлять правило, не лишним бывает собрать статистику о том, как много пакетов ему соответствует:

# sudo ipfw -q add 00100 count udp from me to any out via em0
# sudo ipfw -q add 00200 count udp from any to me in via em0

Как видите, тут демонстрируется не только новое действие (count), но и расширенный синтаксис с частью in/out и указанием конкретного сетевого интерфейса. Кстати, при срабатывании count-правила следующие за ним правила продолжают применяться.

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

# sudo ipfw -a list

# или:

# sudo ipfw show

Счетчики можно при желании обнулить так:

для конкретного правила

# sudo ipfw zero 00200

для всех правил

# sudo ipfw zero

В правилах можно использовать не только слова me и any, но и указывать конкретные хосты или подсети:

# sudo ipfw -q add 00100 deny tcp from any to 192.168.0.1
# sudo ipfw -q add 00200 deny tcp from any to 192.168.0.1/24

Также можно указывать порты или диапазоны портов:

# sudo ipfw -q add 00100 deny tcp from any to 192.168.0.1/24 80
# sudo ipfw -q add 00200 deny tcp from any to 192.168.0.1/24 1-1024

Помимо сбора статистики о срабатывании правил, их также можно логировать:

# sudo ipfw enable verbose

Пример добавления логируемых правил:

# sudo ipfw -q add 00200 deny log \
  tcp from any to 212.193.240.1/24 80

# sudo ipfw -q add 00200 deny log logamount 3 \
  tcp from any to 212.193.240.1/24 80

Если теперь несколько раз попытаться прителнетиться к хосту из используемой выше сети и заглянуть в /var/log/security, то увидим что-то вроде:

ipfw: 200 Deny TCP 10.0.2.15:41738 212.193.240.242:80 out via em0
ipfw: 200 Deny TCP 10.0.2.15:43564 212.193.240.242:80 out via em0
ipfw: 200 Deny TCP 10.0.2.15:55804 212.193.240.242:80 out via em0
ipfw: limit 3 reached on entry 200

Логирование можно глобально включать и выключать таким образом:

# sudo sysctl net.inet.ip.fw.verbose=1
# sudo sysctl net.inet.ip.fw.verbose=0

Если в правиле не указывается logamount, используется следующее значение:

# sudo sysctl net.inet.ip.fw.verbose_limit=5

Значение по умолчанию равно нулю, что означает отсутствие ограничений.

Сбросить счетчики логирования можно так:

# sudo ipfw resetlog

Для сохранения правил при перезагрузке системы создадим файл /etc/ipfw.rules следующего содержания:

#!/bin/sh

fwcmd="ipfw -q add"

ipfw -q -f flush

$fwcmd 00100 deny log tcp from any to 1.2.3.0/24
$fwcmd 00200 deny log tcp from any to 4.5.6.0/24
$fwcmd 65000 allow ip from any to any

Важно! Если хотите подключиться к машине после перезагрузки, обязательно добавьте последнее правило. Сейчас оно добавляется автоматически, благодаря описанному выше хаку с net.inet.ip.fw.default_to_accept. Однако после ребута вернется поведение фаервола по умолчанию, при котором запрещается вообще все.

Заметьте, что только что мы написали обыкновенный шелл скрипт. Следовательно, в нем можно использовать сокращения имен команд, как продемонстрировано выше, а также условные операторы, процедуры и вот это все. Проверяем скрипт:

# sudo sh /etc/ipfw.rules
# sudo ipfw list

Если все ОК, в /etc/rc.conf дописываем:

firewall_enable="YES"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"

Если решили включить логирование, убедитесь, что вы не забыли дописать в /etc/sysctl.conf что-то вроде:

net.inet.ip.fw.verbose_limit=5

Проверяем:

# sudo kldunload ipfw
# service ipfw start
# sudo ipfw list

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

Это все, о чем я хотел рассказать. Подробности вы найдете в man 8 ipfw. Маны во FreeBSD, как всегда, классные. В частности, из мана вы узнаете про такие элементы синтаксиса правил ipfw, оставшиеся за рамками поста, как skipto, tag / untag и другие.

Неправда ли, синтаксис в ipfw куда более читаемый, чем вот эти все -A, -p, -j, --sport и -m multiport в iptables?

Материал взят с сайта: https://eax.me/freebsd-ipfw/

Главная > Программы > ipfw