- PVSM.RU - https://www.pvsm.ru -
Многие сталкивались с таким явлением как DDoS атака методом HTTP флуда. Нет, это не очередной туториал по настройке nginx, хочу представить свой модуль, работающий как быстрый фильтр между ботами и бэкэндом во время L7 DDoS атаки и позволяющий отсеивать мусорные запросы.
Чаще всего, боты, реализующие HTTP флуд довольно тупые, и не имеют механизмов HTTP Cookie и редиректа. Иногда попадаются более продвинутые — такие могут использовать cookies и обрабатывать редиректы, но почти никогда DoS бот не несет в себе полноценного JavaScript движка.
Для понимания принципа работы фильтра ниже приведен flow общения клиент-сервер в зависимости от сценария атаки.
[2]
[3]
server {
listen 80;
server_name domain.com;
testcookie off;
testcookie_name BPC;
testcookie_secret keepmescret;
testcookie_session $remote_addr;
testcookie_arg attempt;
testcookie_max_attempts 3;
testcookie_fallback /cookies.html?backurl=http://$host$request_uri;
testcookie_get_only on;
location = /cookies.html {
root /var/www/public_html;
}
location / {
testcookie on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:8080;
}
}
server {
listen 80;
server_name domain.com;
testcookie off;
testcookie_name BPC;
testcookie_secret keepmescret;
testcookie_session $remote_addr;
testcookie_arg attempt;
testcookie_max_attempts 3;
testcookie_fallback /cookies.html?backurl=http://$host$request_uri;
testcookie_get_only on;
testcookie_redirect_via_refresh on;
testcookie_refresh_template '<html><body><script>document.cookie="BPC=$testcookie_set";document.location.href="$testcookie_nexturl";</script></body></html>';
location = /cookies.html {
root /var/www/public_html;
}
location / {
testcookie on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:8080;
}
}
server {
listen 80;
server_name domain.com;
testcookie off;
testcookie_name BPC;
testcookie_secret keepmescret;
testcookie_session $remote_addr;
testcookie_arg attempt;
testcookie_max_attempts 3;
testcookie_fallback /cookies.html?backurl=http://$host$request_uri;
testcookie_get_only on;
testcookie_redirect_via_refresh on;
testcookie_refresh_template '<html><body><script>function bla() { document.cookie="BPC=$testcookie_set";document.location.href="$testcookie_nexturl";}</script><input type="submit" value="click me" onclick="bla();"></body></html>';
location = /cookies.html {
root /var/www/public_html;
}
location / {
testcookie on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:8080;
}
}
server {
listen 80;
server_name domain.com;
testcookie off;
testcookie_name BPC;
testcookie_secret keepmescret;
testcookie_session $remote_addr;
testcookie_arg attempt;
testcookie_max_attempts 3;
testcookie_fallback /cookies.html?backurl=http://$host$request_uri;
testcookie_get_only on;
testcookie_redirect_via_refresh on;
testcookie_refresh_encrypt_cookie on;
testcookie_refresh_encrypt_cookie_key random;
testcookie_refresh_encrypt_cookie_iv random;
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="BPC="+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>';
location = /aes.min.js {
gzip on;
gzip_min_length 1000;
gzip_types text/plain;
root /var/www/public_html;
}
location = /cookies.html {
root /var/www/public_html;
}
location / {
testcookie on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:8080;
}
}
server {
listen 80;
server_name domain.com;
testcookie off;
testcookie_name BPC;
testcookie_secret keepmescret;
testcookie_session $remote_addr;
testcookie_arg attempt;
testcookie_max_attempts 3;
testcookie_fallback /cookies.html?backurl=http://$host$request_uri;
testcookie_get_only on;
testcookie_redirect_via_refresh on;
testcookie_refresh_encrypt_cookie on;
testcookie_refresh_encrypt_cookie_key deadbeefdeadbeefdeadbeefdeadbeef; #меняем по крону
testcookie_refresh_encrypt_cookie_iv deadbeefdeadbeefdeadbeefdeadbeef; #меняем по крону
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({используем любимый JS обфускатор чтобы спрятать значение iv, меняем по крону}),b=toNumbers({используем любимый JS обфускатор чтобы спрятать значение ключа, меняем по крону}),c=toNumbers("$testcookie_enc_set");document.cookie="BPC="+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>';
location = /aes.min.js {
gzip on;
gzip_min_length 1000;
gzip_types text/plain;
root /var/www/public_html;
}
location = /cookies.html {
root /var/www/public_html;
}
location / {
testcookie on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:8080;
}
}
Модуль с инструкциями по установке и документацией доступен на github [4] под BSD лицензией.
Патчи, дополнения, баг-репорты приветствуются.
Автор: kyprizel
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/nginx/3545
Ссылки в тексте:
[1] SlowAES: http://code.google.com/p/slowaes/
[2] Image: http://habrastorage.org/storage2/039/931/1a9/0399311a9a4257fd6298fe1e2d4e098c.png
[3] Image: http://habrastorage.org/storage2/5a2/d5a/3cf/5a2d5a3cf0fed6ebfc3865556ef65c54.png
[4] github: https://github.com/kyprizel/testcookie-nginx-module
Нажмите здесь для печати.