NetFilter/iptables

Netfilter — Firewall, NAT, и модификатор пакетов, встроен в ядро Linux с версии 2.4.

Iptables — утилита командной строки, является стандартным интерфейсом управления работой межсетевого экрана Netfilter. С её помощью создаются и изменяются правила, управляющие фильтрацией и перенаправлением пакетов.

$ type iptables

iptables is /usr/sbin/iptables

$ 

Для работы с семейством протоколов IPv6 существует Ip6tables.

Netfilter/iptables - в общем и целом совокупность цепочек определяющих правила, сгруппированные в таблицы, поскольку все дествия производятся над пакетами (udp, ip), соответственно название утилиты редактирующей эти таблицы -  iptables, поскольку видимо таблица  и является еденицей "админисрирования" netfilter

Ключевыми понятиями netfilter/iptables являются:

Правило — (критерий-действие-счетчик) каждое правило -- это строка, содержащая в себе критерии определяющие, подпадает ли пакет под заданное правило, и действие, которое необходимо выполнить в случае выполнения критерия..  Если пакет соответствует критерию, к нему применяется действие, и он учитывается счетчиком. Критерия может и не быть — тогда неявно предполагается критерий «все пакеты». Указывать действие тоже не обязательно — в отсутствие действия правило будет работать только как счетчик. 

Правила для каждой цепочки срабатывают в порядке их следования, поэтому порядок важен. 

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

В общем виде правила при редактировании записываются примерно так:

iptables [-t table] command [match] [target/jump]

Опция -t указывает на используемую таблицу. Если в правило не включается спецификатор [-t table], то по умолчанию предполагается использование таблицы filter,

Правило:     счётчик   команда - цепочка   критерии  действие

Критерий — логическое выражение, анализирующее свойства пакета и/или соединения и определяющее, подпадает ли данный конкретный пакет под действие текущего правила. Критерии соединяются логическим «И». ( если оба операнда будут истинными, логический оператор  «И» будет true. Если нет,  false.)

Действие — (действия и переходы) действия, или переход к действию которое нужно проделать с пакетом и/или соединением в том случае, если они подпадают под действие этого правила. Чаще всего употребляются действия ACCEPT и DROP (разрешить/отбросить).

Счетчик — компонент правила, обеспечивающий учет количества пакетов, которые попали под критерий данного правила. Также счетчик учитывает суммарный объем таких пакетов в байтах.

Сhain (цепочка) — упорядоченная последовательность правил. Цепочки можно разделить на пользовательские и базовые:

Существует 5 типов встроенных стандартных цепочек:

1. PREROUTING — для изначальной обработки входящих пакетов (incoming traffic). 

2. INPUT — для входящих пакетов адресованных непосредственно локальному процессу (клиенту или серверу). 

3. FORWARD — для входящих пакетов перенаправленных на выход  (пакеты проходят сначала цепь PREROUTING, затем FORWARD и POSTROUTING). 

4. OUTPUT — для пакетов генерируемых локальными процессами. 

5. POSTROUTING — для окончательной обработки исходящих пакетов. (outcoming traffic)

Также можно создавать и уничтожать собственные цепочки при помощи утилиты iptables.

                                

NAT - Network Address Translation — Преобразование сетевых адресов  NAT - это механизм в сетях TCP/IP, позволяющий изменять IP-адрес в заголовке пакета, проходящего через устройство маршрутизации трафика. Также имеет названия IP Masquerading,  Network Masquerading и Native Address Translation.

DNAT - Destination Network Address Translation -- Изменение Сетевого Адреса получателя. DNAT - это изменение адреса назначения в заголовке пакета.  Зачастую используется в паре с SNAT. Основное применение -- использование единственного реального IP-адреса несколькими компьютерами для выхода в Интернет и предоставления дополнительных сетевых услуг внешним клиентам.

SNAT - Source Network Address Translation -- Изменение Сетевого Адреса Отправителя. SNAT - это изменение исходного адреса в заголовке пакета. Основное применение --использование единственного реального IP-адреса несколькими компьютерами для выхода в Интернет. В натоящее время диапазон реальных IP-адресов, по стандарту IPv4, недостаточно широк, и его не хватает на всех (переход на IPv6 разрешит эту проблему).

 Таблица — совокупность базовых и пользовательских цепочек, объединенных общим функциональным назначением. Имена таблиц (как и модулей критериев) записываются в нижнем регистре, так как в принципе не могут конфликтовать с именами пользовательских цепочек. При вызове команды iptables таблица указывается в формате -t имя_таблицы. При отсутствии явного указания, используется таблица filter. Цепочки организованны в 4 таблицы: 

Цепочки с одинаковым названием, но в разных таблицах — совершенно независимые объекты. Например, raw PREROUTING и mangle PREROUTING обычно содержат разный набор правил; пакеты сначала проходят через цепочку raw PREROUTING, а потом через mangle PREROUTING.

Состояния

В системе netfilter, каждый пакет проходящий через механизм определения состояний, может иметь одно из четырёх возможных состояний: 

"Состояние" любой из таблиц удобно просматривать "командой": iptables -t <таблица> -L: 

iptables -t raw -L      iptables -t mangle -L      iptables -t filter -L      iptables -t nat -L

Команды

Команды  -  В контексте iptables "команда" это то посредством  чего   мы сообщаем действие, которое должен выполнить меж-сетевой экран. Обычно предполагается одно из двух  или трех действий

Команда  по большому счету одна, это; # iptables с набором соответствующих аргументов, команда должна быть указана всегда. Список доступных команд можно просмотреть с помощью команды iptables --help.   Некоторые команды могут использоваться совместно с дополнительными ключами. 

Дополнительные ключи  (без дополнительных ключей, которые используются при построении критериев (matches) или действий (targets)).

Критерии

Общие критерии допустимо употреблять в любых правилах, они не зависят от типа протокола и не требуют подгрузки модулей расширения.

Этот набор критериев зависит от типа протокола и работает только с TCP пакетами. Чтобы использовать их, необходимо в правилах указывать тип протокола --protocol tcp. Важно: критерий --protocol tcp обязательно должен стоять перед специфичным критерием. Эти расширения загружаются автоматически как для tcp протокола, так и для udp и icmp протоколов

Эти расширения подгружаются автоматически при указании типа протокола --protocol udp. Важно отметить, что пакеты UDP не ориентированы на установленное соединение, и поэтому не имеют различных флагов которые дают возможность судить о предназначении датаграмм. Получение UDP пакетов не требует какого либо подтверждения со стороны получателя. Если они потеряны, то они просто потеряны (не вызывая передачу ICMP сообщения об ошибке). Это предполагает наличие значительно меньшего числа дополнительных критериев, в отличие от TCP пакетов.

Существует только один специфичный критерий для ICMP пакетов. Это расширение загружается автоматически, если указан критерий --protocol icmp. Для проверки ICMP пакетов могут употребляться и общие критерии, поскольку известны и адрес источника и адрес  назначения и пр.

Общие критерии

Неявные критерии

Критерии, которые подгружаются неявно и становятся доступны, например при указании  критерия  --protocol tcp. На сегодняшний день существует три автоматически подгружаемых расширения,  это TCP критерии, UDP критерии и ICMP критерии. Загрузка этих расширений может производиться и явным образом с помощью ключа -m, -match, например -m tcp.

TCP критерии

Этот набор критериев зависит от типа протокола и работает только с TCP пакетами. Чтобы использовать их, вам потребуется в правилах указывать тип протокола --protocol tcp. Важно: критерий --protocol tcp обязательно должен стоять перед специфичным критерием. Эти расширения загружаются автоматически как для tcp протокола, так и для udp и icmp протоколов.

UDP критерии

Критерии, специфичные только для протокола UDP. Эти расширения подгружаются автоматически при указании типа протокола --protocol udp. Важно отметить, что пакеты UDP не ориентированы на установленное соединение, и поэтому не имеют различных флагов которые дают возможность судить о предназначении датаграмм. Получение UDP пакетов не требует какого либо подтверждения со стороны получателя. Если они потеряны, то не вызывают передачу ICMP сообщения об ошибке. Это предполагает наличие значительно меньшего числа дополнительных критериев, в отличие от TCP пакетов.

ICMP критерии

Этот протокол используется, как правило, для передачи сообщений об ошибках и для управления соединением. Он не является подчиненным IP протоколу, но тесно с ним взаимодействует, Заголовки ICMP пакетов очень похожи на IP заголовки, но имеют и отличия. Главное свойство этого протокола заключается в типе заголовка, который содержит информацию о том, что это за пакет. Полный список типов ICMP сообщений, вы можете посмотреть в приложении "Типы ICMP"(см PDF). Существует только один специфичный критерий для ICMP пакетов. Это расширение загружается автоматически, когда мы указываем критерий --protocol icmp. Для проверки ICMP пакетов могут употребляться и общие критерии, поскольку известны и адрес источника и адрес назначения и пр.

 Критерий --icmp-type

 Пример  iptables -A INPUT -p icmp --icmp-type 8

 Описание Тип сообщения ICMP определяется номером или именем. Числовые значения определяются в RFC 792. Чтобы получить список имен ICMP значений выполните команду iptables --protocol icmp --help, или посмотрите приложение Типы ICMP. Как и ранее, символ ! инвертирует критерий,например --icmp-type ! 8.

Явные критерии

Перед использованием этих расширений, они должны быть загружены явно, с помощью ключа -m или --match. Так, например, если мы собираемся использовать критерии state, то мы должны явно указать это в строке правила: -m state левее используемого критерия. Некоторые из этих критериев пока еще находятся в стадии разработки, а посему могут работать не всегда, однако, в большинстве случаев, они работают вполне устойчиво. Все отличие между явными и неявными критериями заключается только в том, что первые нужно подгружать явно, а вторые подгружаются автоматически.

Критерий Limit

Должен подгружаться явно ключом -m limit. Прекрасно подходит для правил, производящихзапись в системный журнал (logging) и т.п. Добавляя этот критерий, мы тем самым устанавливаем   предельное число пакетов в единицу времени, которое способно пропустить правило. Можно   использовать символ ! для инверсии, например -m limit ! --limit 5/s. В этом случае подразумевается, что пакеты будут проходить правило только после превышения ограничения.

1. Расширение -m limit подразумевает наличие ключей --limit и --limit-burst. Если вы не указываете эти ключи, то они принимают значение по-умолчанию.

2. Ключ --limit-burst - это максимальное значение счетчика пакетов, при котором срабатывает ограничение.

3. Ключ --limit - это скорость, с которой счетчик burst limit "откручивается назад". 

Ключи критерия limit

Критерий MAC

Критерий используется для проверки исходного MAC-адреса пакета. Расширение -m mac, на сегодняшний день, предоставляет единственный критерий, модуль расширения должен подгружаться явно ключом -m mac.

Ключи критерия MAC

 Ключ  --mac-source

 Пример   iptables -A INPUT -m mac --mac-source 00:00:00:00:00:01

 Описание  MAC адрес сетевого узла, передавшего пакет. MAC адрес должен указываться в форме XX:XX:XX:XX:XX:XX. Как и ранее, символ ! используется для инверсии критерия, например --mac-source ! 00:00:00:00:00:01, что означает - "пакет с любого узла, кроме узла, который имеет MAC адрес 00:00:00:00:00:01" . Этот критерий имеет смысл только в цепочках PREROUTING, FORWARD и INPUT и нигде более.

Критерий Mark

Критерий mark предоставляет возможность "пометить" пакеты специальным образом. Mark - специальное поле, которое существует только в области памяти ядра и связано с конкретным пакетом. Может использоваться в самых разнообразных целях, например, ограничение трафика и фильтрация. На сегодняшний день существует единственная возможность установки метки на пакет в Linux -- это использование действия MARK. Поле mark представляет собой беззнаковоецелое число в диапазоне от 0 до 4294967296 для 32-битных систем.

Ключи критерия Mark

 Ключ --mark

 Пример iptables -t mangle -A INPUT -m mark --mark 1

 Описание Критерий производит проверку пакетов, которые были предварительно "помечены". Метки устанавливаются действием MARK. Все пакеты, проходящие через netfilter имеют специальное поле mark. Нет никакой возможности передать состояние этого поля вместе с пакетом в сеть. Поле mark является целым беззнаковым, таким образом можно создать не более 4294967296 различных меток. Допускается использовать маску с меткам. В данном случае критерий будет выглядеть подобным образом: --mark 1/1. Если указывается маска, то выполняется логическое AND метки и маски.

Критерий Multiport

Расширение multiport позволяет указывать в тексте правила несколько портов и диапазонов портов. Вы не сможете использовать стандартную проверку портов и расширение -m multiport (например --sport 1024:63353 -m multiport --dport 21,23,80) одновременно, подобные правила будут просто отвергаться iptables.

Ключи критерия Multiport

Критерий Owner

Расширение owner предназначено для проверки "владельца" пакета. Изначально данное расширение было написано как пример демонстрации возможностей iptables. Допускается

использовать этот критерий только в цепочке OUTPUT. Такое ограничение наложено потому, что на сегодняшний день нет реального механизма передачи информации о "владельце" по сети, для некоторых пакетов невозможно определить "владельца" в этой цепочке. К такого рода пакетам относятся различные ICMP responses. Поэтому не следует применять этот критерий к ICMP responses пакетам.

Ключи критерия Owner

Критерий State

Критерий state используется совместно с кодом трассировки соединений и позволяет получать информацию о признаке состояния соединения, что позволяет судить о состоянии соединения, причем даже для таких протоколов как ICMP и UDP. Данное расширение необходимо загружать явно, с помощью ключа -m state.

Ключи критерия State

 Ключ --state

 Пример iptables -A INPUT -m state --state RELATED,ESTABLISHED

 Описание Проверяется признак состояния соединения (state) На сегодняшний день можно указывать 4 состояния: INVALID, ESTABLISHED, NEW и RELATED. INVALID подразумевает, что пакет связан с неизвестным потоком или соединением и, возможно содержит ошибку в данных или в заголовке. 

ESTABLISHED указывает на то, что пакет принадлежит уже установленному соединению через которое пакеты идут в обеих направлениях. 

NEW подразумевает, что пакет открывает новое соединение или пакет принадлежит однонаправленному потоку. 

RELATED указывает на то что пакет принадлежит уже существующему соединению, но при этом он открывает новое соединение

Примером тому может служить передача данных по FTP, или выдача сообщения ICMP об ошибке, которое связано с существующим TCP или UDP соединением, признак NEW это не то же самое, что установленный бит SYN в пакетах TCP, посредством которых открывается новое соединение, и, подобного рода пакеты, могут быть потенциально опасны в случае, когда для защиты сети вы используете один сетевой экран.

Критерий TOS

Критерий TOS предназначен для проведения проверки битов поля TOS. TOS -- Type Of Service  представляет собой 8-ми битовое, поле в заголовке IP-пакета. Модуль должен загружаться явно, ключом -m tos.

Данное поле служит для нужд маршрутизации пакета. Установка любого бита может привести к тому, что пакет будет обработан маршрутизатором не так как пакет со сброшенными битами TOS. Каждый бит поля TOS имеет свое значение. В пакете может быть установлен только один из битов этого поля, поэтому комбинации не допустимы. Каждый бит определяет тип сетевой службы:

Используется в ситуациях, когда время передачи пакета должно быть минимальным, т.е., если есть возможность, то маршрутизатор для такого пакета будет выбирать более скоростной канал. Например, если есть выбор между оптоволоконной линией и спутниковым каналом, то предпочтение будет отдано более скоростному оптоволокну.

Указывает, что пакет должен быть переправлен через канал с максимальной пропускной способностью. Например спутниковые каналы, обладая большей задержкой имеют высокую пропускную способность.

Выбирается максимально надежный маршрут во избежание необходимости повторной передачи пакета. Примером могут служить PPP и SLIP соединения, которые по своей надежности уступают, к примеру, сетям X.25, поэтому, сетевой провайдер может предусмотреть специальный маршрут с повышенной надежностью.

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

В данной ситуации все биты поля TOS сброшены. Маршрутизация такого пакета полностью отдается на усмотрение провайдера.

Ключи критерия TOS

 Ключ --tos

 Пример iptables -A INPUT -p tcp -m tos --tos 0x16

 Описание Данный критерий предназначен для проверки установленных битов TOS, которые описывались выше. Как правило поле используется для нужд маршрутизации, но вполне может быть использовано с целью "маркировки" пакетов для использования с iproute2 и дополнительной маршрутизации в linux. В качестве аргумента критерию может быть передано десятичное или шестнадцатиричное число, или мнемоническое описание бита, мнемоники и их числовое значение вы можете получить выполнив команду iptables -m tos -h. Ниже приводятся мнемоники и их значения.

    Minimize-Delay 16 (0x10) (Минимальная задержка),

    Maximize-Throughput 8 (0x08) (Максимальная пропускная способность),

    Maximize-Reliability 4 (0x04) (Максимальная надежность),

    Minimize-Cost 2 (0x02) (Минимальные затраты),

    Normal-Service 0 (0x00) (Обычный сервис)

Критерий TTL

TTL (Time To Live) является числовым полем в IP заголовке. При прохождении очередного маршрутизатора, это число уменьшается на 1. Если число становится равным нулю, то отправителю пакета будет передано ICMP сообщение типа 11 с кодом 0 (TTL equals 0 during transit) или с кодом 1 (TTL equals 0 during reassembly) . Для использования этого критерия необходимо явно загружать модуль ключом -m ttl.

Ключи критерия TTL

 Ключ --ttl

 Пример iptables -A OUTPUT -m ttl --ttl 60

 Описание Производит проверку поля TTL на равенство заданному значению. Данный критерий может быть использован при наладке локальной сети, например: для случаев, когда какая либо машина локальной сети не может подключиться к серверу в Интернете, или для поиска "троянов" и пр. Вобщем, области применения этого поля ограничиваются только вашей фантазией. Еще один пример: использование этого критерия может быть направлено на поиск машин с некачественной реализацией стека TCP/IP или с ошибками в конфигурации ОС.

Критерий "мусора" (Unclean match)

Критерий unclean не имеет дополнительных ключей и для его использования достаточно явно загрузить модуль. Будьте осторожны, данный модуль находится еще на стадии разработки и поэтому в некоторых ситуациях может работать некорректно. Данная проверка производится для вычленения пакетов, которые имеют расхождения с принятыми стандартами, это могут быть пакеты с поврежденным заголовком или с неверной контрольной суммой и пр., однако использование этой проверки может привести к разрыву и вполне корректного соединения.

Действия и переходы

Действия и переходы сообщают правилу, что необходимо выполнить, если пакет соотвествует заданному критерию. Чаще всего употребляются действия ACCEPT и DROP. Описание переходов в правилах выглядит точно так же как и описание действий, т.е. ставится ключ -j и указывается название цепочки правил, на которую выполняется переход. На переходы накладывается ряд ограничений:

Например, создадим цепочку tcp_packets в таблице filter с помощью команды: 

iptables -N tcp_packets

Теперь мы можем выполнять переходы на эту цепочку подобно:

iptables -A INPUT -p tcp -j tcp_packets

Т.е. встретив пакет протокола tcp, iptables произведет переход на цепочку tcp_packets и продолжит движение пакета по этой цепочке. Если пакет достиг конца цепочки то он будет возвращен в вызывающую цепочку (в нашем случае это цепочка INPUT) и движение пакета продолжится с правила, следующего за правилом, вызвавшем переход. Если к пакету во вложенной цепочке будет применено действие ACCEPT, то автоматически пакет будет считаться принятым и в вызывающей цепочке и уже не будет продолжать движение по вызывающим цепочкам. Однако пакет пойдет по другим цепочкам в других таблицах. Дополнительную информацию о порядке прохождения цепочек и таблиц в главе Порядок прохождения таблиц и цепочек.

Действие

Действие - это предопределенная команда, описывающая действие, которое необходимо выполнить, если пакет совпал с заданным критерием. Например, можно применить действие DROP или ACCEPT к пакету, в зависимости от наших нужд. В результате выполнения одних действий, пакет прекращает свое прохождение по цепочке, например DROP и ACCEPT, в результате других, после выполнения неких операций, продолжает проверку, например, LOG, в результате работы третьих даже видоизменяется, например DNAT и SNAT, TTL и TOS, но так же продолжает продвижение по цепочке.

Действие ACCEPT

Данная операция не имеет дополнительных ключей. Если над пакетом выполняется действие ACCEPT, то пакет прекращает движение по цепочке (и всем вызвавшим цепочкам, если текущая цепочка была вложенной) и считается ПРИНЯТЫМ (пропускается), тем не менее, пакет продолжит движение по цепочкам в других таблицах и может быть отвергнут там. Действие задается с помощью ключа -j ACCEPT.

Действие DROP

Данное действие просто "сбрасывает" пакет и iptables "забывает" о его существовании. "Сброшенные" пакеты прекращают свое движение полностью, т.е. они не передаются в другие таблицы, как это происходит в случае с действием ACCEPT. Следует помнить, что данное действие может иметь негативные последствия, поскольку может оставлять незакрытые "мертвые" сокеты как на стороне сервера, так и на стороне клиента, наилучшим способом защиты будет использование действия REJECT особенно при защите от сканирования портов.

Действие DNAT

DNAT (Destination Network Address Translation) используется для преобразования адреса места назначения в IP заголовке пакета. Если пакет подпадает под критерий правила, выполняющего DNAT, то этот пакет, и все последующие пакеты из этого же потока, будут подвергнуты преобразованию адреса назначения и переданы на требуемое устройство, хост или сеть. Данное действие может, к примеру, успешно использоваться для предоставления доступа к вашему web-серверу, находящемуся в локальной сети, и не имеющему реального IP адреса. Для этого вы строите правило, которое перехватывает пакеты, идущие на HTTP порт брандмауэра и выполняя DNAT передаете их на локальный адрес web-сервера. Для этого действия так же можно указать диапазон адресов, тогда выбор адреса назначения для каждого нового потока будет производиться случайнам образом. Действие DNAT может выполняться только в цепочках PREROUTING и OUTPUT таблицы nat, и во вложенных под-цепочках. Важно запомнить, что вложенные подцепочки, реализующие DNAT не должны вызываться из других цепочек, кроме PREROUTING и OUTPUT.

Ключи действия DNAT

 Ключ --to-destination     (iptables -t nat -L   просмотреть)

 Пример iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10

 Описание Ключ --to-destination указывает, какой IP адрес должен быть подставлен в качестве адреса места назначения. В выше приведенном примере во всех пакетах, пришедших на адрес 15.45.23.67, адрес назначения будет изменен на один из диапазона от 192.168.1.1 до 192.168.1.10. Как уже указывалось выше, все пакеты из одного потока будут направляться на один и тот же адрес, а для каждого нового потока будет выбираться один из адресов в указанном диапазоне случайным образом. Можно также определить единственный IP адрес. Можно дополнительно указать порт или диапазон портов, на который (которые) будет перенаправлен траффик. Для этого после ip адреса через двоеточие укажите порт, например --to-destination 192.168.1.1:80, а указание диапазона портов выглядит так: --to-destination 192.168.1.1:80-100. Как вы можете видеть, синтаксис действий DNAT и SNAT во многом схож. Не забывайте, что указание портов допускается только при работе с протоколом TCP или UDP, при наличии опции --protocol в критерии.

Действие DNAT достаточно сложно в использовании и требует дополнительного пояснения.

Рассмотрим простой пример. У нас есть WEB сервер и мы хотим разрешить доступ к нему из Интернет. Мы имеем только один реальный IP адрес, а WEB-сервер расположен в локальной сети.

Для начала добавим простое правило в цепочку PREROUTING таблицы nat: 

iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP

В соответствии с этим правилом, все пакеты, поступающие на 80-й порт адреса $INET_IP перенаправляются на наш внутренний WEB-сервер. Если теперь обратиться к WEB-серверу из Интернет, то все будет работать прекрасно. Но что же произойдет, если попробовать соединиться с ним из локальной сети? Соединение просто не установится. Давайте посмотрим как маршрутизируются пакеты, идущие из Интернет на наш WEB-сервер. Для простоты изложения примем адрес клиента в Интернет равным $EXT_BOX.

1. Пакет покидает клиентский узел с адресом $EXT_BOX и направляется на $INET_IP

2. Пакет приходит на наш брандмауэр.

3. Брандмауэр, в соответствии с вышеприведенным правилом, подменяет адрес назначения и передает его дальше, в другие цепочки.

4. Пакет передается на $HTTP_IP.

5. Пакет поступает на HTTP сервер и сервер передает ответ через брандмауэр, если в таблице маршрутизации он обозначен как шлюз для $EXT_BOX. Как     правило, он назначается шлюзом по-умолчанию для HTTP сервера.

6. Брандмауэр производит обратную подстановку адреса в пакете, теперь все выглядит так, как будто бы пакет был сформирован на брандмауэре.

7. Пакет передается клиенту $EXT_BOX.

А теперь посмотрим, что произойдет, если запрос посылается с узла, расположенного в той же локальной сети. Для простоты изложения примем адрес клиента в локальной сети равным $LAN_BOX.

1. Пакет покидает $LAN_BOX.

2. Поступает на брандмауэр.

3. Производится подстановка адреса назначения, однако адрес отправителя не подменяется, т.е. исходный адрес остается в пакете без изменения.

4. Пакет покидает брандмауэр и отправляется на HTTP сервер.

5. HTTP сервер, готовясь к отправке ответа, обнаруживает, что клиент находится в локальной сети (поскольку пакет запроса содержал оригинальный IP          адрес, который теперь превратился в адрес назначения) и поэтому отправляет пакет непосредственно на $LAN_BOX.

6. Пакет поступает на $LAN_BOX. Клиент "путается", поскольку ответ пришел не с того узла, на который отправлялся запрос. Поэтому клиент "сбрасывает"     пакет ответа и продолжает ждать "настоящий" ответ. 

Проблема решается довольно просто с помощью SNAT. Ниже приводится правило, которое выполняет эту функцию. Это правило вынуждает HTTP сервер передавать ответы на наш брандмауэр, которые затем будут переданы клиенту.

iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \ --to-source $LAN_IP


Запомните, цепочка POSTROUTING обрабатывается самой последней и к этому моменту пакет уже прошел процедуру преобразования DNAT, поэтому критерий строится на базе адреса назначения $HTTP_IP.

Если вы думаете, что на этом можно остановиться, то вы ошибаетесь! Представим себе ситуацию, когда в качестве клиента выступает сам брандмауэр. Тогда, к сожалению, пакеты будут передаваться на локальный порт с номером 80 самого брандмауэра, а не на $HTTP_IP. Чтобы разрешить и эту проблему, добавим правило:

iptables -t nat -A OUTPUT --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP

Теперь никаких проблем, с доступом к нашему WEB-серверу, уже не должно возникать. Каждый должен понять, что эти правила предназначены только лишь для корректной обработки адресации пакетов. В дополнение к этим правилам вам может потребоваться написать дополнительные правила для цепочки FORWARD таблицы filter. Не забудьте при этом, что пакеты уже прошли цепочку PREROUTING и поэтому их адреса назначения уже изменены действием DNAT.

Действие LOG

LOG -- действие, которое служит для журналирования отдельных пакетов и событий. В журнал могут заноситься заголовки IP пакетов и другая интересующая вас информация. Информация из журнала может быть затем прочитана с помощью dmesg или syslogd либо с помощью других программ. Превосходное средство для отладки ваших правил. Неплохо было бы на период отладки правил вместо действия DROP использовать действие LOG, чтобы до конца убедиться, что ваш брандмауэр работает безупречно. Обратите ваше внимание так же на действие ULOG, которое наверняка заинтересует вас своими возможностями, поскольку позволяет выполнять запись журналируемой информации не в системный журнал, а в базу данных MySQL и т.п..

Обратите внимание - если у вас имеются проблемы с записью в системный журнал, то это проблемы не iptables или netfilter, а syslog. Действие LOG имеет пять ключей, которые перечислены ниже.

Ключи действия LOG

Действие MARK

Используется для установки меток для определенных пакетов. Это действие может выполняться только в пределах таблицы mangle. Установка меток обычно используется для нужд маршрутизации пакетов по различным маршрутам, для ограничения трафика и т.п.. За дополнительной информацией вы можете обратиться к Linux Advanced Routing and Traffic Control HOW-TO. Не забывайте, что "метка" пакета существует только в период времени пока пакет не покинул брандмауэр, т.е. метка не передается по сети. Если необходимо как-то пометить пакеты, чтобы использовать маркировку на другой машине, то можете попробовать манипулировать битами поля TOS.

Ключи действия MARK

 Ключ --set-mark

 Пример iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2

 Описание Ключ --set-mark устанавливает метку на пакет. После ключа --set-mark должно следовать целое беззнаковое число.

Действие MASQUERADE

Маскарадинг (MASQUERADE) в основе своей представляет то же самое, что и SNAT только не имеет ключа --to-source

Причиной тому то, что маскарадинг может работать, например, с dialup подключением или DHCP, т.е. в тех случаях, когда IP адрес присваивается устройству динамически. Если у вас имеется динамическое подключение, то нужно использовать маскарадинг, если же у вас статическое IP подключение, то бесспорно лучшим выходом будет использование действия SNAT.

Маскарадинг подразумевает получение IP адреса от заданного сетевого интерфейса, вместо прямого его указания, как это делается с помощью ключа --to-source в действии SNAT. Действие MASQUERADE имеет хорошее свойство - "забывать" соединения при остановке сетевого интерфейса. В случае же SNAT, в этой ситуации, в таблице трассировщика остаются данные о потерянных соединениях, и эти данные могут сохраняться до суток, поглощая ценную память. Эффект "забывчивости" связан с тем, что при остановке сетевого интерфейса с динамическим IP адресом, есть вероятность на следующем запуске получить другой IP адрес, но в этом случае любые соединения все равно будут потеряны, и было бы глупо хранить трассировочную информацию.

Действие MASQUERADE может быть использовано вместо SNAT, даже если вы имеете постоянный IP адрес, однако, невзирая на положительные черты, маскарадинг не следует считать предпочтительным , поскольку он дает большую нагрузку на систему.

Действие MASQUERADE допускается указывать только в цепочке POSTROUTING таблицы nat, так же как и действие SNAT. MASQUERADE имеет ключ, описываемый ниже, использование которого необязательно.

Ключи  действия MASQUERADE

 Ключ --to-ports

 Пример iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000

 Описание Ключ --to-ports используется для указания порта источника или диапазона портов исходящего пакета. Можно указать один порт, например: -- to-ports 1025, или диапазон портов как здесь: --to-ports 1024-3000. Этот ключ можно использовать только в правилах, где критерий содержит явное указание на протокол TCP или UDP с помощью ключа --protocol

Действие REDIRECT

Выполняет перенаправление пакетов и потоков на другой порт той же самой машины. К примеру, можно пакеты, поступающие на HTTP порт перенаправить на порт HTTP proxy. 

Действие REDIRECT очень удобно для выполнения "прозрачного" проксирования (transparent proxying), когда машины в локальной сети даже не подозревают о существовании прокси. REDIRECT может использоваться только в цепочках PREROUTING и OUTPUT таблицы nat. И конечно же это действие можно выполнять в подцепочках, вызываемых и вышеуказанных. Для действия REDIRECT предусмотрен только один ключ.

Ключ действия REDIRECT

 Ключ --to-ports

 Пример iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

 Описание Ключ --to-ports определяет порт или диапазон портов назначения. Без указания ключа --to-ports, перенаправления не происходит, т.е. пакет идет на тот порт, куда и был назначен. В примере, приведенном выше, --to-ports 8080 указан один порт назначения. Если нужно указать диапазон портов, то мы должны написать нечто подобное --to-ports 8080-8090. Этот ключ можно использовать только в правилах, где критерий содержит явное указание на протокол TCP или UDP с помощью ключа --protocol.

Действие REJECT


REJECT используется, как правило, в тех же самых ситуациях, что и DROP, но в отличие от DROP, команда REJECT выдает сообщение об ошибке на хост, передавший пакет. Действие REJECT на сегодняшний день может использоваться только в цепочках INPUT, FORWARD и OUTPUT (и во вложенных в них цепочках). Пока существует только единственный ключ, управляющий поведением команды REJECT.

Ключ действия REJECT

 Ключ --reject-with

 Пример iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset

 Описание Указывает, какое сообщение необходимо передать в ответ, если пакет совпал с заданным критерием. При применении действия REJECT к пакету, сначала на хост-отправитель будет отослан указанный ответ, а затем пакет будет "сброшен". Допускается использовать следующие типы ответов: icmp-net-unreachable, icmp-host-unreachable, icmp-port-unreachable, icmp-proto-unreachable, icmp-net-prohibited и icmp-host- prohibited. По-умолчанию передается сообщение port-unreachable.

Все вышеуказанные типы ответов являются ICMP error messages. Дополнительную информацию по типам ICMP сообщений вы можете получить в приложении Типы ICMP. В заключение укажем еще один тип ответа - tcp-reset, который используется только для протокола TCP. Если указано значение tcp-reset, то действие REJECT передаст в ответ пакет TCP RST, пакеты TCP RST используются для закрытия TCP соединений. За дополнительной информацией обращайтесь к RFC 793  Transmission Control Protocol. (Список типов ICMP ответов и их алиасов вы сможете получить введя команду iptables -j REJECT -h ).

 Действие RETURN

Действие RETURN прекращает движение пакета по текущей цепочке правил и производит возврат в вызывающую цепочку, если текущая цепочка была вложенной, или, если текущая цепочка лежит на самом верхнем уровне (например INPUT), то к пакету будет применена политика по-умолчанию. Обычно, в качестве политики по-умолчанию назначают действия ACCEPT или DROP .

Для примера, допустим, что пакет идет по цепочке INPUT и встречает правило, которое производит переход во вложенную цепочку - --jump EXAMPLE_CHAIN. Далее, в цепочке EXAMPLE_CHAIN пакет встречает правило, которое выполняет действие --jump RETURN. Тогда произойдет возврат пакета в цепочку INPUT. Другой пример, пусть пакет встречает правило, которое выполняет действие --jump RETURN в цепочке INPUT. Тогда к пакету будет примененаполитика по-умолчанию цепочки INPUT.

Действие SNAT

SNAT используется для преобразования сетевых адресов (Source Network Address Translation), т.е. изменение исходящего IP адреса в IP заголовке пакета. Например, это действие можно использовать для предоставления выхода в Интернет другим компьютерам из локальной сети, имея лишь один уникальный IP адрес. Для этого. необходимо включить пересылку пакетов (forwarding) в ядре и затем создать правила, которые будут транслировать исходящие IP адреса нашей локальной сети в реальный внешний адрес. В результате, внешний мир ничего не будет знать о нашей локальной сети, он будет считать, что запросы пришли с нашего брандмауэра. SNAT допускается выполнять только в таблице nat, в цепочке POSTROUTING. Другими словами, только здесь допускается преобразование исходящих адресов. Если первый пакет в соединении подвергся преобразованию исходящего адреса, то все последующие пакеты, из этого же соединения, будут преобразованы автоматически и не пойдут через эту цепочку правил.

Ключи действия SNAT

 Ключ --to-source

 Пример iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source   194.236.50.155-194.236.50.160:1024-32000

 Описание Ключ --to-source используется для указания адреса, присваемового пакету. Все просто, вы указываете IP адрес, который будет подставлен в заголовок пакета в качестве исходящего. Если вы собираетесь перераспределять нагрузку между несколькими брандмауэрами, то можно указать диапазон адресов, где начальный и конечный адреса диапазона разделяются дефисом, например: 194.236.50.155-194.236.50.160. Тогда, конкретный IP адрес будет выбираться из диапазона случайным образом для каждого нового потока.

Дополнительно можно указать диапазон портов, которые будут использоваться только для нужд SNAT. Все исходящие порты будут после этого перекартироваться в заданный диапазон. iptables старается, повозможности, избегать перекартирования портов, однако не всегда это возможно, и тогда производится перекартирование . Если диапазон портов не задан, то исходные порты ниже 512 перекартируются в диапазоне 0-511, порты в диапазоне 512-1023 перекартируются в диапазоне 512-1023, и, наконец порты из диапазона 1024-65535 перекартируются в диапазоне 1024-65535. 

Что касается портов назначения, то они не подвергаются перекартированию.

Действие TOS

Команда TOS используется для установки битов в поле Type of Service IP заголовка. Поле TOS содержит 8 бит, которые используются для маршрутизации пакетов. Это один из нескольких полей, используемых iproute2. Так же важно помнить, что данное поле может обрабатываться различными маршрутизаторами с целью выбора маршрута движения пакета. Как уже указывалось выше, это поле, в отличие от MARK, сохраняет свое значение при движении по сети, а поэтому может использоваться вами для маршрутизации пакета. На сегодняшний день, большинство маршрутизаторов в Интернете никак не обрабатывают это поле, однако есть и такие, которые смотрят на него. Если вы используете это поле в своих нуждах, то подобные маршрутизаторы могут принять неверное решение при выборе маршрута, поэтому, лучше всего использовать это поле для своих нужд только в пределах вашей WAN или LAN.

Действие TOS воспринимает только предопределенные числовые значения и мнемоники, которые вы можете найти в linux/ip.h. Если вам действительно необходимо устанавливать произвольные значения в поле TOS, то можно воспользоваться "заплатой" FTOS с сайта Paksecured Linux Kernel patches, поддерживаемого Matthew G. Marsh. Однако, будьте крайне осторожны с этой "заплатой". Не следует использовать нестандартные значения TOS иначе как в особенных ситуациях. Данное действие допускается выполнять только в пределах таблицы mangle. В некоторых старых версиях iptables (1.2.2 и ниже) это действие реализовано с ошибкой (не исправляется контрольная сумма пакета), а это ведет к нарушению протокола обмена и в результате такие соединения обрываются. Команда TOS имеет только один ключ, который описан ниже.

Ключ действия TOS

 Ключ --set-tos

 Пример  iptables -t mangle -A PREROUTING -p TCP --dport 22 -j TOS --set-tos 0x10

 Описание Ключ --set-tos определяет числовое значение в десятичном или шестнадцатиричном виде. Поскольку поле TOS является 8-битным, то вы можете указать число в диапазоне от 0 до 255 (0x00 - 0xFF). Однако, большинство значений этого поля никак не используются. Вполне возможно, что в будущих реализациях TCP/IP числовые значения могут быть изменены, поэтому, во-избежание ошибок, лучше использовать мнемонические обозначения:

Minimize-Delay (16 или 0x10),

Maximize-Throughput (8 или 0x08),

Maximize-Reliability (4 или 0x04),

Minimize-Cost (2 или 0x02) или Normal-Service (0 или 0x00).

По-умолчанию большинство пакетов имеют признак Normal-Service, или 0. Список мнемоник вы сможете получить, выполнив команду iptables -j TOS -h.

Действие TTL

Действие TTL используется для изменения содержимого поля Time To Live в IP заголовке. Один из вариантов применения этого действия - это устанавливать значение поля Time To Live  ВО ВСЕХ исходящих пакетах в одно и то же значение. Для чего это?! Есть некоторые провайдеры, которые очень не любят, когда одним подключением пользуется несколько компьютеров, если мы начинаем устанавливать на все пакеты одно и то же значение TTL, то тем самым мы лишаем провайдера одного из критериев определения того, что подключение к Интернету разделяется несколькими компьютерами. 

Для примера можно привести число TTL = 64, которое является стандартным для ядра Linux. За дополнительной информацией по установке значения по-умолчанию обращайтесь к ip-sysctl.txt, который вы найдете в приложении Ссылки на другие ресурсы.

Действие TTL можно указывать только в таблице mangle и нигде больше. Для данного действия предусмотрено 3 ключа, описываемых ниже.

Ключи действия TTL

Действие ULOG

Действие ULOG предоставляет возможность журналирования пакетов в пользовательское пространство. Оно заменяет традиционное действие LOG, базирующееся на системном журнале. При использовании этого действия, пакет, через сокеты netlink, передается специальному демону который может выполнять очень детальное журналирование в различных форматах (обычный текстовый файл, база данных MySQL и пр.) и к тому же поддерживает возможность добавления надстроек (плагинов) для формирования различных выходных форматов и обработки сетевых протоколов. Пользовательскую часть ULOGD вы можете получить на домашней странице ULOGD project page.

Ключи действия ULOG

Удаление правил

Анализ

$ sudo iptables-save -c -t filter           # Дамп правил таблицы filter

# Таблица filter

*filter

# Цепочки INPUT, FORWARD, OUTPUT, их политики и счётчики

:INPUT ACCEPT [19302:9473669]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [5462736:4247599532]

$ sudo iptables-save -c -t filter              #Без правил

# Generated by iptables-save v1.4.21 on Fri Mar 13 20:46:23 2015

*filter

:INPUT ACCEPT [467:132031]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [436:45956]

COMMIT

# Completed on Fri Mar 13 20:46:23 2015

----------------------------------------------------------------------

 Правило: [17:1020]   -A INPUT   -i em1 -p tcp -m tcp --dport 22   -j ACCEPT

"[17:1020]"                                               - счётчик,

"-A INPUT"                                                 - команда, цепочка 

"-i em1 -p tcp -m tcp --dport 22"       - критерии

"-j ACCEPT"                                                - действие

[17:1020]   -A INPUT   -i em1 -p tcp -m tcp --dport 22   -j ACCEPT

COMMIT   - фиксировать, совершить,записать

MASQUERADE  NAT

Маскарадинг (MASQUERADE) по сути то же самое, что и SNAT только не имеет ключа --to-source, подразумевает получение IP адреса от заданного сетевого интерфейса, вместо прямого его указания, как это  делается с помощью ключа --to-source в действии SNAT, действие MASQUERADE может быть использовано вместо SNAT, даже если вы имеете постоянный IP адрес, однако, невзирая на положительные черты, маскарадинг не следует считать предпочтительным в этом случае, поскольку он дает большую нагрузку на систему.Действие MASQUERADE допускается указывать только в цепочке POSTROUTING таблицы nat, так же как и действие SNAT. 

MASQUERADE имеет ключ, --to-ports, использование которого необязательно.

Ключ --to-ports используется для указания порта источника или диапазона портов исходящего пакета. Можно указать один порт, например: --to-ports 1025, или диапазон портов как здесь: --to-ports 1024-3000. Этот ключ можно использовать только в правилах, где критерий содержит явное указание на протокол TCP или UDP с помощью ключа --protocol.

Как работает маскарад?

Ваш пакет (например на www.ibm.com) проходит через сервер и в нем сервер меняет адрес источника НА СВОЙ АДРЕС, через который как раз и раздается интернет в локальной сети (111.111.111.111). Пакет приходит на www.ibm.com и хост отвечает по адресу в пакете (111.111.111.111). Так как Ваш сервер запомнил, что пакет для www.ibm.com посылали вы, то он принимает пакет и отдает его вашему компьютеру. Вот и все, пакет ушел и вернулся. Включается маскарад в iptables так:

iptables -A FORWARD -s 192.168.0.0/24 -j ACCEPT

(этой командой вы разрешили прохождение пакетов между сетевыми интерфейсами из локальной сети 192.168.0.0/24)

iptables -A FORWARD -d 192.168.0.0/24 -j ACCEPT

(этой командой вы разрешили прохождение пакетов между сетевыми интерфейсами в локальную сеть 192.168.0.0/24)

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j MASQUERADE

(и последняя команда - ей вы включили маскарад для сети 192.168.0.0/24).

Еще  нужно проверить чтобы был включен forward ip в вашем ядре. Сделать это можно командой;

cat /proc/sys/net/ipv4/ip_forward

если Вы получили 1 на выходе значит все в порядке, если 0, тогда вам нужно включить ip forward командой

echo 1 >/proc/sys/net/ipv4/ip_forward

Как работает NAT ?

Ваш пакет (например на www.ibm.com) проходит через сервер и в нем адрес источника меняется НА УКАЗАННЫЙ АДРЕС (мы же укажем адрес сервера 111.111.111.111, и тогда). Пакет приходит на www.ibm.com и хост отвечает по адресу в пакете (111.111.111.111). Пакет приходит на Ваш сервер и происходит обратная замена. Включается NAT в iptables так:

iptables -A FORWARD -s 192.168.0.0/24 -j ACCEPT

(этой командой вы разрешили прохождение пакетов между сетевыми интерфейсами из локальной сети 192.168.0.0/24)

iptables -A FORWARD -d 192.168.0.0/24 -j ACCEPT

(этой командой вы разрешили прохождение пакетов между сетевыми интерфейсами в локальную сеть 192.168.0.0/24)

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j SNAT --to-source 111.111.111.111

(и последняя команда - ей вы включили трансляцию адресов сети 192.168.0.0/24 на адрес 111.111.111.111). 

Еще вам нужно проверить чтобы был включен forward ip в вашем ядре. Сделать это можно командой;

cat /proc/sys/net/ipv4/ip_forward

если Вы получили 1 на выходе значит все в порядке, если 0, тогда вам нужно включить ip forward командой

echo 1 >/proc/sys/net/ipv4/ip_forward

Архитектура

В системе netfilter, ключевой элемент архитектуры это цепочка, пакеты пропускаются через цепочки. Сhain-цепь other_chain-другая цепь.

Цепочка является упорядоченным списком правил, а каждое правило может содержать критерии и действие или переход. Когда пакет проходит через цепочку, система netfilter по очереди проверяет, соответствует ли пакет всем критериям очередного правила, и если так, то выполняет действие (если критериев в правиле нет, то действие выполняется для всех пакетов проходящих через правило). Вариантов возможных критериев очень много. Например, пакет соответствует критерию –source 192.168.1.1 если в заголовке пакета указано, что отправитель — 192.168.1.1. Самый простой тип перехода, –jump, просто пересылает пакет в начало другой цепочки. Также при помощи –jump можно указать действие. Стандартные действия доступные во всех цепочках

ACCEPT (пропустить),

DROP (удалить),

QUEUE (передать на анализ внешней программе),

RETURN (вернуть на анализ в предыдущую цепочку).

Например, команды:

iptables -A INPUT --source 192.168.1.1 --jump ACCEPT

iptables -A INPUT --jump other_chain

означают «добавить к концу цепочки INPUT следующие правила: пропустить пакеты из 192.168.1.1, а всё, что останется — отправить на анализ в цепочку other_chain».

Диаграмма прохождения таблиц и цепочек

                                                                 iptables-save     ptables-restore

iptables-save [-c] [-t table]

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

-t   можно указать имя таблицы для сохранения. Если ключ -t не задан, то сохраняются все таблицы.

  Без аргументов выведет созданное или измененное правило в stdout, где его копируют и вставлюют в файл правил.

iptables-restore [-c] [-n]

-c    заставляет восстанавливать значения счетчиков.

-n   правила должны быть добавлены к имеющимся.

По-умолчанию утилита (без ключа -n) очистит содержимое таблиц и цепочек перед загрузкой нового набора правил.

Один из плюсов использования утилит iptables-save и iptables-restore состоит в высокой скорости загрузки и сохранения больших наборов правил.

    Главный недостаток, связанный с установкой наборов правил из сценариев командной оболочки состоит в том, что команда iptables копирует набор правил из пространства ядра в пространство пользователя, вставляет, добавляет или изменяет правило и, наконец, весь набор правил копируется обратно в пространство ядра. Эта последовательность действий выполняется для каждого правила, которое вставляется или изменяется в наборе правил. Эта проблема легко решается с помощью iptables-save и iptables-restore

Утилита iptables-save записывает набор правил в обычный текстовый файл в особом формате.                

Утилита iptables-restore загружает набор правил из файла.

Главное преимущество этих утилит состоит в том, что они производят сохранение/восстановление всего набора правил за одно обращение. iptables-save "в один присест" получает из пространства ядра и записывает в файл весь набор правил, а iptables-restore загружает из файла и переписывает за одно обращение в пространство ядра набор правил для каждой таблицы. Или другими словами -- вместо того, чтобы обращаться огромное число раз к ядру для того чтобы получить набор правил, а затем опять записать его в пространство ядра не меньшее число раз, можно просто сохранить набор правил в файл, а затем загружать его из файла, при этом число перемещений наборов в ядро будет зависеть только от числа используемых таблиц.

    Однако использование этих утилит имеет и свои отрицательные стороны. Придется смириться с тем, что iptables-restore не очень хорошо подходит для случая с динамически назначаемым IP-адресом и вообще для случаев, когда вам потребуется динамически изменять набор правил в зависимости от конфигурации системы и т.п..

    Еще один недостаток iptables-restore и iptables-save в том, что их функциональность не всегда соответствует описанной. Проблема состоит в том, что не многие пользуются этими утилитами, еще меньше людей вовлечено в процесс поиска ошибок в этих программах.  

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

Базовая конфигурация

Ниже приведён пример базовой статической конфигурации iptables. При сохранении и загрузке подобной конфигурации необходимо принимать во внимание возможность внесения в неё изменений со стороны других сервисов, например Fail2ban. Кроме того, при использовании IPv6-адресации конфигурацию для IPv6 следует выполнять независимо от IPv4.

Просмотр текущей конфигурации:

sudo iptables-save

Создаём скрипт с дампом правил iptables:

sudo nano /etc/network/if-up.d/iptables-rules

Копируем следующий код:

----------------------------------------

Псевдонимы для оболочки;

alias iptlist='sudo /sbin/iptables -L -n -v --line-numbers'

alias iptlistin='sudo /sbin/iptables -L INPUT -n -v --line-numbers'

alias iptlistout='sudo /sbin/iptables -L OUTPUT -n -v --line-numbers'

alias iptlistfw='sudo /sbin/iptables -L FORWARD -n -v --line-numbers'

ipset

https://serveradmin.ru/blokirovka-dostupa-k-web-serveru-po-stranam-s-pomoshhyu-iptables/

https://russianblogs.com/article

$ sudo apt install ipset

$ sudo ipset -N blacklist nethash

$ sudo ipset -L blacklist

    Name: blacklist

    Type: hash:net

    Revision: 6

    Header: family inet hashsize 1024 maxelem 65536

    Size in memory: 448

    References: 0

    Number of entries: 0

    Members:

$ sudo ipset -A blacklist 104.21.1.92

$ sudo ipset -L blacklist

    Name: blacklist

    Type: hash:net

    Revision: 6

    Header: family inet hashsize 1024 maxelem 65536

    Size in memory: 512

    References: 0

    Number of entries: 1

    Members:

    104.21.1.92

# ipset save

create blacklist hash:net family inet hashsize 1024 maxelem 65536

add blacklist 104.21.1.92

# ipset test blacklist 104.21.1.92

Warning: 104.21.1.92 is in set blacklist.

$ sudo iptables -A INPUT -m set --match-set blacklist src -j DROP

$ sudo iptables -L INPUT -v -n

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)

 pkts bytes target     prot opt in     out     source               destination         

    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set blacklist src

         iptables-save > iptables.rules

sudo iptables-restore < iptables.rules

# ipset test blacklist 127.0.0.1    // Проверить, находится ли 127.0.0.1 в черном списке

127.0.0.1 is NOT in set blacklist.

# ipset del blacklist 127.0.0.1    // Удалить если есть 127.0.0.1 из                                         черного списка

    ipset save blacklist -f blacklist.txt

    ipset save whitelist -f whitelist.txt

ipset destroy blacklist

ipset destroy whitelist

    ipset restore -f blacklist.txt

    ipset restore -f whitelist.txt

$ cat > ipsett

#!/bin/bash

ipset restore -f blacklist.txt

iptables-restore < iptables.rules

^C

$ sudo chmod +x ipsett

$ sudo cp ipsett /usr/local/bin

$ sudo ipsett

$ sudo ipset -L blacklist

Name: blacklist

Type: hash:net

Revision: 6

Header: family inet hashsize 1024 maxelem 65536

Size in memory: 576

References: 1

Number of entries: 2

Members:

172.67.128.246

104.21.1.92

https://losst.ru/ Блокировка IP-адреса IPv4  <----------- средствами netfilter/iptables

$ sudo iptables -t filter -A INPUT -s 104.21.1.92/32 -j DROP

$ su

Password: 

# > /etc/systemd/system/rc-local.service

# vim /etc/systemd/system/rc-local.service

[Unit]

Description=/etc/rc.local

ConditionPathExists=/etc/rc.local

[Service]

Type=forking

ExecStart=/etc/rc.local start

TimeoutSec=0

StandardOutput=tty

RemainAfterExit=yes

SysVStartPriority=99

[Install]

WantedBy=multi-user.target

# > /etc/rc.local

# vim /etc/rc.local

#!/bin/sh -e

exit 0

# chmod +x /etc/rc.local

# systemctl enable rc-local

Created symlink /etc/systemd/system/multi-user.target.wants/rc-local.service → /etc/systemd/system/rc-local.service.

# systemctl start rc-local

# systemctl status rc-local

● rc-local.service - /etc/rc.local

     Loaded: loaded (/etc/systemd/system/rc-local.service; enabled; vendor preset: disabled)

.............................................

Aug 29 10:10:28 KaliLinux systemd[1]: Started /etc/rc.local.

dnsmasq

https://ru.wikipedia.org/wiki/Dnsmasq

https://qastack.ru/how-to-do-domain-filtering-in-linux

https://linux-admins.ru/настройка dnsmasq.conf

$ sudo apt-get install dnsmasq

$ sudo cat /etc/dnsmasq.conf

# Configuration file for dnsmasq.

#  ................................................

# echo 'address=/*.ua/127.0.0.1' >> /etc/dnsmasq.conf

# cat /etc/dnsmasq.conf

....................................

#dhcp-name-match=set:wpad-ignore,wpad

#dhcp-ignore-names=tag:wpad-ignore

address=/*.ua/127.0.0.1

# cat /etc/resolv.conf

# Generated by NetworkManager

nameserver 127.0.0.1

nameserver 8.8.8.8

nameserver 8.8.4.4

# . /etc/dnsmasq.conf

.....по понятным причинам все это не решает проблему "радикально"

#!/sbin/iptables-restore

# Таблица filter и её цепочки

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

# Разрешаем связанные и установленые соединения

-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Разрешаем служебный icmp-трафик

-A INPUT -p icmp -j ACCEPT

# Разрешаем доверенный трафик на интерфейс loopback

-A INPUT -i lo -j ACCEPT

# Сюда можно вставлять дополнительные правила для цепочки INPUT

# Запрещаем всё остальное для INPUT

-A INPUT -j REJECT --reject-with icmp-host-prohibited

# Порядок и смысл правил для цепочек FORWARD и OUTPUT аналогичен INPUT

-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

-A FORWARD -p icmp -j ACCEPT

-A FORWARD -j REJECT --reject-with icmp-host-prohibited

# Фильтровать цепочку OUTPUT настоятельно не рекомендуется

#-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

#-A OUTPUT -p icmp -j ACCEPT

#-A OUTPUT -o lo -j ACCEPT

#-A OUTPUT -j REJECT --reject-with icmp-host-prohibited

COMMIT

----------------------------------------

Дополняем нужными правилами с учётом iptables-save.

Сохраняем и закрываем: Ctrl+O, Enter, Ctrl+X

Делаем скрипт исполняемым и загружаем правила iptables:

sudo chmod +x /etc/network/if-up.d/iptables-rules

sudo /etc/network/if-up.d/iptables-rules

--------------------------------------------------------------------------------------------------

IPv6

Просмотр текущей конфигурации:

sudo ip6tables-save

Создаём скрипт с дампом правил ip6tables:

sudo nano /etc/network/if-up.d/ip6tables-rules

Копируем следующий код:

--------------------------------------------

#!/sbin/ip6tables-restore

# Таблица filter и её цепочки

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

# Разрешаем связанные и установленые соединения

-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Разрешаем служебный icmp-трафик

-A INPUT -p ipv6-icmp -j ACCEPT

# Разрешаем доверенный трафик на интерфейс loopback

-A INPUT -i lo -j ACCEPT

# Сюда можно вставлять дополнительные правила для цепочки INPUT

# Запрещаем всё остальное для INPUT

-A INPUT -j REJECT --reject-with icmp6-adm-prohibited

# Порядок и смысл правил для цепочек FORWARD и OUTPUT аналогичен INPUT

-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

-A FORWARD -p ipv6-icmp -j ACCEPT

-A FORWARD -j REJECT --reject-with icmp6-adm-prohibited

# Фильтровать цепочку OUTPUT настоятельно не рекомендуется

#-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

#-A OUTPUT -p ipv6-icmp -j ACCEPT

#-A OUTPUT -o lo -j ACCEPT

#-A OUTPUT -j REJECT --reject-with icmp6-adm-prohibited

COMMIT

--------------------------------------------

Дополняем нужными правилами с учётом ip6tables-save.

Сохраняем и закрываем: Ctrl+O, Enter, Ctrl+X

Делаем скрипт исполняемым и загружаем правила iptables:

sudo chmod +x /etc/network/if-up.d/iptables-rules

sudo /etc/network/if-up.d/iptables-rules

--------------------------------------------------------------------------------------------------

Дополнительные правила

Ниже приведены некоторые сравнительно часто используемые правила. Цепочки INPUT/OUTPUT применяются для фильтрации локального трафика. Для транзитного трафика необходимо использовать цепочку FORWARD.

Удалённый доступ

-------------------------------------------

# remote.ssh

-A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 22 -j ACCEPT

# remote.rdp

-A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 3389 -j ACCEPT

# remote.vnc

-A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 5900 -j ACCEPT

-------------------------------------------

Веб и файловые сервисы

------------------------------------------

# web.http, web.https

-A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 80,443 -j ACCEPT

# web.ftp + необходима загрузка модуля nf_conntrack_ftp

-A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 21 -j ACCEPT

------------------------------------------

Почта и мгновенные сообщения

------------------------------------------

# mail.pop3, mail.pop3s

-A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 110,995 -j ACCEPT

# mail.imap, mail.imaps

-A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 143,993 -j ACCEPT

# mail.smtp, mail.smtps

-A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 25,465 -j ACCEPT

# im.xmpp

-A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 5222,5223 -j ACCEPT

# im.icq.oscar

-A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 5190 -j ACCEPT

------------------------------------------

Сетевые службы

-----------------------------------------

# network.openvpn.vpn

-A INPUT -p udp -m conntrack --ctstate NEW -m udp --dport 1194 -j ACCEPT

# network.squid.proxy

-A INPUT -p udp -m conntrack --ctstate NEW -m udp --dport 3128 -j ACCEPT

# network.dns

-A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 53 -j ACCEPT

-A INPUT -p udp -m conntrack --ctstate NEW -m udp --dport 53 -j ACCEPT

# network.ntp

-A INPUT -p udp -m conntrack --ctstate NEW -m udp --dport 123 -j ACCEPT

# network.tftp + необходима загрузка модуля nf_conntrack_tftp

-A INPUT -p udp -m conntrack --ctstate NEW -m udp --dport 69 -j ACCEPT

# network.dhserver.dhcp.discover-request

-A INPUT -p udp -m conntrack --ctstate NEW -m udp --sport 68 --dport 67 -j ACCEPT

# network.dhclient.dhcp.discover-request

#-A OUTPUT -p udp -m conntrack --ctstate NEW -m udp --sport 68 --dport 67 -j ACCEPT

# network.dhserver.dhcp.offer-ack

#-A OUTPUT -p udp -m conntrack --ctstate NEW -m udp --sport 67 --dport 68 -j ACCEPT

-----------------------------------------

Тестирование и отладка

Просмотр текущей конфигурации для IPv4 и IPv6:

sudo iptables-save

sudo ip6tables-save

--------------------------------------------------------------------------------------------------

Модули ядра

Просмотр загруженных модулей:

lsmod | grep -E '^ip|^nf' | sort

Для загрузки дополнительных модулей удобно применять автодополнение: 2xTab

sudo modprobe nf

sudo modprobe ip

Часто используемые модули: nf_conntrack_ftp

nf_conntrack_pptp

nf_conntrack_tftp

nf_nat_pptp

Автозагрузка модулей:

man modules-load.d

-------------------------------------------------------------------------------------------------

Ссылки

Netfilter

Список портов TCP и UDP (ru)

Iptables Tutorial (ru)

Iptables Manual (ru)

Communication Networks/IP Tables (en)

Iptables HowTo (en)

Автозагрузка правил iptables

Настройка межсетевого экрана Iptables

Руководство по iptables (Iptables Tutorial 1.1.19)

Статья

--------------------

https://wiki.archlinux.org/index.php/Simple_stateful_firewall

https://wiki.archlinux.org/index.php/Iptables

--------------------

Сбросить

# iptables -P INPUT ACCEPT

# iptables -P FORWARD ACCEPT

# iptables -P OUTPUT ACCEPT

# iptables -F

# iptables -X

Проверка

# iptables -nvL