Игорь Олемской — практические заметки по системному администрированию Linux CentOS

Архив тега ‘ddos’

Отбиваем DDOS mod_evasive + firewall на CentOS (перепечатка)

Комментариев нет

Анализ DDoS можно производить конечно своими скриптами, парсить логи. Но лучше предоставить это апачевскому mod_evasive.

Ставим mod_evasive, в конфигурации пишем

DOSHashTableSize    3097
DOSPageCount        15
DOSSiteCount        15
DOSPageInterval     3
DOSSiteInterval     3
DOSBlockingPeriod   300
DOSSystemCommand    "/usr/bin/sudo /usr/bin/fwban %s"
  • DOSPageInterval – интервал для хитов определенной страницы
  • DOSSiteInterval – интервал для хитов определенного vhost
  • DOSPageCount – после этого количества хитов по определенному URI в течении интервала DOSPageInterval, айпи будет забанен
  • DOSSiteCount – после этого количества хитов по определенному vhost в течении интервала DOSSiteInterval, айпи будет забанен

Нам понадобиться скрипт для бана на уровне файрвола «/usr/bin/fwban» (вариант для Linux):

#!/bin/bash
if [ "x$1" = "x" ] ; then
    echo "USAGE: $0 IPADDR"
    exit
fi
/sbin/iptables -A BAN -s $1 -j DROP

Ему надо поставить права 755.

Так же нам понадобиться утилита sudo. Она стоит практически везде. В «visudo» закомментируем опцию:

#Defaults    requiretty

И добавим строку

apache  ALL = NOPASSWD: /usr/bin/fwban

где apache – юзер от которого работает апач.

Так же нам понадобиться цепочка BAN в iptables:

iptables -N BAN
iptables -I INPUT -j BAN

Сохраним правила файрвола

/etc/init.d/iptables save

Рестартанем апач. Теперь попробуйте уложить ваш сайт (только не со своего айпи!!!):

ab -n 1000  -c 20 http://yoursite.info/

В логах «жертвы» можно увидеть:

May  6 15:18:25 Server1 mod_evasive[26514]: Blacklisting address 1.2.3.4: possible DoS attack.

А в файрволе:

# iptables-save
---многа букав---
-A BAN -s 1.2.3.4 -j DROP
---многа букав---

Ура! No pasaran.

Да. И конечно, апач лучше бы прикрыть извне nginx’ом.

Да. И данный метод банит айпишнеги перманентно, пока не рестартанет сервер, или не будет сброшена цепочка BAN. Вот такой брутальный метод )

Еще один способ отбиться от небольшого DDOS (перепечатка)

Комментариев нет

Все нижеописанное относится к GNU/Linux 2.6.x. ДДОС совершенно тупой, разномастный: syn/tcp/udp/icmp flood тупо на все открытые порты, мегабит на 60. UDP срали вообще куда попало. Но основная атака конечно на HTTP. По этому, тушим сервисы и пишем….

Немного sysctl…

vm.min_free_kbytes=70000
net.core.somaxconn=65536
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.ip_local_port_range = 2000 61000
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_timestamps = 0
net.core.rmem_max=16777216
net.core.wmem_max=32777216
net.ipv4.tcp_no_metrics_save=0
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 187380 32777216
net.core.netdev_max_backlog=16384
net.ipv4.tcp_max_syn_backlog=4096
net.ipv4.ip_conntrack_max=600000
net.ipv4.icmp_echo_ignore_all=1
net.ipv4.netfilter.ip_conntrack_max=500000
net.netfilter.nf_conntrack_max=500000
Не забываем перезапустить Network.

Немного iptables….

# Форвард нам нэ нада
iptables -P FORWARD DROP
# BAN – цепочка для помещения туда айпи хостов, ведущих себя не правильно ) Ну типа
# iptables – I BAN -s 123.123.123.123 -j DROP
iptables -N BAN
# TRUSTED – цепочка для помещения туда правильных хостов и хостов откуда мы сидим в шелле. Типа
# iptables -I TRUSTED -s 111.111.111.111 -j ACCEPT
iptables -N TRUSTED
# Стандартный заголовок, eth1 – наш интерфейс внешний
# если есть еще интерфейсы, надо их тоже запрячь правилами разрешения как у lo
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth1 -m state –state ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth1 -m state –state RELATED -j ACCEPT
# Проход по белым и черным цепочкам
iptables -A INPUT -i eth1 -j TRUSTED
iptables -A INPUT -i eth1 -j BAN
# У меня висит только сервис http, по этому здесь такая себе мини защита по данному порту
# Насчет –seconds 10 –hitcount 10, курим маны, экспериментируем, ставим то, что подойдет.
# Режем всех TCP на порту 80, которые за последние 10 секунд сделали 10 попыток открыть соединение
# (кому то может не подойти!)
iptables -A INPUT -p tcp -m tcp –dport 80 -m state –state NEW -m recent –update –seconds 10 –hitcount 10 –name httpd –rsource -j DROP
# А остальных разрешаем
iptables -A INPUT -i eth1 -p tcp -m tcp –dport 80 -j ACCEPT
# Вот по этой теме ддосеры тоже затрахали, по этому был категоричен
iptables -A OUTPUT -p udp -j DROP
iptables -A OUTPUT -p icmp -j DROP
# Здесь добавить разрешения на прочие порты, у меня прочих не было
# …
# Здесь добавить (!!!) свои айпи, с которых сидишь в шелле
iptables -A TRUSTED -s 111.111.111.111 -j ACCEPT
# Хорошо подумаем, покурим, затаим дыхание и напишем….
iptables -P INPUT DROP
# Что означает зарезать все, что не разрешили на INPUT’е
А теперь запускаем nginx/httpd и прочую лабуду. Надеюсь заработает. У меня заработало, как будто ничего и не происходило :)

Отбил небольшой DDOS ;) (перепечатка)

Комментариев нет

DDOS на HTTP 20 Мбит входящего. Отбито софтварным костылем 8-)

Конфигурация машины: Quad Core Xeon / 4G RAM, CentOS 5.3 x86_64

Сервисы: apache (back) + nginx (front)

Sysctl:

kernel.shmall = 4294967296
vm.min_free_kbytes=70000
net.core.somaxconn=65536
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.ip_local_port_range = 2000 61000
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_timestamps = 0
net.core.rmem_max=8388608
net.core.wmem_max=16777216
net.ipv4.tcp_no_metrics_save=0
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 87380 16777216
net.core.netdev_max_backlog=65536
net.ipv4.tcp_max_syn_backlog=4096
net.ipv4.ip_conntrack_max=300000

nginx:

worker_rlimit_nofile 80000;
events {
worker_connections  65536;
use epoll;
}

http {
gzip off; # ;)
keepalive_timeout  0;
server_tokens off;
reset_timedout_connection on;

server {
listen x.x.x.x default deferred;
log_format IP $remote_addr;
location / {
proxy_pass http://127.0.0.1/;
….
access_log /var/log/nginx/ipban IP;

apache: ServerLimit и MaxClients установить так, чтобы не засрало более чем 80% памяти. (В top’е можно глянуть сколько памяти потребляет каждый процесс).

Собсно скрипт. Запускается по крону раз в минуту и банит нах айпи, которые за эту минуту обратились к скриптовой части более 20 раз.

#!/usr/bin/perl

system (‘mv /var/log/nginx/ipban /var/log/nginx/ipban.proc’);
system (‘touch /var/log/nginx/ipban’);
system («/etc/init.d/nginx reload»);

open $f,’/var/log/nginx/ipban.proc’;

%h=();

while (<$f>) {
chomp;
if (/\d+\.\d+\.\d+\.\d+/) {
unless ($h{$_}) {
$h{$_}=1;
} else {
$h{$_}++;
}
}
}

close $f;

foreach $k (keys (%h)) {
if ($h{$k} > 20) {
system («iptables -I INPUT -s $k -j DROP»);
print «$k banned\n»;
}
}

20 -число вычисленное в ходе проб и ошибок применительно к этому серверу и location’у nginx. После того как скрипт беспощадно побанил 2к хостов, сервер начал подавать внешние признаки жизни, после 3к забаненых зомби начала грузицца морда.

В процессе работы мой рабочий комп был дважды забанен в ходе экспериментов ))

Более серъезный DDOS конечно будет трудно отбивать тупой банилкой.

АПДЕЙТ. Время шло, таблица бана росла, ддосеры не унимались.

Поставил вот эту хрень http://www.configserver.com/cp/csf.html

Софтина умеет вообще много чего. Но практически все что она умеет бесполезно. Кроме temporary ban ip address.

В конфигах отключил практически все, ибо оно (все) мешало. Мне надо было от этой проги только то, чтобы она банила айпи с TTL. Т.е. на время. И крон стал пускать раз в 5 минут.

Соответственно, в кроновом скрипте поменял

if ($h{$k} > 20) {
system («iptables -I INPUT -s $k -j DROP»);

На

if ($h{$k} > 60) {
system («/usr/sbin/csf –tempdeny $k 28800″);

Так же цель атаки – страницу, сделал статичной.  ДДОС просел, сайт ожил.