Мастерство iptables: архитектура, настройка и безопасность

Курс обеспечивает глубокое понимание логики iptables и взаимодействия с хуками Netfilter в ядре Linux [8host.com](https://www.8host.com/blog/arxitektura-iptables-i-netfilter/). Вы научитесь управлять таблицами и цепочками, настраивать NAT, отражать сетевые атаки и анализировать логи [arenda-server.cloud](https://arenda-server.cloud/blog/kak-rabotaet-faervol-iptables-osnovy/).

1. Архитектура и логика работы iptables: хуки Netfilter

Архитектура и логика работы iptables: хуки Netfilter

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

Первое и самое важное правило, которое необходимо усвоить: iptables не является файрволом в прямом смысле этого слова. Это лишь утилита пользовательского пространства (user-space), которая позволяет администратору передавать команды в ядро операционной системы Linux. Настоящим межсетевым экраном, выполняющим всю тяжелую работу по фильтрации и модификации пакетов, является встроенный в ядро фреймворк Netfilter.

> Netfilter — это набор перехватчиков (хуков) внутри сетевого стека ядра Linux, которые позволяют модулям ядра регистрировать функции обратного вызова для обработки каждого проходящего сетевого пакета.

Чтобы понять эту связку, представьте себе современный аэропорт. Netfilter — это физические контрольно-пропускные пункты, рамки металлоискателей и ленты досмотра багажа. А iptables — это свод правил, который вы выдаете службе безопасности: «пассажиров с красными паспортами отправлять на дополнительный досмотр», «жидкости объемом более 100 мл изымать». Без правил (iptables) пункты досмотра (Netfilter) будут просто пропускать всех подряд.

Пять хуков Netfilter

Любой сетевой пакет, попадающий в систему или покидающий ее, движется по строго определенному маршруту. На этом маршруте ядро Linux расставило пять контрольных точек — хуков (hooks). В этих точках пакет может быть приостановлен, изучен, изменен или уничтожен.

  • NF_IP_PRE_ROUTING — перехватывает любой входящий трафик сразу после того, как он попадает в сетевой стек от драйвера сетевой карты, но до того, как ядро примет решение о маршрутизации.
  • NF_IP_LOCAL_IN — срабатывает, если после принятия решения о маршрутизации выясняется, что пакет предназначен самому локальному серверу (например, запрос к вашему веб-серверу на порт 80).
  • NF_IP_FORWARD — активируется, если пакет предназначен другому узлу, а ваш сервер выступает в роли маршрутизатора (роутера).
  • NF_IP_LOCAL_OUT — перехватывает пакеты, которые были сгенерированы локальными процессами самого сервера (например, ваш сервер скачивает обновления) перед их отправкой в сеть.
  • NF_IP_POST_ROUTING — финальная точка для любого исходящего или транзитного трафика перед тем, как он будет передан драйверу сетевой карты для отправки в кабель.
  • Таблицы и цепочки: организация правил

    Утилита iptables организует правила управления трафиком в виде иерархической структуры: Таблицы Цепочки Правила.

    Таблицы (Tables)

    Таблицы группируют правила по их глобальному назначению. Всего существует четыре основные таблицы:

  • filter — таблица по умолчанию. Ее единственная задача — решать, пропустить пакет или заблокировать. Именно здесь настраивается базовый файрвол.
  • nat (Network Address Translation) — отвечает за подмену IP-адресов или портов. Используется для проброса портов, раздачи интернета в локальную сеть и маскарадинга.
  • mangle — предназначена для глубокой модификации заголовков IP-пакетов. Например, здесь можно изменить параметр TTL (Time To Live) или метки качества обслуживания (TOS).
  • raw — используется редко, в основном для того, чтобы исключить определенные пакеты из механизма отслеживания состояний соединений (connection tracking).
  • Цепочки (Chains)

    Цепочки — это прямые проекции хуков Netfilter в интерфейс iptables. Их названия пишутся заглавными буквами и соответствуют точкам перехвата:

  • PREROUTING привязана к хуку NF_IP_PRE_ROUTING
  • INPUT привязана к хуку NF_IP_LOCAL_IN
  • FORWARD привязана к хуку NF_IP_FORWARD
  • OUTPUT привязана к хуку NF_IP_LOCAL_OUT
  • POSTROUTING привязана к хуку NF_IP_POST_ROUTING
  • Не каждая таблица присутствует в каждой цепочке. Ядро оптимизировано так, чтобы не выполнять лишних проверок. Например, таблица filter не имеет смысла в цепочке PREROUTING, так как решение о блокировке логичнее принимать после того, как станет ясно, куда идет пакет.

    | Цепочка / Таблица | raw | mangle | nat | filter | | :--- | :--- | :--- | :--- | :--- | | PREROUTING | Да | Да | Да | Нет | | INPUT | Нет | Да | Нет | Да | | FORWARD | Нет | Да | Нет | Да | | OUTPUT | Да | Да | Да | Да | | POSTROUTING | Нет | Да | Да | Нет |

    !Схема прохождения сетевого пакета через таблицы и цепочки Netfilter

    Жизненный цикл сетевого пакета

    Чтобы научиться писать эффективные правила, необходимо уметь мысленно «пройти» путь вместе с пакетом. Рассмотрим три классических сценария из реальной практики.

    Сценарий 1: Пакет предназначен вашему серверу

    Предположим, хакер пытается подключиться к вашему серверу по SSH (порт 22). Пакет размером 64 байта поступает на сетевой интерфейс eth0.

  • Пакет попадает в цепочку PREROUTING. Сначала он проходит таблицу raw, затем mangle, затем nat. На этом этапе мы могли бы перенаправить его на другой порт, но если правил нет, пакет идет дальше.
  • Решение о маршрутизации (Routing Decision). Ядро смотрит на IP-адрес назначения. Так как адрес совпадает с адресом сервера, ядро направляет пакет локально.
  • Пакет попадает в цепочку INPUT. Здесь он проходит таблицы mangle и filter. Именно в таблице filter цепочки INPUT должно находиться правило, которое проверит IP-адрес хакера и заблокирует пакет.
  • Если пакет не заблокирован, он передается локальному процессу — демону SSH.
  • Сценарий 2: Сервер выступает в роли маршрутизатора

    Ваш сервер работает как шлюз для офисной сети. Сотрудник отправляет запрос к внешнему сайту.

  • Пакет от сотрудника попадает в PREROUTING.
  • Решение о маршрутизации. Ядро видит, что IP-адрес назначения принадлежит внешнему серверу в интернете, а не локальной машине.
  • Пакет направляется в цепочку FORWARD. Здесь в таблице filter мы можем запретить сотрудникам доступ к определенным ресурсам.
  • Пакет переходит в цепочку POSTROUTING. Здесь в таблице nat происходит маскарадинг — внутренний IP-адрес сотрудника подменяется на внешний IP-адрес сервера, чтобы ответ смог вернуться обратно.
  • Пакет уходит в интернет.
  • Сценарий 3: Сервер сам инициирует соединение

    Вы запустили команду обновления системы apt-get update.

  • Локальный процесс генерирует пакет.
  • Решение о маршрутизации. Ядро определяет, через какой сетевой интерфейс нужно отправить пакет.
  • Пакет попадает в цепочку OUTPUT, проходя таблицы raw, mangle, nat и filter.
  • Пакет переходит в POSTROUTING (таблицы mangle и nat).
  • Пакет покидает сервер.
  • Правила и действия (Targets)

    Когда пакет проходит через цепочку, он по очереди, сверху вниз, сверяется с каждым правилом. Правило состоит из критерия (например, «протокол TCP, порт 80») и действия (target).

    Если пакет совпадает с критерием, к нему применяется действие, и дальнейшая проверка в этой цепочке (как правило) прекращается. Если пакет прошел все правила и ни с одним не совпал, применяется политика по умолчанию (default policy).

    Основные действия в таблице filter:

  • ACCEPT — пропустить пакет дальше по маршруту.
  • DROP — молча уничтожить пакет. Отправитель не получит никакого уведомления и будет ждать ответа, пока не истечет время ожидания (тайм-аут). Это лучший выбор для защиты от сканирования портов и DDoS-атак. Если ботнет отправляет вам 10 000 пакетов в секунду, действие DROP заставит ядро просто удалить их из памяти, экономя ресурсы.
  • REJECT — уничтожить пакет, но отправить источнику вежливое уведомление об ошибке (ICMP-сообщение «порт недоступен»). Это полезно для внутренней сети, чтобы клиентские приложения не зависали в ожидании ответа, но категорически не рекомендуется для внешнего интернета, так как это дает злоумышленнику информацию о том, что ваш сервер жив и активно фильтрует трафик.
  • Stateful-фильтрация: память Netfilter

    Исторически первые файрволы были stateless (без сохранения состояния). Они проверяли каждый пакет изолированно. Если вы разрешали входящий трафик на порт 80, вам приходилось вручную разрешать исходящий трафик с порта 80, чтобы сервер мог ответить клиенту.

    Netfilter обладает модулем conntrack (connection tracking), который делает iptables stateful-файрволом. Ядро запоминает контекст передачи данных. Когда ваш сервер отправляет запрос к DNS-серверу, conntrack создает запись в оперативной памяти. Когда возвращается ответный пакет, Netfilter узнает его и пропускает автоматически, как часть уже «установленного» (ESTABLISHED) соединения, даже если явного правила для входящего DNS-трафика нет.

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