Iptables: различия между версиями

Содержимое удалено Содержимое добавлено
+ {{Темы|}} (были: явные категории), Категория:Linux (была: Категория:GNU/Linux), {{Готовность|}}; − ссылки на другие языковые разделы.
Ссылки на несуществующие страницы заменены ссылками на статьи Википедии; →‎Ссылки: оформление; {{Unix man|}}.
Строка 3:
|logo =
|developer = Netfilter Core Team
|programming_language = [[w:Си (язык программирования) |C]]
|operating_system = часть [[w:Ядро Linux (ядро)|ядра Linux]]
|latest_release_version = 1.4.21
|latest_release_date = 2013-Nov-22
|genre = [[{{w |Межсетевой экран]]}}
|license = [[w:GNU General Public License |GNU GPL]]
|website = [http://www.netfilter.org/ www.netfilter.org]
|screenshot = [[File:Iptablesfb.png|300px|iptables]]
}}
'''iptables''' — утилита [[интерфейсw:Интерфейс командной строки |командной строки]], является стандартным интерфейсом управления работой [[межсетевойw:Межсетевой экран |межсетевого экрана]] (брандмауэра) '''[[{{w |netfilter]]}}''' для [[w:Ядро Linux (ядро)|ядер Linux]] версий 2.4 и 2.6. Для использования утилиты iptables требуются привилегии [[суперпользовательw:Root |суперпользователя]] (root).
 
Иногда под словом iptables имеется в виду и сам межсетевой экран netfilter.
 
== История ==
Изначально разработка netfilter и iptables шла совместно, поэтому в ранней истории этих проектов есть много общего. Подробности см. в статье про [[{{w |netfilter]]}}.
 
Предшественниками iptables были проекты [[{{w |ipchains]]}} (применялась для администрирования фаервола ядра Linux версии 2.2) и [[ipfwadm]] (аналогично для ядер Linux версий 2.0). Последний был основан на [[{{w |BSD]]}}-утилите [[{{w |ipfw]]}}.
 
iptables сохраняет идеологию, ведущую начало от ipfwadm: функционирование фаервола определяется набором правил, каждое из которых состоит из критерия и действия, применяемого к пакетам, подпадающим под этот критерий. В ipchains появилась концепция ''цепочек'' — независимых списков правил. Были введены отдельные цепочки для фильтрации входящих (INPUT), исходящих (OUTPUT) и транзитных (FORWARD) пакетов. В продолжении этой идеи, в iptables появились ''таблицы'' — независимые группы цепочек. Каждая таблица решала свою задачу — цепочки таблицы filter отвечали за фильтрацию, цепочки таблицы nat — за преобразование сетевых адресов ([[{{w |NAT]]}}), к задачам таблицы mangle относились прочие модификации заголовков пакетов (например, изменение [[Time_to_livew:Time to live |TTL]] или [[Type_of_Servicew:Тип обслуживания |TOS]]). Кроме того, была слегка изменена логика работы цепочек: в ipchains все входящие пакеты, включая транзитные, проходили цепочку INPUT. В iptables через INPUT проходят только пакеты, адресованные самому хосту.
 
Такое разделение функциональности позволило 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. Таким образом хост, настроенный согласно этому примеру и подключенный к [[{{w |Интернет]]}}у, будет недоступен извне (все попытки установить соединение снаружи блокируются), однако с самого хоста доступ к Интернету будет свободный (исходящие пакеты разрешены, а ответы на них уже относятся к установленным соединениям).
 
=== Основные компоненты ===
Строка 85:
==== iptables ====
 
Userspace-утилита, через которую [[w:Root (суперпользователь)|системный администратор]] может управлять [[{{w |IPv4]]}}-фаерволом (ip_tables). К ее задачам относятся:
* Создание и удаление пользовательских цепочек.
* Установка действий по умолчанию для базовых цепочек.
Строка 93:
* Проверка корректности задания параметров, определяющих работу критериев и действий.
* Вывод справки по использованию критериев (<tt>iptables -m ''критерий'' -h</tt>) и действий (<tt>iptables -j ''действие'' -h</tt>).
Также в комплект поставки вместе с iptables обычно входят вспомогательные утилиты, обеспечивающие сохранение (iptables-save) и последующее восстановление (iptables-restore) состояния фаервола, его инициализацию при запуске системы ([[{{w |init]]}}-скрипт) и т. п.
 
Сегментом фаервола, отвечающим за фильтрацию [[{{w |IPv6]]}}-пакетов (ip6_tables), управляет утилита ip6tables. Так как обычно она поставляется вместе с iptables, имеет похожий синтаксис и выполняет схожие задачи, под термином «iptables» часто подразумевают сразу обе эти утилиты.
 
Также в рамках данного проекта разрабатываются два набора библиотек:
* '''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-[[{{w |скрипт]]}}ов.
* '''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]]. К его задачам относятся:
* Отслеживание состояний отдельных соединений с тем, чтобы классифицировать каждый пакет либо как относящийся к уже установленному соединению, либо как открывающий новое соединение. При этом понятие "состояние соединения" искусственно вводится для протоколов, в которых оно изначально отсутствует ([[{{w |UDP]]}}, [[{{w |ICMP]]}}). При работе же с протоколами, поддерживающими состояния (например, [[{{w |TCP]]}}), conntrack активно использует эту возможность, тесно взаимодействуя с базовой сетевой подсистемой ядра Linux.
* Отслеживание связанных соединений, например, [[{{w |ICMP]]}}-ответов на [[{{w |TCP]]}} и [[{{w |UDP]]}}-пакеты. Более сложный вариант — протоколы, использующие несколько соединений в одной сессии, например, [[{{w |FTP]]}}. Для правильной обработки таких протоколов conntrack использует специальные модули (conntrack helpers), которые анализируют трафик и «выхватывают» информацию протокола о новых соединениях (например, порт, на который оно будет открыто), что позволяет обеспечить их корректную фильтрацию, маршрутизацию, шейпинг и пропускание через NAT.
 
Более подробно о возможностях системы conntrack и их использовании при работе с iptables/netfilter см. [[iptables#Механизм определения состояний|чуть ниже]].
 
В состав conntrack входят следующие компоненты:
* Главный модуль nf_conntrack. Реализует базовую функциональность отслеживания соединений, интерфейсы для работы с модулями расширений, а также механизмы отслеживания протоколов [[{{w |TCP]]}} и [[{{w |UDP]]}}.
* Трекеры протоколов [[Сетевойw:Протоколы сетевого уровня уровень|сетевого уровня]]: nf_conntrack_ipv4 и nf_conntrack_ipv6. Реализуют операции, специфичные для «своих» протоколов ([[{{w |IPv4]]}} и [[{{w |IPv6]]}} соответственно), а также механизмы отслеживания соответствующих протоколов управляющих сообщений ([[{{w |ICMP]]}} и [[{{w |ICMPv6]]}} соответственно).
* Трекеры протоколов [[w:Транспортный уровень |транспортного уровня]] (кроме [[{{w |TCP]]}} и [[{{w |UDP]]}}, реализованных в главном модуле): nf_conntrack_proto_sctp ([[{{w |SCTP]]}}), nf_conntrack_proto_dccp ([[{{w |DCCP]]}}), nf_conntrack_proto_gre ([[w:GRE (протокол) |GRE]]), nf_conntrack_proto_udplite ([[{{w |UDP Lite]]}}).
* Вспомогательные модули (helpers), обеспечивающие отслеживание протоколов [[Прикладнойw:Протоколы прикладного уровня уровень|прикладного]] и [[w:Сеансовый уровень |сеансового]] уровней: nf_conntrack_ftp, nf_conntrack_irc, nf_conntrack_pptp, nf_conntrack_netbios_ns и т. п. Требуются далеко не&nbsp;для всех протоколов, а только для тех, отслеживание которых требует знания специфики протокола. Например, неоднократно упоминающийся в этой статье протокол [[{{w |FTP]]}} использует в одном сеансе два соединения (управляющее соединение и соединение передачи данных), и чтобы корректно отследить соединение передачи данных, необходимо анализировать трафик управляющего соединения и выделять в нем информацию, касающуюся открытия соединения данных.
* Модуль nf_nat. Реализует базовую функциональность [[w:NAT |трансляции сетевых адресов]] и [[w:Трансляция порт-адрес |портов]] с учетом информации о соединениях. Также этот модуль содержит механизмы трансляции для протоколов [[{{w |IPv4]]}}, [[{{w |TCP]]}}, [[{{w |UDP]]}} и [[{{w |ICMP]]}} ([[{{w |IPv6]]}} и [[{{w |ICMPv6]]}} не&nbsp;поддерживаются NAT-подсистемой conntrack).
* NAT-трекеры протоколов [[w:Транспортный уровень |транспортного уровня]]: nf_nat_proto_sctp, nf_nat_proto_dccp, nf_nat_proto_gre, nf_nat_proto_udplite.
* Вспомогательные модули NAT для протоколов [[Прикладнойw:Протоколы прикладного уровня уровень|прикладного]] и [[w:Сеансовый уровень |сеансового]] уровней: nf_nat_ftp, nf_nat_irc, nf_nat_pptp и т. п.
* Модуль взаимодействия с userspace через протокол nfnetlink (см. следующий раздел) nf_conntrack_netlink, которому соответствует userspace-библиотека libnetfilter_conntrack.
* Кроме того, к conntrack можно условно отнести и модули netfilter, обеспечивающие взаимодействие этих двух подсистем: критерий conntrack (xt_conntrack), действия NOTRACK и CT (xt_NOTRACK и xt_CT), практически все действия [[iptables#Таблица nat|таблицы nat]], а также соответствующие модули (библиотеки iptables/ip6tables): libxt_conntrack, libxt_NOTRACK, libxt_CT и т. п.
 
Для взаимодействия с системой conntrack из userspace разработан комплект [http://conntrack-tools.netfilter.org/ conntrack-tools], содержащий две утилиты:
* '''conntrack''' — инструмент, позволяющий [[w:Root (суперпользователь)|системному администратору]] наблюдать таблицы состояний соединений и взаимодействовать с ними: очищать таблицы целиком, удалять отдельные записи, маркировать соединения вручную (аналог действия CONNMARK), устанавливать [[Тайм-аут (Телекоммуникации)|тайм-аут]]ы соединений. Поддерживается фильтрация вывода (например, на основании адресов и/или портов источника и/или назначения), а также вывод в различных форматах, включая [[{{w |XML]]}}. Кроме того, данная утилита позволяет отслеживать в реальном времени события системы conntrack, например, открытие новых соединений или изменение состояния существующих.
* '''conntrackd''' — демон, обеспечивающий синхронизацию таблиц состояний с другими хостами, что в сочетании с возможностями демона [[keepalived]] позволяет создавать фаерволы на [[{{w |кластер]]}}ах высокой доступности (High Availability) — при выходе из строя одного из хостов кластера его соединения будут «подхвачены» другими хостами кластера и корректно обработаны с учетом состояний. Также conntrackd можно использовать просто для удаленного сбора статистики по соединениям.
 
Взаимодействие conntrack с этими программами производится посредством интерфейса nfnetlink, который будет рассмотрен в следующем разделе.
Строка 131:
* '''libnetfilter_conntrack''' (ранее libnfnetlink_conntrack и libctnetlink) — обеспечивает взаимодействие приложений с системой conntrack. В качестве примеров приложений, использующих эту библиотеку, можно упомянуть:
** Описанные выше программы '''conntrack''' и '''conntrackd''' из комплекта conntrack-tools.
** '''iptstate''' — в какой-то мере аналог утилиты conntrack, хотя и не&nbsp;имеющий таких богатых возможностей. Предназначена для непрерывного вывода таблицы состояний соединений с периодическим обновлением, в стиле широко известной утилиты [[{{w |top]]}}. Поддерживает различные виды сортировки (по адресам/портам источника/назначения, [[Тайм-аут (Телекоммуникации)|тайм-ауту]], счетчикам и т. п.). Позволяет удалять записи из таблицы состояний. Не&nbsp;поддерживает работу с таблицей ожидаемых (expected) соединений.
* '''libnetfilter_queue''' (ранее libnfnetlink_queue) — отвечает за передачу пакетов демонам на предмет анализа. По результатам этого анализа пакет может быть заблокирован или пропущен. При пропускании пакета возможна установка или изменение его маркировки (nfmark). Идеологическим предшественником libnetfilter_queue была ныне устаревшая библиотека libipq. В качестве примеров приложений, использующих libnetfilter_queue, можно упомянуть:
** '''nufw''' — фаервол, выполняющий фильтрацию трафика на основе авторизации пользователей. Позволяет устанавливать ограничения на доступ к сетям, находящимся за фаерволом, для отдельных пользователей. Авторизация пользователей на фаерволе обеспечивается отдельным демоном nuauth. Например, в случае, если клиенты используют [[Linux]], авторизация может выполняться совершенно прозрачно, благодаря возможностям [[{{w |PAM]]}} (модуль pam_nufw) в момент входа пользователя в систему. Особенно удобны подобные системы в корпоративных сетях, где используются системы централизованного управления аккаунтами пользователей (nufw/nuauth поддерживает [[{{w |LDAP]]}} и [[winbind]]).
** '''[[{{w |l7-filter]]}}-userspace''' — демон, позволяющий определить протокол [[Прикладнойw:Протоколы прикладного уровня уровень|7-го (прикладного) уровня]] [[Модельw:Сетевая модель OSI |модели OSI]], которому принадлежит полученный пакет, на основании анализа его содержимого при помощи [[Регулярные выражения|регулярных выражений]]. Результат анализа возвращает в маркировке пакета. Полезен при фильтрации и [[w:Шейпинг (информатика) |шейпинге]] трафика протоколов, не&nbsp;имеющих фиксированных номеров портов для соединений данных, например, [[BitTorrent]]. Впрочем, в настоящее время существуют и альтернативные решения — [[{{w |P2P]]}}-протоколы можно выделять при помощи критерия ipp2p (из набора xtables-addons), а вспомогательные соединения в известных системе conntrack протоколах ([[{{w |FTP]]}}, [[{{w |IRC]]}}, [[{{w |SIP]]}}) можно выделять при помощи критерия helper и маркировки соединений.
** '''iplist''' — userspace-альтернатива ipset. Как и ipset, позволяет считывать большие списки [[{{w |IP-адрес]]}}ов и проверять пакеты на предмет нахождения адреса их источника/назначения в данном списке. В зависимости от результата проверки, пакет может быть пропущен или заблокирован, либо промаркирован соответствующим образом. Разумеется, ipset, работая на уровне ядра, обеспечивает более высокую скорость проверки, а также поддерживает дополнительные возможности, например, динамическое изменение списков при помощи действия SET (добавление и удаление записей), сохранение дополнительной информации (номера [[w:Порт (TCP/IPкомпьютерные сети) |портов]], [[{{w |MAC-адрес]]}}а, [[Тайм-аут (Телекоммуникации)|тайм-ауты]] записей). Несмотря на то, что в настоящий момент ipset пока что не&nbsp;принят в ядро, современные дистрибутивы ipset позволяет произвести сборку и установку необходимых компонентов без необходимости наложения [[{{w |патч]]}}ей на ядро и iptables, благодаря возможностям подгружаемых модулей ([[:en:LKM]]) ядра [[Linux]]. Поэтому, с учетом вышесказанного, необходимость в iplist в настоящее время сомнительна.
* '''libnetfilter_log''' (ранее libnfnetlink_log) — предоставляет демонам интерфейс для получения служебной информации о пакетах на предмет регистрации и учета трафика. В настоящее время известен только один проект, использующий данную библиотеку — '''ulogd2''' ([netfilter] userspace logging daemon, версия&nbsp;2). Данный проект находится пока в бета-стадии разработки. Надо заметить, что ulogd2 может получать информацию не&nbsp;только через libnetfilter_log (действие NFLOG), но и через классический механизм libipulog (действие ULOG), а также через libnetfilter_conntrack (данный метод позволяет получать информацию не&nbsp;об отдельных пакетах, а о соединениях в целом).
 
Строка 144:
==== ipset ====
 
Представляет собой набор инструментов, позволяющий работать с большими списками (sets) [[{{w |IP-адрес]]}}ов и/или [[w:Порт (TCP/IPкомпьютерные сети) |портов]]. Поддерживается возможность динамического обновления списков при прохождении пакетов через правила [[{{w |netfilter]]}}.
 
В версии ipset&nbsp;4 и более ранних поддерживалась работа только с семейством адресов [[{{w |IPv4]]}}, однако начиная с пятой версии реализована также и поддержка [[{{w |IPv6]]}}.
 
Стоит отметить, что долгое время проект ipset существовал вне основной ветки развития [[w:Ядро Linux (ядро)|ядра Linux]]. В частности, в четвертой версии ipset «ядерные» компоненты приходилось собирать отдельно, используя заголовочные файлы текущего ядра. Однако, после выхода пятой версии, в которой были учтены все предыдущие замечания, началась работа по включению ipset в основную ветку. Она [http://www.spinics.net/lists/netfilter-devel/msg17027.html завершилась успехом]: поддержка ipset присутствует в Linux начиная с 2.6.39. В ходе этих работ протокол взаимодействия ядерной и userspace-частей ipset подвергся значительной переработке, и окончательная версия [http://git.netfilter.org/cgi-bin/gitweb.cgi?p=ipset.git;a=commit;h=d6ee5bb4e5346b84efa33858091ba4add2b26de2 получила] номер 6.0. Таким образом, в современных ядрах поддержка ipset присутствует штатно, а пользователи более старых ядер могут воспользоваться реализациями ipset версий 4 и 5, включенными в набор [http://xtables-addons.sourceforge.net/ xtables-addons].
 
ipset состоит из следующих элементов:
Строка 157:
** Добавление и удаление записей из списков, проверка наличия записи в списке.
** Вывод справочной информации по работе со списками различного типа.
* Модули расширений для утилиты ipset, соответствующие модулям расширений в ядре, например, ipset_hash_ip (тип данных hash:ip), ipset_bitmap_port (тип данных bitmap:port) и т. д. Каждый такой модуль отвечает за обеспечение [[{{w |интерфейс]]}}а между «своим» модулем ядра и конечным пользователем, в частности, проверку корректности вводимых и форматирование выводимых данных, а также вывод справочной информации по допустимым командам и параметрам. В ранних версиях ipset (до 4 включительно) такие модули выделялись в виде подгружаемых библиотек, однако в современных версиях ipset они статически включаются в основной бинарник, поэтому разделение существует лишь в исходном коде.
* Модуль netfilter xt_set (критерий set и действие SET), а также соответствующие модули (библиотеки) iptables (libxt_set и libxt_SET). Критерий set позволяет проверять различные параметры пакета ([[w:IP-адрес |IP]]/[[{{w |MAC-адрес]]}}а, [[{{w |TCP]]}}/[[{{w |UDP]]}}-[[w:Порт (TCP/IPкомпьютерные сети) |порты]] источника и/или получателя) на предмет нахождения или отсутствия в списке. Действие SET позволяет добавлять или удалять записи из списка на основании указанных параметров пакета. <!-- Отметим, что, начиная с версии iptables 1.4.9 [[{{w |IPv4]]}}-специфичные модули libipt_set и libipt_SET [http://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=commit;h=d40f1628c3717daebc437a398a285e371b5b6f7f заменены] на более универсальные libxt_set и libxt_SET, которые могут использоваться как в iptables, так и в ip6tables. -->
 
ipset поддерживает следующие типы данных (в скобках приведены названия согласно терминологии устаревшей версии ipset&nbsp;4):
* '''bitmap:ip''' (ipmap) — полный перечень [[{{w |IP-адрес]]}}ов.
* '''bitmap:ip,mac''' (macipmap) — полный перечень IP-адресов, причем вместе с каждым IP-адресом может быть сохранен [[{{w |MAC-адрес]]}}.
* '''bitmap:port''' (portmap) — полный перечень [[w:Порт (TCP/IPкомпьютерные сети) |портов]].
* '''hash:ip''' (iphash) — выборочный перечень IP-адресов (либо IP-подсетей с одинаковой маской).
* '''hash:net''' (nethash) — выборочный перечень IP-подсетей (блоков IP-адресов). В отличие от hash:ip, в одном списке могут присутствовать подсети с различными масками.
* '''hash:ip,port''' (ipporthash) — выборочный перечень IP-адресов, причем с каждым адресом может быть сохранен порт. В версии ipset&nbsp;4 и более ранних существует ограничение: адреса в пределах одного перечня должны принадлежать одному [[CIDRw:Бесклассовая адресация |блоку /16]] (/255.255.0.0, максимум 65536 адресов). Начиная с версии ipset&nbsp;5, для каждого номера порта можно также сохранять идентификатор протокола [[w:Транспортный уровень |транспортного уровня]].
* '''hash:ip,port,ip''' (ipportiphash) — выборочный перечень IP-адресов, причем с каждым адресом может быть сохранен порт и еще один IP-адрес. В версии ipset&nbsp;4 и более ранних ограничение на «первичные» адреса (первые в тройке адрес-порт-адрес) такое же, как и для ipporthash. Начиная с версии ipset&nbsp;5, для каждого номера порта можно также сохранять идентификатор протокола транспортного уровня.
* '''hash:ip,port,net''' (ipportnethash) — выборочный перечень IP-адресов, причем с каждым адресом может быть сохранен порт и IP-подсеть. В версии ipset&nbsp;4 и более ранних ограничение на «первичные» адреса такое же, как и у типа ipporthash. Начиная с версии ipset&nbsp;5, для каждого номера порта можно также сохранять идентификатор протокола транспортного уровня.
* '''list:set''' (setlist) — список списков. Может содержать списки любого перечисленного здесь типа, кроме list:set. При обращении к такому объекту из netfilter, включенные в него списки рассматриваются как один большой список. Поиск записей (критерий set) производится по всем вложенным спискам соответствующего типа. При добавлении записей (действие SET), вложенные списки поочередно проверяются (согласно порядку их перечисления) на соответствие типа и наличие свободного места, и запись добавляется в первый же подходящий. В то же время, при обращении к такому списку через утилиту ipset, он рассматривается именно как совокупность элементов-списков, что позволяет добавлять, удалять и проверять наличие именно вложенных списков, но не их элементов.
* '''hash:net,iface''' — выборочный перечень IP-подсетей, причем с каждой подсетью может быть сохранено название сетевого интерфейса. Появился в версии ipset 6.7 (входит в [[w:Ядро Linux (ядро)|Linux]] 3.1), ранние версии ipset не имеют подобных возможностей. Существует ограничение: нельзя сохранять более 64 имен интерфейсов с одним и тем же адресом подсети. Этот тип данных удобен при наличии в системе большого количества сетевых интерфейсов (например, сотен [[{{w |VLAN]]}}-интерфейсов).
 
В четвертой версии дополнительно присутствовали два типа списков, упраздненные в более поздних версиях:
Строка 178:
Практически для всех типов списков, реализованных в ipset, существует общее ограничение на максимальный размер: 65536 записей.
 
Большинство перечисленных типов данных можно разделить на две группы: полные перечни (map, bitmap) и выборочные перечни (hash, tree). Разница между этими типами состоит в следующем: если выборочный перечень сохраняет только те элементы, которые в него входят, то полный перечень представляет собой таблицу логических значений ([[{{w |бит]]}}ов) для всех элементов, которые могут входить в данный перечень, и вхождение конкретного элемента в перечень определяется значением соответствующего бита. Полный перечень всегда формируется на базе ''одного непрерывного'' диапазона значений.
 
Таким образом, выбор необходимого вам типа данных определяется конкретными условиями задачи, прежде всего, отношением усредненного количества элементов в списке к требуемому диапазону охвата. Например, если вы собираетесь хранить в списке блэк-листы адресов, замеченных в атаках на ваш сервер, целесообразнее использовать тип hash:ip, потому что атакующие вас ботнеты, как бы они ни&nbsp;были велики, все равно занимают незначительную долю адресного пространства [[{{w |IPv4]]}}. К тому же, как следует из сказанного в предыдущем абзаце, тип bitmap:ip все равно не&nbsp;может хранить адреса, выходящие за предел одной подсети [[CIDRw:Бесклассовая адресация |префикса&nbsp;16]]. Но в том случае, если вам, например, нужно задать список хостов из вашей локальной сети, имеющих доступ к каким-либо услугам (службам вашего [[{{w |сервер]]}}а, выходу в [[{{w |Интернет]]}}), и этот доступ должно иметь значительное количество хостов (а не&nbsp;единицы), то целесообразнее будет использовать bitmap:ip.
 
По поводу хранения адресов подсетей ([[w:Бесклассовая адресация |блоков]] [[{{w |IP-адрес]]}}ов) можно сказать следующее. Если вам нужно хранить большое количество блоков одного размера из ограниченного диапазона (не&nbsp;более 65536 возможных значений), например, блоки /24 из подсети /8, вы можете использовать тип bitmap:ip, указав маску. Если же вам нужно хранить блоки одного размера из достаточно широкого диапазона, например, /24 из всего адресного пространства [[{{w |IPv4]]}}, используйте тип hash:ip, также с указанием маски. При необходимости хранить в одном списке блоки ''разного'' размера, воспользуйтесь типом hash:net.
 
Что касается улучшений в версиях 5 и 6 по сравнению с четвертой и более ранними, то, помимо уже упомянутых (поддержка адресов [[{{w |IPv6]]}}, поддержка [[Тайм-аут (Телекоммуникации)|тайм-аутов]] для всех типов данных, возможность сохранения идентификатора протокола транспортного уровня в типах hash:ip,port, hash:ip,port,ip и hash:ip,port,net), стоит также отметить переход на использование nfnetlink (см. выше) для связи ядра и userspace, а также более простой синтаксис. Например, те действия, которые в ipset&nbsp;4 выглядели бы так:
<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 является ''кластерная служба''. Она характеризуется адресом ([[{{w |IPv4]]}} или [[{{w |IPv6]]}}), протоколом транспортного уровня (на данный момент IPVS поддерживает протоколы [[{{w |TCP]]}}, [[{{w |UDP]]}} и [[{{w |SCTP]]}}) и номером [[w:Порт (TCP/IPкомпьютерные сети) |порта]]. Обычно для кластерных служб выделяется отдельный адрес, который присваивается активному (на данный момент) балансировщику. В случае его отказа, адрес автоматически передается резервному балансировщику, и кластер продолжает работу. Обратите внимание, что обеспечением отказоустойчивости занимается не IPVS, а keepalived. Впрочем, использование keepalived не является строго обязательным — существуют и альтернативные подходы, например, встраивание IPVS в кластерный стек [http://linux-ha.org/ Linux-HA] (см. [[:en:Heartbeat (program)|Heartbeat]]). В том случае, если отказоустойчивость не критична (требуется только балансировка нагрузки), можно вообще обойтись без дополнительного демона, выполняя всю настройку через ipvsadm.
 
Для перенаправления пакетов на выбранный обработчик, IPVS может использовать один из следующих методов:
* '''Прямая [[{{w |маршрутизация]]}} (gatewaying)''' — применяется в том случае, если между балансировщиком и обработчиками отсутствуют [[{{w |маршрутизатор]]}}ы, т.е. они находятся в одном сегменте сети. В этом случае адрес назначения в заголовке пакетов сохраняется неизменным («кластерный» адрес), подменяются лишь [[{{w |MAC-адрес]]}}а назначения при отправке [[w:Кадр (телекоммуникации) |кадров]] с этими пакетами.
* '''[[w:Инкапсуляция (компьютерные сети) |Инкапсуляция]] IPIP''' — модификация предыдущего метода на тот случай, когда балансировщик и обработчики находятся в разных сегментах сети. При помощи инкапсуляции IP-в-IP создаются [[w:Туннелирование (компьютерные сети) |сетевые туннели]], которые объединяют балансировщик и обработчик в один сегмент виртуальной сети.
* '''[[{{w |Маскарадинг]]}} ([[{{w |NAT]]}})''' — наиболее гибкое и универсальное решение: балансировщик подменяет адреса/порты назначения проходящих пакетов на реальные адреса/порты обработчиков ([[{{w |трансляция порт-адрес]]}}). При этом обеспечивается как простота настройки (не нужно поднимать дополнительные адреса на обработчиках и туннели между балансировщиком и обработчиком), так и гибкость (целевой порт обработчика может отличаться от порта кластерной службы, что невозможно в рамках других методов). Недостатком данного метода является несколько большее потребление системных ресурсов (трансляция адресов является довольно ресурсоемкой задачей).
 
В настоящее время существует довольно обширная библиотека алгоритмов балансировки нагрузки между обработчиками:
* '''rr (round robin)''' — классическая [[w:Round-robin (алгоритм) |кольцевая схема]], когда все обработчики получают новые соединения поочередно.
* '''wrr (weighted round robin)''' — модификация кольцевой схемы на тот случай, когда одни сервера могут обрабатывать больше соединений, чем другие. Такие сервера включаются в один проход очереди по нескольку раз, и соответственно получают больше соединений.
* '''lc (least-connection)''' — новое соединение передается тому серверу, который на текущий момент обрабатывает наименьшее число соединений.
Строка 229:
* '''nq (never queue)''' — пытается передать новое соединение обработчику, который в данный момент не обрабатывает других соединений. Если все обработчики уже заняты, использует предыдущий алгоритм (sed).
 
Для отслеживания соединений к кластерным службам IPVS использует собственную систему трекинга соединений, более примитивную, но менее ресурсоемкую, нежели классический conntrack. При этом поддерживается экспорт информации о кластерных соединениях в conntrack, в целях обеспечения их корректной обработки фаерволом и трансляции адресов (при трансляции адресов используются штатные средства netfilter). Однако, для корректной обработки протоколов, использующих связанные соединения (например, [[{{w |FTP]]}}), IPVS использует возможности conntrack. Синхронизация таблицы соединений между основным и дублирующими балансировщиками полностью реализована на уровне ядра (для сравнения, в conntrack эту задачу выполняет userspace-демон conntrackd).
 
=== Механизм определения состояний ===
 
Важной особенностью iptables/[[{{w |netfilter]]}} является механизм определения состояний (connection tracking, nf_[[conntrack]]) — специальная подсистема, отслеживающая состояния соединений и позволяющая использовать эту информацию при принятии решений о судьбе отдельных пакетов. Наличие этого механизма делает netfilter полноценным stateful-фаерволом.
 
Определение состояния соединения порою бывает довольно сложной задачей. Скажем, в случае [[{{w |TCP]]}} все относительно просто — контроль состояний реализован средствами самого протокола, установлены специальные процедуры открытия и закрытия соединения. А вот в протоколе [[{{w |UDP]]}} для этого специальных процедур не предусмотрено, поэтому UDP-соединением с точки зрения [[conntrack]] является поток пакетов, следующих с интервалом, не превышающим заданный тайм-аут ([[{{w |sysctl]]}}-параметр <tt>net.netfilter.nf_conntrack_udp_timeout</tt>, по умолчанию 30 секунд), с одного и того же порта одного хоста, на один и тот же порт другого хоста.
 
Заметим, что классификация пакетов по отношению к соединениям, реализуемая системой conntrack, во многих случаях отличается от официального описания сетевых протоколов. Например, с точки зрения критерия conntrack, TCP-пакет SYN/ACK (отвечающий на SYN) — уже часть существующего сеанса, а по определению TCP такой пакет — всего лишь элемент открытия сеанса.
 
Существует также понятие «связанных соединений». Например, когда в ответ на [[{{w |UDP]]}}-пакет с нашего хоста удаленный хост отвечает [[{{w |ICMP]]}}-пакетом icmp-port-unreachable, формально этот ответ является отдельным соединением, так как использует совсем другой протокол. [[{{w |netfilter]]}} отслеживает подобные ситуации и присваивает таким соединениям статус «связанных» (RELATED), позволяя корректно пропускать их через фильтры фаервола.
 
Более сложный вариант связанного соединения — соединение данных в пассивном режиме [[{{w |FTP]]}}. FTP-сервер самостоятельно выбирает порт для прослушивания из достаточно большого диапазона, и сообщает номер порта клиенту через управляющее соединение, после чего клиент подключается к этому порту и передает данные. [[{{w |netfilter]]}}, а точнее модуль conntrack_ftp, выделяет в потоке данных управляющего соединения нужный номер порта, что позволяет корректно определить новое соединение как связанное и, соответственно, корректно пропустить его через правила фильтрации.
 
В некоторых случаях целесообразно отключить отслеживание состояния соединений. Например, если ваш сервер находится под [[w:DoS-атака |(D)DoS-атакой]] типа флуд, и вам удалось локализовать ее источники, отслеживать соединения с атакующих хостов и тратить для этого ресурсы своей системы явно не имеет смысла. В подобных случаях используется действие NOTRACK, применяемое в [[iptables#Таблица raw|таблице raw]].
 
Ниже кратко перечислены возможности, предоставляемые системой отслеживания состояний:
Строка 249:
==== Критерий состояния соединения ====
 
При помощи [[iptables#conntrack_2|критерия conntrack]] вы можете классифицировать пакеты на основании их отношения к соединениям. В частности, состояние NEW позволяет выделять только пакеты, открывающие новые соединения, состояние ESTABLISHED — пакеты, принадлежащие к установленным соединениям, состоянию RELATED соответствуют пакеты, открывающие новые соединения, логически связанные с уже установленными (например, соединение данных в пассивном режиме [[{{w |FTP]]}}). Состояние INVALID означает, что принадлежность пакета к соединению установить не удалось.
 
Например, одним простым правилом
Строка 257:
вы можете обеспечить корректное пропускание всех входящих пакетов, принадлежащих установленным соединениям, и сконцентрироваться только на фильтрации новых соединений.
 
Заменив в предыдущем правиле <tt>ESTABLISHED</tt> на <tt>ESTABLISHED,RELATED</tt> и подгрузив соответствующие модули ядра, вы автоматически обеспечите корректную фильтрацию протоколов, использующих связанные соединения — [[{{w |FTP]]}}, [[{{w |SIP]]}}, [[{{w |IRC]]}}, [[{{w |H.323]]}} и других. Такое простое (с точки зрения пользователя) решение сложной (с технической точки зрения) проблемы является безусловным достоинством фаервола [[{{w |netfilter]]}} и ядра [[Linux]] в целом.
 
Более подробно об использовании этого критерия вы можете почитать [[iptables#conntrack_2|ниже]].
 
Кроме критерия conntrack, стоит упомянуть и его идеологического предшественника — [[iptables#state|критерий state]]. Изначально для определения состояния соединения использовался именно он, то есть вместо <tt>-m conntrack --ctstate ESTABLISHED,RELATED</tt> использовалось <tt>-m state --state ESTABLISHED,RELATED</tt>. Подобные формулировки до сих пор сохраняются во многих руководствах по iptables. Однако в настоящее время критерий state считается устаревшим, и разработчики iptables [http://jengelh.medozas.de/documents/Perfect_Ruleset.pdf рекомендуют] использовать вместо него критерий conntrack. Также заметим, что критерий conntrack обладает более широкими возможностями, нежели state, и позволяет использовать дополнительную информацию о соединении, в частности, состояние самого соединения (ctstatus), факт применения к нему [[w:NAT |трансляции адресов]], тайм-аут для «повисших» соединений (ctexpire) и т. п.
 
==== Маркировка соединений ====
 
Этот прием позволяет классифицировать соединение в целом на основании информации об отдельном пакете. Выделив этот пакет, вы применяете к нему действие CONNMARK, и выбранную вами маркировку автоматически приобретают все пакеты в соединении. Впоследствии вы можете, например, модифицировать эти пакеты каким-либо образом, или использовать эту маркировку для [[w:Маршрутизация |маршрутизации]] или [[w:Шейпинг (информатика) |шейпинга]] пакетов. Таким образом, вы оперируете с соединением как с единым целым. Более того, эта маркировка автоматически копируется и на соединения, связанные с текущим.
 
==== [[w:NAT |Трансляция сетевых адресов]] ====
 
В операциях NAT, производимых с помощью iptables, отслеживание состояний используется автоматически. Вам достаточно указать критерии, под которые подпадет лишь первый пакет в соединении — и трансляция адресов будет применена ко всем пакетам в этом соединении, а также в связанных с ним соединениях.
Строка 275:
Применяя критерий connbytes, вы можете контролировать количество байт или пакетов, переданных по каждому конкретному соединению. В простейшем случае этот механизм может использоваться, скажем, для назначения квот. Более сложный пример — шейпинг пакетов в зависимости от «весовой категории» соединения (ставить пониженный приоритет загрузкам больших файлов).
 
Этот критерий рассмотрен ниже, в разделе [[iptables#Лимитирующие критерии|лимитирующие критерии]].
 
==== Ограничение количества соединений ====
 
Используя критерий connlimit, вы можете ограничивать количество одновременно открытых [[{{w |TCP]]}}-соединений с каждого хоста или подсети на ваш сервер, что позволяет обеспечить эффективную защиту от [[w:DoS-атака |DoS-атак]] или просто некорректно работающего клиентского [[w:Программное обеспечение |ПО]].
 
Этот критерий рассмотрен ниже, в разделе [[iptables#Лимитирующие критерии|лимитирующие критерии]].
 
==== Отслеживание информации о соединениях ====
 
Пользователь (точнее, [[w:Root (суперпользователь)|системный администратор]]) или его процессы могут непосредственно наблюдать таблицу контроля состояний, считывать статистику по передаче данных, а также модифицировать эту таблицу (например, удалять из нее соединения). Для этого существуют специальные утилиты, такие как [[conntrack (Программа) | conntrack]] или [[iptstate]]. Впрочем, можно читать информацию и напрямую из псевдофайлов <tt>/proc/net/nf_conntrack</tt> и <tt>/proc/net/nf_conntrack_expect</tt>.
 
== Действия ==
Строка 299:
=== Встроенные действия ===
 
Как уже было сказано выше, каждое встроенное действие реализует какую-либо одну операцию, например, ACCEPT пропускает пакет, MARK меняет его маркировку, MASQUERADE обеспечиват [[{{w |маскарадинг]]}} соединения. Наиболее общими действиями являются:
* '''ACCEPT''', '''DROP''' и '''REJECT''' — базовые операции фильтрации. Более подробно они рассмотрены ниже, при описании таблицы filter.
* '''RETURN''' — обеспечивает возврат из текущей цепочки. В частности, если из цепочки A правилом номер 3 пакет был направлен в цепочку B, то применение к нему в цепочке B действия RETURN приведет к его переходу обратно в цепочку A, и он продолжит ее прохождение со следующего правила (номер 4).
Например, предположим, что нам нужно обеспечить доступ к определенным [[w:Порт (TCP/IPкомпьютерные сети) |портам]] нашего сервера для всех хостов из подсети 10.134.0.64/26, ''кроме'' 10.134.0.67 и 10.134.0.100.
<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), [[{{w |SSH]]}} (22/tcp), [[{{w |SMB]]}} (139,445/tcp, 137,138/udp), [[{{w |DNS]]}} (53/tcp, udp), [[{{w |NTP]]}} (123/udp). Также для этих хостов разрешены [[{{w |ICMP]]}}-эхо-запросы (пинги). Все остальные пакеты (включая пакеты не из нашей подсети, пакеты с запрещенных хостов и пакеты на неразрешенные порты) блокируются действием по умолчанию DROP.
 
Нетрудно заметить, что в нашем простом примере вместо RETURN можно было использовать и DROP. Однако, существует понятие «принципа одного запрета». При организации фильтрующих правил в рамках этого принципа, сначала следует серия разрешающих правил, исключения оформляются в виде RETURN, а все не разрешенные пакеты доходят до конца базовой цепочки и блокируются действием по умолчанию либо последним правилом. Следование этому принципу позволяет достичь гибкости в выборе и смене метода блокирования пакетов. Допустим, вы хотите сменить блокирующее действие DROP на REJECT. Нет ничего проще — просто меняете правило по умолчанию. Так же просто вводятся специфические методы блокировки для TCP, например, REJECT <tt>--reject-with tcp-reset</tt> или DELUDE — достаточно просто добавить это действие (вместе с указанием протокола <tt>-p tcp</tt>) в конец цепочки. Все не-TCP пакеты при этом будут по-прежнему блокироваться действием по умолчанию.
Строка 347:
 
: ''Примечание: следующий пример планируется к переносу в еще не написанный раздел статьи (Прочие критерии → mac)''.
Например, предположим, что у нас есть объединенная через один [[Сетевой_коммутаторw:Сетевой коммутатор |свитч]] подсеть 10.134.0.64/26, к которой наш компьютер подключен через интерфейс eth1. Тогда защиту от [[{{w |спуфинг]]}}а (подделки адресов отправителя) через проверку [[{{w |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]]- и [[{{w |MAC-адрес]]}}ов (цепочка <tt>check_ours_sp00f</tt>). Каждое правило этой цепочки, кроме последнего, выделяет пакеты от одного конкретного хоста нашей подсети. К пакетам, прошедшим проверку, применяется операция RETURN, выводящая пакет из этой цепочки. Если же пакет не подошел ни по одному из этих правил, он считается не прошедшим проверки и блокируется последним правилом <tt>-j DROP</tt>. Для прошедших же проверку пакетов дальнейшая судьба зависит от того, кому они адресованы. Если они идут через наш хост в другие подсети, то они пропускаются. Если же они адресованы непосредственно нашему хосту, то пропускаются только соединения на некоторые [[{{w |TCP]]}}-[[Порт_w:Порт (TCP/UDPкомпьютерные сети) |порты]] ([[w:Прокси-сервер |прокси]], [[{{w |SSH]]}}, [[{{w |SMB]]}}).
* '''LOG''' — позволяет записывать информацию о пакетах в журнал ядра (см. [[{{w |syslog]]}}).
Например, если в предыдущем примере перед строкой
<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), далее — сцепленные вместе [[{{w |MAC-адрес]]}}а источника и назначения (сначала идет адрес назначения, в данном случае это наш интерфейс eth1 с маком 00:15:17:4C:89:35, затем адрес источника, в нашем случае это 00:1D:60:2E:ED:A5, и в конце следует значение [[:en:EtherType|EtherType]], 08:00 соответствует протоколу [[{{w |IPv4]]}}<ref>Если кратко, EtherType указывает тип протокола, инкапсулированного в [[{{w |Ethernet]]}}-[[w:Кадр (телекоммуникации) |кадр]]. При работе с iptables это значение будет всегда равно 08:00 (протокол [[{{w |IPv4]]}}), при работе с ip6tables — 86:DD ([[{{w |IPv6]]}}). Полный список EtherTypes доступен [http://www.iana.org/assignments/ethernet-numbers на сайте IANA], список поддерживаемых netfilter’ом — в файле /etc/ethertypes, который в большинстве дистрибутивов находится в пакете [[{{w |ebtables]]}}.</ref>), потом [[{{w |IP-адрес]]}}а источника (10.134.0.67) и получателя (10.134.0.65, это наш хост), а затем идет различная техническая информация. Например, протокол ([[{{w |TCP]]}}), [[Порт_w:Порт (TCP/UDPкомпьютерные сети) |порты]] источника и назначения (31521 и 8080 соответственно), [[Typew:Тип ofобслуживания Service|TOS]] и [[w:Time to live |TTL]], длина пакета (48 байт), наличие флага SYN и т. д.
 
Указав соответствующие параметры действия LOG, можно дополнить эту информацию [[w:TCP#Номер последовательности |номером TCP-последовательности]] (опция <tt>--log-tcp-sequence</tt>), выводом включенных опций протоколов TCP (опция <tt>--log-tcp-options</tt>) и [[{{w |IP]]}} (<tt>--log-ip-options</tt>), а также идентификатором пользователя, процесс которого отправил данный пакет (<tt>--log-uid</tt>, имеет смысл только в цепочках OUTPUT и POSTROUTING).
 
Параметр <tt>--log-prefix</tt> позволяет задать поясняющую надпись, упрощающую поиск сообщений в системных журналах. Параметр <tt>--log-level</tt> определяет уровень важности лог-сообщения, от которого зависит, в частности, в какой именно из журналов будет записано это сообщение. За более подробными сведениями обратитесь к документации по вашему [[syslogw:Syslog |демону системного лога]].
* '''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> — контекст безопасности [[{{w |SELinux]]}} данного пакета (secmark), <tt>classify</tt> — класс шейпера (также известный как <tt>skb->priority</tt>, соответствует обычной для [[iproute2w:Iproute2 |tc]] форме записи ''MAJOR'':''MINOR'' согласно формуле <tt>skb->priority == ''MAJOR'' << 16 | ''MINOR''</tt>), <tt>ctdir</tt> — направление передачи информации с точки зрения conntrack, <tt>ct</tt> — внутренний идентификатор соединения в системе conntrack (точнее говоря, адрес в памяти, по которому расположена структура, хранящая информацию о соединении), <tt>ctmark</tt> — маркировку соединения (connmark), <tt>ctstate</tt> — состояние соединения, <tt>ctstatus</tt> — статус соединения в системе cоnntrack. Более подробно о параметрах ctdir, ctstate и ctstatus вы можете прочитать [[iptables#conntrack|ниже]], в описании критерия conntrack. Здесь же ограничимся замечаниями, что «<tt>ctstate=NEW ctstatus=</tt>» соответствует первому пакету в соединении, «<tt>ctstate=ESTABLISHED ctstatus=SEEN_REPLY,CONFIRMED</tt>» — второму и нескольким последующим пакетам, «<tt>ctstate=ESTABLISHED ctstatus=SEEN_REPLY,ASSURED,CONFIRMED</tt>» — пакетам в полностью установленном соединении, «<tt>ct=NULL ctmark=NULL ctstate=INVALID ctstatus=NONE</tt>» — пакету, который не удалось отнести к существующим соединениям, «<tt>ct=UNTRACKED ctmark=NULL ctstate=UNTRACKED ctstatus=NONE</tt>» — пакету, для которого была отключена трассировка conntrack (обычно это выполняется действием NOTRACK в таблице raw, см. [[iptables#Таблица raw|ниже]]).
 
Таким образом, в сочетании с традиционным LOG, действие LOGMARK позволяет заносить в системный журнал исчерпывающую информацию о пакетах и соединениях.
 
Заметим, что LOGMARK принимает описанные выше опции <tt>--log-prefix</tt> и <tt>--log-level</tt>.
* '''ULOG''' — позволяет передавать информацию об обработанных пакетах специальным демонам, таким, как [http://www.netfilter.org/projects/ulogd/ ulogd]. Такой подход позволяет эффективно управлять информацией о трафике, в частности, заносить ее в [[{{w |базы данных]]}}, такие как [[{{w |MySQL]]}}, [[{{w |PostgreSQL]]}} или [[{{w |SQLite]]}}. Впоследствии эти данные могут быть проанализированы и визуализированы с помощью таких средств, как [http://software.inl.fr/trac/wiki/EdenWall/NuLog NuLog].
* '''NFLOG''' — более универсальный вариант ULOG, обеспечивающий передачу информации о пакете не напрямую в netlink-[[w:Сокет (программный интерфейс) |сокет]] (как это делает ULOG), а специальной подсистеме — logging backend. Например, бэкенд nfnetlink_log обеспечивает передачу данных в netlink-сокет, то есть с ним NFLOG работает аналогично ULOG.
* '''NFQUEUE''' — во многом похоже на ULOG, но передает специальному демону не информацию о пакете, а сам пакет целиком. Применяется, в частности, для организации работы [[{{w |l7-filter]]}}-userspace.
Например, если демон l7-filter был запущен командой
<source lang="bash">
Строка 418:
Выше были рассмотрены действия «общего назначения», то есть не привязанные по своей специфике к таблицам. Далее, при рассмотрении отдельных таблиц, будут описываться действия, специфичные для каждой таблицы. Термин «специфичные» надо понимать так: совсем не обязательно, что действие, специфичное для одной таблицы, будет в принципе недопустимо в другой, но в любом случае использование этого действия в других таблицах будет «плохим тоном» — ведь таблицы и действия четко разделены по назначению. Не стоит «забивать гвозди микроскопом».
 
Порой эта разница бывает довольно тонкой. Например, если действие NFQUEUE передает пакеты демону [[{{w |l7-filter]]}}-userspace (который занимается маркировкой пакетов на основе анализа их содержимого), то правильнее будет разместить вызов такого действия в таблице mangle. Если же оно передает пакеты демону [[nufw]] (который обеспечивает разрешение или запрещение трафика на основе авторизации пользователя), то логичнее разместить это действие в таблице filter.
 
Кроме того, существуют и ограничения, наложенные непосредственно в коде iptables. Например, действия таблицы nat жестко защищены от употребления за ее пределами. Другой пример: действие REDIRECT можно применять только в цепочках PREROUTING и OUTPUT таблицы nat, то есть ограничения могут быть не только на таблицы, но на отдельные цепочки. Данная статья ни в коем случае не претендует на полноту изложения, поэтому, перед тем как использовать какое-либо действие, обязательно ознакомьтесь с документацией, прилагающейся к вашей версии iptables.
Строка 446:
 
=== Таблица mangle ===
Данная таблица предназначена для операций по классификации и маркировке пакетов и соединений, а также модификации заголовков пакетов (поля [[Time_to_livew:Time to live |TTL]] и [[Type_of_Servicew:Тип обслуживания |TOS]]).
 
==== Цепочки ====
Строка 460:
==== Действия ====
Допустимыми действиями в этой таблице являются:
* '''TOS''' — изменяет поле [[Type_of_Servicew:Тип обслуживания |TOS]] данного пакета. Поддерживаются опции <tt>--set-tos</tt> (установить поле TOS в заданное значение), а также <tt>--and-tos</tt>, <tt>--or-tos</tt> и <tt>--xor-tos</tt>, комбинирующие текущее значение поля TOS с заданным в правиле значением по соответствующему логическому правилу и записывающие результат как новое значения поля TOS.
 
Кроме того, опция <tt>--set-tos</tt> поддерживает расширенный синтаксис <tt>--set-tos ''значение''/''маска''</tt>. При использовании такого синтаксиса в исходном значении TOS пакета зануляются те биты, которые установлены в маске, затем полученное число XOR’ится с указанным в параметрах значением, и полученная величина записывается в поле TOS. Используя синтаксис [[w:Си (язык программирования) |языка C]], это можно записать так: <tt>NEW_TOS = (OLD_TOS & ~''маска'') ^ ''значение''</tt>. Заметим, что в случае с [[{{w |IPv6]]}} операция отрицания маски не&nbsp;выполняется (то есть в исходном значении зануляются те биты, которые в маске ''не&nbsp;установлены''), хотя это и не&nbsp;отражено в документации.
 
Также, в случае [[{{w |IPv4]]}} (iptables) в параметре <tt>--set-tos</tt> вы можете указать одно из допустимых символьных обозначений: Minimize-Delay (TOS 16, требование минимальной задержки), Maximize-Throughput (TOS 8, требование максимальной пропускной способности), Maximize-Reliability (TOS 4, максимальная надежность доставки), Minimize-Cost (TOS 2, минимальная стоимость), Normal-Service (TOS 0, специальные требования отсутствуют). В ip6tables использование этих обозначений не&nbsp;запрещено, однако в этом случае более корректным будет использование действия DSCP (см. ниже).
 
Практический пример использования действия TOS представлен [[Iptables#Лимитирующие критерии|ниже]], в описании критерия connbytes.
 
Отметим, что, в соответствии с современными соглашениями, поле TOS в заголовке IP-пакета разделяется на две части: [[{{w |DSCP]]}} (первые шесть бит кода TOS) и [[w:Explicit Congestion Notification |ECN]] (последние два бита TOS). Современные версии netfilter/iptables не&nbsp;поддерживают изменение значений ECN в IP-заголовках, поэтому фактически действие TOS работает только с полем DSCP, отличаясь от действия DSCP (см. чуть ниже) разве что интерфейсом (фактически, синтаксисом).
 
* '''DSCP''' — изменяет поле [[{{w |DSCP]]}} (класс [[:en:Differentiated services|DiffServ]]) в заголовке пакета. Поддерживаются опции <tt>--set-dscp</tt> (позволяет задать значение DSCP числом) и <tt>--set-dscp-class</tt> (позволяет установить заданный класс DiffServ, например, EF или AF13).
 
* '''TTL''' — изменяет поле [[Time_to_livew:Time to live |TTL]] данного пакета (работает только с [[{{w |IPv4]]}}, для [[{{w |IPv6]]}} используется действие HL). Поддерживаются опции <tt>--ttl-set</tt> (установить поле TTL в заданное значение), а также <tt>--ttl-inc</tt> и <tt>--ttl-dec</tt> (соответственно увеличить или уменьшить текущее значение поля TTL на заданное значение). Допустимые значения TTL — от 0 до 255. При достижении TTL=0 пакет уничтожается.
 
В качестве полезного примера использования этого действия можно привести команду
Строка 478:
iptables -t mangle -I PREROUTING -j TTL --ttl-inc 1
</source>
делающую наш шлюз невидимым для большинства [[w:Traceroute |трассировщиков]].
 
Обратите внимание, что автоматически выполняемая сетевым стеком ядра операция уменьшения TTL на единицу и проверки на равенство нулю выполняется ''после'' цепочки PREROUTING, но ''до'' цепочки FORWARD. Таким образом, переместив это правило в цепочку FORWARD, вы обеспечите «невидимость» следующего за вами шлюза.
Строка 490:
'''Будьте очень осторожны''' с правилами, которые увеличивают или, что особенно опасно, напрямую задают значение TTL, так как, при наличии определенных ошибок маршрутизации, это может привести к появлению «бессмертных» пакетов, которые будут долго циркулировать между одними и теми же узлами, захламляя канал и затрудняя работу сетевого оборудования.
 
* '''HL''' — изменяет поле Hop Limit в заголовке [[{{w |IPv6]]}}-пакета. Является аналогом IPv4-действия TTL и поддерживает те же операции: <tt>--hl-set</tt> (установить поле HL в заданное значение), а также <tt>--hl-inc</tt> и <tt>--hl-dec</tt> (соответственно увеличить или уменьшить текущее значение поля HL на заданное значение).
 
* '''MARK''' — устанавливает или изменяет маркировку пакета. Поддерживает опции <tt>--set-mark</tt>, <tt>--and-mark</tt>, <tt>--or-mark</tt> и <tt>--xor-mark</tt>, аналогичные опциям действия TOS. Важно понимать, что маркировка пакета не хранится в его заголовке или содержимом, и поэтому действует только в пределах одного хоста. Также нужно отличать маркировку пакета от маркировки соединения. Маркировка пакетов может применяться для их дальнейшей обработки фаерволом (критерии mark и connmark), а также для классификации трафика фильтрами [[w:Шейпинг (информатика) |шейпинговой]] подсистемы [[iproute2w:Iproute2 |tc]] (лексема handle ''mark'' fw).
* '''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-сегмента]]. Бывает крайне полезной при использовании [[{{w |VPN]]}}-подключения<ref>Обычно проблемы с пониженным [[{{w |MTU]]}} в [[{{w |Ethernet]]}}-сетях возникают как раз из-за [[{{w |VPN]]}}-туннелей</ref> в том случае, если VPN-сервер блокирует [[{{w |ICMP]]}}-сообщения destination unreachable/fragmentation needed (тип 3, код 4), тем самым нарушая работу процедуры [[MTUw:Maximum transmission unit#Технология Path MTU discovery |Path MTU discovery]].
 
С точки зрения клиента, эта проблема выглядит так: [[{{w |пинг]]}}и проходят нормально, но при попытке открыть какую-либо [[{{w |веб]]}}-страницу, [[{{w |браузер]]}} «подвисает». При этом с самого шлюза все работает нормально. В этом случае достаточно применить на шлюзе следующую команду
<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-пакетов в соответствии с минимальным из известных нашему шлюзу значений [[{{w |MTU]]}} на пути следования пакета. Например, если пакет пришел с интерфейса eth0 (MTU 1500) и уходит через интерфейс ppp0 (MTU 1492), а суммарный размер заголовков [[Сетевойw:Протоколы сетевого уровня уровень|сетевого]] и [[w:Транспортный уровень |транспортного]] уровней составляет 40 [[{{w |байт]]}} (20 байт [[{{w |TCP]]}} и 20 байт [[{{w |IP]]}}), то целесообразно установить MSS равным 1452 байтам.
 
Помимо возможности автоматического выбора 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>). Может использоваться только в [[{{w |IPv4]]}}-модуле (iptables, но не&nbsp;ip6tables) для [[{{w |TCP]]}}-пакетов (<tt>-p tcp</tt>). Данное действие предназначено для защиты пакетов от ECN blackholes (маршрутизаторов, которые некорректно обрабатывают пакеты с установленными в TCP-заголовке ECN-битами) — рекомендуется применять это действие ко всем пакетам, уходящим на такие маршрутизаторы. Обратите внимание, что данное действие никак не&nbsp;влияет на ECN-биты в [[{{w |IP]]}}-заголовках (последние два бита поля [[Typew:Тип ofобслуживания Service|TOS]]).
 
Кроме того, данное действие поддерживает три потенциально опасные опции, не отраженные в документации: <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]). С одной стороны, такое правило будет препятствовать удаленному злоумышленнику определить [[{{w |аптайм]]}} нашего хоста, а также тех хостов, маршрут от которых до злоумышленника проходит через наш хост. С другой стороны, блокирование штампов времени может негативно сказаться на быстродействии сети, особенно если вы используете подключения на скорости [[w:Fast Ethernet |100&nbsp;МБит]] и выше. Заметим также, что если вам нужно управлять использованием именно штампов времени для TCP IPv4-пакетов, исходящих от вашего хоста, вы можете воспользоваться [[{{w |sysctl]]}}-параметром net.ipv4.tcp_timestamps (1 — штампы включены, 0 — выключены).
* '''TPROXY''' — реализует механизм полностью прозрачного [[w:Прокси-сервер |проксирования]]. Такой подход отличается от традиционно используемого «прозрачного» проксирования (действие REDIRECT [[iptables#Таблица nat|таблицы nat]], см. ниже) тем, что заголовок пакета никак не&nbsp;модифицируется, в том числе не&nbsp;заменяется [[{{w |IP-адрес]]}} назначения (при традиционном прозрачном проксировании он заменяется на адрес проксирующего хоста). Кроме того, полностью прозрачное проксирование является прозрачным с точки зрения обеих общающихся сторон. Например, при проксировании обращений некоторой подсети клиентов к серверам из другой подсети, можно сделать так, чтобы не&nbsp;только клиенты считали, что обращаются напрямую к серверам, но и сервера «видели» настоящие исходные адреса клиентов и могли бы устанавливать с ними обратные соединения (например, в случае активного режима [[{{w |FTP]]}}). При традиционном же «прозрачном» проксировании, сервера могут видеть только адрес прокси-сервера.
 
TPROXY позволяет перенаправить транзитный пакет на локальный [[w:Сокет (программный интерфейс) |сокет]] типа AF_INET (iptables) или AF_INET6 (ip6tables), заданный портом, а также может промаркировать пакет таким образом, чтобы система марушрутизации ([[{{w |iproute2]]}}) не&nbsp;позволила пакету покинуть наш хост. Разумеется, поддержка полностью прозрачного проксирования должна быть реализована и в самом [[{{w |прокси-сервер]]}}е. В частности, прозрачное проксирование [[{{w |IPv4]]}} [[{{w |HTTP]]}} [http://wiki.squid-cache.org/Features/Tproxy4 поддерживается] прокси-сервером [[{{w |Squid]]}} начиная с версии 3.1.
 
В качестве примера можно привести простейший случай конфигурации iptables и iproute2 для обеспечения полностью прозрачного проксирования [[{{w |IPv4]]}} {{w [[|HTTP]]}}.
<source lang="bash">
# Добавляем принудительную локальную маршрутизацию для всех адресов в таблицу 120
Строка 535:
=== Таблица nat ===
 
Предназначена для операций stateful-преобразования [[w:IP-адрес |сетевых адресов]] и [[Порт_w:Порт (TCP/IPкомпьютерные сети) |портов]] обрабатываемых пакетов.
 
==== Цепочки ====
Строка 542:
* '''PREROUTING''' — в эту цепочку пакеты попадают ''до'' принятия решения о маршрутизации. По сути, термин «решение о маршрутизации» подразумевает деление трафика на входящий (предназначенный самому хосту) и транзитный (идущий через этот хост на другие хосты). Именно на данном этапе нужно проводить операции проброса (DNAT, REDIRECT, NETMAP).
* '''OUTPUT''' — через эту цепочку проходят пакеты, сгенерированные процессами самого хоста. На данном этапе при необходимости можно повторить операции проброса, так локально сгенерированные пакеты ''не'' проходят цепочку PREROUTING и ''не'' обрабатываются ее правилами. См. пример для действия DNAT ниже.
* '''POSTROUTING''' — через эту цепочку проходят все исходящие пакеты, поэтому именно в ней целесообразно проводить операции [[{{w |маскарадинг]]}}а (SNAT и MASQUERADE).
 
==== Действия ====
 
Допустимыми действиями в таблице nat являются:
* '''MASQUERADE''' — подменяет адрес источника для исходящих пакетов адресом того интерфейса, с которого они исходят, то есть осуществляет [[{{w |маскарадинг]]}}. Такая операция позволяет, например, предоставлять доступ в [[{{w |Интернет]]}} целым [[w:Локальная вычислительная сеть |локальным сетям]] через один [[w:Сетевой шлюз |шлюз]].
 
Допустим, у нас есть локальная сеть 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-адрес, но и отдельные [[{{w |TCP]]}}- или [[{{w |UDP]]}}-[[Порт_w:Порт (TCP/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, а только его [[{{w |TCP]]}}-[[Порт_w:Порт (TCP/IPкомпьютерные сети) |порт]] 80 ([[{{w |HTTP]]}}). Обращения на все остальные [[{{w |TCP]]}}- и [[{{w |UDP]]}}-порты, а также [[{{w |ICMP]]}}-пакеты, поступившие на адрес 208.77.188.166, будут обрабатываться шлюзом, и лишь входящие TCP-соединения на порт 80 будут передаваться на 192.168.1.2.
 
Как и SNAT, DNAT поддерживает указание диапазонов адресов для подмены. Таким образом можно, например, балансировать нагрузку между несколькими серверами.
Строка 638:
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080
</source>
позволяет «завернуть» все исходящие из локальной сети TCP-соединения на порт 80, на TCP-порт 8080 шлюза. Если этот порт обслуживается специально настроенным [[{{w |прокси-сервер]]}}ом, то можно организовать «прозрачное проксирование» — клиенты из локальной сети даже не будут подозревать, что их запросы идут через прокси-сервер. Разумеется, входящие соединения из локалки на TCP-порт 8080 должны быть разрешены в таблице filter.
 
Другой полезный пример:
Строка 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''' — заблокировать пакет и сообщить его источнику об отказе. По умолчанию об отказе сообщается отправкой ответного [[{{w |ICMP]]}}-пакета «icmp-port-unreachable». Однако, это действие поддерживает опцию <tt>--reject-with</tt>, позволяющую указать формулировку сообщения об отказе (возможные значения: <tt>icmp-net-unreachable</tt>, <tt>icmp-host-unreachable</tt>, <tt>icmp-proto-unreachable</tt>, <tt>icmp-net-prohibited</tt>, <tt>icmp-host-prohibited</tt>). Для протокола [[{{w |TCP]]}} поддерживается отказ в форме отправки RST-пакета (<tt>--reject-with tcp-reset</tt>).
* '''DROP''' — заблокировать пакет, не сообщая источнику об отказе. Более предпочтительна при фильтрации трафика на интерфейсах, подключенных к интернету, так как понижает информативность сканирования портов хоста злоумышленниками.
 
Также определенный интерес представляют действия, предоставляемые модулями [http://xtables-addons.sourceforge.net/ xtables-addons] (в настоящее время этот проект уже [http://packages.debian.org/squeeze/xtables-addons-common включен] в [[{{w |Debian]]}} testing). Некоторые из них:
* '''STEAL''' — аналогично DROP, но в случае использования в цепочке OUTPUT при блокировании исходящего пакета не сообщает об ошибке приложению, пытавшемуся отправить этот пакет.
* '''TARPIT''' — «подвесить» [[{{w |TCP]]}}-соединение. Используется лишь в самых крайних случаях, например, при борьбе с [[{{w |DoS-атака]]}}ми. Отвечает на входящее соединение, после чего уменьшает размер фрейма до нуля, блокируя возможность передачи данных. Соединение будет «висеть» в таком состоянии пока не истечет тайм-аут на атакующей стороне (обычно 20—30 минут). При этом на такое соединение расходуются системные ресурсы атакующей стороны (процессорное время и оперативная память), что может быть весьма ощутимо при значительном количестве соединений. В случае правильного использования действия TARPIT ресурсы атакуемой стороны практически не расходуются.
Под правильным применением понимается предотвращение обработки таких соединений подсистемой [[conntrack]], так как в противном случае будут расходоваться системные ресурсы самого атакуемого хоста. Например, перед добавлением правила блокирования порта
<source lang="bash">
Строка 695:
=== Таблица security ===
 
Предназначена для изменения маркировки безопасности (меток [[{{w |SELinux]]}}) пакетов и соединений.
 
==== Цепочки ====
Строка 704:
* '''OUTPUT''' — эта цепочка позволяет обрабатывать трафик, исходящий от самого хоста.
 
Так как эта таблица появилась относительно недавно, ее редко можно увидеть на схемах следования пакетов через цепочки и таблицы [[{{w |netfilter]]}}'а. Поэтому стоит отметить, что все цепочки таблицы security пакеты проходят непосредственно после одноименных цепочек таблицы filter.
 
==== Действия ====
 
Данная таблица добавлена в ядро [[w:Ядро Linux (ядро)|Linux]] в версии 2.6.27. Ранее операции с метками безопасности выполнялись в таблице mangle, и в целях обратной совместимости все действия, разрешенные для таблицы security, можно использовать и в таблице mangle.
 
* '''SECMARK''' — устанавливает для пакета контекст безопасности [[{{w |SELinux]]}} (единственная допустимая опция <tt>--selctx</tt>).
* '''CONNSECMARK''' — позволяет скопировать контекст безопасности SELinux с отдельного пакета на соединение в целом (опция <tt>--save</tt>) и наоборот (опция <tt>--restore</tt>).
 
Строка 728:
<!-- В таблице raw целесообразно применять действие '''NOTRACK''', позволяющее предотвратить обработку пакетов системой conntrack. Разумеется, применять ее стоит не ко всем пакетам подряд, а только к тем, для которых такая обработка не нужна и даже вредна. Например, к пакетам, к которым впоследствии применяется действие TARPIT (см. выше). -->
* '''NOTRACK''' — позволяет предотвратить обработку пакетов системой conntrack. Разумеется, применять его стоит не ко всем пакетам подряд, а только к тем, для которых такая обработка не нужна и даже вредна. Например, к пакетам, к которым впоследствии применяется действие TARPIT (см. выше).
* '''CT''' — более функциональный инструмент, добавленный в версии [[w:Ядро Linux (ядро)|Linux]] 2.6.34. Позволяет задать различные настройки [[conntrack]], в соответствии с которыми будет обрабатываться соединение, открытое данным пакетом. В частности, можно:
:* Отключить отслеживание соединения (опция <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>
: будет предписывать для всех соединений на [[{{w |TCP]]}}-[[w:Порт (TCP/IPкомпьютерные сети) |порт]] 8000 генерировать только события «открытие соединения» (NEW) и «завершение соединения» (DESTROY), игнорируя все прочие события. Полный список возможных событий: new, related, destroy, reply, assured, protoinfo, helper, mark, natseqinfo, secmark.
:* Задать ''зону conntrack'' для данного пакета (параметр <tt>--zone</tt>). Механизм зон conntrack позволяет корректно отслеживать, фильтровать и [[{{w |NAT]]}}'ить соединения даже в том случае, если хост подключен к нескольким сетям, использующим одинаковые пространства имен, через различные интерфейсы (например, интерфейсы eth0 и eth1 подключены к двум разным сетям, но обе эти сети используют пространство 192.168.0.0/24). Традиционно, для идентификации соединений conntrack использует кортежи (tuples) — набор значений в который входят адреса и порты (в случае ICMP — типы и коды ICMP) источника и назначения при передаче данных в прямом и обратном направлении. Очевидно, что при наличии нескольких подсетей с одинаковыми адресными пространствами, возможно возникновение путаницы, когда сразу нескольким соединениям ставится в соответствие одна и та же запись в таблице соединений. Чтобы избежать такой ситуации, в кортеж был добавлен идентификатор зоны conntrack — целое число, которое можно устанавливать через специальное правило в таблице raw в зависимости от входящего/исходящего интерфейса (как уже говорилось выше, цепочки таблицы raw пакеты проходят еще до обработки их conntrack’ом). Например,
<source lang="bash">
iptables -t raw -I PREROUTING -i eth1 -j CT --zone 1
Строка 745:
</source>
: Таким образом, пакеты, входящие или исходящие через интерфейс eth1, будут получать идентификатор зоны 1, в то время как пакеты интерфейса eth0 будут по-прежнему использовать зону по умолчанию (идентификатор 0), и путаницы не&nbsp;произойдет.
: Кроме того, идентификатор зоны можно задать для каждого интерфейса через [[{{w |sysfs]]}}, минуя iptables (псевдофайл <tt>/sys/class/net/имя_интерфейса/nf_ct_zone</tt>):
<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, то есть при указании маски заменяются только те биты в адресе, которые соответствуют единичным битам маски. Биты адреса, соответствующие нулевым битам маски, остаются неизменными. При отсутствии маски изменяется весь адрес.
 
: Отметим, что в отличие от действий [[iptables#Таблица nat|таблицы nat]], которые работают только с соединениями в целом, операции «сырого» преобразования адресов работают только с отдельными пакетами, никак не&nbsp;учитывая контекст их передачи. Вышесказанное можно проиллюстрировать, скажем, таким простым примером: для элементарной операции «проброса» внешнего адреса на другой адрес при использовании обычных операций NAT достаточно одного правила<ref>На самом деле, для «чистого» проброса адреса, даже при использовании stateful NAT, необходимо обычно два или три правила, в частности, для проброса соединений с самого сервера в цепочке OUTPUT. Более подробно это описано при рассмотрении операции DNAT [[iptables#Таблица nat|таблицы nat]], и здесь, с целью упрощения понимания примера, эти аспекты опущены</ref>
<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 ===
 
Данная таблица предназначена для выполнения операций «сырого» преобразования адресов (без использования информации о соединениях), которые не&nbsp;могут быть реализованы в рамках таблицы raw, а именно, для операции «сырой» подмены исходного адреса ([[{{w |маскарадинг]]}}а).
 
Как и в таблице raw, в rawpost отсутствует возможность обращения к [[conntrack]], поэтому критерии, использующие эту подсистему (conntrack, connmark, connlimit, connbytes), в этой таблице работать не&nbsp;будут.
Строка 816:
Позволяет указать протокол транспортного уровня. Наиболее часто употребляются <tt>[[tcp]]</tt>, <tt>[[udp]]</tt>, <tt>[[icmp]]</tt> и <tt>all</tt>. Протокол также можно указать с помощью номера или названия согласно перечню, приведенному в <tt>/etc/protocols</tt>. Значение «любой протокол» можно указать с помощью слова <tt>all</tt> или числа 0. Если протокол не указан, подразумевается «любой протокол».
 
При указании протокола становится возможным использовать специфичные для него критерии. Например, для [[{{w |TCP]]}} и [[{{w |UDP]]}} доступны критерии <tt>--sport</tt> и <tt>--dport</tt>, для [[{{w |ICMP]]}} — <tt>--icmp-type</tt>. Подробнее эти критерии будут рассмотрены ниже.
 
* <tt>[!] '''-s'''</tt>, <tt>--src</tt>, <tt>--source ''адрес''[/''маска''][,''адрес''[/''маска'']...]</tt>
 
Определяет адрес отправителя. В качестве адреса может выступать [[{{w |IP-адрес]]}} (возможно с [[маскаw:Маска подсети |маской]]), имя хоста из /etc/hosts, или [[{{w |доменное имя]]}} (в последних двух случаях перед добавлением правила в цепочку имя [[w:DNS |резольвится]] в IP-адрес). Маска подсети может быть указана в классическом формате (например, 255.255.0.0) либо в формате [[{{w |CIDR]]}} (например, 16)<ref>Заметим, что для расчета масок подсетей и диапазонов адресов существует очень удобная утилита [[ipcalc]].</ref>. Например,
<source lang="bash">
iptables -I INPUT -i eth0 -s 192.168.0.0/16 -j DROP
</source>
(где eth0 — интерфейс, подключенный к интернету), позволяет заблокировать простейший вид [[{{w |спуфинг]]}}а — из интернета ''не могут'' приходить пакеты с обратным адресом, принадлежащим к диапазону, зарезервированному для локальных сетей.
 
Начиная с версии iptables 1.4.6, в одном параметре <tt>-s</tt> можно указывать более одного адреса, разделяя адреса запятой. При этом для каждого адреса будет добавлено ''отдельное'' правило. Например, запись
Строка 838:
При добавлении через команду <tt>-A</tt> (вставка в конец цепочки) порядок добавляемых правил будет соответствовать порядку перечисления адресов в исходной команде, при использовании команды <tt>-I</tt> (вставка в начало цепочки либо после заданного правила) порядок будет обратным исходному.
 
Настойчиво не рекомендуется использовать доменные имена, для разрешения (резольва) которых требуются [[{{w |DNS]]}}-запросы, так как на этапе конфигурирования фаервола DNS может работать некорректно. Также, заметим, имена резольвятся всего один раз — при добавлении правила в цепочку. Впоследствии соответствующий этому имени IP-адрес может измениться, но на уже записанные правила это никак не повлияет (в них останется старый адрес). Если указать доменное имя, которое резольвится в несколько [[{{w |IP-адрес]]}}ов, то для каждого адреса будет добавлено отдельное правило (как и в случае перечисления нескольких адресов, см. выше).
 
* <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:Маскарадинг |маскарадить]] весь трафик, исходящий через интерфейс eth0.
 
=== Критерии, специфичные для протоколов ===
 
==== Протоколы [[w:Транспортный уровень |транспортного уровня]] ====
 
===== [[{{w |TCP]]}} =====
 
* <tt>[!] '''--sport'''</tt>, <tt>--source-port ''порт''[:''порт'']</tt>
Строка 884:
iptables -I INPUT -m conntrack --ctstate NEW -p tcp --sport 0:1023 -j DROP
</source>
заблокирует все входящие соединения с [[Зарезервированные_порты_TCP/w:Список портов TCP и UDP |привилегированных]] портов (''привилегированными'' в TCP/UDP считаются порты с 0 по 1023 включительно, так как для их использования нужны привилегии [[w:Root (суперпользователь)|суперпользователя]], и обычно такие порты используются [[Демон_w:Демон (программа) |демонами]] только в режиме прослушивания).
 
* <tt>[!] '''--dport'''</tt>, <tt>--destination-port ''порт''[:''порт'']</tt>
Строка 892:
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
</source>
разрешит все входящие пакеты на 80 порт ([[{{w |HTTP]]}}).
 
* <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>
будет препятствовать [[{{w |спуфинг]]}}у от нашего имени. Ведь если мы получаем пакет с установленными флагами SYN и ACK (такой комбинацией флагов обладает только ответ на SYN-пакет) по еще не открытому соединению, это означает, что кто-то послал другому хосту SYN-пакет от нашего имени, и ответ пришел к нам. Однако добавление такого правила в конфигурацию фаервола ''не рекомендуется'', поскольку стандартом также предусмотрено использование случайного начального номера последовательности для каждого нового TCP-соединения, как раз для предотвращения возможности спуфинг-атаки. Шансов угадать начальный номер у злоумышленника практически нет, тогда как наш ответ RST-пакетом на такой пакет может серьезно нарушить работоспособность некоторых систем защиты от DoS-атак, полагающихся на метод, называемый out-of-sequence ACK. В случае добавления этого правила в конфигурацию фаервола, системы защиты будут считать, что, раз уж мы отвечаем RST на out-of-sequence ACK, вы действительно пытались установить соединение с ресурсом, и пропустят все последующие поддельные пакеты злоумышленника, отправленные от вашего имени. В результате вы заметно облегчите злоумышленнику осуществление DoS-атаки от вашего имени, и при расследовании этого эпизода следы приведут к вам.
 
* <tt>[!] '''--syn'''</tt>
Строка 927:
Позволяет проверить, установлена ли в заголовке TCP-пакета соответствующая опция. Полный список опций с их номерами представлен [http://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml на сайте IANA].
 
===== [[{{w |UDP]]}} =====
 
* <tt>[!] '''--sport'''</tt>, <tt>--source-port ''порт''[:''порт'']</tt>
Строка 937:
Позволяет указать входящий порт (или их диапазон). Синтаксис и принцип работы аналогичен описанной выше одноименной опции TCP.
 
===== [[{{w |SCTP]]}} =====
 
* <tt>[!] '''--sport'''</tt>, <tt>--source-port ''порт''[:''порт'']</tt>
Строка 959:
разрешит входящие SCTP-пакеты, содержащие секцию DATA с установленным флагом B и снятым флагом E, то есть первый фрагмент фрагментированной DATA-секции.
 
===== [[{{w |DCCP]]}} =====
 
* <tt>[!] '''--sport'''</tt>, <tt>--source-port ''порт''[:''порт'']</tt>
Строка 977:
занесет в лог все входящие RESET и INVALID DCCP-пакеты.
 
===== [[{{w |UDP Lite]]}} =====
 
Поддержка специфических опций протокола UDPLite (а именно, проверки портов источника и/или назначения) в netfilter реализована не вполне очевидным образом: через критерий multiport (см. раздел [[iptables#Вспомогательные критерии|вспомогательные критерии]]).
 
Если для обычного [[{{w |UDP]]}} соответствие номера порта проверялось выражением вида <tt>-p udp --dport ''номер_порта''</tt> (или <tt>-p udp --sport ''номер_порта''</tt>), то в случае UDPLite аналогичное выражение будет выглядеть как <tt>-p udplite -m multiport --dports ''номер_порта''</tt> (или <tt>-p udplite -m multiport --sports ''номер_порта''</tt>). Все опции критерия multiport для UDPLite поддерживаются в полном объеме.
 
==== [[{{w |IPv4]]}} ====
 
Ниже перечислены критерии, которые реализованы только для протокола IPv4 и, соответственно, могут быть вызваны только через iptables, но не&nbsp;через ip6tables.
Строка 993:
iptables -I INPUT -p icmp -f -j DROP
</source>
блокирует фрагменты [[{{w |ICMP]]}}-пакетов. Так как, в силу функционального назначения протокола, ICMP-пакеты должны быть очень небольшими и нормально укладываться в [[{{w |MTU]]}}, наличие их фрагментов обычно свидетельствует об ошибке или попытке атаки.
 
У второго и последующего фрагментов нет заголовка транспортного уровня, поэтому бессмысленно пытаться использовать для них критерии номеров [[Порт_w:Порт (TCP/UDPкомпьютерные сети) |TCP/UDP-портов]] или типа ICMP.
 
* '''addrtype''' — позволяет проверить тип адреса источника и/или назначения с точки зрения подсистемы маршрутизации сетевого стека ядра. Допустимые типы адресов: UNSPEC (адрес 0.0.0.0), [[w:Unicast |UNICAST]], LOCAL (адрес принадлежит нашему хосту), [[w:Broadcast |BROADCAST]], [[w:Anycast |ANYCAST]], [[Multicastw:Мультивещание |MULTICAST]], [[:en:Black hole (networking)|BLACKHOLE]], UNREACHABLE, PROHIBIT, THROW, NAT, XRESOLVE. Подробнее о большинстве перечисленных типов адресов и их использовании в [[w:Ядро Linux (ядро)|Linux]] (точнее, в подсистеме [[{{w |iproute2]]}}) можно почитать [http://linux-ip.net/html/routing-tables.html здесь]. Данный критерий поддерживает следующие параметры:
 
<tt>[!] --src-type ''тип''[,''тип''...]</tt> — проверка, принадлежит ли исходный адрес пакета одному из перечисленных типов.
Строка 1009:
Критерии <tt>--limit-iface-in</tt> и <tt>--limit-iface-out</tt> нельзя указывать одновременно.
 
В качестве практического примера использования данного критерия можно привести простейшую защиту от [[{{w |спуфинг]]}}а:
<source lang="bash">
iptables -I INPUT -m addrtype --src-type LOCAL ! -i lo -j DROP
</source>
Это правило заблокирует пакеты, которые пришли с внешних интерфейсов, но при этом в качестве обратного адреса у них указан один из адресов, принадлежащих нашему хосту (например, [[{{w |127.0.0.1]]}}).
 
* '''ecn''' — позволяет проверять значения битов [[w:Explicit Congestion Notification |ECN]] в заголовках [[{{w |TCP]]}} и [[{{w |IPv4]]}}. Допустимые параметры:
 
<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-битами поля [[Typew:Тип ofобслуживания Service|TOS]] (последние два бита). Возможные значения от 0 до 3.
 
* '''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>), равным или не&nbsp;равным (<tt>[!] --ttl-eq</tt>) указанному значению.
 
===== [[{{w |ICMP]]}} =====
 
ICMP является протоколом контрольных сообщений IPv4. Несмотря на то, что ICMP формально является самостоятельным протоколом, и обращение к соответствующему критерию должно производиться с использованием синтаксиса для протокола (<tt>-p</tt>), а не&nbsp;для вспомогательного критерия (<tt>-m</tt>), де-факто этот протокол неотделим от IPv4, и поэтому соответствующий критерий может использоваться только в iptables, но не&nbsp;в ip6tables.
Строка 1035:
Критерий этого протокола имеет единственный параметр
 
<tt>[!] '''--icmp-type''' ''тип''</tt> — обеспечивает проверку [[w:ICMP#Типы ICMP пакетов (полный список) |типа]] ICMP-пакета. Список возможных типов выводится по команде <tt>iptables -p icmp -h</tt>. Также можно указать стандартные числовые тип и, при
необходимости, код. Например,
<source lang="bash">
Строка 1046:
пропустят все входящие ICMP-эхо-запросы (пинги).
 
==== [[{{w |IPv6]]}} ====
 
Ниже перечислены критерии, которые реализованы только для протокола IPv6 и, соответственно, могут быть вызваны только через ip6tables, но не&nbsp;через iptables.
Строка 1056:
гласящее, что в такое правило никогда не&nbsp;будет срабатывать. Если вы видите подобное предупреждение, удалите правило, которое его вызвало, и перепишите это правило с использованием корректного синтаксиса (<tt>-m</tt>).
 
С другими же критериями, которые представляют более или менее самостоятельные протоколы ([[{{w |ICMPv6]]}}, [[MH]], [[{{w |IPSec]]}} [[:en:IPSec#Authentication_Header|AH]] и [[:en:IPSec#Encapsulating_Security_Payload|ESP]]), все ровно наоборот, и для них корректным будет использование именно синтаксиса протокола (ключ <tt>-p</tt>), а не&nbsp;расширенного критерия. Во избежание путаницы, такие критерии вынесены в отдельные подзаголовки, по аналогии с протоколами транспортного уровня (выше).
 
* '''dst''' — проверят опции назначения (подзаголовок 60 Destination Options). Имеет две опции:
Строка 1064:
<tt>[!] --dst-opts ''код''[:''длина''][,''код''[:''длина'']...]</tt> — позволяет проверить вхождение в данный подзаголовок конкретных опций. Также можно проверить длину каждой из них. Можно указать до 16 опций (представленных числовыми кодами), разделяя их запятой.
 
* '''eui64''' — сравнивает младшие 64 бита исходного IPv6-адреса с битами исходного [[{{w |MAC-адрес]]}}а, преобразованными согласно правилам автоконфигурирования IPv6-адресов на основании MAC-адресов. Таким образом, позволяет проверить, является ли IPv6-адрес отправителя пакета автоматически сконфигурированным (работает, если отправитель находится в одном [[w:Широковещательный домен |широковещательном домене]] с нашим хостом, так как в противном случае сохранность MAC-адреса отправителя не&nbsp;может быть гарантирована).
 
* '''frag''' — позволяет проверять параметры фрагментации (подзаголовок 44 Fragment). Допустимые опции:
Строка 1076:
<tt>--fraglast</tt>/<tt>--fragmore</tt> — проверяют M-флаг, показывающий, является ли данный фрагмент последним в последовательности (в этом случае <tt>--fraglast</tt> дает истину, а <tt>--fragmore</tt> ложь), или после него должны быть еще фрагменты (соответственно, наоборот). Эти две опции являются взаимоисключающими.
 
Также в документации можно найти упоминание параметра <tt>--fraglen </tt>, который якобы проверяет длину подзаголовка Fragment. Однако, согласно текущим соглашениям, длина этого подзаголовка фиксирована и равна 8&nbsp;[[{{w |байт]]}}ам, а названная опция ни на что не&nbsp;влияет.
 
* '''hbh''' — проверяет опции Hop-by-Hop (подзаголовок 0 Hop-by-Hop). Синтаксис аналогичен параметру dst.
Строка 1104:
<tt>--rt-0-not-strict</tt> — делает условие проверки по предыдущем параметру не&nbsp;таким жестким: достаточно, чтобы хотя бы один из перечисленных адресов совпадал с соответствующим адресом в подзаголовке, при соблюдении порядка перечисления.
 
===== [[{{w |ICMPv6]]}} =====
 
ICMPv6 является протоколом контрольных сообщений IPv6. Несмотря на то, что ICMPv6 формально является самостоятельным протоколом, и обращение к соответствующему критерию должно производиться с использованием синтаксиса для протокола (<tt>-p</tt>), а не&nbsp;для вспомогательного критерия (<tt>-m</tt>), де-факто этот протокол неотделим от IPv6, и поэтому соответствующий критерий может использоваться только в ip6tables, но не&nbsp;в iptables.
Строка 1140:
Также к данному критерию допустимо обращение по названию ipv6-mh (<tt>-p ipv6-mh</tt>).
 
==== [[{{w |IPsec]]}} ====
 
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''' — соединение не открыто, то есть пакет является первым в соединении. Полезные примеры использования этого состояния приведены выше, в частности, при описании [[iptables#TCP|TCP-специфичных критериев]].
 
:* '''ESTABLISHED''' — пакет относится к уже установленному соединению. Обычно такие пакеты принимаются без дополнительной фильтрации, как и в случае с RELATED.
 
:* '''RELATED''' — пакет открывает новое соединение, логически связанное с уже установленными, например, открытие канала данных в пассивном режиме [[{{w |FTP]]}}.
Например:
<source lang="bash">
Строка 1189:
Этот набор команд обеспечит функционирование на хосте FTP-сервера с поддержкой как активного, так и пассивного режимов. В пассивном режиме FTP клиент сначала устанавливает управляющее соединение на TCP-порт 21 сервера. Когда возникнет необходимость передачи данных, клиент даст серверу команду PASV. Сервер выберет высокий порт и подключится к нему в режиме прослушивания, отправив номер порта клиенту по управляющему соединению. Система [[conntrack]], при наличии подгруженного модуля ядра nf_conntrack_ftp, зафиксирует это сообщение и выделит номер порта. Когда клиент откроет соединение данных на этот высокий порт, система conntrack присвоит первому пакету статус RELATED, в результате чего пакет пройдет по нашему правилу и будет принят. Остальные пакеты в этом соединении будут иметь уже статус ESTABLISHED и тоже будут приняты.
 
Возможность корректно обрабатывать пассивный режим FTP, как это было описано выше, из всех [[unix]]-фаерволов доступна только в iptables. В других фаерволах для решения данной проблемы используются различные «костыли». Например, в [[{{w |pf]]}} управляющие FTP-соединения [http://www.openbsd.org/faq/pf/ftp.html#client пропускаются] через специальную программу [http://www.openbsd.org/cgi-bin/man.cgi?query=ftp-proxy&sektion=8 ftp-proxy], которая анализирует трафик подобно conntrack и «на лету» добавляет правила для соединений данных. Однако даже подобные «костыли» существуют далеко не для всех протоколов. Поэтому можно утверждать, что в данном аспекте iptables находится вне конкуренции.
 
С обработкой активного режима таких проблем не возникает, так как сервер сам устанавливает соединение данных с порта 20, поэтому первый пакет пропускается согласно правилу по умолчанию цепочки OUTPUT. Правда, проблемы могут возникнуть на стороне фаервола клиента, но это уже не относится к компетенции сервера.
Строка 1200:
:* '''UNTRACKED''' — отслеживание состояния соединения для данного пакета было отключено. Обычно оно отключается с помощью действия NOTRACK в таблице raw.
 
:* '''DNAT''' — показывает, что к данному соединению применена операция подмены адреса назначения (об операциях преобразования адресов см. [[iptables#Таблица nat|выше]]).
 
:* '''SNAT''' — показывает, что к данному соединению применена операция подмены адреса источника (об операциях преобразования адресов см. [[iptables#Таблица nat|выше]]).
 
Остальные параметры критерия conntrack, как уже говорилось, мы опишем лишь конспективно.
Строка 1209:
 
Применяется для определения статуса соединения в системе conntrack. Возможные статусы:
:* '''EXPECTED''' — данное соединение ожидалось системой conntrack по результатам анализа других соединений. Например, после того, как клиент и сервер через управляющее [[{{w |FTP]]}}-соединение согласуют номер порта для соединения данных в пассивном режиме, система [[conntrack]] на сервере будет ожидать входящее соединение на этот порт.
:* '''CONFIRMED''' — подтвержденное соединение. Такой статус присваивается соединению после того, как инициатор начал передачу пакетов.
:* '''SEEN_REPLY''' — соединение, по которому поступил ответ, то есть имеет место передача данных в обоих направлениях (поддержка данного состояния появилась сравнительно недавно).
Строка 1217:
* <tt>[!] '''--ctproto''' ''протокол''</tt>
 
Протокол [[w:Транспортный уровень |транспортного уровня]], определенный системой conntrack. Синтаксис аналогичен стандартному критерию <tt>-p</tt>.
 
* <tt>[!] '''--ctdir''' {ORIGINAL|REPLY}</tt>
Строка 1275:
Система conntrack присваивает каждому соединению тайм-аут (счетчик обратного отсчета времени). Когда этот счетчик доходит до нуля, система conntrack удаляет информацию о соединении из своих таблиц. Тайм-аут устанавливается в значение по умолчанию каждый раз, когда по соединению передаются данные. Таким образом, активно используемые соединения никогда не будут сброшены.
 
Заметим, что значения тайм-аута по умолчанию для разных протоколов, и даже для одного протокола на разных стадиях установки соединения, могут различаться. Например, для протокола [[{{w |TCP]]}} вводятся отдельные значения тайм-аутов для состояний SYN_SENT, SYN_RECV, ESTABLISHED (не путать TCP-состояние ESTABLISHED с conntrack-состоянием ESTABLISHED), FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE. Для [[{{w |UDP]]}} существуют два тайм-аута: для соединений, не получивших статуса ASSURED (conntrack_udp_timeout) и для соединений, по которым передано достаточное количество данных в обе стороны для получения этого статуса (conntrack_udp_timeout_stream). Для [[{{w |ICMP]]}} тайм-аут только один.
 
==== state ====
Строка 1300:
К этой группе можно отнести критерии, расширяющие возможности других критериев.
 
* '''multiport''' — позволяет указать несколько (до 15) портов и/или их диапазонов (для протоколов [[{{w |TCP]]}}, [[{{w |UDP]]}}, [[{{w |SCTP]]}}, [[{{w |DCCP]]}} и [[{{w |UDP Lite]]}}). Поддерживает следующие параметры
 
<tt>[!] --sports</tt>, <tt>--source-ports ''порт''[:''порт''][,''порт''[:''порт''][,...]]</tt> — улучшенная версия критерия <tt>--sport</tt>, описанного выше. Позволяет перечислить (без пробелов, через запятую) до 15 портов или их диапазонов.
Строка 1312:
<tt>[!] --ports ''порт''[:''порт''][,''порт''[:''порт''][,...]]</tt> — пакет будет подпадать под этот критерий, если его исходный порт ''или'' порт назначения присутствует в указанном списке.
 
* '''iprange''' — позволяет указать диапазон [[{{w |IP-адрес]]}}ов, не являющийся подсетью. Поддерживает следующие параметры:
 
<tt>[!] --src-range ''адрес''[-''адрес'']</tt> — позволяет указать диапазон исходных адресов. Например,
Строка 1332:
будет выделять пакеты с маркировкой 15.
 
Если указана маска, то перед сравнением с заданным значением маркировка каждого пакета комбинируется с этой маской посредством логической операции [[w:Конъюнкция |AND]], то есть проверяется условие <tt>x & ''маска'' == ''значение''</tt> (где x — маркировка текущего пакета). Такой подход позволит сравнивать значения отдельных [[{{w |бит]]}}. Например, критерию
<source lang="bash">
-m mark --mark 64/64
Строка 1346:
* '''connmark''' — полностью аналогичен mark, но проверяет не маркировку пакета (nfmark), а маркировку соединения (ctmark). Также имеет параметр <tt>--mark</tt> с аналогичным синтаксисом.
 
В качестве практического примера использования меток пакетов и соединений рассмотрим улучшение работы [[{{w |l7-filter]]}}-userspace.
 
Userspace-вариант [[{{w |l7-filter]]}} является [[w:Демон (программа) |демоном]], взаимодействующим с [[{{w |netfilter]]}} через подсистему nfnetlink_queue — действие NFQUEUE в терминологии iptables. При помощи этого действия определенные пакеты можно направить на анализ демону l7-filter. По результатам анализа демон выставит маркировку пакетов: 1 — пакет принадлежит новому соединению, тип которого пока не идентифицирован; 2 — пакет принадлежит соединению, тип которого идентифицировать так и не удалось. Другие значения соответствуют установленным типам соединений (соответствие задается в конфигурационном файле демона) [http://l7-filter.sourceforge.net/HOWTO-userspace#Does].
 
Задача l7-filter — определить тип протокола [[Прикладнойw:Протоколы прикладного уровня уровень|прикладного уровня]] (см. [[{{w |модель OSI]]}}) для данного пакета/соединения. Решается эта задача путем анализа содержимого пакета с применением [[Регулярные выражения|регулярных выражений]], позволяющих определить типовые лексемы, характерные для различных протоколов (например, «<tt>220 ftp server ready</tt>» для [[{{w |FTP]]}} или «<tt>HTTP/1.1 200 OK</tt>» для [[{{w |HTTP]]}}). Пакет, в котором встречаются такие лексемы, может быть однозначно классифицирован. В принципе, это дает достаточное основание классифицировать соединение в целом. Однако, в этом поведение kernel и userspace версий l7-filter существенно различается.
 
Как описывается в [http://l7-filter.sourceforge.net/technicaldetails документации], версия l7-filter-kernel ''хранит'' данные о соединениях и ''использует'' их для классификации пакетов, принадлежащих к соединениям, тип которых уже установлен. В то же время, аналогичное утверждение в отношении l7-filter-userspace в документации отсутствует. И, как показывает практика, userspace-версия ''не&nbsp;использует'' информацию о соединениях. Возможно, это обусловлено техническими ограничениями 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. Посмотрев на диаграмму выше, вы можете убедиться, что приведенные правила обрабатывают весь трафик, как принадлежащий самому хосту, так и транзитный, за исключением локального. Локальный трафик (идущий через интерфейс [[loopbackw:Loopback |lo]]), бессмысленно шейпить, а значит, не стоит и классифицировать.
 
Теперь добавим правила, обеспечивающие копирование маркировки пакетов в маркировку соединений и обратно:
Строка 1391:
Второй момент, который стоит пояснить — маски специального вида. По сути, они позволяют проверить, лежит ли маркировка пакета в диапазоне от 16 до 31. Такая защита позволяет избежать обработки маркировок 0 (такую маркировку имеет локальный трафик, так как он не проходит процедуру анализа), 1 и 2 (эти значения маркировки, как уже было замечено выше, означают, что тип пакета не определен), а также 32 и выше (эти значения мы оставляем для других задач).
 
Как показывает [http://www.linux.org.ru/jump-message.jsp?msgid=3790164&cid=3791754 практика], даже в самом примитивном случае (детекция протокола [[{{w |HTTP]]}}, сервер — [[{{w |nginx]]}} 0.6.32, клиент — [http://www.hping.org/wbox/ wbox] 4), эффективность детекции возрастает — без использования маркировки соединений регистрируются лишь 2 исходящих пакета (l7-filter работает на сервере), с использованием — 3 исходящих и 2 входящих. Детальное исследование показывает, что детекции избегают лишь первые четыре пакета в соединении — 2 SYN-пакета и 2 пакета с данными. Это цифры, характерные для тестовой задачи — при передаче больших объемов данных количество детектированных пакетов будет значительно больше, в то время как количество не определенных пакетов сохранит тот же порядок.
 
Более того, предложенный метод решает задачу, не решенную даже в реализации l7-filter-kernel — маркировка связанных соединений. Согласно документации iptables, маркировка соединений автоматически копируется с исходных соединений на связанные с ними (например, с управляющего [[{{w |FTP]]}}-соединения на соединение данных).
 
 
: ''Примечание: следующий пример планируется к переносу в еще не написанный раздел статьи (Прочие критерии → statistic)''.
 
В качестве практического примера использования меток пакетов и соединений можно рассмотреть задачу [[w:Случайная величина |стохастической]] балансировки соединений между несколькими [[аплинк]]ами.
Допустим, у нас есть три провайдера, подключенных к интерфейсам eth0, eth1 и eth2 (это могут быть и [[{{w |VLAN]]}}-порты одного интерфейса, суть от этого не меняется, только названия), и их шлюзы имеются соответственно [[{{w |IP-адрес]]}}а 208.77.188.1, 208.77.189.1, 208.77.190.1.
 
Для начала, создадим для каждого провайдера свою таблицу маршрутизации
Строка 1431:
</source>
 
Таблица static предназначена для обслуживания статических маршрутов. В частности, в нее мы занесем подсети провайдеров (предположим, что все они [[CIDRw:Бесклассовая адресация |класса 1C]]), а также наши внутренние локальные сети (если таковые есть):
<source lang="bash">
# Провайдеры
Строка 1447:
По сути дела, таблица static обычно содержит те же маршруты, что и таблица main (главная таблица маршрутизации), за исключением маршрута по умолчанию — таких маршрутов у нас несколько и каждый из них размещается в отдельной таблице, выбор между которыми осуществляется на основании назначенной iptables/netfilter маркировки.
 
Заметим, что ни в таблицу static, ни в какие-либо другие таблицы не&nbsp;нужно вносить [[{{w |loopback]]}}-маршруты, например «127.0.0.1/8 dev lo», так как все эти маршруты фигурируют в автоматически создаваемой таблице local, которую любой пакет проходит в первую очередь (нетрудно убедиться в этом, посмотрев вывод команды «ip rule show»).
 
Далее, отключим статическую антиспуфинговую фильтрацию:
Строка 1455:
Reverse path filtering — штука, конечно, удобная и полезная но, к сожалению, совершенно не совместимая с динамической маршрутизацией.
 
Если вы планируете использовать этот компьютер не&nbsp;только как [[w:Сетевой шлюз |шлюз]], и но и как интернет-[[{{w |сервер]]}} (то есть предоставлять доступ к нему извне), необходимо выполнить привязку входящих соединений к их интерфейсам&nbsp;— в противном случае могут возникнуть проблемы, если обращение извне придет через одного провайдера, а сервер ответит через другого.
<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, и ответные пакеты пойдут именно на этот интерфейс. Чтобы избежать возникновения таких ситуаций, добавим [[{{w |маскарадинг]]}} для всех исходящих соединений (предполагается, что у всех провайдеров наши внешние адреса имеют вид 208.77.x.100):
<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 (ядро)|Linux]] не умеет маршрутизировать пакеты на основании маркировки соединения — только на основании маркировки пакетов. Поэтому действием <tt>CONNMARK --restore-mark</tt> мы копируем маркировку соединений в маркировку пакетов.
 
Осталось только добавить вызов этой цепочки в таблицу 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>
Стоит обратить особое внимание на тот факт, что данный метод балансирует ''пакеты'', а не соединения. Например, в том случае, если вы хотите организовать выход в интернет из локальной сети через нескольких провайдеров, не имея единого внешнего адреса, этот метод может работать некорректно — часть пакетов пройдет через одного провайдера и после операции [[{{w |NAT]]}} получит один исходный адрес, часть пойдет через другого и соответственно получит другой адрес, и в результате удаленные хосты не смогут правильно обрабатывать соединения, исходящие из вашей сети. Однако, в большинстве случаев этот негативный эффект нивелируется другим фактором — кэшированием маршрутов. При прохождении через такое правило серии пакетов, адресованных некоторому хосту, действительно случайным выбор будет только для первого из них, после чего выбранный маршрут будет закэширован, и остальные пакеты к этому хосту будут маршрутизироваться через тот же шлюз. С одной стороны, подобный эффект позволяет соединениям корректно функционировать, с другой стороны — балансировка оказывается не такой уж и случайной. К тому же, после очистки кэша маршрутов (например, посредством ввода команды <tt>ip route flush cached</tt>), работа существующих на этот момент соединений может быть нарушена. В качестве наиболее безопасного и целесообразного применения описанного метода можно привести задачу балансировки транзитного трафика в сетях без NAT (условия «прямой видимости» между балансирующим маршрутизатором и точкой схождения потоков трафика). В том случае, если доступ к шлюзам осуществляется через один сетевой интерфейс, этим методом можно балансировать и соединения, исходящие от самого хоста.
 
Также заметим, что описанные в этом примере методы балансировки не учитывают загруженность каналов. Для этого рекомендуется использовать критерий rateest и действие RATEEST совместно с уже знакомым нам CONNMARK.
Строка 1552:
iptables -P INPUT DROP
</source>
Это пример попытки защитить [[{{w |web-сервер]]}} от [[DDoSw:DoS-атака |DDoS-атаки]], ограничив количество пакетов в единицу времени. Однако, это правило не помешает без особого труда завалить сервер запросами (считая, что на один запрос требуется два входящих пакета — SYN-пакет и пакеты данных, содержащий, например, только GET /, согласно спецификации HTTP 0.9). При этом могут возникнуть помехи для легальных пользователей, например, загружающих на сервер большой файл методом POST. Более корректным решением будет ограничивать не скорость входящего потока данных, а скорость открытия новых соединений:
<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 (подробнее про префиксы и маски см. [[{{w |CIDR]]}}).
По умолчанию 32 (своя очередь для каждого отдельного хоста). Если указать 0, то контроль по параметру srcip теряет смысл.
 
Строка 1616:
iptables -P INPUT DROP # Всех остальных не пускаем
</source>
Теперь очереди ограничений для подключения к службам [[{{w |FTP]]}} и [[{{w |rsync]]}} для нашего сервера будут вводиться независимо, то есть если какой-либо хост превысит предел подключений по FTP, то это никак не повлияет на подключения по rsync. Заметим, что в данном конкретном случае аналогичную функциональность можно реализовать, даже не используя разные хеши:
<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 также имеет ряд параметров, не описанных здесь (максимальный размер таблицы, время жизни записи в таблице, интервал [[Garbage_collectionw:Сборка мусора (программирование) |«сбора мусора»]], и т. п.). За подробными сведениями обратитесь к документации.
 
* '''connlimit''' — позволяет ограничивать количество одновременно открытых соединений с каждого IP-адреса (или подсети). Параметры:
Строка 1650:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
</source>
разрешит не более пяти одновременных соединений на порт 80 с каждой подсети [[CIDRw:Бесклассовая адресация |класса 1C]].
 
Не надо путать connlimit с hashlimit — hashlimit позволяет ограничить ''скорость'' поступления пакетов с хостов или подсетей (в сочетании с <tt>-m conntrack --ctstate NEW</tt> — скорость открытия новых соединений), а connlimit — ''количество'' одновременно открытых соединений.
Строка 1673:
Таким образом, все пакеты, принадлежащие «легким» соединениям, будут маркироваться как наиболее приоритетные, а пакеты, проходящие по «тяжеловесным» соединениям — как наименее приоритетные. Такой подход позволит рационально распределять канал между различными задачами, например, просмотром веб-страниц («легкие» соединения) и скачиванием файлов («тяжелые» соединения).
 
Конечно, при таком подходе даже «тяжелые» соединения будут занимать канал с наивысшим приоритетом, пока не превысят ограничение. Но даже на медленных соединениях (128 Кбит/с) для этого достаточно всего четырех секунд (если эта закачка в данный момент единственная). После превышения лимита 50 Кбайт соединение получит средний приоритет ([[Type_of_Servicew:Тип обслуживания |TOS]] не установлен), а еще через некоторое время соединение превысит второй лимит — 500 Кбайт, и получит минимальный приоритет. В то же время, «легкие» соединения в большинстве случаев не превышают даже первого лимита, и поэтому целиком проходят с повышенным приоритетом.
 
* '''quota''' — позволяет задать квоту в байтах для данного конкретного правила. Имеет единственный параметр
Строка 1700:
echo значение > /proc/net/xt_quota/имя
</source>
Для осуществления этих действий, как и для работы с iptables, нужны полномочия [[w:Root (суперпользователь)|суперпользователя]].
 
<tt>[!] --quota ''количество''</tt> — проверяет текущее значение счетчика и уменьшает его на размер текущего пакета. Этот же параметр задает начальное значение счетчика (если счетчик с таким именем уже существует, он не сбрасывается). Пакет считается подпадающим под критерий, если счетчик еще не дошел до нуля (при указании логической инверсии — наоборот). Если немного усложнить наш предыдущий пример,
Строка 1730:
Обратите внимание, что при указании параметра grow критерий quota2 ''всегда'' будет возвращать истину. Действие для такого правила обычно назначать не имеет смысла — правило изменяет только счетчик квоты, а не сам пакет.
 
* '''length''' — позволяет использовать в качестве критерия размер пакета. Проверятся размер пакета протокола транспортного уровня ([[{{w |TCP]]}}, [[{{w |UDP]]}}, [[{{w |SCTP]]}}, [[{{w |DCCP]]}} и т. д.) или, иначе говоря, размер пакета протокола сетевого уровня ([[{{w |IP]]}}, [[{{w |IPv6]]}}) за вычетом размера заголовков сетевого уровня. Данный критерий имеет единственный параметр
 
<tt>[!] --length ''размер''[:''макс_размер'']</tt>, который может употребляться в нескольких формах:
Строка 1744:
Смысл всех приведенных форм может быть заменен на противоположный, как обычно, указанием перед данным параметром восклицательного знака. Все размеры задаются в байтах.
 
В качестве практического примера использования данного критерия можно рассмотреть установку высокого приоритета [[Typew:Тип ofобслуживания Service|TOS]] (требование минимальной задержки) для небольших транзитных пакетов (размер до 512 байт):
<source lang="bash">
iptables -t mangle -I INPUT -m length --length :512 -j TOS --set-tos Minimize-Delay
</source>
 
* '''length2''' — расширение критерия length, доступное в наборе xtables-addons. Отличается от классического length возможностью проверять размеры пакетов на различных уровнях [[Модельw:Сетевая модель OSI |модели OSI]]. Принимает следующие опции:
 
<tt>--layer3</tt> — проверка размера пакета сетевого уровня (например, IPv4-пакета).
Строка 1755:
<tt>--layer4</tt> — проверка размера пакета транспортного уровня (например, TCP-пакета).
 
<tt>--layer5</tt> — проверка размера полезной нагрузки транспортного уровня (например, содержимого TCP-пакета, ''не''&nbsp;учитывая размер заголовков TCP). Работает корректно только для некоторых протоколов транспортного уровня, на момент написания этих строк (конец 2009) поддерживаются: [[{{w |TCP]]}}, [[{{w |UDP]]}}, [[UDPLite]] ([[:en:UDPLite|en]]), [[{{w |ICMP]]}}, [[{{w |ICMPv6]]}} ([[:en:ICMPv6|en]]), [[{{w |DCCP]]}}, [[{{w |SCTP]]}}, [[{{w |IPSec]]}} (AH и ESP). Для [[{{w |SCTP]]}}-пакета в этот размер включаются все [[:en:SCTP_packet_structure|секции (chunks)]] вместе с их заголовками.
 
<tt>--layer7</tt> — для SCTP проверяется суммарный размер DATA-секций в пакете (то есть его полезная нагрузка), для остальных протоколов аналогично <tt>--layer5</tt>.
Строка 1774:
 
 
'''Подводя краткий итог по разделу «Лимитирующие критерии»''', хотелось бы заметить, что перечисленные в этом разделе критерии предназначены главным образом для ограничения доступа и защиты от различных атак. Не&nbsp;стоит пытаться ограничивать с их помощью трафик. Для ограничения и приоритезации трафика в [[Linux]] рекомендуется использовать стандартный [[Шейпинг_w:Шейпинг (информатика) |шейпер]] ядра, управляемый при помощи утилиты [[iproute2w:Iproute2 |tc]].
<!-- Если же вам нужно ограничить именно трафик, а не отдельные пакеты или соединения, то рекомендуем использовать для этого [[Шейпинг_w:Шейпинг (информатика) |шейпер]]. Управление шейпером ядра Linux производится при помощи утилиты [[iproute2w:Iproute2 |tc]]. Впрочем, этот шейпер позволяет эффективно управлять лишь исходящим трафиком.-->
 
==== Критерий recent ====
Строка 1781:
recent — это специальный критерий, позволяющий запоминать проходящие через него пакеты, а затем использовать полученную информацию для принятия решений. Ввиду его уникальности, широких возможностей и, как следствие, некоторых трудностей в понимании новичками принципов его использования, рассказ о нем был вынесен в отдельный подраздел.
 
Если быть точным, recent запоминает не сами пакеты, а их количество, время поступления, адрес источника (в последних версиях iptables также может запоминать и адрес назначения), а также, при необходимости, [[Time_to_livew:Time to live |TTL]].
 
В начале кратко рассмотрим его опции:
Строка 1799:
Заметим, что, хотя в официальной документации для параметров <tt>--seconds</tt> и <tt>--hitcount</tt> указывается возможность отрицания (указания перед ними восклицательного знака), на самом деле такое отрицание никак не&nbsp;обрабатывается в коде и не&nbsp;меняет смысла параметров, так что указывать его бессмысленно. Эта ошибка в документации исправлена в версии iptables 1.4.7.
 
<tt>--rttl</tt> — дополнительно к адресу источника/назначения, заносить в список и проверять еще и [[Time_to_livew:Time to live |TTL]] пакета.
 
<tt>--rsource</tt> — эта опция появилась в последних версиях iptables, с тех пор, как критерий recent начал поддерживать запоминание адресов не только источника, но и назначения. Позволяет явно указать, что в список вносится именно адрес источника пакета. Однако в целях обратной совместимости этот режим используется по умолчанию, и поэтому указывать данную опцию не обязательно.
Строка 1805:
<tt>--rdest</tt> — эта опция появилась в последних версиях iptables. Позволяет явно указать, что в список вносится именно адрес назначения пакета.
 
<tt>--name ''имя''</tt> — позволяет указать имя списка при использовании нескольких списков. По умолчанию используется список DEFAULT. Каждый список представлен псевдофайлом <tt>/proc/net/xt_recent/''имя''</tt> (на старых ядрах критерий recent реализован только для [[{{w |IPv4]]}}, но не&nbsp;для [[{{w |IPv6]]}}, поэтому вместо <tt>xt_recent</tt> будет <tt>ipt_recent</tt>). В частности, вы можете:
<source lang="bash">
cat /proc/net/xt_recent/имя # вывести список на экран
Строка 1815:
 
Теперь давайте рассмотрим несколько примеров.
* Блокирование [[{{w |bruteforce]]}}-атак (подбор пароля вслепую) на [[{{w |SSH]]}} и аналогичные сервисы.
<source lang="bash">
iptables -N ssh_brute_check # Создаем цепочку для проверки попыток соединений на защищаемый порт
Строка 1830:
iptables -P INPUT DROP # Что не разрешено — то запрещено
</source>
Теперь все попытки открыть новое SSH-соединение проверяются, и с одного [[{{w |IP-адрес]]}}а можно открывать не более 2 соединений за 10 минут. Обратите внимание, что за одно соединение злоумышленник может проверить несколько паролей — число попыток аутентификации до обрыва соединения задает параметр MaxAuthTries в файле <tt>/etc/ssh/sshd_config</tt>. По умолчанию это число равно 6, так что в нашем примере злоумышленник сможет проверять не более 12 паролей за 10 минут.
 
Впрочем, данный пример весьма тривиален, и сходную функциональность можно получить и при помощи критерия hashlimit:
Строка 1869:
iptables -I INPUT -i eth0 -j portscan_check
</source>
В данном случае сканированием портов считается обращение на порт 139/tcp ([[{{w |SMB]]}}). Впрочем, вы можете задать другой порт или, используя критерий multiport, даже список портов. В отличие от предыдущего примера, здесь производится автоматическая очистка списка [[{{w |IP-адрес]]}}ов: по прошествии суток с момента блокировки, первое же обращение с заблокированного адреса на наш сервер приводит к удалению этого адреса из нашего recent-списка. Однако, если это обращение вновь является попыткой сканирования портов, то есть направлено на порт 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 блокировка производится после ''первого'' попадания пакета на нерабочий порт&nbsp;— для достижения такого же эффекта в нашем примере достаточно выкинуть проверки на seconds и hitcount из блокирующих правил.) Однако, использование iptables/recent имеет значительное преимущество перед примитивными userspace-системами наподобие PortSentry&nbsp;— возможность интеграции с системой [[conntrack]], что позволяет избежать ошибочной блокировки, например, при использовании высоких портов для [[{{w |NAT]]}}.
 
* Открытие порта «по стуку».
Строка 1968:
Обратите внимание на технику реализации процесса — цепочки фаз вызываются не через <tt>-j</tt>, а через <tt>-g</tt>, поэтому после прохождения этих цепочек к пакетам сразу применяется правило по умолчанию цепочки INPUT, то есть DROP. В противном случае пакеты доходили бы до правила сброса (которое с multiport), и процесс стука все время сбрасывался бы.
 
Последовательный стук в порты можно организовать, например, утилитой [[{{w |netcat]]}}
<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#Пакет (датаграмма) |содержится]] информация о версии протокола, длине заголовка и [[Typew:Тип ofобслуживания Service|типе обслуживания]], которая нас сейчас не интересует), и проверить значение, формируемого оставшимися двумя байтами (это и есть полная длина пакета в байтах) на принадлежность диапазону от 0x100 (256 в десятичном счислении) до 0xFFFF (65535, максимально возможная длина пакета).
* Проверить, является ли данный пакет [[{{w |ICMP]]}}-пакетом с типом 0 (эхо-ответ). Учитывая переменную длину IP-заголовка, эта проверка требует несколько большего количества операций: <tt>--u32 "6 & 0xFF = 1 && 4 & 0x3FFF = 0 && 0 >> 22 & 0x3C @ 0 >> 24 = 0"</tt>
Рассмотрим эти операции последовательно:
:*'''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, поэтому мы и сравниваем этот байт с нулем.
* Проверить, задают ли байты с восьмого по одиннадцатый полезной нагрузки [[{{w |TCP]]}}-пакета одно из значений: 1, 2, 5, 8. Достигается следующим кодом: <tt>--u32 "6 & 0xFF = 6 && 4 & 0x3FFF = 0 && 0 >> 22 & 0x3C @ 12 >> 26 & 0x3C @ 8 = 1,2,5,8"</tt>
:*'''6 & 0xFF = 6''' — выделение байта с кодом протокола и сравнение его с кодом 6 (соответствует TCP). Описание этой проверки уже приведено при рассмотрении предыдущего примера.
:*'''4 & 0x3FFF = 0''' — проверка, не является ли данный пакет фрагментом. Полностью аналогична описанной в предыдущем примере.
Строка 2105:
=== Модули критериев и действий ===
 
== Параметры [[{{w |sysctl]]}}/[[{{w |procfs]]}} ==
 
=== Псевдофайлы procfs ===
Строка 2120:
=== Параметры, относящиеся к протоколам ===
 
==== [[{{w |TCP]]}} ====
 
==== [[{{w |UDP]]}} ====
 
==== [[{{w |ICMP]]}} ====
 
=== Параметры [[conntrack]] ===
Строка 2148:
 
== Команды ==
Программа позволяет задать правила, которым должны соответствовать проходящие через [[w:Межсетевой экран |брандмауэр]] [[IP-пакет]]ы. Эти правила, как и все настройки [[Linux]], записываются в текстовый файл, находящийся в папке /etc. Последовательность правил называется цепочкой (CHAIN). Для одного и того же сетевого интерфейса используются несколько цепочек. Если проходящий пакет не соответствует ни одному из правил, то выполняется действие по умолчанию.
 
При вызове, параметром указывается команда, которую нужно выполнить. Обычно можно указать только одну команду (но есть исключения). Команду можно указать одной большой буквой или словом. Если при вызове любой команды не указано название таблицы, то команда выполняется в таблице filter. Программа имеет подробную справку, вызываемую командой ''man iptables''.
Строка 2158:
<tt>iptables -t nat -n -L</tt>
 
Часто используются параметры -n (во избежение медленных запросов [[{{w |DNS]]}}) и -v (для вывода более подробной информации).
 
Команду -L можно использовать с -Z (<tt>iptables -L -Z</tt>) для вывода значений счетчиков и одновременного их обнуления.
Строка 2235:
* <tt>'''-s'''</tt>, <tt>--src</tt>, <tt>--source [!] ''адрес''[/''маска'']</tt>
 
Ограничение отправителя. Адрес может быть [[{{w |IP-адрес]]}}ом (возможно с [[маскаw:Маска подсети |маской]]), именем хоста, или доменным именем. Маска может быть в стандартном формате (например 255.255.255.0) или же в виде числа, указывающего число единиц с «левой стороны» маски (например 24). Знак «!» перед адресом изменяет критерий на противоположенный.
 
Настоятельно не рекомендуется использовать имена, для разрешения которых требуется удаленный запрос, например по системе [[{{w |DNS]]}}.
 
* <tt>'''-d'''</tt>, <tt>--dst</tt>, <tt>--destination [!] ''address''[/''mask'']</tt>
Строка 2320:
 
==== mac ====
Сравнение не IP источника пакета, а его [[{{w |ethernet]]}}-адреса
 
<tt>[!] --mac-source address</tt>. [[{{w |MAC-адрес]]}} должен быть указан в стандартном формате XX:XX:XX:XX:XX:XX.
 
Если нужна фильтрация по MAC-адресу в мостовых соединениях (например, pppoe), то можно воспользоваться утилитой [[{{w |ebtables]]}}, которая предназначена как раз для более низкоуровневой фильтрации пакетов.
 
== Примечания ==
Строка 2341:
 
== Ссылки ==
* [[Настройка межсетевого экрана в Linux]]
 
* [[Настройка межсетевого экрана в Linux]]
* [http://www.netfilter.org/ — Сайт] проекта [[{{w |Netfilter]]}}
* [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}}
* [http://freshmeatfreecode.netcom/projects/flex-fw flex-fw — это гибкая надстройка над iptables для построения сервис-ориентированного statefull-фаервола с простым синтаксисом команд].
* [http://linux.die.net/{{Unix man/8/ |iptables linux.die.net/man/|8/iptables]}} {{ref-en}}
* {{Unix man |ufw|8}} {{ref-en}}
* [http://manpages.ubuntu.com/manpages/karmic/en/man8/iptables.8.html 'man iptables' /*ubuntu linux*/]{{ref-en}} [https://help.ubuntu.com/community/IptablesHowTo (ubuntu community)]{{ref-en}}
* {{Unix man |gufw|8}} {{ref-en}}
* [http://manpages.ubuntu.com/manpages/karmic/en/man8/ufw.8.html 'man ufw' /*ubuntu linux*/]{{ref-en}} [https://help.ubuntu.com/community/UFW (ubuntu community)]{{ref-en}}
* [http://manpages.ubuntu.com/manpages/karmic/man8/gufw.8.html 'man gufw' /*ubuntu linux*/]{{ref-en}} [https://help.ubuntu.com/community/GufwIptablesHowTo (ubuntu community)]{{ref-en}}
* [https://help.ubuntu.com/9.10/serverguide/C/firewall.html 'ubuntu fierwall']- [https://wiki.ubuntu.com/UncomplicatedFirewall 'ufw utility'] [https://help.ubuntu.com/community/Firewall (ubuntu community)]UFW {{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 |Компьютерные сети}}