User Tools

Site Tools


Sidebar


Tags Cloud
ddos_ipset

Борьба с DDOS посредством использования утилиты ipset на выделенных серверах с Debian

  • Тянем последний patch-o-matic-ng в /usr/src, распаковываем, заходим в директорию и стартуем ./runme set.
    При этом подразумевается что исходники текущего ядра находятся в /usr/src/linux, а iptables - в /usr/src/iptables.
    После заходим в /usr/src/linux и делаем make oldconfig, где указываем поддержку фич ipset модулями.

Собираем и устанавливаем ядро:

# make-kpkg --bzImage kernel_image
# dpkg -i /usr/src/linux-image-x.x.x-blablabla.deb
  • Устанавливаем ipset из репозитория:
# apt-get install ipset
  • Добавляем загрузку модуля ipset в /etc/modules и либо загружаем модуль modprobe ipset, либо перезагружаемся в новое ядро.
  • Создаем хеш ip-адресов для использования в правилах iptables. Стоит учесть, что максимальное количество ip в списке - 65536 штук:
# ipset -N blacklist iphash
  • Создаем перловый скрипт /root/antiddos/num-filter.pl для отбора ip-адресов, с которых идет большое количество одинаковых запросов:
#!/usr/bin/perl
while ($line = <STDIN>) {
  if ($line =~ /^\s+(\d+) (\d+)\.(\d+)\.(\d+)\.(\d+)/) {
    print $2, ".", $3, ".", $4, ".", $5, "\n" if ($1 > $ARGV[0]);
  }
}
  • Создаем скрипт /root/antiddos/blacklist.sh для cron:
#!/bin/bash
# variables, change them to get script work
BADREQUEST="GET / HTTP/1.1";
LOGPATH="/home/clients/login_ftp0/domains/domain.com/logs/access_log";
MINREQUESTS="50";
SCRIPTHOME="/root/antiddos";
# don't change anything bellow
grep "${BADREQUEST}" $LOGPATH | awk -F ' ' '{ print $ 1 }' | sort | uniq -c | ${SCRIPTHOME}/num-filter.pl $MINREQUESTS >> ${SCRIPTHOME}/in_blacklist.add.pre
sort -u < ${SCRIPTHOME}/in_blacklist.add.pre > ${SCRIPTHOME}/in_blacklist.add
cat ${SCRIPTHOME}/in_blacklist.add > ${SCRIPTHOME}/in_blacklist
for i in `cat ${SCRIPTHOME}/in_blacklist`;
do
  /usr/sbin/ipset -q -A blacklist $i;
done
  • Добавляем правила для iptables:
  /sbin/iptables -F
  /sbin/iptables -X DDOS_HTTP_FILTER
  /sbin/iptables -N DDOS_HTTP_FILTER
  /sbin/iptables -A DDOS_HTTP_FILTER -d $IP -p tcp --syn --dport 80 -m set --set blacklist src -j DROP
  /sbin/iptables -A DDOS_HTTP_FILTER -d $IP -p tcp --syn --dport 80 -m hashlimit --hashlimit 10/min --hashlimit-burst 30 --hashlimit-mode srcip --hashlimit-name DDOS --hashlimit-htable-size 32768 --hashlimit-htable-max 32768 --hashlimit-htable-gcinterval 1000 --hashlimit-htable-expire 100000 -j ACCEPT
  /sbin/iptables -A DDOS_HTTP_FILTER -d $IP -p tcp --dport 80 --syn -j DROP
  /sbin/iptables -A DDOS_HTTP_FILTER -d $IP -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 -j DROP
  /sbin/iptables -A DDOS_HTTP_FILTER -j ACCEPT
  /sbin/iptables -A INPUT -p tcp --dport http -j DDOS_HTTP_FILTER
  • Добавляем запуск скрипта /root/antiddos/blacklist.sh в крон с интервалом в 10 минут.

Фильтрация с GeoIP

# apt-get install xtables-addons-source
#
ПРИМЕР ФАЕРВОЛА С ИСПОЛЬЗОВАНИЕМ GEOIP
#!/bin/bash

iptables=/usr/local/sbin/iptables
ipset=/usr/sbin/ipset
WHITE="195.88.52.82/32"

ddos_enable() {
    # whitelist
    $iptables -N WHITELIST
    for i in $WHITE;
    do
        $iptables -A WHITELIST -s $i -j ACCEPT;
    done
    $iptables -A WHITELIST -j DROP

    $iptables -N DDOS_HTTP_FILTER
    $iptables -A DDOS_HTTP_FILTER -m hashlimit --hashlimit 15/min --hashlimit-burst 30 --hashlimit-mode srcip --hashlimit-name HTTPDDOS --hashlimit-htable-size 32768 --hashlimit-htable-max 32768 --hashlimit-htable-gcinterval 1000 --hashlimit-htable-expire 100000 -j ACCEPT
    $iptables -A DDOS_HTTP_FILTER -m connlimit --connlimit-above 15 -j DROP
    $iptables -A DDOS_HTTP_FILTER -j ACCEPT

    $iptables -N SORT_FILTER
    $iptables -A SORT_FILTER -p tcp --dport 80 --syn -j DDOS_HTTP_FILTER
    $iptables -A SORT_FILTER -p tcp -m multiport --dports 25,53 -j ACCEPT
    $iptables -A SORT_FILTER -p udp --dport 53 -j ACCEPT
    $iptables -A SORT_FILTER -j WHITELIST

    $iptables -N GEOIP_FILTER
    $iptables -A GEOIP_FILTER -m geoip --src-cc AM,AZ,BY -j SORT_FILTER
    $iptables -A GEOIP_FILTER -m geoip --src-cc EE,GE,KZ -j SORT_FILTER
    $iptables -A GEOIP_FILTER -m geoip --src-cc LV,MD,NL,RU -j SORT_FILTER
    $iptables -A GEOIP_FILTER -m geoip --src-cc UA,UZ,US -j SORT_FILTER
    $iptables -A GEOIP_FILTER -j DROP

    $iptables -I INPUT 1 -i lo -j ACCEPT
    $iptables -I INPUT 2 -m set --set blacklist src -j DROP
    $iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    $iptables -A INPUT -j GEOIP_FILTER
}

start_iptables() {
    # whitelist
    $iptables -N WHITELIST
    for i in $WHITE;
    do
        $iptables -A WHITELIST -s $i -j ACCEPT;
    done
    $iptables -A WHITELIST -j DROP

    # default rules
    $iptables -I INPUT 1 -i lo -j ACCEPT
    $iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    $iptables -A INPUT -p tcp -m multiport --dports 25,53,80 -j ACCEPT
    $iptables -A INPUT -p udp --dport 53 -j ACCEPT
    $iptables -A INPUT -j WHITELIST
}

clear_iptables() {
    $iptables -F
    $iptables -X
}

start_ipset() {
    $ipset -q -N blacklist iphash
}

clear_ipset() {
    $ipset -q -F blacklist
    $ipset -q -X blacklist
}

case "$1" in
    normal)
        clear_iptables
        start_iptables
        echo "normal mode activated"
    ;;

    stop)
        clear_iptables
        clear_ipset
        echo "iptabes cleared"
    ;;

    hard)
        clear_iptables
        start_ipset
        ddos_enable
        echo "hard mode activated"

    ;;
    *)
        echo "Usage $0 {normal|hard|stop}"
        exit 1
    ;;
esac

Скрипт для удаления адресов из блеклиста (FreeBSD)

/opt/scripts/unban_ip.sh
#!/usr/bin/env bash
 
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:~/bin
 
SCRIPTHOME="/root/antiddos"
 
function valid_ip()
{
    local  ip=$1
    local  stat=1
 
    [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && {
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
        && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
    stat=$?
    return $stat
}
}
 
###############
 
[[ -d $SCRIPTHOME ]] || exit 1
 
if ! VALID_IP=$(valid_ip "$1")
then
    echo "Usage: $0 <IP ADDR>" >&2
    exit 1
fi
 
sed_cmd="/$1/d;/^[[:space:]]*$/d;s/[[:space:]]*$//"
 
if LISTS=$(grep -lIrx "$1" "$SCRIPTHOME" | grep -v "\.sh")
then
    for i in $LISTS
    do
        echo "Removing $1 from $i"
        sed -i '' "$sed_cmd" ${i}
    done
    nginx -t && nginx -s reload
fi
ddos_ipset.txt · Last modified: 2016/01/27 21:31 by kyxap