Стартовый минигид по пакетному фильтру 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.