Борьба с DDoS атаками средствами iptables и sysctl

Сегодня я попытаюсь привести пример конфигурации файрвола, а также оптимизации системных настроек для повышения устойчивости сервера к так называем атакам типа «отказ в обслуживании». Информации в поисковиках на эту тему море, но, как обычно, это или малограмотные или очень разрознененные и не сведённые в одну схему примеры.

Ниже приводится листинг разрешительной (не такой жёсткой как запретительная) политики настройки iptables, а также пример оптимизации настроек sysctl. В результате будет ограничено количество одновременных подключений с одного ip адреса на порт веб-сервера, сервера DNS, а также ограничено количество подключений к службе ssh (3 подключения за 5 минут с одного ip-адреса). Будет реализована защита от спуфинга на уровне файрвола, а также на уровне ядра.

Хорошее развёрнутое русское руководство по iptables с подробным разъяснением принципов его работы и примерами использования (некоторые из которых используются чуть ниже) можно найти в статье iptables на Википедии (sic!), а про sysctl тут http://debian.telenet.ru/doc/sysctl.conf

# БОРЬБА С DDOS
 
iptables -N ssh_brute_check # Создаем цепочку для проверки попыток соединений на защищаемый порт
# Если за последние 5 минут (300 секунд) с одного адреса было 3 или более новых соединений — блокируем этот адрес
iptables -A ssh_brute_check -m conntrack --ctstate NEW -m recent --update --seconds 300 --hitcount 3 -j DROP
# В противном случае — разрешаем, и при этом заносим в список
iptables -A ssh_brute_check -m recent --set -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_brute_check
# Здесь можно разрешать те порты, для которых такая проверка не нужна. Например, HTTP
iptables -A INPUT -m conntrack --ctstate NEW -p tcp --dport 80 -j ACCEPT
iptables -P INPUT ACCEPT
 
 
# позволяет узнать сколько одновременных подключений на порт с 1 айпи
# netstat -plan | grep :80 | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c
# netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
 
# устанавливаем максимальное количество подключений с одного айпи.
# В браузерах эта количество подключений к серверу ограничено 16 соединениями,
# но стоит учитывать тех, кто сидит за NAT, а также что пользователь
# может открыть 2 сайта на разных айпишниках одного и того же сервера.
# Данный параметр подбирается оптимально с помощью предыдущей команды.
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 32 -j DROP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# то же для DNS
iptables -A INPUT -p udp --dport 53 -m connlimit --connlimit-above 8 -j DROP
iptables -A INPUT -p udp --dport 53 -j ACCEPT
 
# будет препятствовать спуфингу от нашего имени.
# Ведь если мы получаем пакет с установленными флагами SYN и ACK
# (такой комбинацией флагов обладает только ответ на SYN-пакет) по еще не открытому соединению,
# это означает, что кто-то послал другому хосту SYN-пакет от нашего имени, и ответ пришел к нам.
# Конечно, злоумышленнику предстоит еще угадать номер последовательности.
# Согласно приведенному правилу, наш хост ответит RST-пакетом, после получения которого
# атакуемый хост закроет соединение.
iptables -I INPUT -m conntrack --ctstate NEW,INVALID -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT --reject-with tcp-reset
 
# Для защиты от SYN атак включаем SYN-cookies
sysctl -w net.ipv4.tcp_syncookies=1
# Увеличиваем размер очереди полуоткрытых соединений (также полезно при SYN флуде) (default 512)
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
# Проверять TCP-соединение каждую минуту. Если на другой стороне - легальная машина, 
# она сразу ответит. Дефолтовое значение - 2 часа.
sysctl -w net.ipv4.tcp_keepalive_time=60
# Повторить пробу через десять секунд
sysctl -w net.ipv4.tcp_keepalive_intvl=10
# Количество проверок перед закрытием соединения
sysctl -w net.ipv4.tcp_keepalive_probes=5
# Фильтр обратного пути, защита от спуфинга (подмены адресов)
sysctl -w net.ipv4.conf.default.rp_filter=1
# Уменьшение времени удержания «полуоткрытых» соединений
# Сделаем так, чтобы перепередача осуществлялась на 3 секунде
# и  полное время хранения полуоткрытых соединений в очереди составило 9 секунд
sysctl -w net.ipv4.tcp_synack_retries=1
# Изменяем время ожидания приема FIN до полного закрытия сокета
sysctl -w net.ipv4.tcp_fin_timeout=10

One thought on “Борьба с DDoS атаками средствами iptables и sysctl

Leave a Reply

Your email address will not be published. Required fields are marked *