Основная задача файрвола (межсетевого экрана) фильтрация и обработка пакетов, проходящих через сеть. При анализе входного пакета файрвол принимает решение о судьбе этого пакета: выбросить пакет (DROP), принять пакет (ACCEPT) или сделать с ним еще что-то.
В Linux файрвол является модулем ядра, называемым netfilter и представляет собой набор хуков (hooks) для работы с сетевым стеком. Интерфейсом для модификации правил, по которым файрвол обрабатывает пакеты, служит утилита iptables для IPv4 и утилита ip6tables для IPv6.
Всю работу по фильтрации трафика выполняет ядро системы. Iptables не является демоном и не создает новых процессов в системе. Включение или выключение iptables это всего лишь отправка сигнала в ядро. Большая скорость фильтрации достигается за счёт анализа только заголовков пакетов.
К основным возможностям iptables относиться:
Содержание
Рассмотрим основной процесс работы iptables (источник картинки rigacci.org).
Входящий пакет сначала попадает на сетевое устройство, после чего он перехватывается драйвером и передается в ядро. После этого пакет пропускается через ряд таблиц и только потом передается локальному приложению или перенаправляется в другую систему, если это транзитный пакет.
В iptables используется три вида таблиц:
Основное назначение таблицы mangle - внесение изменений в заголовок пакета. В этой таблице могут производиться следующие действия:
Цепочки в таблице mangle:
Таблица используется для преобразования сетевых адресов (Network Address Translation) и когда встречается пакет, устанавливающий новое соединение. В этой таблице могут производиться следующие действия:
Цепочки в этой таблице:
Таблица используется для фильтрации пакетов. В этой таблице есть три цепочки:
Пакет, проходящий через эти цепочки, может подвергаться действиям: ACCEPT, DROP, REJECT, LOG.
Подытожим, прибывший пакет проходит по цепочке правил. Каждое правило содержит условие и цель (действие). Если пакет удовлетворяет условию то он передается на цель, в противном случае к пакету применяется следующее правило в цепочке. Если пакет не удовлетворил ни одному из условий в цепочке, то к нему применяется действие по умолчанию.
Цепочка | Таблица | ||
---|---|---|---|
filter | nat | mangle | |
INPUT | + | + | |
FORWARD | + | + | |
OUTPUT | + | + | + |
PREROUTING | + | + | |
POSTROUTING | + | + |
Установка 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
- переименование пользовательской цепочки;Пакеты можно фильтровать по таким параметрам:
Источник пакета
Для фильтрации по источнику используется опция -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
. Основные действия:
Разница между 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-атаки подразделяются на два вида итсочник:
Сбор информации о сетевых соединениях
Просмотр открытых соединений
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
Проверить настройки iptables можно с помощью nmap.