Руководство FreeBSD
Пред. | Глава 27. Межсетевые экраны | След.

# 27.5. * IPFILTER (IPF)

> Внимание: Перевод раздела не завершен.

> Замечание: Этот раздел находится в процессе написания; содержание может не вполне соответствовать действительности.

Автором IPFILTER является Darren Reed. IPFILTER не зависит от операционной системы: это приложение с открытыми исходными текстами, которое было портировано на операционные системы FreeBSD, NetBSD, OpenBSD, SunOS", HP/UX, и Solaris". IPFILTER активно разрабатывается и поддерживается, регулярно выпускаются обновленные версии.

IPFILTER основан на межсетевом экране и механизме NAT уровня ядра, которые управляются и контролируются утилитами уровня пользовательских процессов. Правила межсетевого экрана могут устанавливаться или удаляться утилитой ipf(8). Правила NAT могут устанавливаться или удаляться утилитой ipnat(1). Утилита ipfstat(8) выводит статистику IPFILTER для ядра. Программа ipmon(8) может заносить действия IPFILTER в файлы системных протоколов.

IPF был первоначально написан с использованием правила ''последнее совпадение применяется'' и только с правилами без сохранения состояния. Со временем IPF был расширен и включает параметры ''quick'' и ''keep state'' (сохранение состояния), которые кардинальным образом изменяют логику обработки пакетов. Официальная документация IPF включает традиционные параметры правил с традиционной последовательностью обработки пакетов. Измененные функции включены в виде дополнительных параметров, они необходимы для создания эффективного межсетевого экрана.

Инструкции этого раздела подразумевают использование параметра ''quick'' и параметра сохранения состояния ''keep state''. Это основа для создания включающего межсетевого экрана.

Детальное описание традиционных методов обработки правил: http://www.obfuscation.org/ipf/ipf-howto.html#TOC_1 и http://coombs.anu.edu.au/~avalon/ip-filter.html.

IPF FAQ находится по адресу http://www.phildev.net/ipf/index.html.

Архив списка рассылки по IPFilter с возможностью поиска доступен по адресу http://marc.theaimsgroup.com/?l=ipfilter.

## 27.5.1. Включение IPF

IPF включен в базовую систему FreeBSD в качестве отдельного загружаемого модуля. Система динамически загрузит модуль IPF, если в `rc.conf` указана переменная `ipfilter_enable="YES"`. Модуль создается с включенным протоколированием и правилом по умолчанию `pass all` (пропускать все). Для изменения правила по умолчанию не обязательно собирать ядро с новыми параметрами. Просто добавьте в конец набора правило, блокирующее все пакеты.

## 27.5.2. Параметры ядра

Включение IPF в ядро FreeBSD не является обязательным требованием. Эта процедура представлена здесь в качестве дополнительной информации. При включении IPF в ядро загружаемый модуль не используется.

Пример параметров настройки ядра для IPF находится в `/usr/src/sys/conf/NOTES` и воспроизведен здесь:

    options IPFILTER
    options IPFILTER_LOG
    options IPFILTER_DEFAULT_BLOCK

`options IPFILTER` включает поддержку межсетевого экрана ''IPFILTER''.

`options IPFILTER_LOG` включает протоколирование трафика через IPF путем записи его в псевдо-устройство протоколирования пакетов `ipl` для каждого правила, содержащего ключевое слово `log`.

`options IPFILTER_DEFAULT_BLOCK` изменяет поведение по умолчанию так, что блокируется каждый пакет, не соответствующий правилу `pass`.

Эти настройки будут работать только после сборки и установки нового ядра.

## 27.5.3. Доступные параметры rc.conf

Для активации IPF во время загрузки в `/etc/rc.conf` потребуется добавить следующие переменные:

    ipfilter_enable="YES"             # Запуск межсетевого экрана ipf
    ipfilter_rules="/etc/ipf.rules"   # Загрузка файла с правилами
    ipmon_enable="YES"                # Включение протоколирования IP monitor
    ipmon_flags="-Ds"                 # D = запуск в виде даемона
                                      # s = протоколирование в syslog
                                      # v = протоколирование tcp window, ack, seq
                                      # n = отображение имен IP и портов

Если за межсетевым экраном находится локальная сеть, использующая приватные IP адреса, для включения NAT потребуется добавить следующие переменные:

    gateway_enable="YES"              # Включение шлюза для локальной сети
    ipnat_enable="YES"                # Запуск функции ipnat
    ipnat_rules="/etc/ipnat.rules"    # Определение файла правил для ipnat

## 27.5.4. IPF

Команда ipf(8) используется для загрузки файла с правилами. Обычно создается файл, содержащий подготовленный набор правил, который полностью замещает набор, используемый на данный момент:

    # ipf -Fa -f /etc/ipf.rules

`-Fa` означает сброс всех внутренних таблиц правил.

`-f` указывает файл с правилами, который необходимо загрузить.

Это дает вам возможность отредактировать файл с правилами, запустить вышеприведенную команду IPF, тем самым обновить набор правил работающего межсетевого экрана без перезагрузки системы. Для обновления правил такой подход очень удобен, поскольку команду можно выполнять столько раз, сколько нужно.

На странице справочной системы ipf(8) находится подробная информация по всем флагам этой команды.

Набор правил для команды ipf(8) должен быть в виде стандартного текстового файла. Правила, написанные в виде скрипта с символами подстановки, не принимаются.

Есть способ составления правил IPF, использующих символы подстановки. Обратитесь к Разд. 27.5.9.

## 27.5.5. IPFSTAT

По умолчанию ipfstat(8) получает и отображает суммарную статистику, полученную в результате применения действующих правил к пакетам, проходящим через межсетевой экран с момента его последнего запуска, или с того момента, когда статистика была последний раз обнулена командой `ipf -Z`.

Детальная информация приводится на странице справочника ipfstat(8).

Вывод команды ipfstat(8) по умолчанию выглядит примерно так:

    input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0
     output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0
     input packets logged: blocked 99286 passed 0
     output packets logged: blocked 0 passed 0
     packets logged: input 0 output 0
     log failures: input 3898 output 0
     fragment state(in): kept 0 lost 0
     fragment state(out): kept 0 lost 0
     packet state(in): kept 169364 lost 0
     packet state(out): kept 431395 lost 0
     ICMP replies: 0 TCP RSTs sent: 0
     Result cache hits(in): 1215208 (out): 1098963
     IN Pullups succeeded: 2 failed: 0
     OUT Pullups succeeded: 0 failed: 0
     Fastroute successes: 0 failures: 0
     TCP cksum fails(in): 0 (out): 0
     Packet log flags set: (0)

При задании флага `-i` или `-o` соответственно для входящих или исходящих пакетов, команда извлечет и отобразит соответствующий список правил, установленных и используемых на данный момент.

`ipfstat -in` отображает правила, применяемые к входящим пакетам, вместе с номерами этих правил.

`ipfstat -on` отображает правила, применяемые к исходящим пакетам, вместе с номерами этих правил.

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

    @1 pass out on xl0 from any to any
    @2 block out on dc0 from any to any
    @3 pass out quick on dc0 proto tcp/udp from any to any keep state

`ipfstat -ih` отображает правила, применяемые к входящим пакетам, со счетчиком количества совпадений для каждого правила.

`ipfstat -oh` отображает правила, применяемые к исходящим пакетам, со счетчиком количества совпадений для каждого правила.

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

    2451423 pass out on xl0 from any to any
    354727 block out on dc0 from any to any
    430918 pass out quick on dc0 proto tcp/udp from any to any keep state

Одна из наиболее важных функций команды `ipfstat` активируется флагом `-t`, правила отображаются подобно тому, как top(1) показывает таблицу запущенных процессов FreeBSD. Когда межсетевой экран подвергается атаке, эта функция позволяет обнаружить соответствующие пакеты. Дополнительные флаги дают возможность выбирать IP адрес назначения или источника, порт или протокол, которые будут отслеживаться в реальном времени. Подробная информация приведена на странице ipfstat(8).

## 27.5.6. IPMON

Для того, чтобы стало возможно использование команды `ipmon`, необходимо включить параметр ядра `IPFILTER_LOG`. Эта команда может использоваться в двух различных режимах. В основном режиме, который используется по умолчанию, она используется без флага `-D`.

В режиме даемона создается непрерывный протокол, и возможен просмотр предыдущих событий. В этом режиме IPFILTER работает в FreeBSD. Поскольку в FreeBSD встроена функция ротации файлов протокола, лучше использовать syslogd(8), чем используемый по умолчанию вывод в обычный файл. В `rc.conf` по умолчанию `ipmon_flags` имеет значение `-Ds`:

    ipmon_flags="-Ds" # D = start as daemon
                      # s = log to syslog
                      # v = log tcp window, ack, seq
                      # n = map IP & port to names

Описывать преимущества протоколирования излишне. Например, оно дает возможность отложенного просмотра информации об отброшенных пакетах, откуда они пришли и куда направлялись. Эта информация существенно помогает при отслеживании атак.

Даже с включенным протоколированием, IPF не ведет протокол для каждого правила. Администратор межсетевого экран должен решить, по каким правилам набора нужно вести протокол и добавить ключевое слово log к этим правилам. Обычно протоколируются только правила, отбрасывающие пакеты.

Включение в набор последнего правила, запрещающего прохождение пакетов, в сочетании с ключевым словом `log` является довольно распространённой практикой. Так вы можете увидеть все пакеты, не попадающие ни под одно правило набора.

## 27.5.7. Протоколирование IPMON

Для разделения собираемых данных syslogd использует свой собственный специальный метод. Он использует группировку по категории (''facility'') и уровню (''level''). IPMON в режиме `-Ds` использует `local0` в качестве имени ''категории''. Для дальнейшего разделения протоколируемых данных, если такое необходимо, могут быть использованы следующие уровни:

    LOG_INFO - packets logged using the "log" keyword as the action rather than pass or block.
    LOG_NOTICE - packets logged which are also passed
    LOG_WARNING - packets logged which are also blocked
    LOG_ERR - packets which have been logged and which can be considered short

Для указания IPFILTER протоколировать все данные в `/var/log/ipfilter.log`, создайте этот файл заранее, выполнив следующую команду:

    # touch /var/log/ipfilter.log

Функционирование syslogd(8) управляется настройками в файле `/etc/syslog.conf`. Файл `syslog.conf` позволяет достаточно гибко настроить обработку системных сообщений, выдаваемых программами, такими как IPF.

Добавьте в `/etc/syslog.conf` следующую запись:

    local0.* /var/log/ipfilter.log

`local0.*` означает запись всех протоколируемых сообщений в указанный файл.

Для применения внесенных в `/etc/syslog.conf` изменений вы можете перезагрузиться или заставить syslogd(8) перечитать `/etc/syslog.conf`, выполнив команду `/etc/rc.d/syslogd reload`.

Не забудьте отредактировать `/etc/newsyslog.conf` для ротации только что созданного лог файла.

## 27.5.8. Формат протоколируемых сообщений

Сообщения, генерируемые `ipmon`, состоят из полей данных, разделенных пробелами. Поля, общие для всех сообщений:

1. Дата получения пакета.

2. Время получения пакета. Формат времени HH:MM:SS.F для часов, минут, секунд и долей секунд (последнее поле может состоять из нескольких цифр).

3. Имя интерфейса, через который прошел пакет, например `dc0`.

4. Группа и номер правила, например `@0:17`.

Эти сообщения могут быть просмотрены командой `ipfstat -in`.

1. Действие: p для пропущенных, b для заблокированных, S для пакетов с неполным заголовком (short packet), n для пакетов, не соответствующих какому-либо правилу, L для соответствующих правилу протоколирования. Порядок следования по флагам: S, p, b, n, L. Знаки P или B в верхнем регистре означают, что пакет был протоколирован в соответствии с общими настройками, а не каким-то конкретным правилом.

2. Адреса. Всего три поля: адрес и порт источника (разделенные запятой), ->, адрес и порт назначения. 209.53.17.22,80 -> 198.73.220.17,1722.

3. `PR`, с последующим именем или номером протокола, например `PR tcp`.

4. `len`, с последующей длиной заголовка и общей длиной пакета, например `len 20 40`.

Для TCP пакетов добавляется дополнительное поле, начинающееся с дефиса, за которым следуют буквы, соответствующие установленным флагам. На странице справочника ipf(5) находится список букв и флагов.

Для пакетов ICMP, в конце находятся два поля, одно всегда ''ICMP'', а второе содержит тип и подтип ICMP сообщения (message и sub-message), разделенные символом косой черты, например ICMP 3/3 для сообщения ''port unreachable''.

## 27.5.9. Создание набора правил с использованием символьной подстановки

Некоторые опытные пользователи IPF создают файл правил, поддерживающий использование символьной подстановки. Основное преимущество использования такого подхода заключается в возможности изменения значения, присваиваемого символьному имени, в результате чего во всех правилах, содержащих эту символьную подстановку, будет использоваться новое значение. В начале скрипта вы можете поместить часто используемые переменные, а затем использовать их сразу в нескольких правилах. Ниже дан пример такого использования.

Синтаксис скрипта совместим с sh(1), csh(1), и tcsh(1).

Символьная подстановка предваряется знаком доллара: `$`.

Для присвоения значения символьным переменным знак $ не используется.

Присваиваемое символической переменной значение должно быть заключено в двойные кавычки (`"`).

Начните файл правил примерно так:

    ############# Start of IPF rules script ########################

    oif="dc0"            # name of the outbound interface
    odns="192.0.2.11"    # ISP's DNS server IP address
    myip="192.0.2.7"     # my static IP address from ISP
    ks="keep state"
    fks="flags S keep state"

    # You can choose between building /etc/ipf.rules file
    # from this script or running this script "as is".
    #
    # Uncomment only one line and comment out another.
    #
    # 1) This can be used for building /etc/ipf.rules:
    #cat > /etc/ipf.rules << EOF
    #
    # 2) This can be used to run script "as is":
    /sbin/ipf -Fa -f - << EOF

    # Allow out access to my ISP's Domain name server.
    pass out quick on $oif proto tcp from any to $odns port = 53 $fks
    pass out quick on $oif proto udp from any to $odns port = 53 $ks

    # Allow out non-secure standard www function
    pass out quick on $oif proto tcp from $myip to any port = 80 $fks

    # Allow out secure www function https over TLS SSL
    pass out quick on $oif proto tcp from $myip to any port = 443 $fks
    EOF
    ################## End of IPF rules script ########################

Это все, что требовалось сделать. В данном примере сами правила не важны; важно то, как используется символьная подстановка. Если вышеприведенный пример помещен в файл `/etc/ipf.rules.script`, то набор правил можно перезагрузить, введя следующую команду:

    # sh /etc/ipf.rules.script

С использованием в правилах символьной подстановки связана одна проблема: IPF не понимает символьную подстановку и не может обработать такой скрипт непосредственно.

Скрипт может использоваться одним из следующих двух способов:

- Уберите комментарий перед строкой, начинающейся с `cat`, и закомментируйте строку, начинающуюся с `/sbin/ipf`. Поместите строку `ipfilter_enable="YES"` в файл `/etc/rc.conf` как обычно, и запускайте скрипт после каждого его обновления для создания или обновления файла `/etc/ipf.rules`.

- Отключите IPFILTER в стартовых скриптах системы, поместив строку `ipfilter_enable="NO"` (это значение по умолчанию) в файл `/etc/rc.conf`.

  Поместите скрипт, подобный нижеприведенному, в каталог `/usr/local/etc/rc.d/`. У него должно быть однозначно говорящее о его назначении имя, например `ipf.loadrules.sh`. Расширение `.sh` обязательно.

      #!/bin/sh
      sh /etc/ipf.rules.script

  Права, установленные на этот файл, должны разрешать чтение, запись и выполнение владельцу `root`.

      # chmod 700 /usr/local/etc/rc.d/ipf.loadrules.sh

Теперь, правила IPF будут загружаться при загрузке системы.

## 27.5.10. Наборы правил IPF

Набор правил ipf это группа правил, составленных для пропускания или блокирования пакетов на основе их содержимого. Двусторонний обмен пакетами между хостами составляет сессию. Межсетевой экран обрабатывает как входящие из Интернет пакеты, так и исходящие пакеты, которые сгенерированы самой системой в ответ на входящий трафик. Для каждой службы TCP/IP (например, telnet, www, mail, и т.п.) назначен протокол и номер привилегированного (прослушиваемого) порта. Пакеты, предназначенные для определенного сервиса, порождаются с некоторым исходящим адресом и портом из непривилегированного диапазона и направляются на определенный адрес и определенный порт назначения. Все упомянутые параметры (номера портов и адреса) могут использоваться как критерии выбора в правилах, пропускающих или блокирующих доступ к службам TCP/IP.

IPF был первоначально написан с использованием логики ''последнее совпадающее правило побеждает'' и только с правилами без сохранения состояния. Со временем в IPF был включен параметр ''quick'' и параметр сохранения состояния ''keep state'', что существенно улучшило логику обработки правил.

Инструкции, помещенные в эту главу, созданы с использованием параметров ''quick'' и ''keep state''. Это основа для создания набора правил включающего межсетевого экрана.

> Внимание: При работе с правилами межсетевого экрана, будьте очень осторожны. Некоторые конфигурации могут заблокировать вам доступ к серверу. В целях предосторожности, первоначальную настройку межсетевого экрана вы можете выполнить с локальной консоли, а не через удаленное подключение, такое как ssh.

Пред. | Начало | След.
Packet Filter (PF, межсетевой экран OpenBSD) и ALTQ | Уровень выше | * IPFW

Этот, и другие документы, могут быть скачаны с ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите <doc@FreeBSD.org>.
По вопросам, связанным с русским переводом документации, пишите в рассылку <frdp@FreeBSD.org.ua>.
Информация по подписке на эту рассылку находится на сайте проекта перевода.