Диагностика DDOS-атаки
Подсчет кол-ва подключений к серверу
1 |
# cat /proc/net/ip_conntrack | wc -l |
— для Centos5
1 |
# cat /proc/net/nf_conntrack | wc -l |
— для Centos6
SYN—flood
Подсчет кол-ва попыток установить соединение
1 |
# netstat -nap | grep SYN_RECV | wc -l |
Просмотр кол-ва запросов с каждого адреса на установку соединений
1 |
# netstat -nap | grep SYN_RECV | awk {'print $5'} | awk -F: {'print $1'} | sort -rn | uniq -c | sort -rn |
Проверка кол-ва полузакрытых соединений
1 |
# netstat -an | grep FIN* | wc -l |
Просмотр кол-ва и типов установленных соединений
1 |
# netstat -np | awk '{print $6}'|awk -F: '{print $1}' | sort -rn | uniq -c | sort -rn | less |
Просмотр кол-ва подключений на каждый порт
1 |
# netstat -nput | awk '{print $4}'|awk -F: '{print $2}' | sort -rn | uniq -c | sort -nr | less |
HTTP-flood
Подсчет кол-ва процессов Apache(если он используется)
1 |
# ps ax | grep httpd | wc -l |
Подсчет кол-ва подключений на 80-порт
1 |
# netstat -na | grep ':80 ' | wc –l |
Подсчет кол-ва подключений с каждого адреса на 80 порт
1 |
# netstat -na |grep ':80 ' | awk '{print $5}' | awk -F: '{print $1}' | sort -rn | uniq -c | sort -rn | less |
Подсчет кол-ва подключений с каждого адреса по протоколу tcp или udp
1 |
# netstat -anp |grep 'tcp\|udp' | awk '{print $5}' | awk -F: '{print $1}' | sort -rn | uniq -c | sort -rn | less |
Запись в файл первых 1000 пакетов на порт 80 на интрфейсе eth0
1 |
# tcpdump -n -i eth0 dst port 80 -c 1000 -w /tmp/ddos.log |
Анализ файла /tmp/ddos.log – просмотр списка адресов, с которых идет подключения на 80 порт отсортированного по кол-ву подключений с каждого адреса
1 |
# tcpdump -nr /tmp/ddos.log | awk '{print $3}' |grep -oE '[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}' | sort | uniq -c | sort –rn | less |
Просмотр логов на предмет резкого увеличения их размеров
1 |
# watch -d -n 1 "ls -laS /var/log/httpd/" |
1 |
# watch -d -n 1 "ls -alS /var/log/nginx" |
Определение через server-status имени сайта, на который направлен DDOS при использовании apache(предварительно нужно настроить модуль mod_status)
1 |
http://<IP-address-server>/server-status |
после обнаружения имени сайта закрываем доступ к нему
а) в Apache через добавление в .htaccess в корне сайта строки
1 |
Deny from All |
b) в Nginx через добавление в файл описания вирт.хоста
в секцию server после директивы server_name строки deny all;
1 2 3 4 5 6 |
server { ………………………………… server_name deny all; .............. } |
Фильтрация пакетов
Блокирование доступа к 80 порту с конкретного адреса xxx.xxx.xxx.xxx
1 |
# iptables -A INPUT -p tcp --src xxx.xxx.xxx.xxx --dport 80 -j DROP |
или с подсети xxx.xxx.0.0/16
1 |
# iptables -A INPUT -p tcp --src xxx.xxx.0.0/16 --dport 80 -j DROP |
Ограничение максимального числа «полуоткрытых» соединений с одного IP к конкретному порту (необходим соответствующий модуль):
1 |
# iptables -I INPUT -p tcp --syn --dport 80 -m iplimit --iplimit-above 10 -j DROP |
Ограничение кол-ва одновременных соединений с одного IP-адреса
1 |
# iptables -A INPUT -p tcp --dport 80 -m iplimit --iplimit-above 10 -j REJECT |
Добавление в ipset адресов,которые имеют больше,например, 1000 подключений при анализе log-файла виртуального хоста
1 |
# cat /var/log/nginx/vhost.com.access.log | awk '{print $1}' | sort -rn | uniq -c | sort –rn | awk '($1>1000){print $2}' | xargs -tl -I _ ipset -A ddos _ |
Добавление в ipset адресов,которые имеют больше,например, 1000 подключений при анализе текущих подключений на 80 порт
1 |
# netstat -na |grep ':80 ' | awk '{print $5}' | awk -F: '{print $1}' | sort -rn | uniq -c | sort -rn | grep -v "127.0.0.1\|0.0.0.0" | grep -v ^$ | awk '($1>1000){print $2}' | xargs -tl -I _ ipset -A ddos _ |
Скрипт для автоматизации – который каждые 30 секунд проверяет кол-во подключений и блокирует доступ к порту 80 для адресов, которые, например, имеют больше 1000 подключений(если адрес уже добавлен в ipset, то он дублироваться не будет)
1 2 3 4 5 |
#!/bin/bash while true; do tail -n 10000 /var/log/nginx/vhost.com.access.log | awk '{print $1}' | sort -rn | uniq -c | sort -rn | awk '($1>1000){print $2}' | xargs -tl -I _ ipset -A ddos _; sleep 30; done |
Аналогично,только не блокировка адресов при обработке лога конкретного виртуального хоста, а блокировка текущих подключений на 80 порт для всех виртуальных хостов.
1 2 3 4 5 |
#!/bin/bash while true; do netstat -na |grep ':80 ' | awk '{print $5}' | awk -F: '{print $1}' | sort -rn | uniq -c | sort -rn | grep -v "127.0.0.1\|0.0.0.0" | grep -v ^$ | awk '($1>1000){print $2}' | xargs -tl -I _ ipset -A ddos _; sleep 30; done |
ICMP—flood
Защита от ICMP-флуда
1 |
# iptables -A INPUT -p icmp -j DROP --icmp-type 8 |
Настройки перемнных ядра (sysctl) для уменьшения эффективности DDOS-атаки, направленной на израсходование ресурсов сервера
ICMP-flood
Команда ниже поможет при отражении атаки типа icmp-flood.
1 |
sysctl net.ipv4.icmp_echo_ignore_all=1 |
(по умолчанию — 0)
SYN-flood
Уменьшение времени удержания «полуоткрытых» соединений:
1 |
sysctl -w net.ipv4.tcp_synack_retries=1 |
(по умолчанию — 5)
Включение TCP syncookies:
1 |
sysctl -w net.ipv4.tcp_syncookies=1 |
(по умолчанию — 1)
Увеличиваем размер очереди полуоткрытых соединений.
1 |
sysctl -w net.ipv4.tcp_max_syn_backlog=4096 |
(по умолчанию — 2048)
Проверять TCP-соединение каждую минуту. Если на другой стороне — легальная машина, она сразу ответит.
1 |
sysctl -w net.ipv4.tcp_keepalive_time=60 |
(по умолчанию – 7200=2часа)
Повторить проверку через 20 секунд
1 |
sysctl -w net.ipv4.tcp_keepalive_intvl=20 (по умолчанию – 75) |
Количество проверок перед закрытием соединения
1 |
sysctl -w net.ipv4.tcp_keepalive_probes=3 |
(по умолчанию – 9)
Изменяем время ожидания приема FIN
1 |
sysctl -w net.ipv4.tcp_fin_timeout=10 |
(по умолчанию – 60)
Защита от спуфинга(подмены адреса)
1 |
sysctl -w net.ipv4.conf.default.rp_filter=1 |
1 |
sysctl -w net.ipv4.conf.all.rp_filter=1 |
Для применения настроек после перезагрузки добавляем их в
1 |
/etc/sysctl.conf |
1 2 3 4 5 6 7 8 9 10 |
#DDOS protection net.ipv4.tcp_synack_retries=1 net.ipv4.tcp_syncookies=1 net.ipv4.tcp_max_syn_backlog=4096 net.ipv4.tcp_keepalive_time=60 net.ipv4.tcp_keepalive_intvl=20 net.ipv4.tcp_keepalive_probes=3 net.ipv4.tcp_fin_timeout=10 net.ipv4.conf.default.rp_filter=1 net.ipv4.conf.all.rp_filter=1 |
Борьба с DDOS-атакой с помощью готовых решений
http://10serv.com/borba-s-ddos-atakoy-s-pomoshhyu-d-dos-deflate/
Защита от использования злоумышленником Вашего сервера в участии в DDOS-атаках
(NTP-amplification)
В качестве меры для предотвращения участия NTP-серверов в DDoS-атаках рекомендуется запретить выполнение команды мониторинга через директиву «disable monitor»
1 |
# /usr/sbin/ntpdc |
1 2 3 |
ntpdc> monlist ……………………… ntpdc> quit |
1 |
# nano /etc/ntp.conf |
1 |
disable monitor |
1 |
# /etc/init.d/ntpd restart |
проверка
1 |
# /usr/sbin/ntpdc |
1 2 3 |
ntpdc> monlist ***Server reports data not found ntpdc> |
Источник:
Базовая работа с Ipset
1 |
# yum install ipset |
1 |
# ipset –V |
1 |
ipset v6.11, protocol version: 6 |
1 |
# ipset -N ddos iphash |
1 |
# iptables -A INPUT -p tcp --dport 80 -m set --set ddos src -j DROP |
1 |
# ipset -A ddos 1.1.1.1 |
1 |
# ipset -L |
1 2 3 4 5 6 7 |
Name: ddos Type: hash:ip Header: family inet hashsize 1024 maxelem 65536 Size in memory: 16536 References: 1 Members: 1.1.1.1 |
1 |
# ipset test ddos 1.1.1.1 |
1 |
1.1.1.1 is in set ddos. |
1 |
# ipset -D ddos 1.1.1.1 |
1 |
# ipset -L ddos |
1 2 3 4 5 6 |
Name: ddos Type: hash:ip Header: family inet hashsize 1024 maxelem 65536 Size in memory: 16536 References: 1 Members: |
1 |
# ipset -A ddos 1.1.1.1 |
1 |
# ipset -A ddos 2.2.2.2 |
1 |
# ipset -L ddos |
1 2 3 4 5 6 7 8 |
Name: ddos Type: hash:ip Header: family inet hashsize 1024 maxelem 65536 Size in memory: 16536 References: 1 Members: 2.2.2.2 1.1.1.1 |
1 |
# ipset flush ddos |
1 |
# ipset -L ddos |
1 2 3 4 5 6 |
Name: ddos Type: hash:ip Header: family inet hashsize 1024 maxelem 65536 Size in memory: 16504 References: 1 Members: |
1 |
# iptables -D http 1 |
1 |
# ipset -x ddos |