
Стартовый минигид по пакетному фильтру FreeBSD ipfw
Активация ipfw в FreeBSD
Для начала активируем пакетный фильтр (здесь и далее: «пакетный фильтр» == «файрволл»
== стандартный пакетный фильтр FreeBSD ipfw).
Правда, его (строго говоря, как и ЛЮБОЙ файрволл на ЛЮБОЙ платформе) ПЕРЕД
использованием НЕОБХОДИМО адаптировать к наличным условиям.
ipfw помимо фильтрации пакетов может быть использован как минимум для
управления пропускной способностью канала. Эту возможность в базовом обзоре
я не рассматриваю.
В /etc/rc.conf добавляется следующий блок:
#
#### Basic network and firewall/security options: ###
# Set to YES to enable firewall functionality
firewall_enable="YES"
# Which script to run to set up the firewall
firewall_script="/etc/rc.firewall"
# Firewall type (see /etc/rc.firewall)
firewall_type="/etc/ipfw.rules"
# Set to YES to suppress rule display
firewall_quiet="NO"
# Set to YES to enable events logging
firewall_logging="YES"
# Flags passed to ipfw when type is a file
firewall_flags=""
Значение по умолчанию (для выбранного типа) поведения файрволла (правило под
номером 65535), зашитое в ядро, может принимать либо разрешать, либо
запрещать всем и всё (можно как рулить параметрами при сборке ядра, так и
опциями в /etc/rc.conf).
Зашитое в GENERIC по умолчанию значение можно посмотреть (причём вовсе не
обязательно при запущенном файрволле), например, командой:
# ipfw list
Выглядит это правило следующим образом:
65535 deny ip from any to any
Типы файрволла
Файрволл на базе ipfw может быть следующих типов:
open — пропускать весь трафик.
client — защищать только эту машину.
simple — защищать всю сеть.
closed — полностью отключить IP-трафик за исключением интерфейса loopback.
UNKNOWN — отключение загрузки правил файрволла.
имя_файла — абсолютный путь к файлу, содержащему правила.
В процитированном примере я уже заменил значение по умолчанию UNKNOWN на
единственное удовлетворяющее меня CUSTOM (оно же имя_файла или путь к файлу,
содержащему список правил файрволла).
Логика работы файрволла: получив пакет он, проверяет список правил на
соответствие пакету; найдя первое правило, соответствующее полученному
пакету, пакет обрабатывается в соответствии с данным правилом; и так далее
для всех последующих пакетов.
Базовый набор правил, как уже было отмечено выше, записан в файле, который в
моём случае именуется /etc/ipfw.rules.
Правила ipfw
Диапазон номеров — от 1 до 65534 (последнее 65535 зарезервировано и жёстко —
с точностью до двух возможных вариантов поведения — определено).
При этом необходимо учитывать, что обычно файрволл ведёт себя тихо и при
обнаружении синтаксической ошибки все последующие строки файла с правилами
игнорирует.
Поэтому при загрузке новой версии правил полезно проверять список
действующих правил как минимум на предмет контроля опечаток.
Формат файла с правилами ipfw:
00100 allow all from any to any via lo0
Пояснения по столбцам:
Номер правила.
Выполняемое действие. Принимает значение allow (синонимом является pass) или
deny с необязательной опцией log, указывающей на необходимость записи отчёта
в журнал /var/log/security.
Протокол, на который распространяется правило. Ходовые варианты: icmp
(Internet Control Message Protocol, иначе говоря — пинги), udp, tcp, ip
(синонимом которого является all).
«Откуда?»: from $ADRESS $PORT. Обязательным является указание только первого
параметра, допускается использование ключевого слова all. Пропуск любого из
двух последующих значений означает, что правило распространяется на все
возможные значения. Необязательный параметр адресации — порт. Допускается
указание нескольких значений. Для диапазона — через дефис, для простого
списка — разделителем значений является запятая.
«Куда?» Аналогичен предыдущему.
Тип трафика (входящий или исходящий). Фактически обретает смысл только при
использовании сервера в качестве шлюза и активном использовании в правилах
параметра адресации any. Иначе — фактически дублирует адресную часть.
Сетевой интерфейс.
Тип пакетов. За подробностями посылаю к странице руководства. Желающие
ознакомиться поподробнее могут почитать описание стека протоколов TCP/IP. Я
же отмечу только две группы: setup — TCP-пакеты, используемые при
установлении соединения, и established — TCP-пакеты, используемые при
передаче данных по уже установленному соединению. Аналогично уже описанному:
если параметр присутствует, правило распространяется только на
соответствующие указанному признаку пакеты, иначе — на все возможные
значения этого признака.
И в случае использование динамической конфигурации файрволла в девятом
столбце может указываться параметр keep-state, задающий необходимость
пропустить поступающие в ответ на запрос пакеты.
Разделителем параметров в файле является пробел. «#» традиционно является
символом комментария.
Пример файла с правилами для ipfw
В качестве примера для построения желаемой рекомендации очень неплохо
почитать скрипт примера в Handbook, используя информацию о реальной
конфигурации сети (и /etc/services) в качестве дополнительного справочника.
Минимальный, балансирующий на грани достаточности пример приведу и я:
# Немалая часть приложений под *nix
# использует сетевой интерфейс loopback,
# фильтровать трафик через который
# в нулевом приближении — смысла никакого.
add 100 allow all from any to any via lo0
# Пинги тоже разрешаем — я добрый. Пока.
add 300 allow icmp from any to any
# И передачу почты разрешаем.
add 500 allow tcp from any to any 25 setup
# Запрещаем broadcast.
add 700 deny all from any to $MYNET.255 in
add 703 deny ip from any to 255.255.255.255 in
#
# Правило-метка, означающее переход
# к динамической части блока правил.
add 900 check-state
# Разрешается передавать пакеты по уже
# установленным на момент запуска файрволла
# соединениям.
add 920 allow tcp from any to any established
# Разрешаю устанавливать соединения
# данным сервером со всеми.
add 2100 allow all from $MYNET.$MYHOST to any setup keep-state
# Разрешаю устанавливать соединения
# с сервером всем компьютерам своей сети
add 2200 allow all from $MYNET.0/24 to $MYNET.$MYHOST setup keep-state
# Всё остальное запрещаю. Информацию
# о запретах файрволла по доступу на типовые
# порты пишу в лог /var/log/security, а остальное
# сбрасываю тихо.
add 60000 deny log all from any to any
20,21,22,23,53,80,110,137,138,139,443,563,8080,8888
add 60010 deny all from any to any
Жёстко определённое правило по умолчанию в такой конфигурации работать не
должно.
Запуск ipfw и работа с ним
Теперь файрволл можно запускать:
# /etc/rc.d/ipfw start
Просмотр статистики применения правил осуществляется командой:
# /sbin/ipfw show
Формат вывода — следующий:
Номер правила Число пакетов Байты Правило
00100 0 0 allow all from any to any via lo0
(Число пакетов (байт) == число пакетов, к которым было применено данное
правило.)
Динамическое (не сохраняемое в файле) добавление правил осуществляется
следующим образом:
# /sbin/ipfw -q add 4000 deny log icmp from 194.186.213.105 to
194.186.213.118
Вывод списка правил в формате конфигурационного файла осуществляется
командой:
# /sbin/ipfw list
Посвящается fly4life, или В чём глубокий смысл журнала /var/log/security
Часто в процессе поиска причин неработоспособности сетевого приложения
разработчики рекомендуют убедиться в том, что оной причиной является не
конфигурация файрволла. При этом отдельные особо некомпетентные и
неблагонадёжные разработчики рекомендуют попросту отключить файрволл.
Правильным же путём является использование параметра log и анализ журнала /var/log/security.
Если разработчики не потрудились предоставить внятного описания принципов
работы, то не остаётся ничего кроме как в последнее правило прописать
параметр log и шерстить весь журнал. Иначе — в правиле, например, с номером
60004 придется прописать запрет на пропуск пакетов приложения с логированием:
если пакеты пропускаются одним из ранее прописанных правил, они и так
пройдут; если же они режутся по умолчанию и тихо, то это правило засветит
фильтруемые файрволлом пакеты в /var/log/security.