Наиболее часто для нарушения работы сайта злоумышленники используют HTTP-флуд. Для защиты от HTTP-флуда я буду использовать связку из Nginx и модуля nginx-module-testcookie
Для начала необходимо добавить репозиторий rpms.southbridge.ru в систему. Для этого выполните команду:
rpm -Uhv http://rpms.southbridge.ru/southbridge-rhel7-stable.rpm
Далее стандартной командой устанавливаем пакеты:
yum install nginx nginx-module-testcookie
С учетом того, что Nginx я обновляю достаточно редко, по ряду причин на постоянной основе я не хочу использовать выше указанный репозиторий, то я выполню установку непосредственно из скачанных rpm-пакетов:
wget http://rpms.southbridge.ru/rhel7/stable/x86_64/nginx-1.9.5-1.el7.centos.ngx.x86_64.rpm
wget http://rpms.southbridge.ru/rhel7/stable/x86_64/nginx-module-testcookie-1.15.6.1.24-1.el7.ngx.x86_64.rpm
Если в системе ранее уже был установлен Nginx, нужно его удалить. Устанавливаем Nginx и nginx-module-testcookie:
rpm -Uhv nginx-1.15.6-1.el7.ngx.x86_64.rpm
rpm -Uhv nginx-module-testcookie-1.15.6.1.24-1.el7.ngx.x86_64.rpm
Чтобы включить модуль добавьте строку ниже в файл /etc/nginx/nginx.conf:
Для включение и отключения testcookie нам необходимо периодически просматривать статистику подключений. Для этого добавьте в конфиг:
1 2 3 4 5 6 7 8 9 10 11 |
server { listen 80; server_name localhost; location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } } |
Применяем настройки, проверяем:
# service nginx restart
# curl http://localhost/nginx_status
Active connections: 4
server accepts handled requests
137 137 190
Reading: 0 Writing: 1 Waiting: 3
Берем файл https://github.com/duy13/vDDoS-Protection/blob/master/aes.min.js.txt и копируем его в отдельный каталог на сервере /www/public_html/aes.min.js
Добавляем в конфиг вашего сайта следующие строки:
1 2 3 4 5 6 7 |
location = /aes.min.js { gzip on; gzip_min_length 1000; gzip_types text/plain; gzip_static on; root /www/public_html; } |
Сохраняем настройки:
nginx reload
Проверяем, что файл доступен по адресу http://site.ru/aes.min.js
Добавляем в конфиг вашего сайта параметры по примеру ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
http { testcookie off; testcookie_name RCPC; testcookie_secret nlos7m5hYc6gNmm7NvhCZJ8W7lJHuAaV2dp73px9diYMYzKmhvrpjZLNaoK989wW; testcookie_session $remote_addr; testcookie_arg attempt; testcookie_max_attempts 3; testcookie_get_only on; testcookie_redirect_via_refresh on; testcookie_refresh_encrypt_cookie on; testcookie_refresh_encrypt_cookie_key ea5891045bdfddd19682146f1e88e6e8; testcookie_refresh_encrypt_cookie_iv ea5891045bdfddd19682146f1e88e6e8; testcookie_refresh_template '<html><body>setting cookie…<script type=\"text/javascript\" src=\"/aes.min.js\" ></script><script>function toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}function toHex(){for(var d=[],d=1==arguments.length&&arguments[0].constructor==Array?arguments[0]:arguments,e="",f=0;f<d.length;f++)e+=(16>d[f]?"0":"")+d[f].toString(16);return e.toLowerCase()}var a=toNumbers("$testcookie_enc_key"),b=toNumbers("$testcookie_enc_iv"),c=toNumbers("$testcookie_enc_set");document.cookie="RCPC="+toHex(slowAES.decrypt(c,2,a,b))+"; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/";document.location.href="$testcookie_nexturl";</script></body></html>'; server { listen 80; server_name test.com; location = /aes.min.js { gzip on; gzip_min_length 1000; gzip_types text/plain; root /var/www/public_html; } #Если используется проксирование, в противном случае не использовать location / { testcookie off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:80; } } |
Параметр testcookie_secret
заполняем случайным набором из 64 символов. Для testcookie_refresh_encrypt_cookie_key
и testcookie_refresh_encrypt_cookie_iv
генерируем hex число длиной 32 символа этим генератором.
Теперь осталось настроить скрипт, который будет автоматически проверять количество подключений к Nginx и в случае превышения лимита, автоматически включать testcookie
и атпровлять уведомление администратору на почту.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#!/bin/sh NGINX_CONF=/etc/nginx/conf.d/default.conf MAIL="admin@site.ru" MAILTO=root LA_ACTIVATE=17 LA_DEACTIVATE=5 NGINX_CONNECT=1000 TMPLOG=/tmp/testcookie_module.tmp NGINXCONN=`curl -s http://localhost/nginx-status | grep "Active" | awk '{print($3)}'` LA=`cat /proc/loadavg | awk -F '.' '{print($1)}'` function e { echo -en $(date "+%F %T"): "$1" } if [ ! -f $TMPLOG ];then echo 0 > $TMPLOG; fi LASTRESULT=`cat $TMPLOG` if [ -n "$NGINXCONN" ]; then if [ $NGINXCONN -gt $NGINX_CONNECT ]; then ALERT1="1" fi fi if [ -n "$LA" ]; then if [ $LA -gt $LA_ACTIVATE ]; then ALERT2="1" fi fi ALERT=$ALERT1$ALERT2 if [ -n "$ALERT" -a $LASTRESULT -eq 0 ]; then e; printf "Nginx connect: %-4s LA: %-3s | Activate testcookie\n" "$NGINXCONN" "$LA" sed -i 's/.*##-AUTO-DDOS-LABEL-##/\ttestcookie on; ##-AUTO-DDOS-LABEL-##/g' $NGINX_CONF /sbin/service nginx reload >/dev/null 2>&1 echo 1 > $TMPLOG if [ "$MAIL" = "true" ];then echo "Nginx connect $NGINXCONN, LA $LA. Nginx test-cookie enable" | mail -s "`hostname` DDOS detected. Nginx test-cookie enable" $MAILTO fi fi if [ $LA -le $LA_DEACTIVATE -a $LASTRESULT -eq 1 ]; then e; printf "Nginx connect: %-4s LA: %-3s | Dectivate testcookie\n" "$NGINXCONN" "$LA" sed -i 's/.*##-AUTO-DDOS-LABEL-##/\ttestcookie off; ##-AUTO-DDOS-LABEL-##/g' $NGINX_CONF /sbin/service nginx reload >/dev/null 2>&1 echo 0 > $TMPLOG fi |
Добавляем задание в cron:
* * * * * /etc/nginx/check.sh >/dev/null 2>&1