Опубликовано
Как выглядит DDoS атака
Как выглядит DDoS атака

Здравсвуйте начинающие и другие администраторы unix.

Данный метод не есть панацения и 100% защита от DDoS. Если Вас решили положить — Вас положат, но данный метод даст вам возможность отреагировать оперативно и попытаться решить проблемы быстро, так же спасет не небольшого DDoS.

И так, первое, что Вам нужно, это скачать: mod_evasive
Далее распакуйте его:
gunzip mod_evasive_1.10.1.tar.gz
tar xvf mod_evasive_1.10.1.tar.gz

перейдите в mod_evasive_1.10.1
и сделайте для apache 2.x
$APACHE_ROOT/bin/apxs -i -a -c mod_evasive20.c

Если выдаст:-bash: apxs: command not found

сделайте whereis apxs или поставьте apache2-devel

Когда процесс копиляции пройдет успешно, то модуль будет скопирован в $APACHE_ROOT/modules.

Далее Вам нужно настроить httpd.conf добавив следующие строки:

DOSHashTableSize 5000000
DOSPageCount 3 — после скольки раз в DOSPageInterva будем банить IP
DOSSiteCount 30
DOSPageInterval 1 — время в секундах
DOSBlockingPeriod 300 — насколько блокировать — в секундах
DOSEmailNotify alert@your_host.com
DOSLogDir «/hsphere/shared/apache2/logs/evasive» — где будут хранится логи
DOSWhiteList белый лист
DOSWhiteList 127.0.0.1
DOSSystemCommand «sudo /backups/ddos.pl %s» — ну собственно магическая команда, которая будет блокировать IP в Iptables

Вот сам код ddos.pl

#!/usr/bin/perl

use MIME::Lite;
use Date::Format;
use Mysql;
use Class::Date qw(:errors date localdate gmdate now -DateParse);

use Sys::Hostname::FQDN qw(
asciihostinfo
gethostinfo
inet_ntoa
inet_aton
fqdn
short
);

`rm -f /hsphere/shared/apache2/logs/evasive.log/*`;

$date = new Class::Date [$year,$month,$day,$hour,$min,$sec];
$date=now;
my $dt=$date->year."-".$date->month."-".$date->day." ".$date->hour.":".$date->min;

my $min_count = 0;
my $min_period = 180;
my $min_block = 300;
my $max_count = 10;
my $max_period = 1800;
my $max_block = 1800;
my $expire = 3600;

my $do_block = 1;
my $do_log = 1;
my $do_mail = 1;
my $email = 'куда слать';
my $hostname = short();

my $ip_to_block = shift @ARGV;
my $vhost = shift @ARGV;
my $uri = shift @ARGV;
my $args = shift @ARGV;
if ($args) { $args="?".$args; }

$vhost=short();
$uri='/';

$db = Mysql->connect("mysql.hoster.kg","antiddos", "xxxxx", "xxxxxxxx");

$time=time;

$sql="select id,time,block_time,ip from blocks where host='$vhost'";
$res = $db->query($sql);
#$res=$db->prepare($sql);

while (@arr = $res->fetchrow) {
if (($time-$arr[1])>$arr[2]) { unblock($arr[3],$arr[0]); }
}

$sql="delete from main where time < ($time - $expire) and host='$vhost'"; $res = $db->query($sql);
if ($ip_to_block) {

$sql="insert into main (ip,time,vhost,url,host) values (\"$ip_to_block\",$time,\"$vhost\",\"$uri\",'$vhost')";
$res = $db->query($sql);

$sql="select count(*) from main where time between ($time-$max_period) and $time and ip=\"$ip_to_block\" and host='$vhost'";
$res = $db->query($sql);
@arr=$res->fetchrow;
if ($arr[0]>$max_count) { block ($ip_to_block,$max_block); }
else {
$sql="select count(*) from main where time between ($time-$min_period) and $time and ip=\"$ip_to_block\" and host='$vhost'";
$res = $db->query($sql);
@arr=$res->fetchrow;
if ($arr[0]>$min_count) { block ($ip_to_block,$min_block); }
}
}

sub block {
$sql="select count(*) from blocks where ip=\"$_[0]\" and host='$vhost' ";
$res = $db->query($sql);
@arr=$res->fetchrow;

if (!$arr[0]) {
$sql="insert into blocks (ip,block_time,time,host) values (\"$_[0]\",$_[1],$time,'$vhost')";
$res = $db->query($sql);

if ($do_log) {
$cmd=`echo "$dt block $_[0] for $_[1] seconds on $vhost" >> /tmp/ddos_log`;
}

if ($do_mail) {
$t=$_[1]/60;
$data="IP: $_[0]\nURL: $vhost$uri$args\nTime: $t minutes";
$msg = MIME::Lite->new (
From =>"",
To =>$email,
Subject =>"IP-address block on $hostname",
Data =>$data
);
$msg->send;
}

if ($do_block = 1) {
$str="/sbin/iptables -I INPUT -s ".$_[0]." -j REJECT --reject-with icmp-port-unreachable";
$cmd=`$str`;
}

}
return 0;
}

sub unblock {
$sql1="delete from blocks where id=$_[1] and host='$vhost'";
$res1 = $db->query($sql1);

if ($do_log) {
$cmd=`echo "$dt unblock $_[0] on $vhost" >> /tmp/ddos_log`;
}

$str="/sbin/iptables -D INPUT -s ".$_[0]." -j REJECT --reject-with icmp-port-unreachable";
$cmd=`$str`;

return 0;
}

exit 0;

Структура базы данных:

DROP TABLE IF EXISTS `blocks`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `blocks` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`ip` varchar(15) NOT NULL,
`time` int(11) NOT NULL,
`block_time` int(11) NOT NULL,
`host` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1000 DEFAULT CHARSET=cp1251;
/*!40101 SET character_set_client = @saved_cs_client */;

CREATE TABLE `main` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`ip` varchar(15) NOT NULL,
`vhost` varchar(255) NOT NULL,
`url` varchar(512) NOT NULL,
`time` int(11) NOT NULL,
`host` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1294 DEFAULT CHARSET=cp1251;
/*!40101 SET character_set_client = @saved_cs_client */;

Сохраняете данные строки в файл antiddos.sql, создаете базу данных antiddos через phpmyadmin или mysqladmin и заливаете дамп туда: mysql -uroot -p antiddos < anti.sql Сохраняем код ddos.pl и указываем путь в к нему в DOSSystemCommand "sudo /backups/ddos.pl %s". Но это еще не все, нужно узнать, под каким юзером работает Ваш апач: ps aux | grep httpd httpd 9179 2.6 2.6 409220 91784 ? S 10:43 0:18 /hsphere/shared/apache2/bin/httpd.prefork -k start -DLIBPHP5 -DSSL -DFASTCGI -DSTATUS -DCACHE -f /hsphere/local/config/httpd2/httpd.conf -E /hsphere/local/var/httpd/logs/error_startup_log Теперь вы знаете, что он работает под httpd. делаете visudo в шелл и добавляете: /usr/sbin/visudo Добавляем httpd ALL=(ALL) NOPASSWD: /bin/echo, /backups/ddos.pl, /sbin/iptables И выставляем Defaults !requiretty Сохраняем все это и перезапускаем апач: /etc/init.d/httpd restart Удачи Вам!

Share and Enjoy:
  • Мой Мир
  • Facebook
  • Twitter

3 Комментариев для “Администрирование : Защита от Ddos mod_evasive”

  1. вообще, вычислять ddos на уровне конечного приложения, мне чего то кажется не особо быстродейственным..

    опять же, при наличии большой бот-сети, апач ляжет раньше, чем успеет всех перебанить..
    имхо, решение с ограничением скорости (кол-ва пакетов) с одного ip на хост выглядит более жизнеспособным..

  2. Я полностью согласен, метод этот от небольшего DDoS или остановить флуд. По крайне мере нам это помогает. На счет ограничения количества подключений с одного IP в единицу времени тоже хороший вариант.. который мы тоже используем. О нем я чуть позже и расскажу =)

Добавить комментарий