В началоLinux не для идиотов → Фильтры пакетов
Gentoo-doc HOME Пред.: Маршрутизация IP и форвардингВ началоУровень выше: Linux не для идиотовСлед.: Управление пользователями, NSS и PAM

17. Фильтры пакетов

Возможность инсталляции фильтров пакетов является очень интересной возможностью, предоставляемой стеком TCP/IP ядра Linux. Не углубляясь в детали просто отметим, что IP-стек Linux позволяет различным модулям установить “ловушки” (hooks) для пакетов. При этом каждый пакет, попадающий в такую ловушку, передается для обработки драйверу, установившему эту ловушку. Драйвер, в свою очередь, может проанализировать пакет, проделать какие-либо действия с пакетом, после чего вернуть код обработки, инструктируя таким образом ядро о том, что следует делать с пакетом дальше – вернуть ли отправителю сообщение об ошибке, прервать ли обработку и уничтожить пакет, либо продолжать обработку пакета обычным образом.

В настоящее время для фильтрации пакетов наиболее часто используются средства iptables. iptables – это название утилиты, которая позволяет настроить множество драйверов сетевой подсистемы NETFILTER ядра Linux, позволяющих осуществить анализ, произвести преобразование, или изменить обработку IP-пакетов. Основным объектом в iptables является цепочка правил (chain). Каждое правило в цепочке содержит набор условий совпадения (condition matches) и действие (action). Цепочки сгруппированы в таблицы (tables).

Действий есть две разновидности – прерывающие обработку пакета в цепочке, например действия DROP или ACCEPT, и не прерывающие обработку пакета цепочкой – например, LOG или MARK.

Цепочки используются для проверки пакетов – то есть пакет поочередно последовательно сравнивается с каждым из правил цепочки, и если он удовлетворяет всем условиям в правиле, к пакету применяется действие, указанное в этом правиле. Если действие является прерывающем, то на этом обработка пакета этой цепочкой заканчивается, если действие не прерывающее, то пакет продолжает проверяться этой же цепочкой.

Стандартные цепочки также содержат специальное неявное действие по умолчанию, называемое политикой цепочки (chain policy). Действие, указанное как политика цепочки, применяется ко всем пакетам, которые не попали ни под одно правило с “прерывающим” действием.

17.1. Стандартные таблицы и цепочки

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

Таблица

Назначение

Цепочки

Назначение

mangle Модификация пакетов PREROUTING Модификация всех пришедших пакетов
INPUT Модификация пакетов, пришедших на адрес компьютера
FORWARD Модификация пакетов, которые должны быть отмаршрутизированы (пересланы на другой хост)
OUTPUT Модификация пакетов, сгенерированных процессами данного хоста
POSTROUTING Модификация всех переданных пакетов
filter Фильтрация пакетов – принятие решения об их дальнейшей обработке или отказе от обработки) INPUT Фильтрация адресованных этому компьютеру пакетов
OUTPUT Фильтрация сгенерированных этим компьютером пакетов
FORWARD Фильтрация маршрутизируемых (транзитных) пакетов
nat Трансляция адресов PREROUTING Трансляция адресов всех принимаемых пакетов
FORWARD Трансляция адресов транзитных пакетов
POSTROUTING Трансляция адресов всех передаваемых пакетов

Таблица nat обладает “двойственным” действием, т.е. если вы включите преобразование для входящих пакетов, исходящие пакеты также будут модифицироваться, и наоборот. Таблицы mangle и nat изменяют пакеты, но mangle не ведет список изменений, т.е. является “однонаправленной” таблицей.

17.2. Порядок применения стандартных таблиц и цепочек

Рассмотрим, какой путь проходит пакет в цепочках и таблицах iptables. Для входящих пакетов (адресованных компьютеру, на котором активизирована поддержка iptables) верна следующая последовательность применения цепочек:

  1. mangle.PREROUTING

  2. nat.PREROUTING

  3. mangle.INPUT

  4. filter.INPUT

Для пакетов, отправляемых с компьютера, реализуется следующая цепочка обработки:

  1. filter.OUTPUT

  2. mangle.OUTPUT

  3. nat.POSTROUTING

  4. mangle.POSTROUTING

Пакеты, являющиеся транзитными (маршрутизируемыми), т.е. не адресованные фильтрующему компьютеру и не сгенерированные фильтрующим компьютером, проходят по следующей последовательности цепочек и таблиц:

  1. mangle.PREROUTING

  2. nat.PREROUTING

  3. mangle.FORWARD

  4. filter.FORWARD

  5. nat.FORWARD

  6. nat.POSTROUTING

  7. mangle.POSTROUTING

17.3. Стандартные действия

Каждое правило в любой цепочке может ссылаться на одно из стандартных или дополнительных действий, либо на какую-либо пользовательскую цепочку. Основное различие между стандартными и дополнительными действиями в том, что стандартные действия могут указываться в правилах любых цепочек любых таблиц, а дополнительные действия можно указывать только для некоторых цепочек некоторых таблиц. Перечислим стандартные действия:

ACCEPT

Прервать проверку пакета цепочкой и перейти к следующей в порядке обработки пакета стандартной цепочке

DROP

Прервать обработку пакета, сам пакет удалить

RETURN

Прервать проверку пакета цепочкой и вернуться к проверке вышестоящей цепочкой, а если действие встретилось в одно из стандартных цепочек, поступить с пакетом так, как предписано в политике цепочки (chain policy)

QUEUE

Передать пакет некоторому процессу для дальнейшей обработки

Интересной особенностью также является то, что существуют так называемые target extensions, которые реализованы как модули и также могут использоваться для указания проводимого над пакетом действия. В частности, к таким действиям, например, относятся действия LOG – запротоколировать факт получения пакета, MASQUERADE – подменить IP-адрес отправителя пакета, MARK – пометить пакет и многие другие. Некоторые действия могут встречаться не во всех цепочках, а только в некоторых цепочках некоторых таблиц.

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

17.4. Условия отбора

Условия отбора делятся на две группы – стандартные условия, которые применимы ко всем пакетам, и расширенные условия, называемые также match extensions. Расширенные условия могут применяться не для всех пакетов, а только для некоторых из них – например, дополниетельные условия для протокола UDP включают в себя адреса портов отправителя и получателя, а для ICMP – тип и код ICMP-сообщения.

17.5. Примеры конфигураций iptables

Попробуем рассмотреть несколько простых примеров, достаточно часто используемых в реальных конфигурациях. Стоит заметить, что самостоятельная конфигурация пакетного фильтра требует некоторых (точнее, достаточно значительных) знаний сетевых протоколов, поскольку в конфигурации необходимо задавать множество критериев, которые сильно зависят от ситуации и от используемых сервисов.

Пример 1: простейшая конфигурация iptables для домашнего компьютера, подключенного к Internet. В этой конфигурации мы запретим все входящие соединения, а также все исходящие пакеты UDP кроме тех, которые необходимы для нормальной работы в Internet с использованием PPP-соединения. В этой конфигурации мы разрешаем передачу всех пакетов в рамках локальной машины, разрешаем исходящие TCP-пакеты, разрешаем входящие пакеты TCP для уже установленных соединений, и разрешаем передачу и прием UDP-пакетов для службы DNS и пакетов автоматической конфигурации соединения PPP (пакетов DHCP). Кроме того, следует разрешить прием управляющих пакетов ICMP и отправку запросов и прием ответов PING:

# iptables -P INPUT DROP
# iptables -A INPUT -j ACCEPT -i lo
# iptables -A INPUT -j ACCEP -p tcp ! --syn
# iptables -A INPUT -j ACCEPT -p udp --source-port 53
# iptables -A INPUT -j ACCEPT -p udp --source-port 67 --destination-port 68
# iptables -A INPUT -j ACCEPT -p icmp --icmp-type destination-unreachable
# iptables -A INPUT -j ACCEPT -p icmp --icmp-type time-exceeded
# iptables -A INPUT -j ACCEPT -p icmp --icmp-type parameter-problem
# iptables -A INPUT -j ACCEPT -p icmp --icmp-type echo-reply
# iptables -P OUTPUT DROP
# iptables -A OUTPUT -j ACCEPT -p tcp
# iptables -A OUTPUT -j ACCEPT -p udp --destination-port 53
# iptables -A OUTPUT -j ACCEPT -p udp --destination-port 67 --source-port 68
# iptables -A OUTPUT -j ACCEPT -p icmp --icmp-type echo-request

Пример 2: то же самое, что в примере 1, но все “отбитые” пакеты протоколируются. Для того, чтобы добиться такого эффекта, нужно создать дополнительную цепочку, которая будет протоколировать и удалять пакеты. Эту цепочку мы назовем KILLER – вполне обоснованно, не так ли? Кроме того, мы исправим политики стандартных цепочек так, чтобы запрещенные пакеты не удалялись, а “забрасывались” в созданную нами цепочку KILLER, а нашей основной цели (сначала протоколировать, потом удалить пакет) можно добиться просто указав два действия – сначала LOG, затем DROP. Поскольку действие LOG не является прерывающим обработку, мы получим требуемый нам эффект:

# iptables -N KILLER
# iptables -A KILLER -j LOG
# iptables -A KILLER -j DROP
# iptables -P INPUT KILLER
# iptables -A INPUT -j ACCEPT -i lo
# iptables -A INPUT -j ACCEP -p tcp ! --syn
# iptables -A INPUT -j ACCEPT -p udp --source-port 53
# iptables -A INPUT -j ACCEPT -p udp --source-port 67 --destination-port 68
# iptables -A INPUT -j ACCEPT -p icmp --icmp-type destination-unreachable
# iptables -A INPUT -j ACCEPT -p icmp --icmp-type time-exceeded
# iptables -A INPUT -j ACCEPT -p icmp --icmp-type parameter-problem
# iptables -A INPUT -j ACCEPT -p icmp --icmp-type echo-reply
# iptables -P OUTPUT KILLER
# iptables -A OUTPUT -j ACCEPT -p tcp
# iptables -A OUTPUT -j ACCEPT -p udp --destination-port 53
# iptables -A OUTPUT -j ACCEPT -p udp --destination-port 67 --source-port 68
# iptables -A OUTPUT -j ACCEPT -p icmp --icmp-type echo-request

Пример 3: маскарад пакетов. Маскарадом называют преобразование IP-адресов проходящих пакетов так, чтобы они выглядели как отправленные с системы-маршрутизатора, а не с какого-либо узла “за” маршрутизатором. Достигается это путем изменения IP-адреса (и, возможно, номера порта) в “транзитных” пакетах. Собственно преобразование задается путем указания действий SNAT – замена адреса отправителя, DNAT – замена адреса получателя, или MASQUERADE – функционально аналогично SNAT, но без указания конкретного IP-адреса (IP-адресом для замены назначается IP-адрес интерфейса через который уходит пакет, со всеми отсюда вытекающими – например, если интерфейс меняет IP-адрес или просто деактивируется все «маскированные» через него соединения сбрасываются). Предположим, что наш “внешний” интерфейс имеет адрес 193.267.14.6, а внутренняя сеть имеет адрес 192.168.0.0/24. Тогда для того, чтобы дать всем компьютерам нашей сети доступ по протоколу TCP “наружу”, мы должны подать примерно следующую команду:

# iptables -A POSTROUTING -t nat -j SNAT -o ppp0 \
>   --to-source 193.267.14.6 -p tcp \
>   --source 192.168.0.0/24 \
>   --destination ! 192.168.0.0/24

Если у нас внешний адрес динамический, а не статический (мы работаем по dialup-соединению), то мы можем использовать динамический маскарад без привязки к внешнему адресу – ну или с использованием динамической привязки, кому как больше нравится:

# iptables -A POSTROUTING -t nat -j MASQUERADE -o ppp0 \
>   --source 192.168.0.0/24 \
>   --destination ! 192.168.0.0/24

Действие SNAT более эффективно, MASQUERADE проще в использовании, но обладает рядом существенных недостатков (не вдаваясь в подробности, просто заметим, что на системе с несколькими интерфейсами и сложной таблицей маршрутизации проблемы почти наверняка будут). Особое внимание нужно обратить на указание -o ppp0, то есть действие применяется ТОЛЬКО для пакетов, отправляемых через интерфейс ppp0. Еще вы можете увидеть, что мы указываем это правило только один раз, и обратного к нему правила не строим – об этом позаботится функция connection tracking (отслеживание состояния соединений), и обратная замена адресов в отправляемых в ответ на наши запросы пакетах будет произведена системой автоматически.

Пример 4: “проброс” пакетов во внутреннюю сеть. Обычно это используется, если мы хотим перебросить пакеты, пришедшие на адрес маршрутизатора, на какую-либо из машин внутренней сети (например, так можно предоставить доступ ко внутреннему WWW-серверу). Достигается это использованием действия DNAT (destination NAT). В нашем случае мы перебрасываем все TCP-пакеты, пришедшие на интерфейс маршрутизатора ppp0 на порт 80, на порт 85 компьютера с адресом 192.168.0.6:

# iptables -A PREROUTING -t nat -j DNAT -i ppp0 \
>   --to-destination 192.168.0.6:85 -p tcp --destination-ports 80

Конечно, приведенными примерами возможности iptables не исчерпываются, скорее даже наоборот – это лишь малая часть того, что умеет эта подсистема. Приведенные же примеры демонстрируют наиболее простые случаи, позволяющие составить некоторое представление об iptables и возможностях этой технологии.

В системах, основанных на RedHat Linux и его вариациях, есть специальный стартовый сценарий загрузки, также называемый iptables. Расположен он как правило в каталоге /etc/rc.d/init.d/. Этот сценарий при загрузке системы инсталлирует правила, созданные администратором, и его можно использовать для сохранения конфигурации iptables. В процессе конфигурации системный администратор задает конфигурацию подсистемы iptables, используя утилиту /sbin/iptables, а после окончания настройки дает команду /etc/rc.d/init.d/iptables save, после чего текущая конфигурация сохраняется в файл /etc/sysconfig/iptables. Существует также множество “фронтендов” для настройки iptables, которые могут использоваться начинающими пользователями и не слишком опытными администраторами, но “ручной” способ настройки все-таки предпочтительней, поскольку позволяет очень точно настроить подсистему iptables.

Пред.: Маршрутизация IP и форвардингВ началоУровень выше: Linux не для идиотовСлед.: Управление пользователями, NSS и PAM
В началоLinux не для идиотов → Фильтры пакетов