Главная > Программы > 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 В правилах можно использовать не только слова # 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
Важно! Если хотите подключиться к машине после перезагрузки, обязательно добавьте последнее
правило. Сейчас оно добавляется автоматически, благодаря описанному выше хаку с
Заметьте, что только что мы написали обыкновенный шелл скрипт. Следовательно, в нем можно использовать сокращения имен команд, как продемонстрировано выше, а также условные операторы, процедуры и вот это все. Проверяем скрипт: # sudo sh /etc/ipfw.rules # sudo ipfw list Если все ОК, в firewall_enable="YES"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"
Если решили включить логирование, убедитесь, что вы не забыли дописать в net.inet.ip.fw.verbose_limit=5
Проверяем: # sudo kldunload ipfw # service ipfw start # sudo ipfw list Если все было сделано правильно, долждны увидеть наши правила. Кроме того, они должны сохраняться и после перезагрузки. Это все, о чем я хотел рассказать. Подробности вы найдете в Неправда ли, синтаксис в ipfw куда более читаемый, чем вот эти все Главная > Программы > ipfw |