При разработке IP Firewall Chains, Paul Russell решил, что IP firewall
должен быть проще. Он стал совершенствовать код фильтра и создал пакет,
который оказался много проще и мощнее. Это netfilter.
Внимание: во время
подготовки этой книги проект netfilter еще не был
стабильным. Я надеюсь, что Вы простите ошибки в описании
netfilter или связанных с пакетом инструментальных средств конфигурации,
которые следуют из изменений, происшедших после подготовки этого материала.
Если возникают сомнения, обратитесь к документам HOWTO в сети. Я постарался
описать netfilter максимально точно.
Так, что было неправильно с IP chains? Они значительно улучшили
эффективность и управление правилами firewall. Но они все равно обрабатывали
пакеты очень длинным путем, особенно в связке с другими возможностями
firewall, например, IP masquerade (описан в главе 11)
и другими формами трансляции адреса. Часть этой проблемы существовала потому,
что IP masquerade (маскировка IP) и Network Address Translation (сетевая
трансляция адресов) были разработаны независимо от IP firewall и
интегрированы в него позже.
Однако, имелись другие проблемы. В частности, набор правил input описывал
весь входной поток уровня IP как одно целое. Этот набор
воздействовал как на пакеты, которые предназначены для этого компьютера, так
и на те, которые будут переданы им далее. Это было неправильно потому, что
такой подход спутал функцию цепочки input с функцией цепочки forward, которая
применялась только к исходящим пакетам. Возникали весьма замысловатые
конфигурации для разной обработки входящих и транслируемых пакетов.
Еще одной проблемой было то, что механизм фильтрации находился прямо в
ядре системы, и изменить логику его работы было невозможно без коренной
переработки всего ядра. Так возник netfilter, который
позволяет встраивать в ядро дополнительные модули с другой логикой фильтрации
и имеет более простую схему настройки.
Ключевыми различиями стало удаление из ядра кода для маскировки IP и
изменение в логике работы наборов правил input и output. Появился новый
расширяемый инструмент конфигурации iptables.
В IP chains набор правил input применяется ко всем пакетам, полученным
компьютером, независимо от того, предназначены ли они для локального
компьютера или направлены на другой компьютер. В
netfilter набор правил input применяется только к
пакетам, предназначенным для локального компьютера. Цепочка forward теперь
применяется исключительно к пакетам, предназначенным
для передачи другому компьютеру. В IP Сhains набор
правил output применяется ко всем пакетам, исходящим с компьютера, независимо
от того, сгенерированы ли они на локальном компьютере. В
netfilter этот набор применяется только к
пакетам, сгенерированным на этом компьютере, и не применяется к пакетам,
проходящим транзитом. Это изменение резко упростило настройку.
Еще одной новостью стало вынесение компонентов работы с маскировкой IP в
отдельные модули ядра. Они были переписаны как модули
netfilter.
Рассмотрим случай конфигурации, в которой по умолчанию для input, forward
и output задана стратегия deny. В IP chains для
пропуска всех пакетов потребовалось бы шесть правил.
В netfilter эта сложность исчезает полностью. Для
сервисов, которые должны проходить через firewall, но не завершаются на
локальном компьютере, требуются только два правила: по одному для прямого и
обратного прохода в наборе правил forward.
Документ PACKET-FILTERING-HOWTO предлагает очень подробный список
изменений, которые были сделаны. Поэтому давайте сосредоточимся на более
практических аспектах.
Замечательная гибкость Linux netfilter
иллюстрируется способностью подражать интерфейсам ipfwadm
и ipchains. Эмуляция делает переход к новому
поколению программного обеспечения firewall немного проще.
Два модуля ядра из netfilter с именами
ipfwadm.o и ipchains.o
обеспечивают обратную совместимость с ipfwadm и
ipchains. Можно загрузить одновременно только один
из этих модулей и использовать его только при условии, что модуль
ip_tables.o не загружен. Когда соответствующий
модуль загружен, netfilter работает аналогично
заданной реализации firewall.
Чтобы netfilter копировал интерфейс
ipchains скомандуйте:
Утилита iptables используется для настройки правил
netfilter. Синтаксис заимствован у
ipchains, но имеет важное отличие: он расширяемый. Это
означает, что функциональные возможности могут быть расширены без
перекомпиляции пакета. Для этого используются разделяемые библиотеки.
Имеются стандартные расширения, ряд которых мы сейчас изучим.
Перед использованием команды iptables Вы должны
загрузить модуль ядра netfilter, который позволяет
ей работать. Проще всего сделать это командой modprobe:
# modprobe ip_tables
Команда iptables используется для настройки IP
filter и Network Address Translation. Для этого используются две таблицы:
filter и nat. Если не задана
опция -t, используется таблица filter. Доступны пять
встроенных цепочек (наборов правил): INPUT и
FORWARD для таблицы filter,
PREROUTING и POSTROUTING
для таблицы nat и OUTPUT
для всех таблиц. В этой главе я расскажу только о таблице
filter, таблица nat описана в
главе 11.
Синтаксис команд iptables в общем виде таков:
iptablescommand rule-specification extensions
Теперь мы будем рассмотрим некоторые параметры подробно, после чего перейдем
к примерам.
Команды позволяют управлять правилами и наборами правил
iptables. К IP firewall относятся:
-A chain
Добавляет одно или большее количество правил к концу назначенной
цепочки. Если имя машины задано для источника или адресата, и оно
соответствует нескольким IP-адресам, правило будет добавлен для каждого
адреса.
-I chain rulenum
Добавляет одно или большее количество правил в начало назначенной
цепочки. Если имя машины задано для источника или адресата, и оно
соответствует нескольким IP-адресам, правило будет добавлен для каждого
адреса.
-D chain
Удаляет одно или несколько правил из определенной цепочки, которая
соответствует заданной спецификации правил.
-D chain rulenum
Удаляет правило в позиции rulenum
указанной цепочки. Нумерация начинается с 1.
-R chain rulenum
Заменяет правило в позиции rulenum
указанной цепочки заданным правилом.
-C chain
Проверяет пакет спецификацией правила по заданной цепочке. Эта команда
возвратит сообщение, описывающее, как пакет обработан цепочкой. Это очень
полезно для тестирования Вашей конфигурации firewall, и мы рассмотрим это
подробно чуть позже.
-L [chain]
Выведет список правил в наборе, или всех правил, если конкретный набор
не задан.
-F [chain]
Стирает правила в наборе или во всех наборах, если конкретный набор
не задан.
-Z [chain]
Обнуляет счетчикик пакетов и байтов для всех правил в наборе или для
всех наборов, если конкретный набор не задан.
-N chain
Создает новую цепочку с заданным именем. Таким способом создаются
задаваемые пользователем цепочки.
-X [chain]
Удаляет определенную пользовательскую цепочку или все цепочки, если
никакая конкретная цепочка не задана. На удаляемую цепочку не должно быть
ссылок из других цепочек, иначе она не будет удалена.
-P chain policy
Задает стратегию по умолчанию для указанной цепочки. Допустимые
стратегии: ACCEPT, DROP,
QUEUE и RETURN.
ACCEPT пропускает пакет. DROP
отбрасывает пакет. QUEUE передает пакет
пользовательской цепочке для дальнейшей обработки. RETURN
заставляет IP firewall вернуться к цепочке, правило которой вызвало эту
ситуацию, и предписывает продолжить ее обработку со следующего правила.
Параметры iptables создают правила, определяя какие
типы пакетов соответствуют критериям. Если любой из этих параметров опущен
из спецификации правила, он предполагается по умолчанию.
-p [!]protocol
Указывает протокол, соответствующий правилу. Допустимы имена
протоколов tcp, udp,
icmp. Можно задать номер протокола для протоколов,
которые здесь не определены. Например, 4 для
протокола ipip. Если задан префикс
!, правило превращается в
отрицательное, и принимаются все пакеты, не соответствующие этому протоколу.
Значение по умолчанию: все протоколы.
-s [!]address[/mask]
Указывает исходный адрес и порт, с которого пришел пакет. Адрес может
задавать имя машины, имя сети или IP-адрес. Опция mask
задает сетевую маску. Она может быть задана в обычной форме (например,
/255.255.255.0) или в новой (например, /24). Опция port
задает порт TCP или UDP, или тип пакетов ICMP. Вы можете задать
спецификацию порта только, если Вы задали параметр -p
с одним из протоколов tcp, udp
или icmp. Порты могут быть определены как
диапазон, определяя верхние и нижние границы диапазона с двоеточием в
качестве разделителя. Например, 20:25 определяет
порты с 20 по 25 включительно. Символ ! превращает
правило в его противоположность.
-d [!]address[/mask]
Задает адрес и порт назначения. Во всем остальном аналогичен параметру
-s.
-j target
Указывает, что делать при срабатывании правила. Допустимые действия:
ACCEPT, DROP,
QUEUE и RETURN. Ранее я уже
описал значение каждого действия. Однако, Вы можете также задать имя
определяемой пользователем цепочки, в которой продолжится обработка. Если
этот параметр опущен, будут только изменены данные пакетов и счетчиков, но
ничего с этим пакетом сделано не будет.
-i [!]interface-name
Задает интерфейс, с которого пришел пакет, или через который пакет
будет передан. Символ ! переворачивает результат
сравнения. Если имя интерфейса кончается на +, ему
будут соответствовать все интерфейсы, имена которых начинаются на заданную
строку. Например, -i ppp+ совпадает со всеми
PPP-интерфейсами, а -i ! eth+ соответствует всем
интерфейсам, кроме Ethernet.
-o [!]interface-name
Указывает, что пакеты будут передаваться через этот интерфейс. В
остальном аналогично -i.
[!] -f
Указывает, что это правило применяется ко второму и последующим, но не
к первому, фрагментам пакета.
Ранее мы рассматривали, что iptables расширяется с
помощью модулей. Имеется стандарт расширений, который обеспечивает некоторые
из свойств ipchains. Чтобы использовать расширение, Вы
должны определить имя через параметр -m name в
iptables. Следующий список показывает опции
-m и -p, которые
устанавливают расширения контекста.
Определяет порт, который должен использовать источник пакетов, чтобы
соответствовать этому правилу. Можно задать диапазон, указав верхние и нижние
границы, например: 20:25 задает все порты с 20 по 25
включительно. Символ ! переворачивает значение.
- -dport [!] [port[:port]]
Задает порт, который должны использовать исходящие пакеты. В остальном
аналогичен - -sport.
- -tcp-flags [!] mask comp
Определяет, что это правило должно работать, когда флажки в TCP-пакете
соответствуют определениям mask и
comp. mask задает (через запятую) перечень флажков, а
comp указывает их состояние. Допустимы флажки:
SYN, ACK,
FIN, RST,
URG, PSH,
ALL или NONE. Это сложный
параметр: ознакомьтесь со значением флажков в каком-нибудь хорошем описании
протокола TCP, например, в RFC-793. Действие символа !
обычное для всех правил: он переворачивает значение.
[!] - -syn
Устанавливает, что у пакета должны быть выставлены в 1 флажок
SYN и в 0 флажки ACK и
FIN. Пакет с этими параметрами используется для
создания TCP-соединения, и эту опцию можно использовать для отлова запросов
подключения. Эта опция эквивалент для:
- -tcp-flags SYN,RST,ACK SYN
Когда Вы используете оператор отрицания, правило будет соответствовать всем
пакетам, флажки SYN и ACK
которых вместе не установлены в 1.
Определяет порт, который должен использовать источник пакетов, чтобы
соответствовать этому правилу. Можно задать диапазон, указав верхние и нижние
границы, например: 20:25 задает все порты с 20 по 25
включительно. Символ ! переворачивает значение.
- -dport [!] [port[:port]]
Задает порт, который должны использовать исходящие пакеты. В остальном
аналогичен - -sport.
Указывает подходящие этому правилу сообщения ICMP. Типы сообщений
можно задать номерами или именами. Допустимые имена:
echo-request, echo-reply,
source-quench,
time-exceeded,
destination-unreachable,
network-unreachable,
host-unreachable,
protocol-unreachable и
port-unreachable.
Задает, с какого адреса в сети Ethernet должен придти пакет для этого
правила. Это имеет смысл только в правилах input или forward, поскольку любой
передаваемый нами пакет должен соответствовать правилам output.
Теперь используя netfilter, Вы могли бы просто
загружать модуль ipchains.o и работать с ним, как с
ipchains. Вместо этого, мы повторно напишем наши
правила, используя iptables.
Как и раньше, мы предполагаем, что есть сеть некоей организации, на
Linux-машине запущен firewall. Все внутренние пользователи имеют доступ к
WWW-серверам в Internet, но и только.
Если сеть использует сетевую маску в 24 бита (класс C) и имеет адрес сети
172.16.1.0, нужно использовать правила iptables:
В этом примере iptables работает точно как команда
ipchains. Вся разница в том, что надо предварительно
загрузить модуль ip_tables.o. Обратите внимание,
что iptables не поддерживает опцию
-b, так что мы должны отдельно задать правило для каждого направления.