Infosecurity
Raiting:
12

Using Nginx module to fight against DDoS attacks


Many people have faced the DDoS attacks and HTTP flooding. No, this is not just another tutorial on setting up nginx, but I would like to introduce my module that works as a quick filter between the bots and backend during L7 DDoS attacks, as well it allows filtering the garbage requests.

The module can do:


• To set cookies in a standard way through HTTP header Set-Cookie. After the cookies are set it redirects the user using the response code 301 and Location header.
• After the cookies are set it redirects the user using the response code 200 and HTML tag Meta refresh.
• To count the number of attempts to set the cookies and to direct the user to a specified URL after exceeding the maximum number of unsuccessful attempts.
• To use the custom templates for the filter response, for example, to set cookies through JavaScript.
• To prevent automated parsing of responses that are aimed at the execution of JavaScript, to encrypt the value of variables in the template using the symmetric encryption algorithm to further decryption through JavaScript on the client side (using SlowAES).
• To whitelist the network (e.g., networks where live searching robots)
• To do some useful things during the DoS attacks.

The module cannot do:


• This module only returns to the client the specified answers and you must make your own decision about blocking the client (for example, using fail2ban).
• Some people may say that I simulate JavaScript, but let's be realistic, that you often get DoS attack by bots with full emulation.
• There is nothing in the documentation about captcha and flash, but if you want, you can get them yourself, you just need to use your imagination in the configuration.
• This module is not a panacea it is only a small component in a complex of protective measures, a tool that can help you, if it will be properly used.

How does it work?


Most often, the bots that implement HTTP flood are doll, and they do not have any mechanisms for HTTP Cookie and redirects. Sometimes, there are more advanced bots that could use cookies and redirects, but almost never DoS bot could have JavaScript engine.
To understand the operation concept of this filter, there is given below the communication flow of client-server, depending on the scenario of attack.

The bots do not understand the redirects and the cookies
image
The bots understand the redirects and the cookies, but they do not do JavaScript
image
Configuration examples for the main attack scenarios

The bots do not understand the redirects and the cookies
(a typical case)
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;
}
}
The bots understand the redirects and the cookies
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;
}
}
protected URL is inserted in an iframe on the popular website
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;
}
}
bots have learned to pull out the value of cookies through regexp
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;
}
}
bots have learned to pull out the parameters through regexp and to decrypt the value of cookies (I doubt that anyone will bother that)
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; #change cron
testcookie_refresh_encrypt_cookie_iv deadbeefdeadbeefdeadbeefdeadbeef; #change cron

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({use your favorite JS obfuscator to hide the value of iv, change cron}),b=toNumbers ({use your favorite JS obfuscator to hide the key value, change}),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;
}
}

Source texts


The module with an installation user guide and documentation are available on github under the terms of BSD license.
The patches, additions, bug reports are welcome!
ZimerMan 22 april 2012, 16:30
Vote for this post
Bring it to the Main Page
 

Comments

0 mathsonic August 31, 2012, 10:20
Hi,

Thanks for this module

How do you deal with Search Engine Crawlers ?

Leave a Reply

B
I
U
S
Help
Avaible tags
  • <b>...</b>highlighting important text on the page in bold
  • <i>..</i>highlighting important text on the page in italic
  • <u>...</u>allocated with tag <u> text shownas underlined
  • <s>...</s>allocated with tag <s> text shown as strikethrough
  • <sup>...</sup>, <sub>...</sub>text in the tag <sup> appears as a superscript, <sub> - subscript
  • <blockquote>...</blockquote>For  highlight citation, use the tag <blockquote>
  • <code lang="lang">...</code>highlighting the program code (supported by bash, cpp, cs, css, xml, html, java, javascript, lisp, lua, php, perl, python, ruby, sql, scala, text)
  • <a href="http://...">...</a>link, specify the desired Internet address in the href attribute
  • <img src="http://..." alt="text" />specify the full path of image in the src attribute