Linux
April 16, 2019

Борьба с SYN-флудом при помощи iptables и SYNPROXY

Начиная с ядра Linux 3.12 и инструментария IPTables 1.4.21 в iptables доступна

поддержка новой цели - SYNPROXY, позволяющей в десятки раз увеличить

интенсивность обработки SYN-пакетов при противостоянии таким атакам, как SYN

Flood, SYN-ACK Flood и ACK Flood. Например, если в обычной конфигурации ядра

сервер на базе CPU Xeon X5550 способен обработать приблизительно 200 тысяч SYN-

или ACK-пакетов в секунду, то при включении SYNPROXY производительность

возрастает до нескольких миллионов, чего достаточно для отражения небольших

атак без привлечения специализированного оборудования.

Включаем в /etc/sysctl.conf syncookies и timestamps, так как они необходимы для работы SYNPROXY:

sysctl -w net/ipv4/tcp_syncookies=1

sysctl -w net/ipv4/tcp_timestamps=1

Исключаем ACK-пакеты из обработки системой отслеживания соединений (отслеживаем

только уже установленные соединения, ACK-пакеты снабжаются меткой INVALID), что

помогает снизить нагрузку при ACK-флуде:

sysctl -w net/netfilter/nf_conntrack_tcp_loose=0

Увеличивает размер хэша для отслеживания соединений:

echo 2500000 > /sys/module/nf_conntrack/parameters/hashsize

sysctl -w net/netfilter/nf_conntrack_max=2000000

Исключаем SYN-пакеты из обработки в системе отслеживания соединений (таблица

raw обрабатывает соединений без их отслеживания, а опция "--notrack" позволяет

обойти цель CT ("conntrack")):

iptables -t raw -I PREROUTING -p tcp -m tcp --syn -j CT --notrack

Выделяем SYN- и ACK-пакеты без отслеживания (UNTRACKED и INVALID), как в

прошлом правиле и направляем их в цель SYNPROXY, в которой будет выполнена

проверка syncookies и если всё нормально установлено TCP-соединение:

iptables -I INPUT -p tcp -m tcp -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460

Отбрасываем все остальные пакеты, не прошедшие проверку в прошлом правиле:

iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Если необходимо обеспечить защиту для отдельного IP, правила можно изменить

следующим образом (если атака ведётся только на 80 сетевой порт, можно добавить

"--dport 80"):

iptables -t raw -I PREROUTING -p tcp -m tcp -d 192.168.1.10 --syn -j CT --notrack

iptables -I INPUT -p tcp -m tcp -d 192.168.1.10 -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460

iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Для просмотра статистики:

iptables -t raw -vnL

cat/proc/net/stat/synproxy

Если нужно на низком уровне заблокировать некоторые HTTP-запросы, явно

связанные с проведением атаки, можно использовать следующее правило (маску

можно выделить из логов или через "tcpdump -nnA dst host 192.168.1.10 and port http"):

iptables -A INPUT -p tcp --dport 80 -m string --string "маска_блокировки" --algo bm -j DROP