Инструменты пользователя

Инструменты сайта


linux:firewall:iptables

Iptables

Управление

Сохранить правила

iptables-save [-m modprobe] [-c] [-t таблица] [-f имя файла]

  • -m modproble - путь к программе modproble, можно пропустить.
  • -c - включает в поток вывода все счетчики байтов и пакетов.
  • -t таблица - если указать, выведет только ее.
  • -f имя файла - файл для сохранения, если не указать, выведет на экран.
# iptables-save -f /etc/iptables-conf/rules.ipv4

Загрузить правила

iptables-restore [-chntvV] [-w сек] [-W миллисек] [-M modproble] [-T таблица] [имя файла]

  • -c - восстановить значение всех счетчиков.
  • -n - дописать правила в конец текущей таблицы.
  • -t - только сборка и тестирование набора из файла, без обновления iptables.
  • -v - дополнительная информация.
  • -V - номер версии программы.
  • -w - дождаться монопольной блокировки xtables.
  • -W - интервал ожидания для каждой попытке монопольного реж.
  • -T таблица - восстановит только указанную таблицу.
# iptables-restore -vV /etc/iptables-conf/rules.ipv4

Для автозагрузки правил при включении ОС, можно поместить скрипт в папку /etc/network/if-pre-up.d/, назвав его iptables, так же, рекомендуется сменить владельца на root и права доступа к файлу 700.

Команды

  • -F, –flush [цепочка] - очистить все цепочки в таблице. Не сбрасывает действие по умолчанию. По умолчанию выбрана filter (-t для указания табл).
  • -A, –append цепочка правило - добавление правила в конец цепочки.
  • -I, –insert цепочка [номер-правила] правило - добавление правила в указанную позицию, №1 по умолчанию.
  • -D, –delete цепочка номер-правила - удаление указанного правила из цепочки.
    # iptables -D INPUT 1
  • -P, –policy цепочка цель - стратегия для цепочки.
    Пример: Действие по умолчанию
    # iptables -P INPUT DROP
  • -L, –list [цепочка] - список правил.
  • -N, –new-chain [цепочка] - создать новую цепочку.
  • -X, –delete-chain [цепочка] - удалить пользовательскую цепочку.
  • -E, –rename-chain старое новое-имя - переименовать пользовательскую цепочку.

Параметры

  • -v, –verbose - увеличить подробность сообщений.
  • -n, -numeric - ip-адреса и порты в числовом виде, без DNS.
  • –line-numbers - номера строк (правил)

Расширения

  • -m multiport - позволяет указывать перечень портов (так же, объединить перечень и диапазон)
  • -

Критерии

В одном правиле можно указать несколько критериев, неявно объединяются логическим AND.
Многие критерии и параметры можно инвертировать, с помощью восклицательного знака ! (! -s 127.0.0.1).

Универсальные критерии

  • -p, –protocol протокол - например tcp, udp, icmp или all (по умолчанию, если не указано явно).
  • -s, –src, –source адрес[/маска] - адрес (маска) отправителя. При указании нескольких адресов, через запятую, для каждого адреса создается отдельное правило.
    Пример: (eth0 - интерфейс интернета) Из интернета не могут приходить пакеты с адресом из локальной сети. Защита от простейшего спуфинга.
    # iptables -I INPUT -i eth0 -s 192.168.0.0/16 -j DROP
  • -d, –dst, –destination адрес[/маска] - адрес получателя (аналогично -s).
  • -i, –in-interface имя_интерфейса - входящий сетевой интерфейс, если имя заканчивается знаком «+», то соответствуют все интерфейсы начинающиеся на указанное имя.
  • -o, –out-interface имя_интерфейса - исходящий сетевой интерфейс (аналогично -i).
    Пример: «Маскарадит» весь трафик с eth0.
    # iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE

Специфичные для протоколов

TCP

  • –sport, –source-port порт[:порт] - исходящий порт (диапазон портов).
    Пример Блокировать все исходящие соединения по системным портам (они обычно только слушаются службами).
    # iptables -I INPUT -m conntrack --ctstate NEW -p tcp --sport 0:1023 -j DROP
  • –dport, –destination-port порт[:порт] - входящие порты (аналогично –sport).
    Пример Разрешить входящие на 80й порт.
    # iptables -I INPUT -p tcp --dport 80 -j ACCEPT
  • –tcp-flags маска установленные_флаги - позволяет указать список установленных и снятых TCP-флагов.
    В «маске» перечисляются все проверяемые флаги (без пробелов), далее, после пробела, те из них, что должны быть установлены. ⇒ все остальные должны быть сняты.
    Возможные флаги SYN, ACK, FIN, RST, URG, PSH (+ псевдо флаги ALL и NONE).
    Пример: Заносим в лог все входящие SYN пакеты (установлен только SYN, остальные сняты)
    # iptables -I INPUT -p tcp --tcp-flags SYN,RST,ACK,FIN SYN -j LOG --log-level DEBUG --log-prefix "TCP SYN: "
  • –syn - сокращение предыдущего примера.
    Пример: Блокируем все попытки открыть TCP соединение не с SYN-пакета (возможно ошибка оборудования либо атака)
    (PS хотя вопрос, понимает ли conntrack что это открытие соединения, не имея пакета SYN ? О_О)
    # iptables -I INPUT -m conntrack --ctstate NEW -p tcp ! --syn -j DROP
  • –tcp-option номер - позволяет проверить, используется ли в заголовке TCP-пакета соответствующая опция. Перечень опций.

UDP - (–sport, –dport)

IPv4

  • -f, –fragment - фрагменты пакета (у фрагментов нет заголовков транспортного уровня, номеров портов в т.ч.).
    Пример: Блокирует фрагменты ICMP-пакетов, т.к. обычно они очень небольшие и нормально укладываются в один пакет, наличие их фрагментов - обычно ошибки или атака
    # iptables -I INPUT -p icmp -f -j DROP
  • addrtype - позволяет проверить тип адреса источника (назначения) с точки зрения подсистемы маршрутизации сетевого стека ядра.
  • ecn - позволяет проверять значения битов ECN в заголовках TCP и IPv4.
  • realm - проверка области маршрутизации пакета.
  • ttl - проверка поля TTL в заголовке.

ICMP

Протокол контрольных сообщений IPv4.
–icmp-type тип - проверка типа ICMP-пакета. Список возможных - iptables -p icmp -h.
Пример: Пропускать все входящие эхо-запросы.

# iptables -I INPUT -p icmp --icmp-type echo-request -j ACCEPT

Критерии состояния (conntack)

  • –ctstate маска - маска содержит возможные состояния (NEW, ESTABLISHED, RELATED, INVALID, UNTRACKED, DNAT, SNAT). Описание есть тут.
    Пример: Разрешаем пакеты в уже установленных соединениях и связанных с ними
    # iptables -I INPUT -m conntrack --ctstate ESTABLISHED, RELATED -j ACCEPT
  • –ctstatus маска - статус соединения в системе conntrack (EXPECTED, CONFIRMED, SEEN_REPLY, ASSURED, NONE). Описание есть тут.
  • –ctdir {ORIGINAL|REPLY} - направление пакетов (original - от инициатора, reply - от отвечающего), по умолчанию все.
  • и т.д.

Лимитирующие критерии

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

  • –limit количество[/second(minute,hour,day)] - ограничение на кол-во пакетов, сверх - не удовлетворяют критерию. «Скорость вытекания»
  • –limit-burst кол-во - задает длину очереди. «Объем ведра»
    Пример: Оба параметра реализуют т.н. модель «дырявого ведра». У каждого такого правила своя очередь. Пакеты сверх очереди - не регистрируются и не удовлетворяют критерию.
    # iptables -I INPUT -m limit --limit 3/min --limit-burst 5 -j LOG --log-level debug

    Пример: Ограничиваем скорость открытия новых соединений (32 в сек)

    # iptables -I INPUT -p tcp --dport 80 -m conntrack --ctstate NEW -m limit --limit 32/sec --limit-burst 32 -j ACCEPT
  • hashlimit - позволяет применять аналогичные ограничения к группам хостов, подсетей или портов.
  • connlimit - ограничение кол-ва одновременных соединений с IP-адреса или подсети.
  • connbytes - ограничение кол-ва переданных байт или пакетов.
  • quota, quota2 - квота в байтах, для каждого правила.
  • length, length2 - размер пакета

Доп механизмы обработки

LOG

Позволяет вносить в протокол ядра записи о пакетах, для который указанная данная цель. Протокол ядра доступен по команде dmesg. Не терминальная цель.

  • –log-level уровень - степень подробности (см syslog.conf(5)).
  • –log-prefix префикс - префикс, для выделения записей.
  • –log-uid - вносить ИД пользователя, которому принадлежит процесс, пославший пакет.
  • –log-tcp-option (–log-ip-option) - вносить параметры заголовка tcp (ip).

REJECT

Тоже самое что и DROP, только позволяет отправить ответ запросившему хосту. (–reject-with 'тип ошибки ICMP')

Критерий recent

Позволяет запоминать проходящие через него пакеты (кол-во, время, адреса, ttl) и использовать эту информацию для принятия решений.
Имеет ряд доп параметров, рассматривать их здесь не будем, приведем пару интересных примеров.

защита_от_сканирования_портов.sh
iptables -F INPUT # Очищаем цепочку INPUT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Разрешаем пакеты по установленным соединениям
# Если за последний час было 10 или более запросов на нерабочие порты — блокируем
iptables -A INPUT -m recent --rcheck --seconds 3600 --hitcount 10 --rttl -j RETURN
# Если за последнюю минуту было 2 или более запросов на нерабочие порты — блокируем
iptables -A INPUT -m recent --rcheck --seconds 60 --hitcount 2 --rttl -j RETURN
# Разрешаем рабочие порты
iptables -A INPUT -m conntrack --ctstate NEW -p tcp -m multiport --dport 21,25,53,80,110 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate NEW -p udp -m multiport --dport 53,123 -j ACCEPT
# Всех, кто ломится в нерабочие порты — регистрируем
iptables -A INPUT -m recent --set
iptables -P INPUT DROP # Что не разрешено — то запрещено
очистка_списка_адресов.sh
# Создаем цепочку для проверки на необходимость удаления
iptables -N recent_remove
# Последнее обращение на неиспользуемые порты было менее суток назад
# поэтому оставим-ка пока этот адресок в черном списке
iptables -A recent_remove -m recent --rcheck --seconds 86400 -j RETURN
# Если адрес в есть в списке — удаляем его оттуда
iptables -A recent_remove -m recent --remove
# Вставляем эту проверку вторым правилом (сразу после проверки ctstate)
iptables -I INPUT 2 -j recent_remove

Открытие порта «по стуку»:
Защищаемый порт открывается на 10 секунд после стука в заданный порт, более одного стука в этот порт или стук в соседние, считается ошибкой и сразу закрывает порт.

открытие_после_стука_в_заданный_порт.sh
 iptables -N ssh_knock # Создаем цепочку для проверки попыток соединений на защищаемый порт
# Если за последние 60 секунд было 2 и более стука — блокируем, на всякий случай
iptables -A ssh_knock -m recent --rcheck --seconds 60 --hitcount 2 -j RETURN
# Если за последние 10 секунд стук в нужный порт был — разрешить соединение
iptables -A ssh_knock -m recent --rcheck --seconds 10 -j ACCEPT
iptables -F INPUT # Очищаем цепочку INPUT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Разрешаем пакеты по установленным соединениям
# Все попытки открыть новое соединение по SSH направляем на проверку
iptables -A INPUT -m conntrack --ctstate NEW -p tcp --dport 22 -j ssh_knock
# Здесь мы добавляем правило для регистрации стука
iptables -A INPUT -m conntrack --ctstate NEW -p tcp --dport 27520 -m recent --set
# Опять же на всякий случай — при стуке в соседние порты закрываем SSH
iptables -A INPUT -m conntrack --ctstate NEW -p tcp -m multiport --dport 27519,27521 -m recent --remove
iptables -P INPUT DROP # Что не разрешено — то запрещено
стук_в_серию_портов.sh
iptables -N reset_knock # Цепочка для сброса процесса стука
iptables -A reset_knock -m recent --name PHASE1 --remove
iptables -A reset_knock -m recent --name PHASE2 --remove
iptables -A reset_knock -m recent --name PHASE3 --remove
iptables -A reset_knock -m recent --name PHASE4 --remove
iptables -N in_phase_2 # Создаем цепочку для фазы 2
iptables -A in_phase_2 -m recent --name PHASE1 --remove # Удаляем запись из списка первой фазы
iptables -A in_phase_2 -m recent --name PHASE2 --set # Добавляем ее в список второй фазы
iptables -N in_phase_3 # Создаем цепочку для фазы 3
iptables -A in_phase_3 -m recent --name PHASE2 --remove # Удаляем запись из списка второй фазы
iptables -A in_phase_3 -m recent --name PHASE3 --set # Добавляем ее в список третьей фазы
iptables -N in_phase_4 # Создаем цепочку для фазы 4
iptables -A in_phase_4 -m recent --name PHASE3 --remove # Удаляем запись из списка третьей фазы
iptables -A in_phase_4 -m recent --name PHASE4 --set # Добавляем ее в список четвертой фазы
iptables -N checked # Для записей, прошедших проверку
iptables -A checked -j reset_knock # Очищаем списки
iptables -A checked -j ACCEPT # Разрешаем пакет
iptables -F INPUT # Очищаем цепочку INPUT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Разрешаем пакеты по установленным соединениям
# Первая фаза
iptables -A INPUT -p tcp --dport 21210 -m recent --name PHASE1 --set -j RETURN
# Для тех, кто присутствует в списке первой фазы — переход во вторую
iptables -A INPUT -p tcp --dport 11992 -m recent --rcheck --name PHASE1 --seconds 5 -g in_phase_2
# И т.д.
iptables -A INPUT -p tcp --dport 16043 -m recent --rcheck --name PHASE2 --seconds 5 -g in_phase_3
iptables -A INPUT -p tcp --dport 23050 -m recent --rcheck --name PHASE3 --seconds 5 -g in_phase_4
# Если стучатся не в том порядке — сброс
iptables -A INPUT -p tcp -m multiport --dport 21210,11992,16043,23050 -j reset_knock
# Для тех, кто прошел все четыре фазы — разрешаем доступ
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --rcheck --name PHASE4 --seconds 5 -j checked
iptables -P INPUT DROP # Дефолтное правило цепочки INPUT

Последовательный стук в серию портов можно организовать скриптом, использую утилиту netcat

for it in {21210,11992,16043,23050}; do
    echo " " | nc -w 1 host $it
done
ssh user@host

Примеры

Базовая настройка пустого сервера. Исполняемый файл - /etc/network/if-pre-up.d/iptables, root:root-700

#!/bin/bash
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Перенаправление всего трафика на другой IP Софт (браузеры в т.ч.) быстро определяют примитивное перенаправление трафика и блокируют доступ

sysctl net.ipv4.ip_forward=1 # Разрешаем передавать транзитный трафик
iptables -t nat -A PREROUTING -j DNAT --to-destination <ip-addr>
iptables -t nat -A POSTROUTING -j SNAT --to-source <ip-addr> # Для обратной связи
# или 
iptables -t nat -A POSTROUTING -j MASQUERADE # Скорее правильнее будет

MASQUERADE. Маскардинг локальной сети, на шлюзе.
На шлюзе 2 интерфейса, один из них (eth0) подключен к сети интернет, второй (eth1) к локальной сети. Обеспечение локальным хостам доступа в интернет:

маскардинг_локальной_сети.sh
sysctl net.ipv4.ip_forward=1 # Разрешаем шлюзу передавать транзитный трафик
iptables -F FORWARD # На всякий случай очистим цепочку FORWARD
# Разрешаем проходить пакетам по уже установленным соединениям
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Разрешаем исходящие соединения из локальной сети к интернет-хостам
iptables -A FORWARD -m conntrack --ctstate NEW -i eth1 -s 192.168.1.0/24 -j ACCEPT
iptables -P FORWARD DROP # Весь остальной транзитный трафик — запрещаем.
iptables -t nat -F POSTROUTING # На всякий случай очистим цепочку POSTROUTING таблицы nat
# Маскарадим весь трафик, идущий через eth0
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

PS. Если имеется статический IP адрес шлюза, целесообразнее использовать SNAT, тогда он (адрес) не будет вычисляться каждый раз заново. Тогда в последней строке нужно указать: «iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to-source `address`[-`address`]«

Правила NAT

  # Перечень
iptables -t nat -L -v
 
  # Добавление
iptables -t nat -A POSTROUTING -p udp -o tun1 -j SNAT --to-source 10.200.199.24 (на какой адрес отправлять/или с какого)
iptables -A POSTROUTING -s 192.168.0.0/24 -o eth1 -j SNAT —to-source 10.188.106.33
 
  # Удаление
iptables -D -t nat POSTROUTING 13
linux/firewall/iptables.txt · Последнее изменение: 2022/12/08 04:04 — admin