Як я з DDoS боровся

Після певних подій, сайти УГКЦ підпали під потужний DDoS штурм. Важко було не те, що на сайт зайти, а й підключитися по SSH до консолі. Боротьба тривала кілька днів. Розповім, що саме мені допомогло подолати цю напасть.

Тюнінг iptables
На рівні мережевого екрану, я додав додаткові правила:

# DDoS
# Не відповідаємо на ping
iptables -A INPUT -p icmp -j DROP --icmp-type 8
# Блокуємо більше 2-х звернень на головну сторінку з одного IP за 10 сек.
iptables -A INPUT -p tcp -m tcp --dport 80 -m string --string "GET / HTTP" --algo kmp --to 1024 -m recent --set --name httpddos --rsource
iptables -A INPUT -p tcp -m tcp --dport 80 -m string --string "GET / HTTP" --algo kmp --to 1024 -m recent --update --seconds 10 --hitcount 2 --name httpddos --rsource -j DROP
# Блокуємо більше 32 конектів з 1 IP
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 32 -j DROP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Це дозволило трохи розвантажити Apache.

Тюнінг TCP
Сервер під управлінням Debian Linux. В /etc/sysctl.conf було прописано:

# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1

# Controls the maximum size of a message, in bytes
kernel.msgmnb = 65536

# Controls the default maxmimum size of a mesage queue
kernel.msgmax = 65536

# Controls the maximum shared segment size, in bytes
kernel.shmmax = 4294967295

# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 268435456

# через 60 секунд с момента наступления тишины в канале сервером выполняется проба. Если клиент жив, то серверу высылается ответный пакет
net.ipv4.tcp_keepalive_time = 60

# если ответа на проверку нет, то с интервалом в 10 секунд повторить
net.ipv4.tcp_keepalive_intvl = 10

# Сколько раз повторить проверку после чего закрыть соединение
net.ipv4.tcp_keepalive_probes = 5

net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
net.ipv4.tcp_timestamps = 0

net.ipv4.netfilter.ip_conntrack_max = 65536
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close = 30
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 30
net.ipv4.netfilter.ip_conntrack_tcp_timeout_last_ack = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 30
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 190
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv = 30
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent = 30

Це допомогло мені отримати доступ до сервера по ssh навіть при потужних атаках.

Блокуємо цілі країни
Атаки йшли з Китаю, Іран та інших країн. З допомогою простого скрипта, блокуємо ці країни:

#!/bin/bash
### Block all traffic from AFGHANISTAN (af), CHINA (CN), IRAN (IR) and BRASIL (BR). Use ISO code ###
ISO="af cn ir br"

### Set PATH ###
IPT="`which iptables`"
WGET="`which wget`"
EGREP="`which egrep`"

### No editing below ###
SPAMLIST="BLK-List-01-INPUT"
ZONEROOT="/var/cache/iptables/country"
DLROOT="http://www.ipdeny.com/ipblocks/data/countries"

cleanOldRules(){

  $IPT -t filter -F "$SPAMLIST"
  $IPT -t filter -X "$SPAMLIST"

}

# create a dir
[ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT

# clean old rules
cleanOldRules

# create a new iptables list
$IPT -t filter -N $SPAMLIST

for c  in $ISO
do
	# local zone file
	tDB=$ZONEROOT/$c.zone

	# get fresh zone file
	$WGET -O $tDB $DLROOT/$c.zone

	# country specific log message
	SPAMDROPMSG="Dropping country: [$c] "

	# get
	BADIPS=$(egrep -v "^#|^$" $tDB)
	for ipblock in $BADIPS
	do
	   $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
	   $IPT -A $SPAMLIST -s $ipblock -j DROP
	done
done

# Drop everything
$IPT -I INPUT -j $SPAMLIST
$IPT -I OUTPUT -j $SPAMLIST
$IPT -I FORWARD -j $SPAMLIST

# call your other iptable script
# /path/to/other/iptables.sh

exit 0

Переходимо до хмарного захисту
Знайшов сервіс CloudFlare, який дозволив прийняти на себе основний удар, а лише “живі” запити перенаправляти на Web-сервер.

Аналітика CloudFlare
Аналітика CloudFlare

Такими 4-ма кроками було цілком подолано DDoS атаку на сервер.

Leave a Reply

Your email address will not be published. Required fields are marked *