This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
ddos_ipset [2007/11/28 11:18] kyxap |
ddos_ipset [2016/01/27 21:31] (current) kyxap |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Борьба с Apache DDOS посредством использования утилиты ipset на выделенных серверах с Debian ====== | + | {{tag>ddos_mitigation debian squeeze ipset geoip bash perl iptables kernel}}====== Борьба с DDOS посредством использования утилиты ipset на выделенных серверах с Debian ====== |
| * Тянем последний [[ftp://ftp.netfilter.org/pub/patch-o-matic-ng/snapshot/|patch-o-matic-ng]] в ''/usr/src'', распаковываем, заходим в директорию и стартуем **./runme set**. \\ При этом подразумевается что исходники текущего ядра находятся в ''/usr/src/linux'', а ''iptables'' - в ''/usr/src/iptables''. \\ После заходим в ''/usr/src/linux'' и делаем **make oldconfig**, где указываем поддержку фич ''ipset'' //модулями//. | * Тянем последний [[ftp://ftp.netfilter.org/pub/patch-o-matic-ng/snapshot/|patch-o-matic-ng]] в ''/usr/src'', распаковываем, заходим в директорию и стартуем **./runme set**. \\ При этом подразумевается что исходники текущего ядра находятся в ''/usr/src/linux'', а ''iptables'' - в ''/usr/src/iptables''. \\ После заходим в ''/usr/src/linux'' и делаем **make oldconfig**, где указываем поддержку фич ''ipset'' //модулями//. | ||
| Собираем и устанавливаем ядро: | Собираем и устанавливаем ядро: | ||
| Line 16: | Line 16: | ||
| * Создаем перловый скрипт **/root/antiddos/num-filter.pl** для отбора ip-адресов, с которых идет большое количество одинаковых запросов: | * Создаем перловый скрипт **/root/antiddos/num-filter.pl** для отбора ip-адресов, с которых идет большое количество одинаковых запросов: | ||
| - | #!/usr/bin/perl | + | <code perl> |
| - | while ($line = <STDIN>) { | + | #!/usr/bin/perl |
| + | while ($line = <STDIN>) { | ||
| if ($line =~ /^\s+(\d+) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { | if ($line =~ /^\s+(\d+) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { | ||
| - | print $2, ".", $3, ".", $4, ".", $5, "\n" if ($1 > $ARGV[0]); | + | print $2, ".", $3, ".", $4, ".", $5, "\n" if ($1 > $ARGV[0]); |
| - | } | + | |
| } | } | ||
| + | } | ||
| + | </code> | ||
| * Создаем скрипт **/root/antiddos/blacklist.sh** для ''cron'': | * Создаем скрипт **/root/antiddos/blacklist.sh** для ''cron'': | ||
| - | #!/bin/bash | + | <code bash> |
| - | # variables, change them to get script work | + | #!/bin/bash |
| - | BADREQUEST="GET / HTTP/1.1"; | + | # variables, change them to get script work |
| - | LOGPATH="/home/clients/login_ftp0/domains/domain.com/logs/access_log"; | + | BADREQUEST="GET / HTTP/1.1"; |
| - | MINREQUESTS="50"; | + | LOGPATH="/home/clients/login_ftp0/domains/domain.com/logs/access_log"; |
| - | SCRIPTHOME="/root/antiddos"; | + | MINREQUESTS="50"; |
| - | # don't change anything bellow | + | SCRIPTHOME="/root/antiddos"; |
| - | grep "$BADREQUEST}" $LOGPATH | awk -F ' ' '{ print $ 1 }' | sort | uniq -c | ${SCRIPTHOME}/num-filter.pl $MINREQUESTS >> ${SCRIPTHOME}/in_blacklist.add.pre | + | # don't change anything bellow |
| - | sort -u < {SCRIPTHOME}/in_blacklist.add.pre > ${SCRIPTHOME}/in_blacklist.add | + | grep "${BADREQUEST}" $LOGPATH | awk -F ' ' '{ print $ 1 }' | sort | uniq -c | ${SCRIPTHOME}/num-filter.pl $MINREQUESTS >> ${SCRIPTHOME}/in_blacklist.add.pre |
| - | cat ${SCRIPTHOME}/in_blacklist.add > ${SCRIPTHOME}/in_blacklist | + | sort -u < ${SCRIPTHOME}/in_blacklist.add.pre > ${SCRIPTHOME}/in_blacklist.add |
| - | for i in `cat ${SCRIPTHOME}/in_blacklist`; | + | cat ${SCRIPTHOME}/in_blacklist.add > ${SCRIPTHOME}/in_blacklist |
| - | do | + | for i in `cat ${SCRIPTHOME}/in_blacklist`; |
| - | /usr/sbin/ipset -q -A blacklist $i; | + | do |
| - | done | + | /usr/sbin/ipset -q -A blacklist $i; |
| + | done | ||
| + | </code> | ||
| * Добавляем правила для ''iptables'': | * Добавляем правила для ''iptables'': | ||
| - | iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT | + | <code bash> |
| - | iptables -A INPUT -m set --set blacklist src,dst -j DROP | + | /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 | ||
| + | </code> | ||
| * Добавляем запуск скрипта **/root/antiddos/blacklist.sh** в крон с интервалом в 10 минут. | * Добавляем запуск скрипта **/root/antiddos/blacklist.sh** в крон с интервалом в 10 минут. | ||
| + | |||
| + | ----------------------------------------------------------------------------------- | ||
| + | |||
| + | Фильтрация с GeoIP | ||
| + | # apt-get install xtables-addons-source | ||
| + | # | ||
| + | |||
| + | == ПРИМЕР ФАЕРВОЛА С ИСПОЛЬЗОВАНИЕМ GEOIP == | ||
| + | <code bash> | ||
| + | #!/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 | ||
| + | </code> | ||
| + | |||
| + | ===== Скрипт для удаления адресов из блеклиста (FreeBSD) ===== | ||
| + | <file bash /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 | ||
| + | |||
| + | </file> | ||
| + | |||
| + | |||