|
Bog BOS: netfilter и iptables/arptables: фильтрация пакетов в Linux: принципы работы, установка и настройка
|
Последнее изменение файла: 2019.10.16
Скопировано с www.bog.pp.ru: 2024.11.23
Bog BOS: netfilter и iptables/arptables: фильтрация пакетов в Linux: принципы работы, установка и настройка
netfilter (встроенные в ядро Linux 2.4/2.6
средства фильтрации пакетов) и программы (iptables, iptables-save, iptables-restore)
управления ими могут быть использованы для организации сетевого экрана (firewall),
NAT (Network Address Translation; NPT - Network Port Translation;
DNAT - Destination Network Address Translation;
SNAT - Source Network Address Translation) или усиления защиты сервера.
В отличие от ipchains умеет отслеживать соединения
(stateful packet filtering), при этом пакеты обязательно дефрагментируются;
цепочки правил объединяются в таблицы различного назначения (filter, nat, mangle),
используются специальные модули для различных протоколов (в т.ч. прикладного уровня).
Также позволяет менять заголовки пакетов и помечать пакеты для дальнейшего использования
при маршрутизации и управлении трафиком (iproute2, tc).
В основном, работает на межсетевом уровне TCP/IP, но захватывает транспортный уровень (TCP, UDP)
и уровень доступа к сети (MAC адреса).
Одновременное использование данных из 2 пакетов по-прежнему невозможно,
для настоящей фильтрации на прикладном уровне пользуйтесь прокси серверами.
Для управления фильтрацией пакетов протокола ARP используется
утилита arptables (пакет arptables_jf).
В статье описываются:
Для работы netfilter необходимо иметь ядро 2.3.15 или более новое,
при генерации которого включены CONFIG_NETFILTER, CONFIG_IP_NF_IPTABLES,
CONFIG_IP_NF_FILTER (таблица filter), CONFIG_IP_NF_NAT (таблица nat),
CONFIG_BRIDGE_NETFILTER,
а также многочисленные дополнительные модули: CONFIG_IP_NF_CONNTRACK (отслеживание соединений),
CONFIG_IP_NF_FTP (вспомогательный модуль для отслеживания FTP соединений),
CONFIG_IP_NF_MATCH_* (дополнительные типы шаблонов соответствия пакетов:
LIMIT, MAC, MARK, MULTIPORT, TOS, TCPMSS, STATE, UNCLEAN, OWNER),
CONFIG_IP_NF_TARGET_* (дополнительные действия в правилах:
REJECT, MASQUERADE, REDIRECT, LOG, TCPMSS),
CONFIG_IP_NF_COMPAT_IPCHAINS для совместимости с ipchains,
CONFIG_BRIDGE_NF_EBTABLES и CONFIG_BRIDGE_EBT_* для работы в режиме моста,
прочие CONFIG_IP_NF_* и CONFIG_IP6_NF_*.
Полезно также указать CONFIG_PACKET.
Наличие netfilter в ядре определяется по файлам
/proc/net/ip_tables_names (список используемых таблиц),
/proc/net/ip_tables_targets (2.6) и /proc/net/ip_tables_matches (2.6).
Управление осуществляется с помощью утилиты iptables.
Функциональность netfilter может расширяться с помощью модулей ядра.
Головной модуль ядра называется iptable_filter, модуль поддержки утилиты iptables называется ip_tables,
вспомогательные модули обычно имеют префикс "ipt_" (ipt_state, ipt_REJECT, ipt_LOG;
хотя - ip_conntrack/nf_conntrack). Большинство модулей загружается автомагически, но некоторые
всё же приходиться загружать вручную (ip_conntrack_ftp - иначе может не работать
в режиме Active; ip_conntrack_irc - иначе может не работать отсылка файлов по DCC;
ip_nat_ftp; ip_nat_irc; ip_conntrack_tftp/nf_conntrack_tftp на клиенте - иначе не будет работать TFTP).
Управление дополнительными модулями ядра осуществляется с помощью разделяемых библиотек
(см. /lib/iptables/) для утилиты iptables.
netfilter позволяет эмулировать ipfwadm и ipchains с помощью модулей ядра
(с некоторых пор перестали включаться в стандартное ядро), при этом модуль ip_tables необходимо
выгрузить.
Каждый проверяемый IP-пакет проходит по цепочке ("сквозь строй")
правил, определяющих, что с ним делать. Правило состоит из шаблона, которому должен
соответствовать пакет, и действия. Каждая цепочка имеет действие по умолчанию (политику).
В отличие от ipchains правила входной цепочки (INPUT) применяются
после принятия решения о том, что это "наш" пакет и маршрутизировать его не надо;
правила выходной цепочки (OUTPUT) применяются не только к исходящим наружу пакетам, но
и к передаваемым на локальный интерфейс. Правила цепочки FORWARD применяются только
к транзитным пакетам. Имеется возможность добавлять к набору свои цепочки.
netfiler обрабатывает несколько наборов (таблиц) цепочек:
- таблица filter приблизительно соответствует набору цепочек в ipchains
- таблица nat обеспечивает функциональность подстановки адресов (только первый пакет соединения
обрабатывается полностью, в последующих пакетах соединения адреса подменяются по аналогии
с первым пакетом, остальные действия не производятся)
- таблица mangle - преобразование пакетов (манипулирование TOS, TTL, маркеры)
Приблизительная схема обработки пакетов (взята из NAG2; по-моему, ради красоты
картинки художник пожертвовал истиной: пропал маршрут из второй точки маршрутизации на localhost,
он не проходит через FORWARD):
В таблицах nat и mangle имеются цепочки PREROUTING и POSTROUTING.
Правила цепочки PREROUTING применяется к пакетам сразу после получения пакета на входе
интерфейса перед выбором маршрута, а правила цепочки POSTROUTING непосредственно перед
выводом пакета через интерфейс. В таблице nat нет цепочек INPUT и FORWARD.
Реальная последовательность обработки входящего пакета, предназначенного для локального
процесса такова:
- просматривается цепочка PREROUTING таблицы mangle (используется для преобразования пакетов),
здесь же происходит отслеживание соединений
- просматривается цепочка PREROUTING таблицы nat (используется для DNAT,
фильтровать здесь не стоит)
- маршрутизация: если пакет надо маршрутизовать вовне, то переходим к обработке проходящего пакета
- просматривается цепочка INPUT таблицы mangle
- просматривается цепочка INPUT таблицы filter
Реальная последовательность обработки пакета, уходящего с нашего хоста такова:
- маршрутизация: определение исходящего адреса, адреса назначения, используемого интерфейса;
если пакет маршрутизируется внутрь, то переходим к предыдущей процедуре (п. 1 или 4?)
- просматривается цепочка OUTPUT таблицы mangle, фильтровать здесь не стоит,
здесь же происходит отслеживание локально создаваемых соединений
- просматривается цепочка OUTPUT таблицы nat (NAT для локально сгенерированных пакетов)
- повторная маршрутизация, т.к. в таблицах mangle и nat пакет мог быть изменён;
если пакет маршрутизируется внутрь, то переходим к предыдущей процедуре (п. 1 или 4?)
- просматривается цепочка OUTPUT таблицы filter
- просматривается цепочка POSTROUTING таблицы mangle
- просматривается цепочка POSTROUTING таблицы nat (используется для SNAT,
фильтровать здесь не стоит)
Реальная последовательность обработки проходящего пакета (от п.3 первой процедуры):
- просматривается цепочка FORWARD таблицы mangle
- просматривается цепочка FORWARD таблицы filter
- повторная маршрутизация, т.к. в таблице mangle пакет мог быть изменён;
если пакет маршрутизируется внутрь, то переходим к первой процедуре (п. 1 или 4?)
- просматривается цепочка POSTROUTING таблицы mangle
- просматривается цепочка POSTROUTING таблицы nat (используется для SNAT и Masquerading,
фильтровать здесь не стоит)
Текст и иллюстрации документации netfilter имеют множество разночтений,
оставляя свободу воли (то ли пакетов, то ли разработчиков ;). Автор iptables-tutorial
рекомендует использовать тестовый набор правил, записывающий в журнал имя каждой пройденной
пакетом цепочки и таблицы.
netfilter отслеживает соединения с помощью модуля ip_conntrack
(имеет параметр hashsize, задающий размер хеша) и протоколозависимых модулей
(icmp, tcp, ftp, tftp, irc, amanda, sctp)
при обработке цепочки PREROUTING таблицы nat
(для локально сгенерированных пакетов при обработке цепочки OUTPUT)
и хранит их в специальной таблице.
При этом все пакеты обязательно дефрагментируется.
Соединения удаляются из таблицы по истечению интервала ожидания при отсутствии очередного пакета.
При выгрузке модуля (см. IPTABLES_MODULES_UNLOAD в /etc/sysconfig/iptables-config)
таблица соединений очищается.
Рассматриваемый пакет может находиться с точки зрения настройки (у ядра своя таблица состояний)
в одном из 4 состояний относительно ранее отслеженных соединений:
- NEW (замечен первый пакет в соединении; обычно это пакет с флагом SYN, но может быть
и без него: в результате удаления из таблицы по истечению периода ожидания
ранее установленного соединения или балансировки нагрузки по нескольким сетевым экранам;
однако, см. ниже /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_loose)
- ESTABLISHED (после получения ответного пакета соединение переходит в это состояние
из состояния NEW или RELATED; в частности, второй пакет при установлении TCP-соединения (SYN/ACK)
уже находится в состоянии ESTABLISHED; для ICMP: Echo, Timestamp, Information, Address mask;
[ответы ICMP также могут иметь это состояние, если они являются
результатом посланного нами пакета?])
- RELATED (соединение, порождённое соединением в состоянии ESTABLISHED, например,
передача ftp данных, порождённая управляющим ftp соединением, или DCC для IRC
или ICMP сообщение об ошибке; требуется протоколозависимый модуль)
- INVALID (классифицировать пакет не удалось; например, ICMP ответ на несуществующий пакет;
такие пакеты рекомендуется выбрасывать)
Пакет в состоянии NEW с точки зрения conntrack
может быть продолжением реального соединения (т.е. не иметь бита SYN), например,
в результате изменения цепочек, загрузки модуля и т.д.. В любом случае, при "отлове"
подозрительных соединений необходимо предусмотреть сброс попыток соединений,
в которых мошенниками подставлен наш адрес:
-A INPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP
Максимально возможное число отслеживаемых соединений
задаётся в файле /proc/sys/net/ipv4/ip_conntrack_max (/proc/sys/net/nf_conntrack_max)
(каждое соединение занимает 350 байт невытесняемой памяти).
Набор заплаток tcp-window-tracking для ядра 2.4 (входит в ядро 2.6) обеспечивает возможность
задать значения по умолчанию для интервалов ожидания при удалении записи о соединении из таблицы
для различных ситуаций в /proc/sys/net/ipv4/netfilter/ip_conntrack_*_timeout* (/proc/sys/net/netfilter/ip_conntrack_*_timeout*) (в секундах).
Мне пришлось (давно было) записать 600 в ip_conntrack_tcp_timeout_close[_wait] по всей цепочке, иначе
завершение соединения блокировалось (FIN/ACK от клиента или RST от сервера),
часть завершающих пакетов всё равно "режется" (клиент закрывает полузакрытый сокет только
когда ему требуется следующее соединения, а запись о соединении из таблицы conntrack уже удалена,
а увеличивать ip_conntrack_tcp_timeout_close до суток не хочется).
Также позволяет "порулить" поведением машины состояний через переменные (/proc/sys/net/ipv4/netfilter/):
- ip_conntrack_tcp_be_liberal (/proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal)
- все пакеты, не попадающие в окно, считаются INVALID
- только RST пакеты, не попадающие в окно, считаются INVALID (пришлось поставить)
- ip_conntrack_log_invalid (выводить в журнал INVALID пакеты) (/proc/sys/net/netfilter/nf_conntrack_log_invalid)
- ip_conntrack_tcp_loose (при "подхватывании" уже установленного
соединения сколько пакетов требуется в обоих направлениях для подтверждения;
если 0, то установленное соединение не подхватывается вовсе; по умолчанию - 3)
- ip_conntrack_max_retrans (число повторных пакетов без подтверждения ACK, которое
требуется для удаления соединения из таблицы после дополнительного
ожидания ip_conntrack_timeout_max_retrans секунд; по умолчанию - 3)
Таблицу текущих соединений можно посмотреть в файле /proc/net/ip_conntrack (/proc/net/nf_conntrack)
- тип протокола
- номер протокола
- осталось секунд до удаления этого соединения из таблицы
- [состояние-соединения-в-терминах-ядра]
- исходящий адрес
- адрес назначения
- исходящий порт или ICMP-тип
- порт назначения или ICMP-код
- [ICMP-идентификатор]
- [UNREPLIED] (соединение в состоянии ESTABLISHED, но ждёт подтверждения от прпотоколозависимого
модуля, например, это был второй пакет при установлении TCP-соединения)
- ожидаемые адреса и порты (ICMP-тип и код) ответного пакета
- [ASSURED] (соединение перешло в состояние ESTABLISHED и протоколозависимый модуль подтвердил
наличие соединения, например, завершён третий этап установления TCP-соединения)
- use=1 (?)
Управление цепочками производится с помощью программы iptables.
После загрузки определены цепочки (все с политикой ACCEPT) INPUT, FORWARD и OUTPUT в таблице filter;
PREROUTING, POSTROUTING и OUTPUT в таблице nat;
PREROUTING, INPUT, FORWARD, OUTPUT и POSTROUTING в таблице mangle. Удалить их нельзя.
Формат команды:
iptables [-t имя-таблицы] команда [шаблон] [-j действие]
Команды:
- -A имя-цепочки правило (добавить правило в конец цепочки;
ключ --set-counters позволяет установить счётчики пакетов и байтов)
- -I имя-цепочки номер правило (вставить
правило в цепочку перед правилом с указанным номером, нумерация с 1;
ключ --set-counters позволяет установить счётчики пакетов и байтов)
- -R имя-цепочки номер правило (заменить;
ключ --set-counters позволяет установить счётчики пакетов и байтов)
- -D имя-цепочки номер (удалить правило с указанным
номером, нумерация с 1)
- -D имя-цепочки правило (удалить правило по текстуальному совпадению)
- -C имя-цепочки пакет (тестировать прохождение пакета;
исходящий адрес, адрес назначения, протокол, интерфейс, порты задаются соответствующими
ключами)
- -L [имя-цепочки] (показать список правил; дополнительные ключи:
- -n (не преобразовывать адреса в имена)
- -v (вывести дополнительную информацию, в частности, счётчики)
- --exact (показывать счётчики без округления до KB, MB и т.д.)
- --numeric (показывать адреса и номера портов в виде чисел)
- --line-numbers (выводить номера правил)
- -F имя-цепочки (удалить все правила из цепочки)
- -Z имя-цепочки (обнулить счетчики)
- -N имя-цепочки (создать цепочку)
- -X имя-цепочки (удалить пустую цепочку, на которую нет ссылок)
- -P имя-цепочки действие (изменить действие по умолчанию: ACCEPT,
DROP, QUEUE, RETURN)
- -E старое-имя-цепочки новое-имя-цепочки (переименовать цепочку)
Действия (действие в недопустимом месте эквивалентно DROP), при завершении
просмотра текущей цепочки, производится просмотр следующих по порядку таблиц:
- ACCEPT - пропустить пакет; просмотр таблицы завершается
- DROP - выбросить молча; просмотр завершается не только для текущей цепочки,
но и для других таблиц
- REJECT - выбросить, известив отправителя (--reject-with тип-извещения);
типы извещения: tcp-reset (только для TCP!), icmp-net-unreachable, icmp-host-unreachable,
icmp-port-unreachable (по умолчанию), icmp-proto-unreachable, icmp-net-prohibited
или icmp-host-prohibited;
для цепочек INPUT, FORWARD и OUTPUT;
просмотр завершается не только для текущей цепочки, но и для других таблиц
- LOG - записать в журнал syslog;
приоритет по умолчанию - warning (--log-level приоритет);
источник всегда - kern;
каждая запись содержит имена входного (IN=) и выходного (OUT=) интерфейсов,
MAC адреса (MAC=), исходный IP-адрес (SRC=), IP-адрес назначения (DST=), длину пакета,
флаги и указатели TCP (SYN, URGP=, WINDOW=), ToS (TOS=), ? (PREC=), TTL (TTL=), флаги IP (DF),
идентификатор (ID=), протокол (PROTO=), порты источника (SPT=) и назначения (DPT=), ? (RES=);
в начале записи можно вставить свою строку длиной до 29 символов
(--log-prefix "строка" - позволяет rsyslog фильтровать эти сообщения в отдельный файл);
можно добавить в журнал номера TCP-последовательностей (--log-tcp-sequence),
TCP опции (--log-tcp-options) и IP опции (--log-ip-options)
- ULOG - записать в собственный журнал (используется интерфейс netlink и групповая рассылка;
позволяет делать такие вещи, как запись журнала в MySQL, обработка в реальном времени
и т.д. (см. проект ULOGD);
параметры: --ulog-nlgroup netlink-группа, --ulog-prefix "строка", --ulog-cprange длина,
--ulog-qthreshold пакетов-в-группе
- имя пользовательской цепочки - происходит переход на выполнение подпрограммы
(пользовательской цепочки), по завершении её выполняется следующее правило, если в подпрограмме
не было выполнено какое завершающее просмотр действие (ACCEPT, DROP, REJECT)
- RETURN - завершение просмотра текущей цепочки; если это была пользовательская цепочка,
то происходит возврат к месту вызова; для базовой цепочки производится действие по умолчанию
- QUEUE - поставить пакет в очередь на обработку пользовательской программой
(см. Netfilter Hacking HOW-TO)
- действия только для таблицы nat:
- DNAT - подмена в пакете адреса назначения;
проверка производится только для первого пакета соединения (цепочка PREROUTING или OUTPUT),
остальные пакеты преобразуются "по аналогии"; ответные пакеты преобразуются соответственно;
новый адрес назначения (или адреса для балансировки нагрузки) задаётся параметром
--to-destination IP-адрес[:порт][-IP-адрес];
используется для "проброса" соединения из интернет на сервер, находящийся внутри;
чтобы к такому серверу можно было обратиться изнутри сети по внешнему адресу,
необходимо в дополнение к DNAT преобразовать исходный адрес (SNAT),
иначе ответы сервера пойдут клиенту напрямую минуя обратное преобразование DNAT,
а клиент их не примет;
к сожалению, при этом в журнал сервера не попадут реальные IP адреса клиентов;
также при этом легко получить open relay из своего SMTP сервера;
поэтому SNAT необходимо ограничить локальными исходящими адресами;
проблему можно решить, сделав отдельный DNS сервер для локальной сети;
и не забудьте добавить аналогичное (DNAT) правило в цепочку OUTPUT для доступа к серверу
с самого сетевого экрана (если это необходимо) и правила в таблицу filter
- SNAT - подменить в пакете исходящий адрес на указанный или из указанного интервала,
при необходимости исходящий номер порта на случайный номер своего порта из заданного интервала,
занести эту информацию в таблицу, чтобы при получении ответа было можно проделать обратную операцию;
новый исходящий адрес (или адреса для балансировки нагрузки) задаётся параметром
--to-source IP-адрес[-IP-адрес][:порт-порт];
проверка производится только для первого пакета соединения (цепочка POSTROUTING),
остальные пакеты преобразуются "по аналогии"; ответные пакеты преобразуются соответственно;
используется для скрытия структуры внутренней сети при выходе пользователей в интернет
или при нехватке общемаршрутизируемых IP-адресов;
если свой IP-адрес получается динамически, то лучше воспользоваться MASQUERADE;
- MASQUERADE - подменить в пакете исходящий адрес на адрес своего исходящего интерфейса
(этот адрес может выделяться динамически по DHCP или PPP),
при необходимости исходящий номер порта на случайный номер своего порта из заданного интервала,
занести эту информацию в таблицу, чтобы при получении ответа было можно проделать обратную операцию;
интервал портов задаётся параметром --to-ports порт-порт;
проверка производится только для первого пакета соединения (цепочка POSTROUTING),
остальные пакеты преобразуются "по аналогии"; ответные пакеты преобразуются соответственно;
таблица очищается при отключении интерфейса;
используется для скрытия структуры внутренней сети при выходе пользователей в интернет
или при нехватке общемаршрутизируемых IP-адресов при динамическом получении внешнего
IP-адреса; более общее средство - см. SNAT
- REDIRECT - подмена в пакете номера порта назначения на указанный порт,
адрес назначения на свой адрес (?); локальные пакеты перенаправляются на адрес 127.0.0.1;
проверка производится только для первого пакета соединения (цепочка PREROUTING или OUTPUT),
остальные пакеты преобразуются "по аналогии"; ответные пакеты преобразуются соответственно;
новый порт (интервал портов?) назначения задаётся параметром
--to-ports порт-порт;
используется для организации прозрачного прокси
- MIRROR - удалён в ядре 2.6 (меняет местами исходящий IP адрес и IP адрес назначения;
предполагалось удивить хакеров)
- действия только для таблицы mangle:
- CLASSIFY - установка маркера классификации при управлении трафиком (tc, qdiscs),
цепочка POSTROUTING (--set-class MAJOR:MINOR)
- TOS - установка или изменение полей TOS (--set-tos тип-сервиса);
типы сервиса: Normal-Service, Minimize-Cost,
Maximize-Reliability, Maximize-Throughput, Minimize-Delay;
только в цепочках FORWARD и OUTPUT;
используется при маршрутизации
- DSCP - установка или изменение полей Differentiated Services, развитие ToS
(--set-dscp число или --set-dscp-class класс)
- ECN - сброс полей ECN (--ecn-tcp-remove)
- TTL - изменение TTL (--ttl-set число; --ttl-dec число;
--ttl-inc число); можно использовать увеличение на 1 в дополнение к NAT,
чтобы скрыть наличие сетевого экрана, или установку в одно и то же значение,
чтобы скрыть внутреннюю структуру сети
- TCPMSS - изменение размера TCP сегмента (Maximum Segment Size) явно
(--set-mss байт) или с привязкой к размеру MTU (--clamp-mss-to-pmtu
устанавливает MSS равным Path MTU - 40);
только в момент установления соединения (т.е. у пакета д.б. установлен флаг SYN);
особенно полезен, если ISP блокирует сообщения ICMP о необходимости фрагментации,
а в результате при пересылке маленьких блоков (ssh) всё работает, а когда доходит
до больших блоков (scp), то соединение "подвисает"
- MARK - устанавливается маркер данного пакета (--set-mark число);
сохраняется только в пределах хоста;
используется при маршрутизации
- NETMAP - адреса из указанной исходящей сети преобразуются в новые указанные адреса (--to);
номера хостов внутри сети не изменяются; используется вместо перенумерации сети;
использовать в цепочке PREROUTING;
аналогичный результат (но более эффективно) можно получить с помощью
iproute2
- SAME - адреса из указанной исходящей сети преобразуются в новые указанные адреса (--to);
номер хоста изменяется (интервал новых IP-адресов меньше исходного), но только при необходимости;
использовать в цепочке PREROUTING
- имя цепочки, определяемой модулем расширения
- пустое действие - только увеличить счетчики байтов и пакетов и перейти к следующему
правилу в цепочке, счетчики - 64-битные
Шаблон правила может включать (если в качестве адреса хоста указывается
имя, соответствующее нескольким адресам, то добавляется соответствующее
количество правил; восклицательный знак инвертирует шаблон; несколько подшаблонов действуют как "И"):
- --proto[col] | -p [!] протокол
(можно указывать имя протокола (см. /etc/protocols) или номер протокола; имя протокола ALL
означает tcp или udp или icmp)
- --source | -s | --src [!] address[/mask]
(маска может быть записана как в виде 4-х десятичных чисел через точку, так и указанием длины
маски сети)
- --destination | -d | --dst [!] address[/mask]
- --in-interface | -i [!] имя[+] (имя входного интерфейса;
например, ppp0, lo, eth0; шаблон "+" - соответствует любой подстроке;
можно использовать только в цепочках INPUT, FORWARD и PREROUTING)
- --out-interface | -o [!] имя[+] (имя выходного интерфейса;
например, ppp0, lo, eth0; шаблон "+" - соответствует любой подстроке;
можно использовать только в цепочках OUTPUT, FORWARD и POSTROUTING)
- [!] --fragment | -f (только для последующих кусков
фрагментированных пакетов; при использовании отслеживания соединений все пакеты
дефрагментируются при обработке цепочки PREROUTING таблицы nat)
- --match | -m имя-модуля-расширения (модули tcp, udp и icmp
приводятся в действие неявно, при использовании шаблона --protocol)
Параметры модуля расширения tcp
- --source-port [!] [port[:port]]
(можно использовать номера портов или имена сервисов из /etc/services;
если опустить первый порт интервала, то подразумевается 0;
если опустить последний порт интервала, то подразумевается 65535)
- --destination-port [!] [port[:port]]
- --tcp-flags [!] маска-флагов обязательные-флаги
(маска-флагов - список через запятую проверяемых флагов (SYN, ACK, FIN, RST, URG, PSH, ALL, NONE);
обязательные-флаги - список через запятую флагов, которые д.б. установлены в пакете;
остальные флаги из числа проверяемых должны быть сброшены)
- [!] --syn | -y (пакеты с установленным флагом SYN,
эквивалент записи "--tcp-flags SYN,RST,ACK SYN"; отрицание обеспечивает соответствие
пакетов, не имеющих флагов SYN и ACK одновременно)
- [!] --tcp-option номер-опции
Параметры модуля расширения udp
- --source-port [!] [port[:port]]
- --destination-port [!] [port[:port]]
Параметры модуля расширения icmp
- --icmp-type [!] тип-сообщения[/код]
(можно использовать номера или имена типов и кодов: 8, 8/0, network-redirect;
чтобы получить список допустимых имён, выполните команду: iptables -p icmp --help)
Параметры модуля расширения mac
- --mac-source [!] MAC-адрес (только в цепочках PREROUTING, FORWARD
и INPUT)
Параметры модуля расширения mark
- --mark [!] число (маркер пакета (число без знака) устанавливается
действием MARK, только в пределах данного хоста)
Параметры модуля расширения limit
(защита от DoS атак или ограничение записей в журнал; используется модель дырявого ведра:
задаётся объём ведра и скорость его самоопустошения,
шаблону соответствуют пакеты, помещающиеся в ведро):
- [!] --limit штук/единица-времени
(задаёт скорость самоопустошения ведра;
допустимы следующие единицы времени: second, minute, hour, day)
- --limit-burst штук (задаёт ёмкость ведра)
Параметры модуля расширения iprange (задание интервалов IP-адресов)
- [!] --src-range начальныйIPадрес-конечныйIPадрес
- [!] --dst-range начальныйIPадрес-конечныйIPадрес
Параметры модуля расширения multiport (список портов, до 15 портов)
- --source-port список,портов,через,запятую
- --destination-port список,портов,через,запятую
- --port список,портов,через,запятую (из порта в порт с тем же номером)
Параметры модуля расширения length (длина пакета)
Параметры модуля расширения owner (только в цепочке OUTPUT, не всегда срабатывает)
- --uid-owner uid
- --gid-owner gid
- --pid-owner pid
- --sid-owner session-id
Параметры модуля расширения pkttype
- --pkt-type [!] {unicast | broadcast | multicast}
Параметры модуля расширения recent (динамическая генерация правил по событию;
ведётся несколько именованных списков событий, для каждого события записывается время,
исходящий адрес, исходящий порт, число пакетов, TTL)
- --name имя (какой список использовать)
- [!] --set (добавить событие в список)
- [!] --rcheck (проверить, что исходящий адрес данного пакета имеется в списке
событий)
- [!] --update (проверить, что исходящий адрес данного пакета имеется в списке
событий и обновить время)
- [!] --remove (проверить, что исходящий адрес данного пакета имеется в списке
событий и удалить)
- --seconds секунд (только в сочетании с --rcheck или --update; какой интервал
времени допустим)
- [!] --hitcount штук (только в сочетании с --rcheck или --update;
можно в сочетании с --seconds; соответствие после указанного числа пакетов)
- [!] --rttl (дополнительно проверить, что TTL такой же)
- --rdest (сохранить в списке адрес и порт назначения)
Параметры модуля расширения state (состояние соединения согласно conntrack):
- --state перечень,состояний,через,запятую (состояния:
INVALID, ESTABLISHED, NEW, RELATED)
Параметры модуля расширения conntrack (расширение возможностей модуля state):
- [!] --ctstate список,состояний,соединения (допустимо использовать
имена состояний: INVALID, ESTABLISED, NEW, RELATED, SNAT, DNAT)
- [!] --ctstatus список,внутренних,состояний,соединения (допустимо использовать
имена внутренних состояний: NONE, EXPECTED, SEEN_REPLY, ASSURED
- [!] --ctproto протокол
(можно указывать имя протокола (см. /etc/protocols) или номер протокола)
- --ctorigsrc [!] address[/mask]
(проверка исходящего адреса до преобразования)
- --ctorigdst [!] address[/mask]
(проверка адреса назначения до преобразования)
- --ctreplsrc [!] address[/mask]
(проверка исходящего адреса предполагаемого ответа)
- --ctrepldst [!] address[/mask]
(проверка адреса назначения предполагаемого ответа)
Параметры модуля расширения helper (протоколозависимый модуль отслеживания
соединений):
- --helper имя_модуля_расширения_conntrack[-номер-порта]
Параметры модуля расширения tos (также имеются модуля dscp, ecn)
- --tos [!] тип-сервиса (Normal-Service, Minimize-Cost,
Maximize-Reliability, Maximize-Throughput, Minimize-Delay; это только названия!)
Параметры модуля расширения tcpmss (Maximum Segment Size in TCP, только для
пакетов с SYN или SYN/ACK)
Параметры модуля расширения ttl
Модуль расширения unclean не имеет параметров. Позволяет отлавливать
"неправильные" пакеты.
Параметры модуля расширения ah (IPSec, необходимо также указать номер протокола 51)
- --ahspi Security-Parameter-Index
Параметры модуля расширения esp (IPSec, необходимо также указать номер протокола 50)
- --espspi Security-Parameter-Index
Тщательно составленные и отлаженные цепочки необходимо
сохранять с помощью утилиты iptables-save, выводит на stdout, параметры:
- -c (выводить счётчики)
- -t имя-таблицы (выводить только указанную таблицу)
Вывод утилиты имеет простой текстовый формат, допускающий редактирование.
Комментарии начинаются с символа '#'.
Таблицы выводятся по очереди, перед каждой таблицей в отдельной строке выводится имя таблицы
после символа '*', затем перечисляются имеющиеся в таблице цепочки, каждое имя цепочки
выводится в отдельной строке после символа ':', после имени выводится политика цепочки
и счётчики, затем выводятся все правила таблицы, каждое правило выводится отдельной строкой,
в конце таблицы выводится ключевое слово "COMMIT".
Правила выводятся в формате утилиты iptables, только не указывается имя таблицы.
Сохранённые ранее цепочки можно загрузить в ядро с помощью утилиты
iptables-restore (читает с stdin,
по умолчанию восстанавливаемые таблицы сбрасываются, параметры):
- -c (восстанавливать счётчики)
- -n (не сбрасывать восстанавливаемые таблицы)
В дистрибутивах Red Hat Linux имеется сервис iptables
(управляемый обычными chkconfig и service)
в /etc/rc.d/init.d с функциями:
- start (настройки берутся из /etc/sysconfig/iptables - делаются
либо с помощью функции save, либо iptables-save)
- stop
- restart
- status
- save (сохранить текущие настройки в /etc/sysconfig/iptables)
- panic (полная блокировка, использовать в случае атаки)
При настройке правил на удалённом хосте рекомендуется оставлять себе пути
отступления, например, перед внесением изменений добавить в crontab строку, возвращающую
настройки обратно, если что-то пойдёт не так (/sbin/service iptables stop).
Часто используемые правила должны быть в начале цепочки.
Для дальнейшей оптимизации цепочка разбивается на подцепочки (например, по типу протокола).
Пример настройки рабочей станции или небольшого внутреннего сервера:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:icmp_packets - [0:0]
# ICMP (other types covered by RELATED)
-A icmp_packets -p icmp --icmp-type 8 -j ACCEPT
-A icmp_packets -p icmp --icmp-type 11 -j ACCEPT
# replies
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#
-A INPUT -p icmp -j icmp_packets
-A INPUT -i lo -j ACCEPT
# CUPS server
#-A INPUT -i eth0 -p udp -m udp --dport 631 -j ACCEPT
# SSH server
-A INPUT -i eth0 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
# to prevent mass logging
-A INPUT -i eth0 -p udp -d широковещательный-адрес --sport 137:139 --dport 137:139 -j DROP
-A INPUT -i eth0 -p udp -d 255.255.255.255 --dport 445 -j DROP
-A INPUT -j LOG
#
-A OUTPUT -p ALL -s 127.0.0.1 -j ACCEPT
-A OUTPUT -p ALL -s свой-адрес -j ACCEPT
-A OUTPUT -j LOG
COMMIT
Пример настройки маршрутизатора между отделами (eth0 - DMZ)
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:icmp_packets - [0:0]
#
# output anything
#
-A OUTPUT -p ALL -s 127.0.0.1 -j ACCEPT
-A OUTPUT -p ALL -s 192.168.0.6 -j ACCEPT
-A OUTPUT -p ALL -s 192.168.1.6 -j ACCEPT
-A OUTPUT -p ALL -s 192.168.2.6 -j ACCEPT
...
-A OUTPUT -j LOG
#
# ICMP (other types covered by RELATED)
#
-A icmp_packets -p icmp --icmp-type 8 -j ACCEPT
-A icmp_packets -p icmp --icmp-type 11 -j ACCEPT
#
# input
#
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j icmp_packets
-A INPUT -i lo -j ACCEPT
# SSH
-A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT
# to prevent mass logging
-A INPUT -p udp -d 192.168.1.255 --sport 137:139 --dport 137:139 -j DROP
...
-A INPUT -p udp -d 255.255.255.255 --dport 445 -j DROP
-A INPUT -p udp -d 255.255.255.255 --sport 68 --dport 67 -j DROP
-A INPUT -j LOG
#
# forward
#
-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -p icmp -j icmp_packets
-A FORWARD -i lo -j ACCEPT
# SSH выборочно
-A FORWARD -i ethX -p tcp -s откуда --dport 22 -d куда -j ACCEPT
...
# общий syslog
-A FORWARD -i ethX -p udp --dport 514 -d адрес-сервера -j ACCEPT
...
# главный NTP сервер и сервера отделов
-A FORWARD -i ethX -p udp -s NTP-сервер-отдела -d главный-NTP-сервер --dport 123 -j ACCEPT
...
# нормальный DNS не для всех отделов
-A FORWARD -i eth1 -p udp -m udp -d внешний-DNS-сервер --dport 53 -j ACCEPT
-A FORWARD -i eth2 -p udp -m udp --dport 53 -j DROP
...
# SMTP
-A FORWARD -i eth0 -p tcp -d SMTP-сервер-отдела --dport 25 -j ACCEPT
-A FORWARD -i eth1 -p tcp -d внешний-SMTP-сервер --dport 25 -j ACCEPT
...
# LMTP/POP/IMAP
-A FORWARD -i eth0 -p tcp -d IMAP-сервер --dport 24 -j ACCEPT
-A FORWARD -i eth1 -m multiport -p tcp -d IMAP-сервер --dport 110,143,993,995 -j ACCEPT
...
# этот отдел имеет почти полноценный доступ в интернет
-A FORWARD -i eth1 -o eth0 -p tcp -j ACCEPT
# а этот только через прокси
-A FORWARD -i eth2 -p tcp -d прокси-сервер --dport 3128 -j ACCEPT
# доступ к webdav серверу с удалённой точки (HTTPS, т.к. внешний канал)
-A FORWARD -i eth5 -s внешняя-сеть -p tcp -d сервер --dport 443 -j ACCEPT
# to prevent mass logging
-A FORWARD -i eth1 -p udp -d 192.168.1.255 --sport 137:139 --dport 137:139 -j DROP
-A FORWARD -i eth1 -p udp -d 255.255.255.255 --dport 445 -j DROP
-A FORWARD -i eth1 -p udp -d 255.255.255.255 --sport 68 --dport 67 -j DROP
-A FORWARD -i eth1 -p udp -d 255.255.255.255 --sport 67 --dport 68 -j DROP
...
-A FORWARD -m state --state NEW -j LOG --log-prefix "NEW "
-A FORWARD -m state --state INVALID -j LOG --log-prefix "INVALID "
-A FORWARD -m state --state ESTABLISHED -j LOG --log-prefix "ESTABLISHED "
-A FORWARD -m state --state RELATED -j LOG --log-prefix "RELATED "
COMMIT
*mangle
:FORWARD ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# доступ к webdav серверу с удалённой точки (HTTPS, т.к. внешний канал)
-A PREROUTING -i eth5 -p tcp -s внешняя-сеть -d 192.168.5.6 --dport 443 -j DNAT --to-destination сервер:443
Пример настройки входного маршрутизатора (eth0 - DMZ, eth1 и eth2 - внешние каналы)
*filter
:FORWARD DROP [0:0]
:INPUT DROP [0:0]
:OUTPUT DROP [0:0]
:icmp_packets - [0:0]
#
# output anything
#
-A OUTPUT -p ALL -s 127.0.0.1 -j ACCEPT
-A OUTPUT -p ALL -s 192.168.0.2 -j ACCEPT
-A OUTPUT -p ALL -s внешний-адрес-1 -j ACCEPT
-A OUTPUT -p ALL -s внешний-адрес-2 -j ACCEPT
-A OUTPUT -j LOG
#
# ICMP (other types covered by RELATED)
#
-A icmp_packets -p icmp --icmp-type 8 -j ACCEPT
-A icmp_packets -p icmp --icmp-type 11 -j ACCEPT
#
#
# input
#
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j icmp_packets
-A INPUT -i lo -j ACCEPT
# SSH изнутри
-A INPUT -i eth0 -m state --state NEW -p tcp --dport 22 -j ACCEPT
# SSH из головной организации
-A INPUT -m state --state NEW -p tcp -s адрес --dport 22 -j ACCEPT
# our DNS
-A INPUT -p udp -i eth0 -d 192.168.0.2 --dport 53 -j ACCEPT
-A INPUT -p tcp -i eth0 -d 192.168.0.2 --dport 53 -j ACCEPT
-A INPUT -p udp -i eth1 -d внешний-адрес-1 --dport 53 -j ACCEPT
-A INPUT -p tcp -i eth1 -d внешний-адрес-1 --dport 53 -j ACCEPT
...
# smtp
-A INPUT -p tcp -i eth0 -d 192.168.0.2 --dport 25 -j ACCEPT
-A INPUT -p tcp -i eth1 -d внешний-адрес-1 --dport 25 -j ACCEPT
-A INPUT -p tcp -i eth2 -d внешний-адрес-2 --dport 25 -j ACCEPT
# to prevent mass logging
-A INPUT -p tcp -i eth2 --dport 445 -j DROP
-A INPUT -j LOG
#
# forward
#
-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -p icmp -j icmp_packets
# www сервер в DMZ, но виден снаружи как внешний-адрес-1
-A FORWARD -i eth0 -p tcp -d адрес-сервера --dport 80 -j ACCEPT
-A FORWARD -i eth1 -p tcp -d адрес-сервера --dport 80 -j ACCEPT
# выход прокси сервера наружу
-A FORWARD -i eth0 -s адрес-прокси -m state --state NEW -j ACCEPT
# to prevent mass logging
-A FORWARD -i eth1 -p tcp -d внешний-адрес-1 --dport 445 -j DROP
-A FORWARD -j LOG
COMMIT
#
*mangle
:FORWARD ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
#
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# доступ к www серверу изнутри (через прокси)
-A PREROUTING -i eth0 -p tcp -d внешний-адрес-1 --dport 80 -j DNAT --to-destination адрес-сервера:80
# доступ к www серверу снаружи
-A PREROUTING -i eth1 -p tcp -d внешний-адрес-1 --dport 80 -j DNAT --to-destination адрес-сервера:80
# адрес преобразуется, чтобы пакет вернулся тем же маршрутом
-A POSTROUTING -s прокси-сервер -p tcp -d адрес-сервера --dport 80 -j SNAT --to-source 192.168.0.2
# NAT
-A POSTROUTING -o eth1 -j SNAT --to-source внешний-адрес-1
...
Управление цепочками производится с помощью программы arptables (пакет arptables_jf или arptables).
После загрузки определены цепочки (все с политикой ACCEPT) IN, FORWARD и OUT в таблице filter
(модуль arptable_filter). Удалить их нельзя. Формат команды:
arptables [-t имя-таблицы] команда [шаблон] [-j действие]
Команды:
- -A имя-цепочки правило (добавить правило в конец цепочки;
ключ --set-counters позволяет установить счётчики пакетов и байтов)
- -I имя-цепочки номер правило (вставить
правило в цепочку перед правилом с указанным номером, нумерация с 1;
ключ --set-counters позволяет установить счётчики пакетов и байтов)
- -R имя-цепочки номер правило (заменить;
ключ --set-counters позволяет установить счётчики пакетов и байтов)
- -D имя-цепочки номер (удалить правило с указанным
номером, нумерация с 1)
- -D имя-цепочки правило (удалить правило по текстуальному совпадению)
- -L[Z] [имя-цепочки] (показать список правил; дополнительные ключи:
- -n (не преобразовывать адреса в имена)
- -v (вывести дополнительную информацию, в частности, счётчики)
- --exact (показывать счётчики без округления до KB, MB и т.д.)
- --numeric (показывать адреса и номера портов в виде чисел)
- --line-numbers (выводить номера правил)
- -F имя-цепочки (удалить все правила из цепочки)
- -Z имя-цепочки (обнулить счетчики)
- -N имя-цепочки (создать цепочку)
- -X имя-цепочки (удалить пустую цепочку, на которую нет ссылок)
- -P имя-цепочки действие (изменить действие по умолчанию: ACCEPT,
DROP, QUEUE, RETURN)
- -E старое-имя-цепочки новое-имя-цепочки (переименовать цепочку)
Действия (действие в недопустимом месте эквивалентно DROP), при завершении
просмотра текущей цепочки, производится просмотр следующих по порядку таблиц:
- ACCEPT - пропустить пакет; просмотр таблицы завершается
- DROP - выбросить молча; просмотр завершается не только для текущей цепочки,
но и для других таблиц
- имя пользовательской цепочки - происходит переход на выполнение подпрограммы
(пользовательской цепочки), по завершении её выполняется следующее правило, если в подпрограмме
не было выполнено какое завершающее просмотр действие (ACCEPT, DROP)
- RETURN - завершение просмотра текущей цепочки; если это была пользовательская цепочка,
то происходит возврат к месту вызова; для базовой цепочки производится действие по умолчанию
- QUEUE - поставить пакет в очередь на обработку пользовательской программой
(см. Netfilter Hacking HOW-TO)
- пустое действие - только увеличить счетчики байтов и пакетов и перейти к следующему
правилу в цепочке, счетчики - 64-битные
Шаблон правила может включать (если в качестве адреса хоста указывается
имя, соответствующее нескольким адресам, то добавляется соответствующее
количество правил; восклицательный знак инвертирует шаблон; несколько подшаблонов действуют как "И"):
- --source | --src [!] address[/mask]
(маска может быть записана как в виде 4-х десятичных чисел через точку, так и указанием длины
маски сети)
- --destination | --dst [!] address[/mask]
- --source-hw | --source-mac | -z [!] address[mask]
(адрес и маска записываются в виде последовательности шестнадцатеричных чисел через двоеточие)
- --target-hw | --target-mac | -y [!] address[mask]
(адрес и маска записываются в виде последовательности шестнадцатеричных чисел через двоеточие)
- --in-interface | -i [!] имя[+] (имя входного интерфейса;
например, ppp0, lo, eth0; шаблон "+" - соответствует любой подстроке;
можно использовать только в цепочках IN, FORWARD)
- --out-interface | -o [!] имя[+] (имя выходного интерфейса;
например, ppp0, lo, eth0; шаблон "+" - соответствует любой подстроке;
можно использовать только в цепочках OUTPUT, FORWARD)
- --arhln | -a [!] длина[mask]
(задать размер аппаратного адреса, шестнадцатеричное число)
- --arpop | -p [!] операция[mask]
(задать ARP операцию, шестнадцатеричное число или имя (Request, Reply, Request_Reverse,
Reply_Reverse, DRARP_Request, DRARP_Reply, DRARP_Error, InARP_Request, ARP_NAK))
- --arhrd | -H [!] тип[mask]
(задать тип оборудования, шестнадцатеричное число или имя (Ethernet))
- --arpro | -w [!] протокол[mask]
(задать протокол, шестнадцатеричное число или имя (IPV4))
Имеется модуль mangle, который позволяет изменить IP и MAC адреса
отправителя и получателя. Действия: DROP, CONTINUE и ACCEPT.
Тщательно составленные и отлаженные цепочки необходимо
сохранять с помощью утилиты arptables-save, выводит на stdout, параметры
(отсутствуют в новом пакете arptables)):
- -c (выводить счётчики)
- -t имя-таблицы (выводить только указанную таблицу)
Вывод утилиты имеет простой текстовый формат, допускающий редактирование.
Комментарии начинаются с символа '#'.
Таблицы выводятся по очереди, перед каждой таблицей в отдельной строке выводится имя таблицы
после символа '*', затем перечисляются имеющиеся в таблице цепочки, каждое имя цепочки
выводится в отдельной строке после символа ':', после имени выводится политика цепочки
и счётчики, затем выводятся все правила таблицы, каждое правило выводится отдельной строкой,
в конце таблицы выводится ключевое слово "COMMIT" (отсутствуют в новом пакете arptables).
Правила выводятся в формате утилиты arptables, только не указывается имя таблицы.
В новом пакете arptables имена таблиц фиксированы: INPUT, OUTPUT, FORWARD.
Сохранённые ранее цепочки можно загрузить в ядро с помощью утилиты
arptables-restore (читает с stdin,
по умолчанию восстанавливаемые таблицы сбрасываются, параметры (отсутствуют в новом пакете arptables):
- -c (восстанавливать счётчики)
- -n (не сбрасывать восстанавливаемые таблицы)
В дистрибутивах Red Hat Linux имеется сервис arptables_jf
(управляемый обычными chkconfig и service)
в /etc/rc.d/init.d с функциями:
- start (настройки берутся из /etc/sysconfig/arptables - делаются
либо с помощью функции save, либо arptables-save)
- stop
- restart
- status
- save (сохранить текущие настройки в /etc/sysconfig/arptables)
- panic (полная блокировка, использовать в случае атаки)
Например, для "полной развязки" интерфейсов необходимо задать следующие правила:
*filter
:IN DROP [0:0]
-A IN -d адрес-на-eth0 -i eth0 -j ACCEPT
-A IN -d адрес-на-eth1 -i eth1 -j ACCEPT
:OUT DROP [0:0]
-A OUT --source-mac адрес-eth0 -s адрес-на-eth0 -o eth0 -j ACCEPT
-A OUT --source-mac адрес-eth1 -s адрес-на-eth1 -o eth1 -j ACCEPT
:FORWARD DROP [0:0]
COMMIT
|
Bog BOS: netfilter и iptables/arptables: фильтрация пакетов в Linux: принципы работы, установка и настройка
|
Copyright © 1996-2024 Sergey E. Bogomolov; www.bog.pp.ru