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.
# iptables -D INPUT 1
# iptables -P INPUT DROP
В одном правиле можно указать несколько критериев, неявно объединяются логическим AND.
Многие критерии и параметры можно инвертировать, с помощью восклицательного знака ! (! -s 127.0.0.1).
# iptables -I INPUT -i eth0 -s 192.168.0.0/16 -j DROP
# iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
# iptables -I INPUT -m conntrack --ctstate NEW -p tcp --sport 0:1023 -j DROP
# iptables -I INPUT -p tcp --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp --tcp-flags SYN,RST,ACK,FIN SYN -j LOG --log-level DEBUG --log-prefix "TCP SYN: "
# iptables -I INPUT -m conntrack --ctstate NEW -p tcp ! --syn -j DROP
UDP - (–sport, –dport)
# iptables -I INPUT -p icmp -f -j DROP
Протокол контрольных сообщений IPv4.
–icmp-type тип - проверка типа ICMP-пакета. Список возможных - iptables -p icmp -h.
Пример: Пропускать все входящие эхо-запросы.
# iptables -I INPUT -p icmp --icmp-type echo-request -j ACCEPT
# iptables -I INPUT -m conntrack --ctstate ESTABLISHED, RELATED -j ACCEPT
Лимитирующие критерии предназначены главным образом для ограничения доступа и защите от атак, для ограничения и приоритезации трафика следует использовать шейпер ядра.
# 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
Позволяет вносить в протокол ядра записи о пакетах, для который указанная данная цель. Протокол ядра доступен по команде dmesg. Не терминальная цель.
Тоже самое что и DROP, только позволяет отправить ответ запросившему хосту. (–reject-with 'тип ошибки ICMP')
Позволяет запоминать проходящие через него пакеты (кол-во, время, адреса, ttl) и использовать эту информацию для принятия решений.
Имеет ряд доп параметров, рассматривать их здесь не будем, приведем пару интересных примеров.
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 # Что не разрешено — то запрещено
# Создаем цепочку для проверки на необходимость удаления 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 секунд после стука в заданный порт, более одного стука в этот порт или стук в соседние, считается ошибкой и сразу закрывает порт.
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 # Что не разрешено — то запрещено
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) к локальной сети. Обеспечение локальным хостам доступа в интернет:
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