Оптимальная защита от DDoS с помощью netstat и iptables
Совсем недавно столкнулся с такой проблемой, как DDoS. Сразу скажу, я вообще ни разу не линуксоид, но зато чуточку программист, так что все что ниже, основано чисто на логике, а не на фактах, плюс переписанное с некоторыми добавками от уже известного.
Перекопав полчища статей и опробовав множество вариантов, так и не нашел, что помогло бы с защитой. Взяв за основу статьи Простой и эффективный метод отразить http DDoS от 50мбит с помощью nginx и iptables и (D)DoS Deflate решил написать свой скрипт. Ну вернее не решил, а методом тыка и исправлений он получился сам.
Должен заметить, что статья от Алексея Кузьмина не идеальна, т.к. в логах nginx`a не достаточно копаться, да и обработка логов может потребовать много ресурсов. А именно в моем случае создавались логи более 50 Гиг, плюс запросы шли не «GET / HTTP/1.1», а «GET / HTTP/1.0», плюс, как оказалось, мой сервер сам от себя получал редиректы (127.0.0.1), которые не отображались в логах, которые отображались в запросе
netstat -ntu | awk '' | cut -d: -f1 | sort | uniq -c | sort -n
Суть скрипта такова, что через определенное время кроном запускается скрипт и проверяет все соединения с сервером, ip и кол-во их соединений которые записываются в файл. Потом запускается другой скрипт, который смотрит, если соединения, превышают заданное число (у меня стоит 20), то создается скрипт с блокировкой этих айпишников через iptables.
Я создавал отдельные файлы, чтобы прослеживать весь ход работы отдельно, и по своей некомпетентности, легко было обнаружить где и что не срабатывало.
Теперь к практике:
создаем каталог, где будет скрипт
chmod 0755 /usr/local/ddos/ddos.sh
#!/bin/sh # находим все соединения и записываем их во временный файл ddos.iplist в каталоге tmp netstat -ntu | awk '' | cut -d: -f1 | sort | uniq -c | sort -n > /tmp/ddos.iplist # очищаем скрипт бана айпишников cat /dev/null > /tmp/iptables_ban.sh # создаем DROP правила для 50 самых агрессивных ботов awk ' 20) >' /tmp/ddos.iplist >> /tmp/iptables_ban.sh # следующая строка нужна только для того, чтобы создавался файл с просмотром всех правил iptables echo "/sbin/iptables -L INPUT -v -n > /tmp/iptables.log" >> /tmp/iptables_ban.sh # запускаем скрипт бана айпишников bash /tmp/iptables_ban.sh # делаем ротацию лога cat /dev/null > /var/log/ddos/error.log [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
Вот в принципе и все. Теперь запускаем кронтаб, предпочитаю команду:
*/10 * * * * /bin/sh /usr/local/ddos/ddos.sh
Также я изменил ротацию логов в файле /etc/logrotate.d/nginx от nginx`a, чтобы многогиговые файлы не создавались
и записал еще задачу в крон, выполняющуюся каждый час
0 * * * * /usr/sbin/logrotate /etc/logrotate.conf
ну и для больше комфорта еще и раз в сутки решил перезагружать сервак, опять же через крон:
общий список заданий, выведенный через crontab -l:
*/10 * * * * /bin/sh /usr/local/ddos/ddos.sh 0 * * * * /usr/sbin/logrotate /etc/logrotate.conf 0 4 * * * /sbin/reboot
я записывал все под пользователем root, поэтому если вы не под этим пользователем, перед каждой командой стоит добавить root, типа:
*/10 * * * * root /bin/sh /usr/local/ddos/ddos.sh
Все пути делал абсолютными, т.к. не все команды без полного пути срабатывали.
Надеюсь кому-нибудь пригодится данная статейка. Прошу строго не судить по самому коду, т.к. я вообще впервые сам что-то делал на серваке )
Защита от DDoS с iptables, готовый скрипт
Надоели атаки на компьютер или на сервер, то я покажу готовый и хороший скрипт для решение DDoS атак на ваш сервер.
Сейчас я расскажу, про виды которые часто используются для защиты серверов или сайтов.
- Защита на уровне PHP. Честно, не могу врубится в работу этой логики. То есть, нужно запретить доступ для ботов на этот уровень, чтобы не было огромной нагрузки. Не очень хорошее решение!
- Защита на уровне Apache. Есть модуль mod_evasive, но толку от него тоже не сильно много, не больше чем от PHP!
- Защита на уровне nginx. Самый оптимальный вариант для решение многих атак. Можно прокешировать все страницы и энжинкс будет отдавать страницы почти без нагрузки на процессор. Только канал будет нагружаться весьма прилично. Также можно настроить и использовать limit_req.
- Защита на уровне iptables. Это один из самых эффективных и надежных способов защиты вашего сервера от различных атак.
Для получения списка доступных модулей для IPTables, выполните:
# ls /lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/
Чтобы получить информацию о всех модулях:
# modinfo /lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/*.ko
Защита от атаки с использованием SYN flood.
Одна из распространенных DoS атак — это посылка очень большого числа SYN пакетов к серверу.
Чтобы узнать о атаке SYN служит команда netstat, которая показывает список открытых подключений на сервере:
# netstat -n --tcp | grep SYN_RECV
Так же, можно подсчитать их количество, выполнив:
# netstat -n --tcp | grep SYN_RECV | wc -l
Первое что необходимо сделать, так это установить опцию tcp_syncookies в значение 1, посмотреть можно так:
# cat /proc/sys/net/ipv4/tcp_syncookies
Следующим действием служит увеличения очереди открытых соединений — tcp_max_syn_backlog, например до (но сначала проверим сколько сейчас):
# cat /proc/sys/net/ipv4/tcp_max_syn_backlog
Чтобы увеличить, выполните:
# echo "40000" > /proc/sys/net/ipv4/tcp_max_syn_backlog
Так же, уменьшаем время ожидания соединения — это параметр tcp_synack_retries,но посмотрим сколько имеется на данный момент:
# cat /proc/sys/net/ipv4/tcp_synack_retries
Уменьшим их до 1. Данный параметр говорит что будет ожидаться соединения около 9 секунд:
# echo "1" > /proc/sys/net/ipv4/tcp_synack_retries
Уменьшаем параметр tcp_fin_timeout — который определяет время хранения сокета в состоянии FIN-WAIT-2 и после чего будет закрыт на локальной стороне (выводим сколько сейчас):
# cat /proc/sys/net/ipv4/tcp_fin_timeout
Изменим данный параметр и уменьшим его до 30:
# echo "30" > /proc/sys/net/ipv4/tcp_fin_timeout
Уменьшаем опцию tcp_keepalive_probes — это число служит для передачи проб keepalive, по завершению, соединение будет считаться разорванным. Данный параметр имеет 9 проб по умолчанию. Чтобы посмотреть какое число имеет данный параметр, используйте:
# cat /proc/sys/net/ipv4/tcp_keepalive_probes
# echo "5" > /proc/sys/net/ipv4/tcp_keepalive_probes
Опция tcp_keepalive_intvl задает интервал передачи для проб и по умолчанию, имеет число 75 сек. Уменьшим данный параметр, но прежде убедимся что он уже не прописан оптимальным:
# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
# echo "15" > /proc/sys/net/ipv4/tcp_keepalive_intvl
Опция netdev_max_backlog служит для указания максимального количества пакетов в очередь на обработку в случае чего, интерфейс будет получать пакеты быстрей чем ядро сможет обработать их. Данный параметр должен быть увеличен, но смотрим что имеется:
# cat /proc/sys/net/core/netdev_max_backlog
# echo "20000" > /proc/sys/net/core/netdev_max_backlog
Выставляем оптимальное цисло для somaxconn который задает максимальное число всех открытых сокетов которые ждут соединения. Его нужно увеличить:
# cat /proc/sys/net/core/somaxconn
# echo "20000" > /proc/sys/net/core/somaxconn
Прописываем еще один не маловажный параметр:
# echo 1 > /proc/sys/net/ipv4/tcp_syncookies
PS: Данные применения для опций ядра не сохраняются после перезагрузки ОС, то их нужно добавить в /etc/rc.local:
# echo "20000" > /proc/sys/net/ipv4/tcp_max_syn_backlog # echo "1" > /proc/sys/net/ipv4/tcp_synack_retries # echo "30" > /proc/sys/net/ipv4/tcp_fin_timeout # echo "5" > /proc/sys/net/ipv4/tcp_keepalive_probes # echo "15" > /proc/sys/net/ipv4/tcp_keepalive_intvl # echo "20000" > /proc/sys/net/core/netdev_max_backlog # echo "20000" > /proc/sys/net/core/somaxconn
После чего, нужно добавить ограничения в iptables:
# iptables -N syn_flood # iptables -A INPUT -p tcp --syn -j syn_flood # iptables -A syn_flood -m limit --limit 500/s --limit-burst 2000 -j RETURN # iptables -A syn_flood -j DROP
В данных правилах, я задал определенное число для новых SYN пакетов ( 500 за сек), и если привысит ограничение 2000, то все новые новые пакеты будут заблокированы.
Добавляем в iptables еще полезные опции:
# iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
Установить FIN, без ожидаемого сопутствующего ACK:
# iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
Установить PSH,без ожидаемого сопутствующего ACK:
# iptables -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP
Установить URG, без ожидаемого сопутствующего ACK:
# iptables -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP
Приведу скрипт, который нашел в интернете для зашиты от DDoS атак с использованием ipset. Почему именно я использую ipset а не iptables? Да все потому что, после блокировки больше чем 100 IP адресов iptables начинает тормозить весь сервер.
PS: нужно установить пакет ipset. Если не знаете как, то можете воспользоваться инструкцией что ниже.
Установка IPset.
После установки добавлем правило блокировки в iptables:
# iptables -I INPUT 1 -m set --set dos src -j DROP
dos — это таблица из ipset.
Следующим шагом необходимо создать хеш для таблицы dos:
ВНИМАНИЕ! При необходимости можно заблокировать даже всю подсети, но для этого вместо iphash стоит использовать nethash.
После завершения необходимо сохранить все правила iptables:
#/sbin/service iptables save
Собственно, все уже готово, за исключением скрипта который будет блокировать флуд на сервере.
Вы его можете прочитать и поглядеть тут, чтобы скачать себе на сервер выполните команду:
# wget http://linux-notes.org/wp-content/uploads/scripts/Anti_SYN_Flood_IPTables.sh
После чего, запускаем скачанный скрипт:
# bash Anti_SYN_Flood_IPTables.sh
Стоит заметить, что целесообразно установить данный скрипт на выполнение в crontab на каждые 1-5 минут. Промежуток выберите сами. Если не знаете как, то можете воспользоваться моей инструкцией:
Чтобы вывести все заблокированные IP адресы, выполняем команду:
Более подробно о ipset я расскажу в своей статье:
Защита от DDos атаки
Атаку можно найти если выполнить команду:
# netstat -ntu | awk '' | cut -d: -f1 | sort | uniq -c | sort -n
Вот еще полезный материал:
На этом тема «Защита от DDoS с iptables, готовый скрипт» подошла к завершению. Надеюсь поможет этот скрипт, как помог он мне.