Содержание

Iptables

Управление

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

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

# iptables-save -f /etc/iptables-conf/rules.ipv4

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

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

# iptables-restore -vV /etc/iptables-conf/rules.ipv4

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

Команды

Параметры

Расширения

Критерии

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

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

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

TCP

UDP - (–sport, –dport)

IPv4

ICMP

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

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

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

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

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

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

LOG

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

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