Iptables: различия между версиями
Содержимое удалено Содержимое добавлено
+ {{Темы|}} (были: явные категории), Категория:Linux (была: Категория:GNU/Linux), {{Готовность|}}; − ссылки на другие языковые разделы. |
Ссылки на несуществующие страницы заменены ссылками на статьи Википедии; →Ссылки: оформление; {{Unix man|}}. |
||
Строка 3:
|logo =
|developer = Netfilter Core Team
|programming_language = [[w:Си (язык программирования) |C]]
|operating_system = часть [[w:Ядро Linux
|latest_release_version = 1.4.21
|latest_release_date = 2013-Nov-22
|genre =
|license = [[w:GNU General Public License |GNU GPL]]
|website = [http://www.netfilter.org/ www.netfilter.org]
|screenshot = [[File:Iptablesfb.png|300px|iptables]]
}}
'''iptables''' — утилита [[
Иногда под словом iptables имеется в виду и сам межсетевой экран netfilter.
== История ==
Изначально разработка netfilter и iptables шла совместно, поэтому в ранней истории этих проектов есть много общего. Подробности см. в статье про
Предшественниками iptables были проекты
iptables сохраняет идеологию, ведущую начало от ipfwadm: функционирование фаервола определяется набором правил, каждое из которых состоит из критерия и действия, применяемого к пакетам, подпадающим под этот критерий. В ipchains появилась концепция ''цепочек'' — независимых списков правил. Были введены отдельные цепочки для фильтрации входящих (INPUT), исходящих (OUTPUT) и транзитных (FORWARD) пакетов. В продолжении этой идеи, в iptables появились ''таблицы'' — независимые группы цепочек. Каждая таблица решала свою задачу — цепочки таблицы filter отвечали за фильтрацию, цепочки таблицы nat — за преобразование сетевых адресов (
Такое разделение функциональности позволило iptables при обработке отдельных пакетов использовать информацию о соединениях в целом (ранее это было возможно только для NAT). В этом iptables значительно превосходит ipchains, так iptables может отслеживать состояние соединения и перенаправлять, изменять или отфильтровывать пакеты, основываясь не только на данных из их заголовков (источник, получатель) или содержимом пакетов, но и на основании данных о соединении. Такая возможность фаервола называется stateful-фильтрацией, в отличие от реализованной в ipchains примитивной stateless-фильтрации (подробнее о видах фильтрации см. статью о [[w:Межсетевой экран |фаерволах]]). Можно сказать, что iptables анализирует не только передаваемые данные, но и контекст их передачи, в отличие от ipchains, и поэтому может принимать более обоснованные решения о судьбе каждого конкретного пакета. Более подробно о stateful-фильтрации в netfilter/iptables см. [[w:Netfilter#Механизм определения состояний]].
В будущем, разработчики netfilter планируют заменить iptables на [[nftables]] — инструмент нового поколения, пока находящийся в ранней стадии разработки<ref>[http://www.opennet.ru/opennews/art.shtml?num=20843 Разработчики Netfilter представили замену iptables]</ref>.
Строка 52:
iptables -P OUTPUT ACCEPT # Разрешаем все исходящие пакеты
</source>
Теперь цепочка INPUT таблицы filter содержит единственное правило, которое пропускает все пакеты, относящиеся к уже установленным соединениям. Ко всем остальным входящим пакетам будет применено действие по умолчанию — DROP. Цепочка же OUTPUT вообще не содержит правил, поэтому ко всем исходящим пакетам будет применяться действие по умолчанию ACCEPT. Таким образом хост, настроенный согласно этому примеру и подключенный к
=== Основные компоненты ===
Строка 85:
==== iptables ====
Userspace-утилита, через которую [[w:Root
* Создание и удаление пользовательских цепочек.
* Установка действий по умолчанию для базовых цепочек.
Строка 93:
* Проверка корректности задания параметров, определяющих работу критериев и действий.
* Вывод справки по использованию критериев (<tt>iptables -m ''критерий'' -h</tt>) и действий (<tt>iptables -j ''действие'' -h</tt>).
Также в комплект поставки вместе с iptables обычно входят вспомогательные утилиты, обеспечивающие сохранение (iptables-save) и последующее восстановление (iptables-restore) состояния фаервола, его инициализацию при запуске системы (
Сегментом фаервола, отвечающим за фильтрацию
Также в рамках данного проекта разрабатываются два набора библиотек:
* '''libiptc''' — содержит функции, осуществляющие вышеперечисленные операции по управлению цепочками и правилами. Именно с этими функциями и работают утилиты iptables (библиотека libip4tc) и ip6tables (библиотека libip6tc). Приложения, использующие эти библиотеки, могут обращаться к netfilter напрямую, минуя вызов утилит iptables и ip6tables. В качестве примера такого приложения можно назвать [[Perl]]-модуль [http://search.cpan.org/~hawk/IPTables-libiptc-0.18/lib/IPTables/libiptc.pm IPTables::libiptc], предоставляющий доступ к функциям этих библиотек из Perl-
* '''libipq''' — содержит функции, позволяющие пользовательским приложениям принимать [[IP-пакет]]ы на обработку. Отправка со стороны ядра выполняется через модуль ip_queue (ip6_queue для IPv6), что соответствует действию QUEUE. В настоящее время этот механизм [http://netfilter.org/projects/libnetfilter_queue/index.html объявлен устаревшим], и вместо него рекомендуется использовать действие NFQUEUE, работа которого реализуется через модуль ядра nfnetlink_queue и библиотеку libnetfilter_queue.
Строка 104:
Компонент netfilter, обеспечивающий отслеживание состояния соединений и классификацию пакетов с точки зрения принадлежности к соединениям, что позволяет netfilter осуществлять полноценную stateful-фильтрацию трафика. Как и netfilter, система conntrack является частью ядра [[Linux]]. К его задачам относятся:
* Отслеживание состояний отдельных соединений с тем, чтобы классифицировать каждый пакет либо как относящийся к уже установленному соединению, либо как открывающий новое соединение. При этом понятие "состояние соединения" искусственно вводится для протоколов, в которых оно изначально отсутствует (
* Отслеживание связанных соединений, например,
Более подробно о возможностях системы conntrack и их использовании при работе с iptables/netfilter см. [[
В состав conntrack входят следующие компоненты:
* Главный модуль nf_conntrack. Реализует базовую функциональность отслеживания соединений, интерфейсы для работы с модулями расширений, а также механизмы отслеживания протоколов
* Трекеры протоколов [[
* Трекеры протоколов [[w:Транспортный уровень |транспортного уровня]] (кроме
* Вспомогательные модули (helpers), обеспечивающие отслеживание протоколов [[
* Модуль nf_nat. Реализует базовую функциональность [[w:NAT |трансляции сетевых адресов]] и [[w:Трансляция порт-адрес |портов]] с учетом информации о соединениях. Также этот модуль содержит механизмы трансляции для протоколов
* NAT-трекеры протоколов [[w:Транспортный уровень |транспортного уровня]]: nf_nat_proto_sctp, nf_nat_proto_dccp, nf_nat_proto_gre, nf_nat_proto_udplite.
* Вспомогательные модули NAT для протоколов [[
* Модуль взаимодействия с userspace через протокол nfnetlink (см. следующий раздел) nf_conntrack_netlink, которому соответствует userspace-библиотека libnetfilter_conntrack.
* Кроме того, к conntrack можно условно отнести и модули netfilter, обеспечивающие взаимодействие этих двух подсистем: критерий conntrack (xt_conntrack), действия NOTRACK и CT (xt_NOTRACK и xt_CT), практически все действия [[
Для взаимодействия с системой conntrack из userspace разработан комплект [http://conntrack-tools.netfilter.org/ conntrack-tools], содержащий две утилиты:
* '''conntrack''' — инструмент, позволяющий [[w:Root
* '''conntrackd''' — демон, обеспечивающий синхронизацию таблиц состояний с другими хостами, что в сочетании с возможностями демона [[keepalived]] позволяет создавать фаерволы на
Взаимодействие conntrack с этими программами производится посредством интерфейса nfnetlink, который будет рассмотрен в следующем разделе.
Строка 131:
* '''libnetfilter_conntrack''' (ранее libnfnetlink_conntrack и libctnetlink) — обеспечивает взаимодействие приложений с системой conntrack. В качестве примеров приложений, использующих эту библиотеку, можно упомянуть:
** Описанные выше программы '''conntrack''' и '''conntrackd''' из комплекта conntrack-tools.
** '''iptstate''' — в какой-то мере аналог утилиты conntrack, хотя и не имеющий таких богатых возможностей. Предназначена для непрерывного вывода таблицы состояний соединений с периодическим обновлением, в стиле широко известной утилиты
* '''libnetfilter_queue''' (ранее libnfnetlink_queue) — отвечает за передачу пакетов демонам на предмет анализа. По результатам этого анализа пакет может быть заблокирован или пропущен. При пропускании пакета возможна установка или изменение его маркировки (nfmark). Идеологическим предшественником libnetfilter_queue была ныне устаревшая библиотека libipq. В качестве примеров приложений, использующих libnetfilter_queue, можно упомянуть:
** '''nufw''' — фаервол, выполняющий фильтрацию трафика на основе авторизации пользователей. Позволяет устанавливать ограничения на доступ к сетям, находящимся за фаерволом, для отдельных пользователей. Авторизация пользователей на фаерволе обеспечивается отдельным демоном nuauth. Например, в случае, если клиенты используют [[Linux]], авторизация может выполняться совершенно прозрачно, благодаря возможностям
** '''
** '''iplist''' — userspace-альтернатива ipset. Как и ipset, позволяет считывать большие списки
* '''libnetfilter_log''' (ранее libnfnetlink_log) — предоставляет демонам интерфейс для получения служебной информации о пакетах на предмет регистрации и учета трафика. В настоящее время известен только один проект, использующий данную библиотеку — '''ulogd2''' ([netfilter] userspace logging daemon, версия 2). Данный проект находится пока в бета-стадии разработки. Надо заметить, что ulogd2 может получать информацию не только через libnetfilter_log (действие NFLOG), но и через классический механизм libipulog (действие ULOG), а также через libnetfilter_conntrack (данный метод позволяет получать информацию не об отдельных пакетах, а о соединениях в целом).
Строка 144:
==== ipset ====
Представляет собой набор инструментов, позволяющий работать с большими списками (sets)
В версии ipset 4 и более ранних поддерживалась работа только с семейством адресов
Стоит отметить, что долгое время проект ipset существовал вне основной ветки развития [[w:Ядро Linux
ipset состоит из следующих элементов:
Строка 157:
** Добавление и удаление записей из списков, проверка наличия записи в списке.
** Вывод справочной информации по работе со списками различного типа.
* Модули расширений для утилиты ipset, соответствующие модулям расширений в ядре, например, ipset_hash_ip (тип данных hash:ip), ipset_bitmap_port (тип данных bitmap:port) и т. д. Каждый такой модуль отвечает за обеспечение
* Модуль netfilter xt_set (критерий set и действие SET), а также соответствующие модули (библиотеки) iptables (libxt_set и libxt_SET). Критерий set позволяет проверять различные параметры пакета ([[w:IP-адрес |IP]]/
ipset поддерживает следующие типы данных (в скобках приведены названия согласно терминологии устаревшей версии ipset 4):
* '''bitmap:ip''' (ipmap) — полный перечень
* '''bitmap:ip,mac''' (macipmap) — полный перечень IP-адресов, причем вместе с каждым IP-адресом может быть сохранен
* '''bitmap:port''' (portmap) — полный перечень [[w:Порт (
* '''hash:ip''' (iphash) — выборочный перечень IP-адресов (либо IP-подсетей с одинаковой маской).
* '''hash:net''' (nethash) — выборочный перечень IP-подсетей (блоков IP-адресов). В отличие от hash:ip, в одном списке могут присутствовать подсети с различными масками.
* '''hash:ip,port''' (ipporthash) — выборочный перечень IP-адресов, причем с каждым адресом может быть сохранен порт. В версии ipset 4 и более ранних существует ограничение: адреса в пределах одного перечня должны принадлежать одному [[
* '''hash:ip,port,ip''' (ipportiphash) — выборочный перечень IP-адресов, причем с каждым адресом может быть сохранен порт и еще один IP-адрес. В версии ipset 4 и более ранних ограничение на «первичные» адреса (первые в тройке адрес-порт-адрес) такое же, как и для ipporthash. Начиная с версии ipset 5, для каждого номера порта можно также сохранять идентификатор протокола транспортного уровня.
* '''hash:ip,port,net''' (ipportnethash) — выборочный перечень IP-адресов, причем с каждым адресом может быть сохранен порт и IP-подсеть. В версии ipset 4 и более ранних ограничение на «первичные» адреса такое же, как и у типа ipporthash. Начиная с версии ipset 5, для каждого номера порта можно также сохранять идентификатор протокола транспортного уровня.
* '''list:set''' (setlist) — список списков. Может содержать списки любого перечисленного здесь типа, кроме list:set. При обращении к такому объекту из netfilter, включенные в него списки рассматриваются как один большой список. Поиск записей (критерий set) производится по всем вложенным спискам соответствующего типа. При добавлении записей (действие SET), вложенные списки поочередно проверяются (согласно порядку их перечисления) на соответствие типа и наличие свободного места, и запись добавляется в первый же подходящий. В то же время, при обращении к такому списку через утилиту ipset, он рассматривается именно как совокупность элементов-списков, что позволяет добавлять, удалять и проверять наличие именно вложенных списков, но не их элементов.
* '''hash:net,iface''' — выборочный перечень IP-подсетей, причем с каждой подсетью может быть сохранено название сетевого интерфейса. Появился в версии ipset 6.7 (входит в [[w:Ядро Linux
В четвертой версии дополнительно присутствовали два типа списков, упраздненные в более поздних версиях:
Строка 178:
Практически для всех типов списков, реализованных в ipset, существует общее ограничение на максимальный размер: 65536 записей.
Большинство перечисленных типов данных можно разделить на две группы: полные перечни (map, bitmap) и выборочные перечни (hash, tree). Разница между этими типами состоит в следующем: если выборочный перечень сохраняет только те элементы, которые в него входят, то полный перечень представляет собой таблицу логических значений (
Таким образом, выбор необходимого вам типа данных определяется конкретными условиями задачи, прежде всего, отношением усредненного количества элементов в списке к требуемому диапазону охвата. Например, если вы собираетесь хранить в списке блэк-листы адресов, замеченных в атаках на ваш сервер, целесообразнее использовать тип hash:ip, потому что атакующие вас ботнеты, как бы они ни были велики, все равно занимают незначительную долю адресного пространства
По поводу хранения адресов подсетей ([[w:Бесклассовая адресация |блоков]]
Что касается улучшений в версиях 5 и 6 по сравнению с четвертой и более ранними, то, помимо уже упомянутых (поддержка адресов
<source lang="bash">
ipset -N foo macipmap --network 192.168.0.0/16 # Создаем список
Строка 202:
ipset destroy foo
</source>
Кроме того, современные версии ipset поддерживают работу в режиме простой [[w:Командный интерпретатор |оболочки]], принимающей команды со [[stdin]]. При этом в них обеспечивается полная обратная совместимость синтаксиса с четвертой версией, то есть синтаксис, корректно работающий для четвертой версии ipset, будет точно так же работать в пятой и шестой.
==== ipvs ====
Разработанный в рамках проекта [http://www.linuxvirtualserver.org/ Linux Virtual Server] инструментарий для балансировки входящих соединений на [[w:Транспортный уровень |транспортном уровне]], позволяющий создавать отказоустойчивые (highly available, HA) [[w:Кластер (группа компьютеров) |кластеры]] с балансировкой нагрузки. В структуру такого кластера входит один или несколько хостов-балансировщиков (front-end), а также группа хостов-обработчиков (back-end). Хост-балансировщик принимает входящие соединения и перенаправляет их на хосты-обработчики, причем выбор хоста-обработчика осуществляется по специальному алгоритму, обеспечивающему гибкое распределение нагрузки между обработчиками. В кластере также могут присутствовать дополнительные (резервные) балансировщики, которые вступают в игру в случае отказа основного балансировщика.
Как правило, IPVS работает в связке с демоном [[keepalived]], который обеспечивает отказоустойчивость балансировщика (с использованием протокола [[:en:VRRP|VRRP]]) и поддержку в актуальном состоянии списка обработчиков (демон периодически проверяет работоспособность обработчиков и выводит из состава кластера неработоспособные хосты). Также допускается «ручное» управление настройками кластера — через программу [[ipvsadm]].
Как уже упоминалось выше, IPVS обеспечивает балансировку нагрузки на транспортном уровне, т.е. конфигурационной единицей IPVS является ''кластерная служба''. Она характеризуется адресом (
Для перенаправления пакетов на выбранный обработчик, IPVS может использовать один из следующих методов:
* '''Прямая
* '''[[w:Инкапсуляция (компьютерные сети) |Инкапсуляция]] IPIP''' — модификация предыдущего метода на тот случай, когда балансировщик и обработчики находятся в разных сегментах сети. При помощи инкапсуляции IP-в-IP создаются [[w:Туннелирование (компьютерные сети) |сетевые туннели]], которые объединяют балансировщик и обработчик в один сегмент виртуальной сети.
* '''
В настоящее время существует довольно обширная библиотека алгоритмов балансировки нагрузки между обработчиками:
* '''rr (round robin)''' — классическая [[w:Round-robin (алгоритм) |кольцевая схема]], когда все обработчики получают новые соединения поочередно.
* '''wrr (weighted round robin)''' — модификация кольцевой схемы на тот случай, когда одни сервера могут обрабатывать больше соединений, чем другие. Такие сервера включаются в один проход очереди по нескольку раз, и соответственно получают больше соединений.
* '''lc (least-connection)''' — новое соединение передается тому серверу, который на текущий момент обрабатывает наименьшее число соединений.
Строка 229:
* '''nq (never queue)''' — пытается передать новое соединение обработчику, который в данный момент не обрабатывает других соединений. Если все обработчики уже заняты, использует предыдущий алгоритм (sed).
Для отслеживания соединений к кластерным службам IPVS использует собственную систему трекинга соединений, более примитивную, но менее ресурсоемкую, нежели классический conntrack. При этом поддерживается экспорт информации о кластерных соединениях в conntrack, в целях обеспечения их корректной обработки фаерволом и трансляции адресов (при трансляции адресов используются штатные средства netfilter). Однако, для корректной обработки протоколов, использующих связанные соединения (например,
=== Механизм определения состояний ===
Важной особенностью iptables/
Определение состояния соединения порою бывает довольно сложной задачей. Скажем, в случае
Заметим, что классификация пакетов по отношению к соединениям, реализуемая системой conntrack, во многих случаях отличается от официального описания сетевых протоколов. Например, с точки зрения критерия conntrack, TCP-пакет SYN/ACK (отвечающий на SYN) — уже часть существующего сеанса, а по определению TCP такой пакет — всего лишь элемент открытия сеанса.
Существует также понятие «связанных соединений». Например, когда в ответ на
Более сложный вариант связанного соединения — соединение данных в пассивном режиме
В некоторых случаях целесообразно отключить отслеживание состояния соединений. Например, если ваш сервер находится под [[w:DoS-атака |(D)DoS-атакой]] типа флуд, и вам удалось локализовать ее источники, отслеживать соединения с атакующих хостов и тратить для этого ресурсы своей системы явно не имеет смысла. В подобных случаях используется действие NOTRACK, применяемое в [[
Ниже кратко перечислены возможности, предоставляемые системой отслеживания состояний:
Строка 249:
==== Критерий состояния соединения ====
При помощи [[
Например, одним простым правилом
Строка 257:
вы можете обеспечить корректное пропускание всех входящих пакетов, принадлежащих установленным соединениям, и сконцентрироваться только на фильтрации новых соединений.
Заменив в предыдущем правиле <tt>ESTABLISHED</tt> на <tt>ESTABLISHED,RELATED</tt> и подгрузив соответствующие модули ядра, вы автоматически обеспечите корректную фильтрацию протоколов, использующих связанные соединения —
Более подробно об использовании этого критерия вы можете почитать [[
Кроме критерия conntrack, стоит упомянуть и его идеологического предшественника — [[
==== Маркировка соединений ====
Этот прием позволяет классифицировать соединение в целом на основании информации об отдельном пакете. Выделив этот пакет, вы применяете к нему действие CONNMARK, и выбранную вами маркировку автоматически приобретают все пакеты в соединении. Впоследствии вы можете, например, модифицировать эти пакеты каким-либо образом, или использовать эту маркировку для [[w:Маршрутизация |маршрутизации]] или [[w:Шейпинг (информатика) |шейпинга]] пакетов. Таким образом, вы оперируете с соединением как с единым целым. Более того, эта маркировка автоматически копируется и на соединения, связанные с текущим.
==== [[w:NAT |Трансляция сетевых адресов]] ====
В операциях NAT, производимых с помощью iptables, отслеживание состояний используется автоматически. Вам достаточно указать критерии, под которые подпадет лишь первый пакет в соединении — и трансляция адресов будет применена ко всем пакетам в этом соединении, а также в связанных с ним соединениях.
Строка 275:
Применяя критерий connbytes, вы можете контролировать количество байт или пакетов, переданных по каждому конкретному соединению. В простейшем случае этот механизм может использоваться, скажем, для назначения квот. Более сложный пример — шейпинг пакетов в зависимости от «весовой категории» соединения (ставить пониженный приоритет загрузкам больших файлов).
Этот критерий рассмотрен ниже, в разделе [[
==== Ограничение количества соединений ====
Используя критерий connlimit, вы можете ограничивать количество одновременно открытых
Этот критерий рассмотрен ниже, в разделе [[
==== Отслеживание информации о соединениях ====
Пользователь (точнее, [[w:Root
== Действия ==
Строка 299:
=== Встроенные действия ===
Как уже было сказано выше, каждое встроенное действие реализует какую-либо одну операцию, например, ACCEPT пропускает пакет, MARK меняет его маркировку, MASQUERADE обеспечиват
* '''ACCEPT''', '''DROP''' и '''REJECT''' — базовые операции фильтрации. Более подробно они рассмотрены ниже, при описании таблицы filter.
* '''RETURN''' — обеспечивает возврат из текущей цепочки. В частности, если из цепочки A правилом номер 3 пакет был направлен в цепочку B, то применение к нему в цепочке B действия RETURN приведет к его переходу обратно в цепочку A, и он продолжит ее прохождение со следующего правила (номер 4).
Например, предположим, что нам нужно обеспечить доступ к определенным [[w:Порт (
<source lang="bash">
iptables -F # Очищаем все цепочки таблицы filter
Строка 319:
iptables -P OUTPUT ACCEPT # На выход — можно все
</source>
Теперь все новые входящие пакеты, отправленные из нашей подсети 10.134.0.64/26, отправляются на проверку в цепочку <tt>our_subnet</tt>. К пакетам с «запрещенных» хостов применяется операция RETURN, и они покидают эту цепочку и впоследствии блокируются действием по умолчанию цепочки INPUT. Пакеты с остальных хостов этой подсети пропускаются в том случае, если они адресованы на порты [[w:Прокси-сервер |прокси]] (8080/tcp),
Нетрудно заметить, что в нашем простом примере вместо RETURN можно было использовать и DROP. Однако, существует понятие «принципа одного запрета». При организации фильтрующих правил в рамках этого принципа, сначала следует серия разрешающих правил, исключения оформляются в виде RETURN, а все не разрешенные пакеты доходят до конца базовой цепочки и блокируются действием по умолчанию либо последним правилом. Следование этому принципу позволяет достичь гибкости в выборе и смене метода блокирования пакетов. Допустим, вы хотите сменить блокирующее действие DROP на REJECT. Нет ничего проще — просто меняете правило по умолчанию. Так же просто вводятся специфические методы блокировки для TCP, например, REJECT <tt>--reject-with tcp-reset</tt> или DELUDE — достаточно просто добавить это действие (вместе с указанием протокола <tt>-p tcp</tt>) в конец цепочки. Все не-TCP пакеты при этом будут по-прежнему блокироваться действием по умолчанию.
Строка 347:
: ''Примечание: следующий пример планируется к переносу в еще не написанный раздел статьи (Прочие критерии → mac)''.
Например, предположим, что у нас есть объединенная через один [[
<source lang="bash">
sysctl net.ipv4.ip_forward=1 # Разрешаем шлюзу передавать транзитный трафик
Строка 374:
</source>
<!--В демонстрационных целях этот пример был слегка упрощён (вместо повтора правил с критерием <tt>-s 10.134.0.64/26</tt> эти правила логичнее было бы вынести в отдельные цепочки) но, тем не менее, наглядно показывает принципы работы действия RETURN.-->
Все новые входящие пакеты с обратным адресом из подсети 10.134.0.64/26 проходят двойную проверку в цепочке <tt>check_ours</tt>. Первый этап проверки — соответствие интерфейса. Ведь к нашей подсети, по условию задачи, мы подключены только интерфейсом eth1. Если пакет якобы из этой подсети придет с любого другого интерфейса, он будет заблокирован. Второй этап проверки заключается в последовательном чтении списка соответствующих [[w:IP-адрес |IP]]- и
* '''LOG''' — позволяет записывать информацию о пакетах в журнал ядра (см.
Например, если в предыдущем примере перед строкой
<source lang="bash">
Строка 387:
Jul 16 20:10:40 interdictor kernel: New connection from ours: IN=eth0 OUT= MAC=00:15:17:4c:89:35:00:1d:60:2e:ed:a5:08:00 SRC=10.134.0.67
DST=10.134.0.65 LEN=48 TOS=0x00 PREC=0x00 TTL=112 ID=38914 DF PROTO=TCP SPT=31521 DPT=8080 WINDOW=65535 RES=0x00 SYN URGP=0
Такая запись содержит очень много полезной информации. Начинается она с даты и времени получения пакета. Затем идет имя нашего хоста (interdictor) и источник сообщения (для сообщений фаервола это всегда ядро). Потом идет заданный нами префикс (<tt>New connection from ours:</tt>), после чего следуют данные о самом пакете: входящий интерфейс (определен для цепочек PREROUTING, INPUT и FORWARD), исходящий интерфейс (определен для цепочек FORWARD, OUTPUT и POSTROUTING), далее — сцепленные вместе
Указав соответствующие параметры действия LOG, можно дополнить эту информацию [[w:TCP#Номер последовательности |номером TCP-последовательности]] (опция <tt>--log-tcp-sequence</tt>), выводом включенных опций протоколов TCP (опция <tt>--log-tcp-options</tt>) и
Параметр <tt>--log-prefix</tt> позволяет задать поясняющую надпись, упрощающую поиск сообщений в системных журналах. Параметр <tt>--log-level</tt> определяет уровень важности лог-сообщения, от которого зависит, в частности, в какой именно из журналов будет записано это сообщение. За более подробными сведениями обратитесь к документации по вашему [[
* '''LOGMARK''' — специальная модификация действия LOG, реализованная в комплекте xtables-addons. Отличается тем, что заносит в лог информацию, специфичную для системы [[conntrack]], в частности, маркировку соединения (connmark aka ctmark), состояния соединения (ctstate и ctstatus) и т. п. Например:
Jul 16 20:10:40 interdictor kernel: New connection from ours: iif=1 hook=INPUT nfmark=0x0 secmark=0x0 classify=0x0 ctdir=ORIGINAL
ct=0xf5436bcc ctmark=0x0 ctstate=NEW ctstatus=
<tt>iif</tt> показывает внутренний идентификатор интерфейса, через который прошел пакет (1 в данном случае соответствует eth0, 0 — lo), <tt>hook</tt> — имя цепочки, из которой было вызвано действие LOGMARK, <tt>nfmark</tt> — маркировку пакета (mark), <tt>secmark</tt> — контекст безопасности
Таким образом, в сочетании с традиционным LOG, действие LOGMARK позволяет заносить в системный журнал исчерпывающую информацию о пакетах и соединениях.
Заметим, что LOGMARK принимает описанные выше опции <tt>--log-prefix</tt> и <tt>--log-level</tt>.
* '''ULOG''' — позволяет передавать информацию об обработанных пакетах специальным демонам, таким, как [http://www.netfilter.org/projects/ulogd/ ulogd]. Такой подход позволяет эффективно управлять информацией о трафике, в частности, заносить ее в
* '''NFLOG''' — более универсальный вариант ULOG, обеспечивающий передачу информации о пакете не напрямую в netlink-[[w:Сокет (программный интерфейс) |сокет]] (как это делает ULOG), а специальной подсистеме — logging backend. Например, бэкенд nfnetlink_log обеспечивает передачу данных в netlink-сокет, то есть с ним NFLOG работает аналогично ULOG.
* '''NFQUEUE''' — во многом похоже на ULOG, но передает специальному демону не информацию о пакете, а сам пакет целиком. Применяется, в частности, для организации работы
Например, если демон l7-filter был запущен командой
<source lang="bash">
Строка 418:
Выше были рассмотрены действия «общего назначения», то есть не привязанные по своей специфике к таблицам. Далее, при рассмотрении отдельных таблиц, будут описываться действия, специфичные для каждой таблицы. Термин «специфичные» надо понимать так: совсем не обязательно, что действие, специфичное для одной таблицы, будет в принципе недопустимо в другой, но в любом случае использование этого действия в других таблицах будет «плохим тоном» — ведь таблицы и действия четко разделены по назначению. Не стоит «забивать гвозди микроскопом».
Порой эта разница бывает довольно тонкой. Например, если действие NFQUEUE передает пакеты демону
Кроме того, существуют и ограничения, наложенные непосредственно в коде iptables. Например, действия таблицы nat жестко защищены от употребления за ее пределами. Другой пример: действие REDIRECT можно применять только в цепочках PREROUTING и OUTPUT таблицы nat, то есть ограничения могут быть не только на таблицы, но на отдельные цепочки. Данная статья ни в коем случае не претендует на полноту изложения, поэтому, перед тем как использовать какое-либо действие, обязательно ознакомьтесь с документацией, прилагающейся к вашей версии iptables.
Строка 446:
=== Таблица mangle ===
Данная таблица предназначена для операций по классификации и маркировке пакетов и соединений, а также модификации заголовков пакетов (поля [[
==== Цепочки ====
Строка 460:
==== Действия ====
Допустимыми действиями в этой таблице являются:
* '''TOS''' — изменяет поле [[
Кроме того, опция <tt>--set-tos</tt> поддерживает расширенный синтаксис <tt>--set-tos ''значение''/''маска''</tt>. При использовании такого синтаксиса в исходном значении TOS пакета зануляются те биты, которые установлены в маске, затем полученное число XOR’ится с указанным в параметрах значением, и полученная величина записывается в поле TOS. Используя синтаксис [[w:Си (язык программирования) |языка C]], это можно записать так: <tt>NEW_TOS = (OLD_TOS & ~''маска'') ^ ''значение''</tt>. Заметим, что в случае с
Также, в случае
Практический пример использования действия TOS представлен [[
Отметим, что, в соответствии с современными соглашениями, поле TOS в заголовке IP-пакета разделяется на две части:
* '''DSCP''' — изменяет поле
* '''TTL''' — изменяет поле [[
В качестве полезного примера использования этого действия можно привести команду
Строка 478:
iptables -t mangle -I PREROUTING -j TTL --ttl-inc 1
</source>
делающую наш шлюз невидимым для большинства [[w:Traceroute |трассировщиков]].
Обратите внимание, что автоматически выполняемая сетевым стеком ядра операция уменьшения TTL на единицу и проверки на равенство нулю выполняется ''после'' цепочки PREROUTING, но ''до'' цепочки FORWARD. Таким образом, переместив это правило в цепочку FORWARD, вы обеспечите «невидимость» следующего за вами шлюза.
Строка 490:
'''Будьте очень осторожны''' с правилами, которые увеличивают или, что особенно опасно, напрямую задают значение TTL, так как, при наличии определенных ошибок маршрутизации, это может привести к появлению «бессмертных» пакетов, которые будут долго циркулировать между одними и теми же узлами, захламляя канал и затрудняя работу сетевого оборудования.
* '''HL''' — изменяет поле Hop Limit в заголовке
* '''MARK''' — устанавливает или изменяет маркировку пакета. Поддерживает опции <tt>--set-mark</tt>, <tt>--and-mark</tt>, <tt>--or-mark</tt> и <tt>--xor-mark</tt>, аналогичные опциям действия TOS. Важно понимать, что маркировка пакета не хранится в его заголовке или содержимом, и поэтому действует только в пределах одного хоста. Также нужно отличать маркировку пакета от маркировки соединения. Маркировка пакетов может применяться для их дальнейшей обработки фаерволом (критерии mark и connmark), а также для классификации трафика фильтрами [[w:Шейпинг (информатика) |шейпинговой]] подсистемы [[
* '''CONNMARK''' — устанавливает или изменяет маркировку соединения. Поддерживает те же опции, что и MARK, а также дополнительные опции <tt>--restore-mark</tt> (копирует маркировку соединения в маркировку пакета) и <tt>--save-mark</tt> (копирует маркировку пакета в маркировку соединения).
* '''CLASSIFY''' — устанавливает [[:en:Class Based Queueing|CBQ]]-класс пакета для его последующей обработки [[w:Шейпинг (информатика) |шейпером]] (опция <tt>--set-class</tt>).
* '''TCPMSS''' — устанавливает [[:en:Maximum segment size|максимальный размер TCP-сегмента]]. Бывает крайне полезной при использовании
С точки зрения клиента, эта проблема выглядит так:
<source lang="bash">
iptables -t mangle -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
</source>
которая обеспечит автоматическую установку размера сегмента в TCP-заголовках SYN- и SYN,ACK-пакетов в соответствии с минимальным из известных нашему шлюзу значений
Помимо возможности автоматического выбора TCP MSS, вы можете задать необходимое значение и вручную, используя параметр <tt>--set-mss ''значение''</tt>. Это бывает полезным в том случае, если вам заведомо известно, что дальше на маршруте встречаются участки с еще меньшим MTU, а пограничные сервера этих участков опять же блокируют ICMP destination unreachable/fragmentation needed.
* '''ECN''' — обеспечивает обнуление [[w:Explicit Congestion Notification |ECN]]-битов (флаги CWR и ECE) в TCP-заголовке (единственная опция <tt>--ecn-tcp-remove</tt>). Может использоваться только в
Кроме того, данное действие поддерживает три потенциально опасные опции, не отраженные в документации: <tt>--ecn-tcp-cwr</tt> (установка значения бита CWR в TCP-заголовке, 0 или 1), <tt>--ecn-tcp-ece</tt> (установка значения бита ECE в TCP-заголовке, 0 или 1) и <tt>--ecn-ip-ect</tt> (установка значения ECT codepoint в IPv4-заголовке, от 0 до 3). Использование этих опций настолько опасно, что они не отражены даже во встроенной справке iptables (<tt>iptables -j ECN -h</tt>) — их можно увидеть, только изучив [http://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=blob;f=extensions/libipt_ECN.c исходный код]. Без крайней необходимости применять их не рекомендуется.
Строка 511:
iptables -t mangle -A POSTROUTING -p tcp -j TCPOPTSTRIP --strip-options timestamp
</source>
обеспечит удаление штампов времени ([http://tools.ietf.org/html/rfc1323 RFC 1323]). С одной стороны, такое правило будет препятствовать удаленному злоумышленнику определить
* '''TPROXY''' — реализует механизм полностью прозрачного [[w:Прокси-сервер |проксирования]]. Такой подход отличается от традиционно используемого «прозрачного» проксирования (действие REDIRECT [[
TPROXY позволяет перенаправить транзитный пакет на локальный [[w:Сокет (программный интерфейс) |сокет]] типа AF_INET (iptables) или AF_INET6 (ip6tables), заданный портом, а также может промаркировать пакет таким образом, чтобы система марушрутизации (
В качестве примера можно привести простейший случай конфигурации iptables и iproute2 для обеспечения полностью прозрачного проксирования
<source lang="bash">
# Добавляем принудительную локальную маршрутизацию для всех адресов в таблицу 120
Строка 535:
=== Таблица nat ===
Предназначена для операций stateful-преобразования [[w:IP-адрес |сетевых адресов]] и [[
==== Цепочки ====
Строка 542:
* '''PREROUTING''' — в эту цепочку пакеты попадают ''до'' принятия решения о маршрутизации. По сути, термин «решение о маршрутизации» подразумевает деление трафика на входящий (предназначенный самому хосту) и транзитный (идущий через этот хост на другие хосты). Именно на данном этапе нужно проводить операции проброса (DNAT, REDIRECT, NETMAP).
* '''OUTPUT''' — через эту цепочку проходят пакеты, сгенерированные процессами самого хоста. На данном этапе при необходимости можно повторить операции проброса, так локально сгенерированные пакеты ''не'' проходят цепочку PREROUTING и ''не'' обрабатываются ее правилами. См. пример для действия DNAT ниже.
* '''POSTROUTING''' — через эту цепочку проходят все исходящие пакеты, поэтому именно в ней целесообразно проводить операции
==== Действия ====
Допустимыми действиями в таблице nat являются:
* '''MASQUERADE''' — подменяет адрес источника для исходящих пакетов адресом того интерфейса, с которого они исходят, то есть осуществляет
Допустим, у нас есть локальная сеть 192.168.1.0/255.255.255.0 с несколькими компьютерами, имеющими адреса 192.168.1.2, 192.168.1.3 и т. д. Адрес 192.168.1.1 имеет внутренний (подключенный к локальной сети) сетевой интерфейс шлюза, назовем этот интерфейс eth1. Другой его интерфейс, назовем его eth0, подключен к сети Интернет и имеет адрес, допустим, 208.77.188.166. Тогда, чтобы обеспечить выход хостов из этой локальной сети в Интернет, на шлюзе достаточно выполнить следующие команды
Строка 620:
</source>
Кроме того, при помощи действия DNAT можно пробрасывать не только сразу весь IP-адрес, но и отдельные
<source lang="bash">
iptables -t nat -A PREROUTING -d 208.77.188.166 -j DNAT --to-destination 192.168.1.2
Строка 630:
-p tcp --dport 80
</source>
то мы «пробросим» не сам адрес 208.77.188.166, а только его
Как и SNAT, DNAT поддерживает указание диапазонов адресов для подмены. Таким образом можно, например, балансировать нагрузку между несколькими серверами.
Строка 638:
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080
</source>
позволяет «завернуть» все исходящие из локальной сети TCP-соединения на порт 80, на TCP-порт 8080 шлюза. Если этот порт обслуживается специально настроенным
Другой полезный пример:
Строка 653:
iptables -t nat -A PREROUTING -s 192.168.1.0/24 -d 192.168.3.0/24 -j NETMAP --to 192.168.2.2/24
</source>
Теперь, при обращении, например, хоста 192.168.1.3 на IP-адрес 192.168.3.2 он будет попадать на 192.168.2.2 (при условии, что такой транзитный трафик разрешен на шлюзе в цепочке FORWARD таблицы filter, а также на хостах сети 192.168.1.0/24 наш шлюз [[w:Маршрутизация |прописан]] в качестве шлюза для подсети 192.168.3.0/24).
: ''Примечание: следующее действие планируется к переносу в еще не написанный раздел статьи (Устаревшие критерии и действия)''.
Строка 673:
Допустимыми действиями в таблице filter являются:
* '''ACCEPT''' — пропуск пакета. Пакет покидает текущую базовую цепочку и следует дальше по потоковой диаграмме (см. рис.).
* '''REJECT''' — заблокировать пакет и сообщить его источнику об отказе. По умолчанию об отказе сообщается отправкой ответного
* '''DROP''' — заблокировать пакет, не сообщая источнику об отказе. Более предпочтительна при фильтрации трафика на интерфейсах, подключенных к интернету, так как понижает информативность сканирования портов хоста злоумышленниками.
Также определенный интерес представляют действия, предоставляемые модулями [http://xtables-addons.sourceforge.net/ xtables-addons] (в настоящее время этот проект уже [http://packages.debian.org/squeeze/xtables-addons-common включен] в
* '''STEAL''' — аналогично DROP, но в случае использования в цепочке OUTPUT при блокировании исходящего пакета не сообщает об ошибке приложению, пытавшемуся отправить этот пакет.
* '''TARPIT''' — «подвесить»
Под правильным применением понимается предотвращение обработки таких соединений подсистемой [[conntrack]], так как в противном случае будут расходоваться системные ресурсы самого атакуемого хоста. Например, перед добавлением правила блокирования порта
<source lang="bash">
Строка 695:
=== Таблица security ===
Предназначена для изменения маркировки безопасности (меток
==== Цепочки ====
Строка 704:
* '''OUTPUT''' — эта цепочка позволяет обрабатывать трафик, исходящий от самого хоста.
Так как эта таблица появилась относительно недавно, ее редко можно увидеть на схемах следования пакетов через цепочки и таблицы
==== Действия ====
Данная таблица добавлена в ядро [[w:Ядро Linux
* '''SECMARK''' — устанавливает для пакета контекст безопасности
* '''CONNSECMARK''' — позволяет скопировать контекст безопасности SELinux с отдельного пакета на соединение в целом (опция <tt>--save</tt>) и наоборот (опция <tt>--restore</tt>).
Строка 728:
<!-- В таблице raw целесообразно применять действие '''NOTRACK''', позволяющее предотвратить обработку пакетов системой conntrack. Разумеется, применять ее стоит не ко всем пакетам подряд, а только к тем, для которых такая обработка не нужна и даже вредна. Например, к пакетам, к которым впоследствии применяется действие TARPIT (см. выше). -->
* '''NOTRACK''' — позволяет предотвратить обработку пакетов системой conntrack. Разумеется, применять его стоит не ко всем пакетам подряд, а только к тем, для которых такая обработка не нужна и даже вредна. Например, к пакетам, к которым впоследствии применяется действие TARPIT (см. выше).
* '''CT''' — более функциональный инструмент, добавленный в версии [[w:Ядро Linux
:* Отключить отслеживание соединения (опция <tt>--notrack</tt>). Таким образом, функциональность действия CT включает и функциональность NOTRACK, так что, возможно, действие NOTRACK будет объявлено устаревшим.
:* Задать вспомогательный модуль (conntrack helper) для данного соединения. Если раньше указать нестандартные порты для такого модуля можно было только в параметрах его загрузки (<tt>/etc/modprobe.conf</tt> или <tt>/etc/modprobe.d/netfilter.conf</tt>, например, <tt>options nf_conntrack_ftp ports=2121</tt>), то теперь это можно сделать и через правила netfilter:
Строка 738:
iptables -t raw -I PREROUTING -p tcp --dport 8000 -j CT --ctevents new,destroy
</source>
: будет предписывать для всех соединений на
:* Задать ''зону conntrack'' для данного пакета (параметр <tt>--zone</tt>). Механизм зон conntrack позволяет корректно отслеживать, фильтровать и
<source lang="bash">
iptables -t raw -I PREROUTING -i eth1 -j CT --zone 1
Строка 745:
</source>
: Таким образом, пакеты, входящие или исходящие через интерфейс eth1, будут получать идентификатор зоны 1, в то время как пакеты интерфейса eth0 будут по-прежнему использовать зону по умолчанию (идентификатор 0), и путаницы не произойдет.
: Кроме того, идентификатор зоны можно задать для каждого интерфейса через
<source lang="bash">
echo 1 > /sys/class/net/eth1/nf_ct_zone
</source>
: Однако, стоит заметить, что iptables/netfilter позволяют реализовать более гибкую логику управления идентификатором зоны, опирающуюся на различные параметры пакетов, и поэтом данный параметр действия CT может быть полезен при решении различных сложных задач управления трафиком при использовании зон conntrack.
* '''RAWDNAT''' — позволяет выполнять [[w:NAT |«проброс»]] адресов и портов «сырым» методом — без использования системы conntrack, то есть без учета состояний соединений. Это действие реализовано в рамках проекта xtables-addons. Применять его можно только в таблице raw. Имеет единственную опцию <tt>--to-destination ''адрес''[/''маска'']</tt>, по смыслу аналогичную опции <tt>--to</tt> действия NETMAP, то есть при указании маски заменяются только те биты в адресе, которые соответствуют единичным битам маски. Биты адреса, соответствующие нулевым битам маски, остаются неизменными. При отсутствии маски изменяется весь адрес.
: Отметим, что в отличие от действий [[
<source lang="bash">
iptables -t nat -A PREROUTING -i eth0 -d 212.201.100.135 -j DNAT --to-destination 199.181.132.250
Строка 765:
=== Таблица rawpost ===
Данная таблица предназначена для выполнения операций «сырого» преобразования адресов (без использования информации о соединениях), которые не могут быть реализованы в рамках таблицы raw, а именно, для операции «сырой» подмены исходного адреса (
Как и в таблице raw, в rawpost отсутствует возможность обращения к [[conntrack]], поэтому критерии, использующие эту подсистему (conntrack, connmark, connlimit, connbytes), в этой таблице работать не будут.
Строка 816:
Позволяет указать протокол транспортного уровня. Наиболее часто употребляются <tt>[[tcp]]</tt>, <tt>[[udp]]</tt>, <tt>[[icmp]]</tt> и <tt>all</tt>. Протокол также можно указать с помощью номера или названия согласно перечню, приведенному в <tt>/etc/protocols</tt>. Значение «любой протокол» можно указать с помощью слова <tt>all</tt> или числа 0. Если протокол не указан, подразумевается «любой протокол».
При указании протокола становится возможным использовать специфичные для него критерии. Например, для
* <tt>[!] '''-s'''</tt>, <tt>--src</tt>, <tt>--source ''адрес''[/''маска''][,''адрес''[/''маска'']...]</tt>
Определяет адрес отправителя. В качестве адреса может выступать
<source lang="bash">
iptables -I INPUT -i eth0 -s 192.168.0.0/16 -j DROP
</source>
(где eth0 — интерфейс, подключенный к интернету), позволяет заблокировать простейший вид
Начиная с версии iptables 1.4.6, в одном параметре <tt>-s</tt> можно указывать более одного адреса, разделяя адреса запятой. При этом для каждого адреса будет добавлено ''отдельное'' правило. Например, запись
Строка 838:
При добавлении через команду <tt>-A</tt> (вставка в конец цепочки) порядок добавляемых правил будет соответствовать порядку перечисления адресов в исходной команде, при использовании команды <tt>-I</tt> (вставка в начало цепочки либо после заданного правила) порядок будет обратным исходному.
Настойчиво не рекомендуется использовать доменные имена, для разрешения (резольва) которых требуются
* <tt>[!] '''-d'''</tt>, <tt>--dst</tt>, <tt>--destination ''адрес''[/''маска''][,''адрес''[/''маска'']...]</tt>
Строка 862:
iptables -I INPUT -i lo -j ACCEPT
</source>
позволит принимать весь трафик, входящий через интерфейс [[w:Loopback |обратной петли]].
* <tt>[!] '''-o'''</tt>, <tt>--out-interface ''имя_интерфейса''</tt>
Строка 870:
iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
</source>
будет [[
=== Критерии, специфичные для протоколов ===
==== Протоколы [[w:Транспортный уровень |транспортного уровня]] ====
=====
* <tt>[!] '''--sport'''</tt>, <tt>--source-port ''порт''[:''порт'']</tt>
Строка 884:
iptables -I INPUT -m conntrack --ctstate NEW -p tcp --sport 0:1023 -j DROP
</source>
заблокирует все входящие соединения с [[
* <tt>[!] '''--dport'''</tt>, <tt>--destination-port ''порт''[:''порт'']</tt>
Строка 892:
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
</source>
разрешит все входящие пакеты на 80 порт (
* <tt>[!] '''--tcp-flags''' ''маска'' ''установленные_флаги''</tt>
Позволяет указать список установленных и снятых [[w:TCP#Флаги (управляющие биты) |TCP-флагов]]. В ''маске'' перечисляются (через запятую, без пробелов) все проверяемые флаги, далее, после пробела, перечисляются (также через запятую) те из них, которые должны быть установлены. Все остальные перечисленные в маске флаги должны быть сняты. Возможные флаги: SYN ACK FIN RST URG PSH. Также можно использовать псевдофлаги ALL и NONE, обозначающие «все флаги» и «ни одного флага» соответственно.
Пример:
Строка 908:
iptables -I INPUT -m conntrack --ctstate NEW,INVALID -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT --reject-with tcp-reset
</source>
будет препятствовать
* <tt>[!] '''--syn'''</tt>
Строка 927:
Позволяет проверить, установлена ли в заголовке TCP-пакета соответствующая опция. Полный список опций с их номерами представлен [http://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml на сайте IANA].
=====
* <tt>[!] '''--sport'''</tt>, <tt>--source-port ''порт''[:''порт'']</tt>
Строка 937:
Позволяет указать входящий порт (или их диапазон). Синтаксис и принцип работы аналогичен описанной выше одноименной опции TCP.
=====
* <tt>[!] '''--sport'''</tt>, <tt>--source-port ''порт''[:''порт'']</tt>
Строка 959:
разрешит входящие SCTP-пакеты, содержащие секцию DATA с установленным флагом B и снятым флагом E, то есть первый фрагмент фрагментированной DATA-секции.
=====
* <tt>[!] '''--sport'''</tt>, <tt>--source-port ''порт''[:''порт'']</tt>
Строка 977:
занесет в лог все входящие RESET и INVALID DCCP-пакеты.
=====
Поддержка специфических опций протокола UDPLite (а именно, проверки портов источника и/или назначения) в netfilter реализована не вполне очевидным образом: через критерий multiport (см. раздел [[
Если для обычного
====
Ниже перечислены критерии, которые реализованы только для протокола IPv4 и, соответственно, могут быть вызваны только через iptables, но не через ip6tables.
Строка 993:
iptables -I INPUT -p icmp -f -j DROP
</source>
блокирует фрагменты
У второго и последующего фрагментов нет заголовка транспортного уровня, поэтому бессмысленно пытаться использовать для них критерии номеров [[
* '''addrtype''' — позволяет проверить тип адреса источника и/или назначения с точки зрения подсистемы маршрутизации сетевого стека ядра. Допустимые типы адресов: UNSPEC (адрес 0.0.0.0), [[w:Unicast |UNICAST]], LOCAL (адрес принадлежит нашему хосту), [[w:Broadcast |BROADCAST]], [[w:Anycast |ANYCAST]], [[
<tt>[!] --src-type ''тип''[,''тип''...]</tt> — проверка, принадлежит ли исходный адрес пакета одному из перечисленных типов.
Строка 1009:
Критерии <tt>--limit-iface-in</tt> и <tt>--limit-iface-out</tt> нельзя указывать одновременно.
В качестве практического примера использования данного критерия можно привести простейшую защиту от
<source lang="bash">
iptables -I INPUT -m addrtype --src-type LOCAL ! -i lo -j DROP
</source>
Это правило заблокирует пакеты, которые пришли с внешних интерфейсов, но при этом в качестве обратного адреса у них указан один из адресов, принадлежащих нашему хосту (например,
* '''ecn''' — позволяет проверять значения битов [[w:Explicit Congestion Notification |ECN]] в заголовках
<tt>[!] --ecn-tcp-cwr</tt> — проверка флага ECN CWR (Congestion Window Received) в TCP-заголовке пакета.
Строка 1021:
<tt>[!] --ecn-tcp-ece</tt> — проверка флага ECN ECE (ECN Echo) в TCP-заголовке пакета.
<tt>[!] --ecn-ip-ect ''значение''</tt> — проверка значения, сформированного ECN-битами поля [[
* '''realm''' — проверка области маршрутизации (realm) пакета. Имеет единственный параметр
<tt>[!] --realm ''значение''[/''маска'']</tt>, позволяющий указать численный идентификатор области. Если указана маска, то значение realm каждого проверяемого пакета сначала объединяется с маской при помощи [[w:Битовые операции#Побитовое И (AND) |побитового AND]], а затем сравнивается со значением, указанным в правиле. Также вместо числа можно указать символьное название области согласно обозначениям в файле <tt>/etc/iproute2/rt_realms</tt> (в этом случае маску использовать нельзя).
* '''ttl''' — обеспечивает проверку поля [[w:Time to live |TTL]] в заголовке пакета. Позволяет установить, является ли значение TTL проверяемого пакета большим (<tt>--ttl-gt</tt>), меньшим (<tt>--ttl-lt</tt>), равным или не равным (<tt>[!] --ttl-eq</tt>) указанному значению.
=====
ICMP является протоколом контрольных сообщений IPv4. Несмотря на то, что ICMP формально является самостоятельным протоколом, и обращение к соответствующему критерию должно производиться с использованием синтаксиса для протокола (<tt>-p</tt>), а не для вспомогательного критерия (<tt>-m</tt>), де-факто этот протокол неотделим от IPv4, и поэтому соответствующий критерий может использоваться только в iptables, но не в ip6tables.
Строка 1035:
Критерий этого протокола имеет единственный параметр
<tt>[!] '''--icmp-type''' ''тип''</tt> — обеспечивает проверку [[w:ICMP#Типы ICMP пакетов (полный список) |типа]] ICMP-пакета. Список возможных типов выводится по команде <tt>iptables -p icmp -h</tt>. Также можно указать стандартные числовые тип и, при
необходимости, код. Например,
<source lang="bash">
Строка 1046:
пропустят все входящие ICMP-эхо-запросы (пинги).
====
Ниже перечислены критерии, которые реализованы только для протокола IPv6 и, соответственно, могут быть вызваны только через ip6tables, но не через iptables.
Строка 1056:
гласящее, что в такое правило никогда не будет срабатывать. Если вы видите подобное предупреждение, удалите правило, которое его вызвало, и перепишите это правило с использованием корректного синтаксиса (<tt>-m</tt>).
С другими же критериями, которые представляют более или менее самостоятельные протоколы (
* '''dst''' — проверят опции назначения (подзаголовок 60 Destination Options). Имеет две опции:
Строка 1064:
<tt>[!] --dst-opts ''код''[:''длина''][,''код''[:''длина'']...]</tt> — позволяет проверить вхождение в данный подзаголовок конкретных опций. Также можно проверить длину каждой из них. Можно указать до 16 опций (представленных числовыми кодами), разделяя их запятой.
* '''eui64''' — сравнивает младшие 64 бита исходного IPv6-адреса с битами исходного
* '''frag''' — позволяет проверять параметры фрагментации (подзаголовок 44 Fragment). Допустимые опции:
Строка 1076:
<tt>--fraglast</tt>/<tt>--fragmore</tt> — проверяют M-флаг, показывающий, является ли данный фрагмент последним в последовательности (в этом случае <tt>--fraglast</tt> дает истину, а <tt>--fragmore</tt> ложь), или после него должны быть еще фрагменты (соответственно, наоборот). Эти две опции являются взаимоисключающими.
Также в документации можно найти упоминание параметра <tt>--fraglen </tt>, который якобы проверяет длину подзаголовка Fragment. Однако, согласно текущим соглашениям, длина этого подзаголовка фиксирована и равна 8
* '''hbh''' — проверяет опции Hop-by-Hop (подзаголовок 0 Hop-by-Hop). Синтаксис аналогичен параметру dst.
Строка 1104:
<tt>--rt-0-not-strict</tt> — делает условие проверки по предыдущем параметру не таким жестким: достаточно, чтобы хотя бы один из перечисленных адресов совпадал с соответствующим адресом в подзаголовке, при соблюдении порядка перечисления.
=====
ICMPv6 является протоколом контрольных сообщений IPv6. Несмотря на то, что ICMPv6 формально является самостоятельным протоколом, и обращение к соответствующему критерию должно производиться с использованием синтаксиса для протокола (<tt>-p</tt>), а не для вспомогательного критерия (<tt>-m</tt>), де-факто этот протокол неотделим от IPv6, и поэтому соответствующий критерий может использоваться только в ip6tables, но не в iptables.
Строка 1140:
Также к данному критерию допустимо обращение по названию ipv6-mh (<tt>-p ipv6-mh</tt>).
====
netfilter «знает» два протокола из семейства IPsec: [[:en:IPSec#Authentication_Header|Authentication Header]] (<tt>-p ah</tt>) и [[:en:IPSec#Encapsulating_Security_Payload|Encapsulating Security Payload]] (<tt>-p esp</tt>).
Строка 1171:
Возможные состояния:
:* '''NEW''' — соединение не открыто, то есть пакет является первым в соединении. Полезные примеры использования этого состояния приведены выше, в частности, при описании [[
:* '''ESTABLISHED''' — пакет относится к уже установленному соединению. Обычно такие пакеты принимаются без дополнительной фильтрации, как и в случае с RELATED.
:* '''RELATED''' — пакет открывает новое соединение, логически связанное с уже установленными, например, открытие канала данных в пассивном режиме
Например:
<source lang="bash">
Строка 1189:
Этот набор команд обеспечит функционирование на хосте FTP-сервера с поддержкой как активного, так и пассивного режимов. В пассивном режиме FTP клиент сначала устанавливает управляющее соединение на TCP-порт 21 сервера. Когда возникнет необходимость передачи данных, клиент даст серверу команду PASV. Сервер выберет высокий порт и подключится к нему в режиме прослушивания, отправив номер порта клиенту по управляющему соединению. Система [[conntrack]], при наличии подгруженного модуля ядра nf_conntrack_ftp, зафиксирует это сообщение и выделит номер порта. Когда клиент откроет соединение данных на этот высокий порт, система conntrack присвоит первому пакету статус RELATED, в результате чего пакет пройдет по нашему правилу и будет принят. Остальные пакеты в этом соединении будут иметь уже статус ESTABLISHED и тоже будут приняты.
Возможность корректно обрабатывать пассивный режим FTP, как это было описано выше, из всех [[unix]]-фаерволов доступна только в iptables. В других фаерволах для решения данной проблемы используются различные «костыли». Например, в
С обработкой активного режима таких проблем не возникает, так как сервер сам устанавливает соединение данных с порта 20, поэтому первый пакет пропускается согласно правилу по умолчанию цепочки OUTPUT. Правда, проблемы могут возникнуть на стороне фаервола клиента, но это уже не относится к компетенции сервера.
Строка 1200:
:* '''UNTRACKED''' — отслеживание состояния соединения для данного пакета было отключено. Обычно оно отключается с помощью действия NOTRACK в таблице raw.
:* '''DNAT''' — показывает, что к данному соединению применена операция подмены адреса назначения (об операциях преобразования адресов см. [[
:* '''SNAT''' — показывает, что к данному соединению применена операция подмены адреса источника (об операциях преобразования адресов см. [[
Остальные параметры критерия conntrack, как уже говорилось, мы опишем лишь конспективно.
Строка 1209:
Применяется для определения статуса соединения в системе conntrack. Возможные статусы:
:* '''EXPECTED''' — данное соединение ожидалось системой conntrack по результатам анализа других соединений. Например, после того, как клиент и сервер через управляющее
:* '''CONFIRMED''' — подтвержденное соединение. Такой статус присваивается соединению после того, как инициатор начал передачу пакетов.
:* '''SEEN_REPLY''' — соединение, по которому поступил ответ, то есть имеет место передача данных в обоих направлениях (поддержка данного состояния появилась сравнительно недавно).
Строка 1217:
* <tt>[!] '''--ctproto''' ''протокол''</tt>
Протокол [[w:Транспортный уровень |транспортного уровня]], определенный системой conntrack. Синтаксис аналогичен стандартному критерию <tt>-p</tt>.
* <tt>[!] '''--ctdir''' {ORIGINAL|REPLY}</tt>
Строка 1275:
Система conntrack присваивает каждому соединению тайм-аут (счетчик обратного отсчета времени). Когда этот счетчик доходит до нуля, система conntrack удаляет информацию о соединении из своих таблиц. Тайм-аут устанавливается в значение по умолчанию каждый раз, когда по соединению передаются данные. Таким образом, активно используемые соединения никогда не будут сброшены.
Заметим, что значения тайм-аута по умолчанию для разных протоколов, и даже для одного протокола на разных стадиях установки соединения, могут различаться. Например, для протокола
==== state ====
Строка 1300:
К этой группе можно отнести критерии, расширяющие возможности других критериев.
* '''multiport''' — позволяет указать несколько (до 15) портов и/или их диапазонов (для протоколов
<tt>[!] --sports</tt>, <tt>--source-ports ''порт''[:''порт''][,''порт''[:''порт''][,...]]</tt> — улучшенная версия критерия <tt>--sport</tt>, описанного выше. Позволяет перечислить (без пробелов, через запятую) до 15 портов или их диапазонов.
Строка 1312:
<tt>[!] --ports ''порт''[:''порт''][,''порт''[:''порт''][,...]]</tt> — пакет будет подпадать под этот критерий, если его исходный порт ''или'' порт назначения присутствует в указанном списке.
* '''iprange''' — позволяет указать диапазон
<tt>[!] --src-range ''адрес''[-''адрес'']</tt> — позволяет указать диапазон исходных адресов. Например,
Строка 1332:
будет выделять пакеты с маркировкой 15.
Если указана маска, то перед сравнением с заданным значением маркировка каждого пакета комбинируется с этой маской посредством логической операции [[w:Конъюнкция |AND]], то есть проверяется условие <tt>x & ''маска'' == ''значение''</tt> (где x — маркировка текущего пакета). Такой подход позволит сравнивать значения отдельных
<source lang="bash">
-m mark --mark 64/64
Строка 1346:
* '''connmark''' — полностью аналогичен mark, но проверяет не маркировку пакета (nfmark), а маркировку соединения (ctmark). Также имеет параметр <tt>--mark</tt> с аналогичным синтаксисом.
В качестве практического примера использования меток пакетов и соединений рассмотрим улучшение работы
Userspace-вариант
Задача l7-filter — определить тип протокола [[
Как описывается в [http://l7-filter.sourceforge.net/technicaldetails документации], версия l7-filter-kernel ''хранит'' данные о соединениях и ''использует'' их для классификации пакетов, принадлежащих к соединениям, тип которых уже установлен. В то же время, аналогичное утверждение в отношении l7-filter-userspace в документации отсутствует. И, как показывает практика, userspace-версия ''не использует'' информацию о соединениях. Возможно, это обусловлено техническими ограничениями nfnetlink_queue как средства взаимодействия l7-filter с системой netfilter.
Описанный недостаток значительно снижает эффективность l7-filter — ведь однозначно классифицированы могут быть всего несколько пакетов из каждого соединения, а всего в соединении могут быть миллионы и миллиарды пакетов. Соответственно, применение l7-filter по своему основному назначению — классификация трафика для последующего [[w:Шейпинг (информатика) |шейпинга]] — не оправдывает себя.
Итак, рассмотрим, как, используя возможности netfilter, можно исправить этот недостаток.
Строка 1374:
iptables -t mangle -A OUTPUT ! -o lo -j NFQUEUE --queue-num 2
</source>
Добавлять второе из этих правил в цепочку POSTROUTING не стоило — ведь в нее попадает как трафик, исходящий от самого хоста, так и транзитный трафик, который уже был обработан ранее, в цепочке PREROUTING. Посмотрев на диаграмму выше, вы можете убедиться, что приведенные правила обрабатывают весь трафик, как принадлежащий самому хосту, так и транзитный, за исключением локального. Локальный трафик (идущий через интерфейс [[
Теперь добавим правила, обеспечивающие копирование маркировки пакетов в маркировку соединений и обратно:
Строка 1391:
Второй момент, который стоит пояснить — маски специального вида. По сути, они позволяют проверить, лежит ли маркировка пакета в диапазоне от 16 до 31. Такая защита позволяет избежать обработки маркировок 0 (такую маркировку имеет локальный трафик, так как он не проходит процедуру анализа), 1 и 2 (эти значения маркировки, как уже было замечено выше, означают, что тип пакета не определен), а также 32 и выше (эти значения мы оставляем для других задач).
Как показывает [http://www.linux.org.ru/jump-message.jsp?msgid=3790164&cid=3791754 практика], даже в самом примитивном случае (детекция протокола
Более того, предложенный метод решает задачу, не решенную даже в реализации l7-filter-kernel — маркировка связанных соединений. Согласно документации iptables, маркировка соединений автоматически копируется с исходных соединений на связанные с ними (например, с управляющего
: ''Примечание: следующий пример планируется к переносу в еще не написанный раздел статьи (Прочие критерии → statistic)''.
В качестве практического примера использования меток пакетов и соединений можно рассмотреть задачу [[w:Случайная величина |стохастической]] балансировки соединений между несколькими [[аплинк]]ами.
Допустим, у нас есть три провайдера, подключенных к интерфейсам eth0, eth1 и eth2 (это могут быть и
Для начала, создадим для каждого провайдера свою таблицу маршрутизации
Строка 1431:
</source>
Таблица static предназначена для обслуживания статических маршрутов. В частности, в нее мы занесем подсети провайдеров (предположим, что все они [[
<source lang="bash">
# Провайдеры
Строка 1447:
По сути дела, таблица static обычно содержит те же маршруты, что и таблица main (главная таблица маршрутизации), за исключением маршрута по умолчанию — таких маршрутов у нас несколько и каждый из них размещается в отдельной таблице, выбор между которыми осуществляется на основании назначенной iptables/netfilter маркировки.
Заметим, что ни в таблицу static, ни в какие-либо другие таблицы не нужно вносить
Далее, отключим статическую антиспуфинговую фильтрацию:
Строка 1455:
Reverse path filtering — штука, конечно, удобная и полезная но, к сожалению, совершенно не совместимая с динамической маршрутизацией.
Если вы планируете использовать этот компьютер не только как [[w:Сетевой шлюз |шлюз]], и но и как интернет-
<source lang="bash">
iptables -t mangle -N bind_connect # Создаем отдельную цепочку (для простоты управления)
Строка 1467:
Теперь, в сочетании с операцией <tt>-j CONNMARK --restore-mark</tt>, которой мы подвергнем исходящий с нашего сервера трафик (см. ниже), эта процедура обеспечит корректную обработку входящих соединений. (Отметим, что, если бы нам не нужно было бы балансировать исходящие соединения, мы могли бы обойтись вообще без помощи iptables/netfilter, выполнив привязку входящих соединений через правила вида <tt>ip rule add from 208.77.188.100 table prov1</tt> и т.п. — ответные пакеты всегда уходят с того же адреса, на который пришел запрос, так что в качестве критерия для выбора шлюза можно использовать исходный адрес.)
Ввиду того, что выбор исходящего адреса для каждого нового соединения осуществляется на основании правил статической маршрутизации (таблица main), могут возникнуть ошибки. Например, если в маршруте по умолчанию (default) в таблице main указан интерфейс eth0, то все исходящие от нас во внешнюю сеть (интернет) соединения будут иметь в качестве исходного адреса первый адрес интерфейса eth0, и ответные пакеты пойдут именно на этот интерфейс. Чтобы избежать возникновения таких ситуаций, добавим
<source lang="bash">
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 208.77.188.100
Строка 1495:
iptables -t mangle -A sort_connect -j CONNMARK --restore-mark # Копируем маркировку соединений на пакеты
</source>
Через цепочку <tt>select_prov</tt> мы прогоняем только новые пакеты, то есть первые пакеты каждого соединения. После этой процедуры соединение уже имеет маркировку. К сожалению, на данный момент роутинговая подсистема ядра [[w:Ядро Linux
Осталось только добавить вызов этой цепочки в таблицу mangle:
Строка 1510:
Разумеется, при этом должна быть разрешена передача транзитного трафика, как в таблице filter, так и на уровне sysctl. Как это делается — см. выше.
Заметим, что кроме алгоритма случайной балансировки, критерий statistic позволяет реализовать балансировку в режим [[w:Round-robin (алгоритм) |round robin]]. Для этого поменяем цепочку <tt>select_prov</tt> следующим образом:
<source lang="bash">
iptables -t mangle -F select_prov # Очищаем ее
Строка 1526:
ip route add default scope global nexthop via 208.77.188.1 dev eth0 weight 1 nexthop via 208.77.189.1 dev eth1 weight 1 # И т.д.
</source>
Стоит обратить особое внимание на тот факт, что данный метод балансирует ''пакеты'', а не соединения. Например, в том случае, если вы хотите организовать выход в интернет из локальной сети через нескольких провайдеров, не имея единого внешнего адреса, этот метод может работать некорректно — часть пакетов пройдет через одного провайдера и после операции
Также заметим, что описанные в этом примере методы балансировки не учитывают загруженность каналов. Для этого рекомендуется использовать критерий rateest и действие RATEEST совместно с уже знакомым нам CONNMARK.
Строка 1552:
iptables -P INPUT DROP
</source>
Это пример попытки защитить
<source lang="bash">
iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Строка 1601:
-m hashlimit --hashlimit-mode srcip --hashlimit-srcmask 28
</source>
будет заводить отдельную очередь для каждой подсети с маской 255.255.255.240 (подробнее про префиксы и маски см.
По умолчанию 32 (своя очередь для каждого отдельного хоста). Если указать 0, то контроль по параметру srcip теряет смысл.
Строка 1616:
iptables -P INPUT DROP # Всех остальных не пускаем
</source>
Теперь очереди ограничений для подключения к службам
<source lang="bash">
iptables -F INPUT # Очищаем цепочку INPUT
Строка 1630:
Доступ к таблицам очередей возможен через procfs (файл <tt>/proc/net/ipt_hashlimit/имя_таблицы</tt>). Подробнее о формате этого файла можно почитать [http://www.opennet.ru/base/net/iptables_tbf.txt.html здесь], однако учтите, что большая часть сведений, приведенных в указанной статье, устарела.
Критерий haslimit также имеет ряд параметров, не описанных здесь (максимальный размер таблицы, время жизни записи в таблице, интервал [[
* '''connlimit''' — позволяет ограничивать количество одновременно открытых соединений с каждого IP-адреса (или подсети). Параметры:
Строка 1650:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
</source>
разрешит не более пяти одновременных соединений на порт 80 с каждой подсети [[
Не надо путать connlimit с hashlimit — hashlimit позволяет ограничить ''скорость'' поступления пакетов с хостов или подсетей (в сочетании с <tt>-m conntrack --ctstate NEW</tt> — скорость открытия новых соединений), а connlimit — ''количество'' одновременно открытых соединений.
Строка 1673:
Таким образом, все пакеты, принадлежащие «легким» соединениям, будут маркироваться как наиболее приоритетные, а пакеты, проходящие по «тяжеловесным» соединениям — как наименее приоритетные. Такой подход позволит рационально распределять канал между различными задачами, например, просмотром веб-страниц («легкие» соединения) и скачиванием файлов («тяжелые» соединения).
Конечно, при таком подходе даже «тяжелые» соединения будут занимать канал с наивысшим приоритетом, пока не превысят ограничение. Но даже на медленных соединениях (128 Кбит/с) для этого достаточно всего четырех секунд (если эта закачка в данный момент единственная). После превышения лимита 50 Кбайт соединение получит средний приоритет ([[
* '''quota''' — позволяет задать квоту в байтах для данного конкретного правила. Имеет единственный параметр
Строка 1700:
echo значение > /proc/net/xt_quota/имя
</source>
Для осуществления этих действий, как и для работы с iptables, нужны полномочия [[w:Root
<tt>[!] --quota ''количество''</tt> — проверяет текущее значение счетчика и уменьшает его на размер текущего пакета. Этот же параметр задает начальное значение счетчика (если счетчик с таким именем уже существует, он не сбрасывается). Пакет считается подпадающим под критерий, если счетчик еще не дошел до нуля (при указании логической инверсии — наоборот). Если немного усложнить наш предыдущий пример,
Строка 1730:
Обратите внимание, что при указании параметра grow критерий quota2 ''всегда'' будет возвращать истину. Действие для такого правила обычно назначать не имеет смысла — правило изменяет только счетчик квоты, а не сам пакет.
* '''length''' — позволяет использовать в качестве критерия размер пакета. Проверятся размер пакета протокола транспортного уровня (
<tt>[!] --length ''размер''[:''макс_размер'']</tt>, который может употребляться в нескольких формах:
Строка 1744:
Смысл всех приведенных форм может быть заменен на противоположный, как обычно, указанием перед данным параметром восклицательного знака. Все размеры задаются в байтах.
В качестве практического примера использования данного критерия можно рассмотреть установку высокого приоритета [[
<source lang="bash">
iptables -t mangle -I INPUT -m length --length :512 -j TOS --set-tos Minimize-Delay
</source>
* '''length2''' — расширение критерия length, доступное в наборе xtables-addons. Отличается от классического length возможностью проверять размеры пакетов на различных уровнях [[
<tt>--layer3</tt> — проверка размера пакета сетевого уровня (например, IPv4-пакета).
Строка 1755:
<tt>--layer4</tt> — проверка размера пакета транспортного уровня (например, TCP-пакета).
<tt>--layer5</tt> — проверка размера полезной нагрузки транспортного уровня (например, содержимого TCP-пакета, ''не'' учитывая размер заголовков TCP). Работает корректно только для некоторых протоколов транспортного уровня, на момент написания этих строк (конец 2009) поддерживаются:
<tt>--layer7</tt> — для SCTP проверяется суммарный размер DATA-секций в пакете (то есть его полезная нагрузка), для остальных протоколов аналогично <tt>--layer5</tt>.
Строка 1774:
'''Подводя краткий итог по разделу «Лимитирующие критерии»''', хотелось бы заметить, что перечисленные в этом разделе критерии предназначены главным образом для ограничения доступа и защиты от различных атак. Не стоит пытаться ограничивать с их помощью трафик. Для ограничения и приоритезации трафика в [[Linux]] рекомендуется использовать стандартный [[
<!-- Если же вам нужно ограничить именно трафик, а не отдельные пакеты или соединения, то рекомендуем использовать для этого [[
==== Критерий recent ====
Строка 1781:
recent — это специальный критерий, позволяющий запоминать проходящие через него пакеты, а затем использовать полученную информацию для принятия решений. Ввиду его уникальности, широких возможностей и, как следствие, некоторых трудностей в понимании новичками принципов его использования, рассказ о нем был вынесен в отдельный подраздел.
Если быть точным, recent запоминает не сами пакеты, а их количество, время поступления, адрес источника (в последних версиях iptables также может запоминать и адрес назначения), а также, при необходимости, [[
В начале кратко рассмотрим его опции:
Строка 1799:
Заметим, что, хотя в официальной документации для параметров <tt>--seconds</tt> и <tt>--hitcount</tt> указывается возможность отрицания (указания перед ними восклицательного знака), на самом деле такое отрицание никак не обрабатывается в коде и не меняет смысла параметров, так что указывать его бессмысленно. Эта ошибка в документации исправлена в версии iptables 1.4.7.
<tt>--rttl</tt> — дополнительно к адресу источника/назначения, заносить в список и проверять еще и [[
<tt>--rsource</tt> — эта опция появилась в последних версиях iptables, с тех пор, как критерий recent начал поддерживать запоминание адресов не только источника, но и назначения. Позволяет явно указать, что в список вносится именно адрес источника пакета. Однако в целях обратной совместимости этот режим используется по умолчанию, и поэтому указывать данную опцию не обязательно.
Строка 1805:
<tt>--rdest</tt> — эта опция появилась в последних версиях iptables. Позволяет явно указать, что в список вносится именно адрес назначения пакета.
<tt>--name ''имя''</tt> — позволяет указать имя списка при использовании нескольких списков. По умолчанию используется список DEFAULT. Каждый список представлен псевдофайлом <tt>/proc/net/xt_recent/''имя''</tt> (на старых ядрах критерий recent реализован только для
<source lang="bash">
cat /proc/net/xt_recent/имя # вывести список на экран
Строка 1815:
Теперь давайте рассмотрим несколько примеров.
* Блокирование
<source lang="bash">
iptables -N ssh_brute_check # Создаем цепочку для проверки попыток соединений на защищаемый порт
Строка 1830:
iptables -P INPUT DROP # Что не разрешено — то запрещено
</source>
Теперь все попытки открыть новое SSH-соединение проверяются, и с одного
Впрочем, данный пример весьма тривиален, и сходную функциональность можно получить и при помощи критерия hashlimit:
Строка 1869:
iptables -I INPUT -i eth0 -j portscan_check
</source>
В данном случае сканированием портов считается обращение на порт 139/tcp (
Для предыдущего примера реализация очистки списка адресов достигается следующим образом:
Строка 1884:
</source>
Проводя аналогию с ныне почившим проектом [http://www.opennet.ru/docs/RUS/portsentry/portsentry-security.html.gz PortSentry], первый наш пример соответствует режиму PortSentry «Advanced Stealth Scan Detection», а второй — «Enhanced Stealth Scan Detection». (Правда, заметим, что в режиме Advanced Stealth Scan Detection блокировка производится после ''первого'' попадания пакета на нерабочий порт — для достижения такого же эффекта в нашем примере достаточно выкинуть проверки на seconds и hitcount из блокирующих правил.) Однако, использование iptables/recent имеет значительное преимущество перед примитивными userspace-системами наподобие PortSentry — возможность интеграции с системой [[conntrack]], что позволяет избежать ошибочной блокировки, например, при использовании высоких портов для
* Открытие порта «по стуку».
Строка 1968:
Обратите внимание на технику реализации процесса — цепочки фаз вызываются не через <tt>-j</tt>, а через <tt>-g</tt>, поэтому после прохождения этих цепочек к пакетам сразу применяется правило по умолчанию цепочки INPUT, то есть DROP. В противном случае пакеты доходили бы до правила сброса (которое с multiport), и процесс стука все время сбрасывался бы.
Последовательный стук в порты можно организовать, например, утилитой
<source lang="bash">
for it in {21210,11992,16043,23050}; do
Строка 1980:
==== Критерий u32 ====
Данный критерий предоставляет очень гибкий инструмент, позволяющий производить сложные операции по анализу содержимого пакета. Алгоритм обработки содержимого исследуемого пакета задается на специальном [[Язык программирования|языке программирования]], своеобразном «[[w:Язык ассемблера |ассемблере]]». Такой подход позволяет получить огромную гибкость, но при этом его изучение и использование может представлять определенные трудности для пользователей, не знакомых с основами [[Программирование|программирования]] и принципами работы [[Машина Тьюринга|машины Тьюринга]].
Этот критерий имеет единственный параметр — <tt>[!] --u32</tt>, после которого в двойных кавычках записывается текст «программы». Если все проверки, заданные в программе, дают истинный результат, пакет считается удовлетворяющим данному критерию. Традиционно, если перед параметром указан восклицательный знак, означающий логическое отрицание, то удовлетворяющими критерию считаются только те пакеты, для которых хотя бы одна проверка дала ложный результат.
Строка 1989:
* '''&''' — оператор побитового логического И, позволяющий применить к обрабатываемому значению битовую маску.
* '''<<''' и '''>>''' — операторы побитового сдвига влево и вправо соответственно. Эквивалентны домножению или делению обрабатываемого значения на 2 в соответствующей степени. Обратите внимание, что в одном выражении для проверки можно использовать не более 9 операторов &, << и >>.
* '''@''' — оператор задания смещения. Добавляет результат предыдущего выражения к текущему значению начального смещения (в начале работы программы, до выполнения @-операций, начальное смещение считается нулевым). Очень полезен в тех случаях, когда нужно сместиться на некоторое значение, полученное в результате обработки пакета, например, узнав после некоторых вычислений длину IP-заголовка, мы можем сместиться на данные непосредственно после него, т.е. на начало полезной нагрузки IP-пакета (как правило, там находится заголовок [[w:Транспортный уровень |транспортного уровня]]).
Все операторы имеют равный приоритет, исполнение операций всегда происходит слева направо.
Строка 1995:
Обратите внимание, что программа рассматривает все значения как целые беззнаковые величины, заданные 32 битами, или четырьмя октетами (что соответствует значениям от 0 до 4294967295). Именно поэтому критерий имеет такое название (u32 — unsigned 32-bit).
Другой не вполне очевидный момент — синтаксис операторов =, &, << и >>. Дело в том, что в качестве первого операнда указывается не само значение, а его ''адрес'' в пределах пакета, заданный смещением в байтах от текущего начального смещения. Например, <tt>8 = 0x12345678</tt> означает, что нужно взять четыре байта, начиная с восьмого (обратите внимание, что нумерация байтов в пакете начинается нуля), т.е. байты 8, 9, 10 и 11, и сравнить полученное значение с шестнадцатеричным числом 0x12345678. Как уже говорилось, критерий u32 ''всегда'' манипулирует блоками по четыре байта, поэтому, если вас интересуют блоки меньшего размера, используйте оператор & и маску, например, <tt>8 & 0xFF = 0x78</tt> позволяет проверить только последний в блоке (11-й от начального смещения) байт. Также можно использовать и оператор смещения, например, <tt>8 >> 24 = 0x12</tt> возьмет первый в блоке (8-й от начального смещения) байт и сравнит его с числом 0x12. Более подробно о битовых операциях можно почитать в [[w:Битовые операции |соответствующей статье]].
Рассмотрим возможности критерия u32 на нескольких простых примерах из официальной документации:
* Проверить, превышает ли длина пакета величину 256 байт: <tt>--u32 "0 & 0xFFFF = 0x100:0xFFFF"</tt>.
Эта программа предписывает взять четыре байта, начиная с нулевого, затем занулить первые два байта (в них [[w:IP#Пакет (датаграмма) |содержится]] информация о версии протокола, длине заголовка и [[
* Проверить, является ли данный пакет
Рассмотрим эти операции последовательно:
:*'''6 & 0xFF = 1''' — проверка кода протокола. Код протокола хранится в 9-м (считая с нуля) байте IPv4-заголовка. Чтобы получить это значение, мы берем 4-х байтовый блок с шестого по девятый байт, а затем при помощи маски выделяем последний, интересующий нас байт в это блоке, и сравниваем его с единицей (код протокола ICMP).
Строка 2006:
:*'''0 >> 22 & 0x3C @''' — определение длины IP-заголовка в байтах. Последние четыре бита в первом байте IP-пакета показывают длину IP-заголовка в блоках по четыре байта. Смещая это значение на 22 позиции вправо, мы оставляем справа «зазор» в два бита, которые впоследствии зануляем при помощи маски (3C<sub>16</sub> = 111100<sub>2</sub>). Также эта маска отсекает лишние биты слева (версия протокола). Полученные два нулевых бита справа соответствуют умножению на четыре, так что в результате мы получаем длину заголовка уже в байтах. Например, если длина IP-заголовка составляет 5 четырехбайтовых блоков (т.е. 20 байт), то изначально первый блок заголовка имеет вид <tt>xxxx0101 yyzzzzzz uuuuuuuu uuuuuuuu</tt> (где биты <tt>xxxx</tt> задают версию протокола, 0101<sub>2</sub>=5<sub>10</sub> — собственно длину заголовка, <tt>yyzzzzzz</tt> — тип обслуживания, а два байта <tt>uuuuuuuu uuuuuuuu</tt> показывают полную длину пакета вместе с нагрузкой), то после смещения вправо на 22 бита мы получим в этом блоке следующую картину: <tt>00000000 00000000 000000xx xx0101yy</tt>. После применения маски она пример вид <tt>00000000 00000000 00000000 00010100</tt>. Полученное число — 10100<sub>2</sub>=20<sub>10</sub> и будет равно длине заголовка в байтах. Наконец, оператор @ устанавливает полученное значение в качестве начального смещения, поэтому вся дальнейшая адресация ведется уже начиная с начала ICMP-заголовка, который следует непосредственно после IP-заголовка.
:*'''0 >> 24 = 0''' — выделяет блок с нулевого по третий байт ICMP-заголовка, а затем при помощи смещения (на три байта вправо) оставляет от него только один, нулевой, байт, в котором и хранится тип ICMP. Нас интересует тип 0, поэтому мы и сравниваем этот байт с нулем.
* Проверить, задают ли байты с восьмого по одиннадцатый полезной нагрузки
:*'''6 & 0xFF = 6''' — выделение байта с кодом протокола и сравнение его с кодом 6 (соответствует TCP). Описание этой проверки уже приведено при рассмотрении предыдущего примера.
:*'''4 & 0x3FFF = 0''' — проверка, не является ли данный пакет фрагментом. Полностью аналогична описанной в предыдущем примере.
Строка 2105:
=== Модули критериев и действий ===
== Параметры
=== Псевдофайлы procfs ===
Строка 2120:
=== Параметры, относящиеся к протоколам ===
====
====
====
=== Параметры [[conntrack]] ===
Строка 2148:
== Команды ==
Программа позволяет задать правила, которым должны соответствовать проходящие через [[w:Межсетевой экран |брандмауэр]] [[IP-пакет]]ы. Эти правила, как и все настройки [[Linux]], записываются в текстовый файл, находящийся в папке /etc. Последовательность правил называется цепочкой (CHAIN). Для одного и того же сетевого интерфейса используются несколько цепочек. Если проходящий пакет не соответствует ни одному из правил, то выполняется действие по умолчанию.
При вызове, параметром указывается команда, которую нужно выполнить. Обычно можно указать только одну команду (но есть исключения). Команду можно указать одной большой буквой или словом. Если при вызове любой команды не указано название таблицы, то команда выполняется в таблице filter. Программа имеет подробную справку, вызываемую командой ''man iptables''.
Строка 2158:
<tt>iptables -t nat -n -L</tt>
Часто используются параметры -n (во избежение медленных запросов
Команду -L можно использовать с -Z (<tt>iptables -L -Z</tt>) для вывода значений счетчиков и одновременного их обнуления.
Строка 2235:
* <tt>'''-s'''</tt>, <tt>--src</tt>, <tt>--source [!] ''адрес''[/''маска'']</tt>
Ограничение отправителя. Адрес может быть
Настоятельно не рекомендуется использовать имена, для разрешения которых требуется удаленный запрос, например по системе
* <tt>'''-d'''</tt>, <tt>--dst</tt>, <tt>--destination [!] ''address''[/''mask'']</tt>
Строка 2320:
==== mac ====
Сравнение не IP источника пакета, а его
<tt>[!] --mac-source address</tt>.
Если нужна фильтрация по MAC-адресу в мостовых соединениях (например, pppoe), то можно воспользоваться утилитой
== Примечания ==
Строка 2341:
== Ссылки ==
* [[Настройка межсетевого экрана в Linux]]▼
▲* [[Настройка межсетевого экрана в Linux]]
*
* [http://security.maruhn.com/iptables-manual.html Man page of iptables] {{ref-en}}
* [http://www.frozentux.net/documents/iptables-tutorial/ Frozentux Iptables Tutorial]*{{ref-en}}
Строка 2349:
* [http://wiki.archlinux.org/index.php/Simple_stateful_firewall_HOWTO#Prerequisites Простой полноценный межсетевой экран (готовый шаблон для дектопа)] {{ref-en}}
* [http://posix.ru/network/iptables Настройка межсетевого экрана Iptables (готовый шаблон для дектопа)]*{{ref-ru}}
*
*
* {{Unix man |ufw|8}} {{ref-en}}
* {{Unix man |gufw|8}} {{ref-en}}
*
*
* https://help.ubuntu.com/community/Gufw {{ref-en}}
* https://help.ubuntu.com/9.10/serverguide/C/firewall.html {{ref-en}}
* https://wiki.ubuntu.com/UncomplicatedFirewall {{ref-en}}
* https://help.ubuntu.com/community/Firewall {{ref-en}}
{{Темы |Linux |Компьютерные сети}}
|