Настройка IPFW для FreeBSD


== Введение == 

Начну эту статью кратко: без фаервола FreeBSD - не система. То есть, знать фаервол
нужно обязательно, наизусть и понимать его работу четко и ясно. Иначе FreeBSD -
просто не нужна. Firewall - это основа для множества программ и сервисов, фундамент
безопасности сервера, сети, офиса. По умолчанию FreeBSD подразумевает использование
IPFW, хотя можно также использовать PF и IPF. Эта статья - целиком про IPFW.

== Опции IPFW ==

IPFW бывает модулем, а бывает встроенным в ядро. По умолчанию фаервол IPFW - это
подгружаемый модуль, который в самом простом случае управляется через файл /etc/rc.conf:

firewall_enable="YES"
firewall_type="open"

Параметр firewall_type может принимать значения:

* open = пропускать всё
* closed = не пропускать ничего
* simple = обеспечить простую защиту одного интерфейса, указанного в /etc/rc.firewall
* workstation = обеспечить защиту двух интерфейсов (сервера), указанных в /etc/rc.firewall
* "имя_файла" = выполнить правила из указанного файла

В любом случае всегда нужно посмотреть /etc/rc.firewall и проверить, что же там делается.
Хотя бы в качестве примера.

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

firewall_logging="YES"

== IPFW внутри ядра ==

Для использования IPFW внутри ядра, необходимо перекомпилить ядро со следующими флагами:

# "обязательные" флаги
options    IPFIREWALL
options    IPFIREWALL_VERBOSE
options    IPFIREWALL_VERBOSE_LIMIT=100

# если нужно по умолчанию все пропускать
options    IPFIREWALL_DEFAULT_TO_ACCEPT

# если нужен NAT
options    IPDIVERT

Для IPv6 также имеются соответствующие опции:

options    IPV6FIREWALL
options    IPV6FIREWALL_VERBOSE
options    IPV6FIREWALL_VERBOSE_LIMIT
options    IPV6FIREWALL_DEFAULT_TO_ACCEPT

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

== Управление IPFW из консоли ==

IPFW прекрасно управляется из консоли и позволяет наглядно определить, что было
пропущено, а что - заблокировано. Для этого есть одноименная команда ipfw с
необходимыми ключами:

посмотреть только список правил
# ipfw show

посмотреть список правил и статистику по пакетам:
# ipfw list

посмотреть список правил с датами применения правил
# ipfw -t list

посмотреть список правил и полную статистику фильтров
# ipfw -a list

посмотреть динамически добавленные правила
# ipfw -d list

посмотреть динамически добавленные правила и правила, которые уже истекли
# ipfw -d -e list

обнулить счетчики
# ipfw zero

обнулить счетчики правила N
# ipfw zero N

== Формат правил ipfw ==

Все правила ipfw задаются по одному в строке и каждое правило выполняет свою
функцию. Общий формат правил:

КОМАНДА НОМЕР ДЕЙСТВИЕ ЛОГ ОБЛАСТЬ СОСТОЯНИЕ

* КОМАНДА - это почти всегда значение add - для добавления нового правила

* НОМЕР - это необязательный числовой номер, обычно 100, 200, 300, 400, 500, 600 и т.д.

* ДЕЙСТВИЕ - это значение (allow | accept | pass | permit) (deny | drop)
(check-state). Первые 4 опции - разрешают соединение и эквивалентны, вторые две -
эквивалентно запрещают. check-state - говорит о том, что пакет необходимо проверить
еще раз по набору динамических правил. Там где указано check-state нет параметра
ОБЛАСТЬ.

* ЛОГ - это значение log | logamount. Вообще данный параметр направляет
результат работы ipfw в syslogd, т.е. в лог. В logamount можно указать размер лога,
параметр log подразумевает использование в качестве размера net.inet.ip.fw.verbose_limit. 

* ОБЛАСТЬ - это самое важное значение. Оно определяет область, в которой действует
правило. Области могут быть такими:

по типу пакетов
tcp | udp | icmp

по зоне адресов
from src to dst

по номеру портов
port <N>

по направлению трафика
in | out

по интерфейсу на котором идет проверка
via <IF>

по признаку первичной инициализации
setup

с созданием динамического правила
keep-state

с ограничением по источнику-назначению
src-addr | src-port | dst-addr | dst-port

И всё это может быть в комбинациях, к примеру

ipfw add allow tcp from any to 79.125.230.164 dst-port 3306 via re0

* СОСТОЯНИЕ - это значение check-state, которое заставляет проверять симметричный
"обратный" трафик по автоматически созданным динамическим правилам

Дальше, если понять, о чем именно мы всё-таки тут говорим, - всё очень просто.