time

iptables: сетевая безопасность и фильтрация пакетов

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

В Linux файрвол является модулем ядра, называемым netfilter и представляет собой набор хуков (hooks) для работы с сетевым стеком. Интерфейсом для модификации правил, по которым файрвол обрабатывает пакеты, служит утилита iptables для IPv4 и утилита ip6tables для IPv6.

Всю работу по фильтрации трафика выполняет ядро системы. Iptables не является демоном и не создает новых процессов в системе. Включение или выключение iptables это всего лишь отправка сигнала в ядро. Большая скорость фильтрации достигается за счёт анализа только заголовков пакетов.

К основным возможностям iptables относиться:

  • фильтрация трафика на основе адресов отправителя и получателя пакетов, номеров портов;
  • перенаправление пакетов по определенным параметрам;
  • организация доступа в сеть (SNAT);
  • проброс портов из глобальной сети в локальную (DNAT);
  • ограничение числа подключений;
  • установление квот трафика;
  • выполнение правил по расписанию;

Содержание

  1. Процесс работы iptables
  2. Таблица mangle
  3. Таблица nat
  4. Таблица filter
  5. Утилита iptables
  6. Примеры команд iptables
  7. Защита от DDoS с помощью iptables
  8. Балансировка нагрузки с помощью iptables
  9. Надстройки, GUI к iptables
  10. Дополнительное чтиво

Процесс работы iptables

Рассмотрим основной процесс работы iptables (источник картинки rigacci.org).

iptables: сетевая безопасность и фильтрация пакетов

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

В iptables используется три вида таблиц:

  1. mangle – используется для внесения изменений в заголовок пакета;
  2. nat – используется для трансляции сетевых адресов;
  3. filter – для фильтрации трафика;

Таблица mangle

Основное назначение таблицы mangle - внесение изменений в заголовок пакета. В этой таблице могут производиться следующие действия:

  • установка бита Type Of Service;
  • установка поля Time To Live;
  • установка метки на пакет, которая может быть проверена в других правилах;

Цепочки в таблице mangle:

  • PREROUTING — используется для внесения изменений в пакеты на входе в iptables, перед принятием решения о маршрутизации;
  • POSTROUTING — используется для внесения изменений в пакеты на выходе из iptables, после принятия решения о маршрутизации;
  • INPUT — используется для внесения изменений в пакеты, перед тем как они будут переданы локальному приложению;
  • OUTPUT — используется для внесения изменений в пакеты, поступающие от приложения внутри iptables;
  • FORWARD — используется для внесения изменений в транзитные пакеты;

Таблица nat

Таблица используется для преобразования сетевых адресов (Network Address Translation) и когда встречается пакет, устанавливающий новое соединение. В этой таблице могут производиться следующие действия:

  • DNAT (Destination Network Address Translation) – преобразование адреса назначения в заголовке пакета;
  • SNAT (Source Network Address Translation) – изменение исходного адреса пакета;
  • MASQUERADE – используется в тех же целях, что и SNAT, но позволяет работать с динамическими IP-адресами;

Цепочки в этой таблице:

  • PREROUTING – используется для внесения изменений в пакеты на входе в iptables;
  • OUTPUT – используется для преобразования адресов в пакетах, перед дальнейшей маршрутизацией;
  • POSTROUTING – используется для преобразования пакетов, перед отправкой их в сеть;

Таблица filter

Таблица используется для фильтрации пакетов. В этой таблице есть три цепочки:

  1. INPUT – цепочка для входящих пакетов;
  2. FORWARD – цепочка для пересылаемых (транзитных) пакетов;
  3. OUTPUT – цепочка для исходящих пакетов;

Пакет, проходящий через эти цепочки, может подвергаться действиям: ACCEPT, DROP, REJECT, LOG.

Подытожим, прибывший пакет проходит по цепочке правил. Каждое правило содержит условие и цель (действие). Если пакет удовлетворяет условию то он передается на цель, в противном случае к пакету применяется следующее правило в цепочке. Если пакет не удовлетворил ни одному из условий в цепочке, то к нему применяется действие по умолчанию.

Цепочка Таблица
filter nat mangle
INPUT + +
FORWARD + +
OUTPUT + + +
PREROUTING + +
POSTROUTING + +

Утилита iptables

Установка iptables

# под Arch Linux
yaourt -S iptables

# под Ubuntu
sudo apt-get install iptables

Запуск iptables

# под Arch Linux
sudo systemctl enable iptables
sudo systemctl start iptables

# под Ubuntu
sudo service iptables start

Сохранение правил

# под Arch Linux
sudo sh -c "iptables-save > /etc/iptables/iptables.rules"

# под Ubuntu
sudo sh -c "iptables-save > /etc/iptables.rules"

Восстановление правил из файла

iptables-restore < firewall-config

Каждое правило в iptables — это отдельная строка, сформированная по определенным правилам и содержащая критерии и действия. В общем виде правило имеет такой формат:

iptables [-t table] command [match] [target/jump]
  • t table — задает имя таблицы, для которой будет создано правило;
  • command — команда, которая определяет действие iptables — добавить правило, удалить правило и т. д.;
  • match — задает критерии проверки, по которым определяется, попадает ли пакет под действие правила или нет;
  • target/jump — какое действие должно быть выполнено при выполнении критерия;

Команды iptables:

  • -A - добавление правила в цепочку, правило будет добавлено в конец цепочки;
  • -D - удаление правила из цепочки;
  • -R - заменить одно правило другим;
  • -I - вставить новое правило в цепочку;
  • -L - вывод списка правил в заданной цепочке;
  • -F - сброс всех правил в заданной цепочке;
  • -Z - обнуление всех счетчиков в заданной цепочке;
  • -N - создание новой цепочки с заданным именем;
  • -X - удаление цепочки;
  • -P - задает политику по умолчанию для цепочки;
  • -E - переименование пользовательской цепочки;

Примеры команд iptables

Пакеты можно фильтровать по таким параметрам:

Источник пакета

Для фильтрации по источнику используется опция -s. Например запретим все входящие пакеты с узла 192.168.1.95:

iptables -A INPUT -s 192.168.1.95 -j DROP

Можно использовать доменное имя для указания адреса хоста:

iptables -A INPUT -s test.host.net -j DROP

Также можно указать целую под сеть:

iptables -A INPUT -s 192.168.1.0/24 -j DROP

Также вы можете использовать отрицание (знак !). Например, все пакеты с хостов отличных от 192.168.1.96 будут уничтожаться:

iptables -A INPUT ! -s 192.168.1.96 -j DROP

Разрешаем хождение трафика по localhost:

iptables -A INPUT 1 -i lo -j ACCEPT

Логируем попытки спуфинга с префиксом "IP_SPOOF A: " и дропаем соединение

iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j LOG --log-prefix "IP_SPOOF A: "
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP

Адрес назначения

Для этого нужно использовать опцию -d. Например запретим все исходящие пакеты на хост 192.168.1.95:

iptables -A OUTPUT -d 192.168.156.156 -j DROP

Запретить доступ к ресурсу

iptables -A OUTPUT -d vk.com  -j REJECT

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

Протокол

Опция -p указывает на протокол. Можно использовать all, icmp, tcp, udp или номер протокола (из /etc/protocols).

Разрешаем входящие эхо-запросы

iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

Порт источника

Разрешаем все исходящие пакеты с порта 80:

iptables -A INPUT -p tcp --sport 80 -j ACCEPT

Заблокировать все входящие запросы порта 80:

iptables -A INPUT -p tcp --dport 80 -j DROP

Для указания порта необходимо указать протокол (tcp или udp). Можно использовать отрицание.

Открыть диапазон портов

iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7000:7010 -j ACCEPT

Порт назначения

Разрешить подключения по HTTP

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Разрешить подключения по SSH

iptables -A INPUT -p tcp -i eth0 --dport 22 -j ACCEPT

Разрешаем получать данные от DHCP-сервера

iptables -A INPUT -p UDP --dport 68 --sport 67 -j ACCEPT

Разрешаем rsync с определенной сети

iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT

Разрешаем IMAP/IMAP2 трафик

iptables -A INPUT -i eth0 -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT

Разрешить исходящие HTTP, FTP, DNS, SSH, SMTP

iptables -A OUTPUT -p TCP -o eth0 --dport 443 -j ACCEPT
iptables -A OUTPUT -p TCP -o eth0 --dport 80 -j ACCEPT
iptables -A OUTPUT -p TCP -o eth0 --dport 53 -j ACCEPT
iptables -A OUTPUT -p UDP -o eth0 --dport 53 -j ACCEPT
iptables -A OUTPUT -p TCP -o eth0 --dport 25 -j ACCEPT
iptables -A OUTPUT -p TCP -o eth0 --dport 22 -j ACCEPT
iptables -A OUTPUT -p TCP -o eth0 --dport 21 -j ACCEPT

Разрешаем mysql для локальных пользователей

iptables -I INPUT -p tcp --dport 3306 -j ACCEPT

Разрешить CUPS (сервер печати, порт 631) для пользователей внутри локальной сети

iptables -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 631 -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -p tcp -m tcp --dport 631 -j ACCEPT

Разрешить синхронизацию времени NTP для пользователей внутри локальной сети

iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 123 -j ACCEPT

Разрешить торенты

iptables -A INPUT -p TCP -i eth0 --dport 51413 -j ACCEPT
iptables -A INPUT -p UDP -i eth0 --dport 51413 -j ACCEPT
iptables -A INPUT -p TCP -i eth0 --dport 6881 -j ACCEPT
iptables -A INPUT -p UDP -i eth0 --dport 6881 -j ACCEPT

Разрешить исходящий Google Talk

iptables -A OUTPUT -p TCP -o eth0 --dport 5222 -j ACCEPT

Разрешить TeamViewer

iptables -A OUTPUT -p UDP -o eth0 --dport 5938 -j ACCEPT

Port Forwarding

Для примера направим трафик с порта 442 на 22, это значит что входящие ssh-соединения могут быть принятыми с порта 422 и 22.

iptables -t nat -A PREROUTING -p tcp -d 192.168.1.15 --dport 422 -j DNAT --to 192.168.1.15:22

Также надо разрешить входящие соединения с порта 422

iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT

Как и в случае с портом источника нужно указать протокол. Можно использовать отрицание.

Действия над пакетами

Для указания действия (цели) с пакетом служит опция -j. Основные действия:

  • ACCEPT - разрешить пакет;
  • DROP - уничтожить пакет;
  • REJECT - будет отправлено ICMP сообщение, что порт недоступен;
  • LOG - информация об этом пакете будет добавлена в системный журнал. Не прерывает цепочку.
  • RETURN - возвращает пакет в ту цепочку, из которой он прибыл;
  • SNAT - применить source NAT ко всем удовлетворяющим условию пакетам. Может использоваться только в цепочках POSTROUTING и OUTPUT таблицы NAT;
  • DNAT - применить destination NAT ко всем удовлетворяющим условию пакетам. Может использоваться только в цепочке POSTROUTING таблицы NAT*.
  • MASQUERADE - может применяться только в цепочке POSTROUTING таблицы NAT. Используется при наличии соединения с динамическим IP. Похож на SNAT, однако имеет свойство забывать про все активные соединения при потере интерфейса. Это полезно при наличии соединения, на котором время от времени меняется IP-адрес, но при наличии постоянного IP это только доставит неудобства. В том числе поэтому рекомендуется для статических IP использовать SNAT.
Разница между DROP и REJECT (источник)
 
DROP – просто закрывает соединение и не отправляет ничего в ответ отправителю. Как итог имеем "мертвое"" соединение, которое потом убивается по таймауту. Но зато при сканировании закрытых портов, они будут помечаться как filtered, что потенциально говорит, что что-то всё-таки слушает порт.
 
REJECT – сбрасывает соединение и отправляет в ответ сообщение, указанное в опции –reject-with. По умолчанию отправляется host is unreachable. Зато при сканировании (если установлено –reject-with icmp-port-unreachable) порт светится не будет.
 
И так, что же всё-таки использовать? На мой взгляд, лучше DROP, так как при больших атаках, вы просто перекроете себе кислород, отвечая всем «host is unreachable«. Этот ответ будет потреблять больше ресурсов, нежели мёртвое соединение (при желаении время таймаута можно сократить).

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

iptables -A INPUT -s 192.168.1.0/24 -j LOCAL_NET

Пример базового набора правил

В большинстве случаев конечному пользователю (рабочая станция) достаточно выполнить такую последовательность команд:

iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -P INPUT DROP

Модули

В iptables есть возможность подключать модули, для этого используется опция -m.

Модуль limit предназначен для ограничения нагрузки, например:

iptables -A INPUT -p icmp -m limit --limit 4/second -j ACCEPT

Разрешаем поддерживать открытыми уже установленные соединения

iptables -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Другие правила

Список текущих правил

iptables -nvL --line-numbers

где

  • L - показать список правил;
  • v - отображать дополнительную информацию; *n - отображать ip адрес и порт числами (не используя DNS сервера для определения имен. Это ускорит отображение);
  • -line-numbers - вывод номеров строк;

Очистка всех правил

iptables -F

Очистка правил в цепочке

iptables -F INPUT

Удаления пятого правила в цепочке INPUT:

iptables -D INPUT 5

Удалить правило, в котором адрес источника (192.168.1.15)

iptables -D INPUT -s 192.168.1.15 -j DROP

Защита от DDoS с помощью iptables

DoS-атаки (атаки отказ в обслуживании) - это вид злонамеренной деятельности, основная задача которой вывести компьютерную систему из рабочего состояния и правильного выполнения возложенных на нее функций. Т.е. довести до состояния "зациклевания", что грозит простоями, потерей посетителей/клиентов и убытками. DoS-атаки подразделяются на два вида итсочник:

  • Удаленная эксплуатация ошибок в ПО с целью привести его в нерабочее состояние;
  • Flood - посылка на адрес жертвы огромного количества бессмысленных пакетов. Целью флуда может быть канал связи или ресурсы машины. В первом случае поток пакетов занимает весь пропускной канал и не дает атакуемой машине возможность обрабатывать легальные запросы. Во втором - ресурсы машины захватываются с помощью многократного и очень частого обращения к какому-либо сервису, выполняющему сложную, ресурсоемкую операцию. Это может быть, например, длительное обращение к одному из активных компонентов (скрипту) web-сервера. Сервер тратит все ресурсы машины на обработку запросов атакующего, а пользователям приходится ждать. Флуд бывает разным: ICMP-флуд, SYN-флуд, UDP-флуд и HTTP-флуд

Сбор информации о сетевых соединениях

Просмотр открытых соединений

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

Количество подключений к 80 порту

netstat -na | grep ":80\ " | wc -l

TCP-дамп подключений (на какой домен чаще всего идут запросы)

tcpdump -npi eth0 port domain

SYN-флуд можно проверить через подсчет числа полуоткрытых TCP-соединений

netstat -na | grep ":80 " | grep SYN_RCVD

Защита от разных видов флуда.

ICMP-флуд. Очень примитивный метод забивания полосы пропускания и создания нагрузок на сетевой стек через монотонную посылку запросов ICMP ECHO (пинг). Легко обнаруживается с помощью анализа потока трафика в обе стороны: во время атаки типа ICMP-флуд они практически идентичны. Почти безболезненный способ абсолютной защиты основан на отключении ответов на запросы ICMP ECHO:

sysctl net.ipv4.icmp_echo_ignore_all=1

Или с помощью iptabels:

iptables -A INPUT -p icmp -j DROP --icmp-type 8

SYN-флуд. Один из распространенных способов не только забить канал связи, но и ввести сетевой стек операционной системы в такое состояние, когда он уже не сможет принимать новые запросы на подключение. Основан на попытке инициализации большого числа одновременных TCP-соединений через посылку SYN-пакета с несуществующим обратным адресом. После нескольких попыток отослать ответный ACK-пакет на недоступный адрес большинство ОС ставят неустановленное соединение в очередь. И только после n-ой попытки закрывают соединение. Так как поток ACK-пакетов очень велик, вскоре очередь оказывается заполненной, и ядро дает отказ на попытки открыть новое соединение. Наиболее умные DoS-боты еще и анализируют систему перед началом атаки, чтобы слать запросы только на открытые жизненно важные порты. Идентифицировать такую атаку просто: достаточно попробовать подключиться к одному из сервисов.

Оборонительные мероприятия обычно включают в себя:

Увеличение очереди "полуоткрытых" TCP-соединений:

sysctl -w net.ipv4.tcp_max_syn_backlog=1024

Уменьшение времени удержания "полуоткрытых" соединений:

sysctl -w net.ipv4.tcp_synack_retries=1

Включение механизма TCP syncookies:

sysctl -w net.ipv4.tcp_syncookies=1

Ограничение максимального числа "полуоткрытых" соединений с одного IP к конкретному порту:

iptables -I INPUT -p tcp --syn --dport 80 -m iplimit --iplimit-above 10 -j DROP

UDP-флуд. Типичный метод захламления полосы пропускания. Основан на бесконечной посылке UDP-пакетов на порты различных UDP-сервисов. Легко устраняется за счет отрезания таких сервисов от внешнего мира и установки лимита на количество соединений в единицу времени к DNS-серверу на стороне шлюза:

iptables -I INPUT -p udp --dport 53 -j DROP -m iplimit --iplimit-above 1

HTTP-флуд. Один из самых распространенных на сегодняшний день способов флуда. Основан на бесконечной посылке HTTP-сообщений GET на 80-ый порт с целью загрузить web-сервер настолько, чтобы он оказался не в состоянии обрабатывать все остальные запросы. Часто целью флуда становится не корень web-сервера, а один из скриптов, выполняющих ресурсоемкие задачи или работающий с базой данных. В любом случае, индикатором начавшейся атаки будет служить аномально быстрый рост логов web-сервера.

Определившись с IP виновника начинаем дропать по IP-адресам

iptables -A INPUT -s xxx.xxx.xxx.xxx -p tcp --destination-port http -j DROP

Или сразу по подсетям:

iptables -A INPUT -s xxx.xxx.0.0/16 -p tcp --destination-port http -j DROP

Для ограничения количества одновременных подключений к серверу для клиента по IP используется модуль connlimit. Ограничим количество параллельных подключений по SSH до трех, для одного клиента

iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 3 -j REJECT

Ограничим количество параллельных подключений по HTTP до трех, для одного клиента

iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j DROP

где

  • --connlimit-above 10 - условие для проверки одновременных подключенийне более 10;
  • --connlimit-mask 24 - группировка хостов по длине префикса (для IPv4 это число должно быть 0 и 32;

Также ограничить количество подключений в единицу времени можно с помощью модуля limit.

iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT

где

  • -m limit - подключаем модуль limit;
  • –limit 25/minute - порог в 25 подключений в минуту;
  • –limit-burst 100 - условие включения порога: после достижения 100 подключений;

Полезные советы

Добавь в /etc/sysctl.conf следующие строки:

# vim /etc/sysctl.conf

# Защита от спуфинга
net.ipv4.conf.default.rp_filter = 1

# Проверять TCP-соединение каждую минуту. Если на другой стороне - легальная машина, она сразу ответит. Дефолтовое значение - 2 часа.
net.ipv4.tcp_keepalive_time = 60

# Повторить пробу через десять секунд
net.ipv4.tcp_keepalive_intvl = 10

# Количество проверок перед закрытием соединения
net.ipv4.tcp_keepalive_probes = 5

Интересный материал по теме - Доступные методы борьбы с DDoS-атаками для владельцев vds/dedicated серверов с Linux.

Балансировка нагрузки с помощью iptables

Надстройки, GUI к iptables

Проверить настройки iptables можно с помощью nmap.

Дополнительное чтиво

blog comments powered by Disqus