3

I have a Django web app where people write comments and upvote/downvote others' comments. The webserver is gunicorn + nginx (reverse proxy). The db is postgresql. The db and web app reside in two different ubuntu-based machines.

Some malicious users have begun abusing the voting feature, giving themselves thousands of votes within a few mins (or downvoting others). My servers effectively get DDOSed when such a script is run. Some of these people also impersonate other users by stealing their cookies!

I want to detect this behavior early, at nginx level. I was thinking I'd install fail2ban and write a policy. A policy can then be if more than 10 votes originate from an IP within 15 secs, send that IP to jail (i.e. redirect to a jail url) for 30 mins.

Now in my access.log, a vote (up or down) creates the following: 31.13.113.83 - - [14/Feb/2016:06:51:10 +0000] "POST /vote/ HTTP/1.1" 302 5 "http://example.com/?sorg_service_id_internal=373234912870626%3BAfq3$.

Being new to this, I need help with implementing my policy.Will it be failregex = ^ \vote\ in the .conf file's [Definition] and the following in jail.local:

[nginx-votefraud]

enabled  = true
port     = http,https
filter   = nginx-votefraud
logpath  = /var/log/nginx/access.log
maxretry = 10
findtime = 15
bantime  = 3600
banurl   = /banned/

Is that it?

Note: Also of interest to me is how this can affect performance of the web app. Is implementing fail2ban relatively light in your experience or a substantial cost is incurred? Assume this is the only policy I implement. The discussion here seems to suggest it could be costly on the RAM?

1 Answers1

2

You should look at those two modules of nginx:
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html

This helps you limiting the requests and/or the connections which prevents the hammering of your backend. Then I'd add a check if the user already voted for a specific post and deny a second vote if so.
You then can still check the log for 503 (Service Temporarily Unavailable) and use fail2ban to keep those out who trigger nginx limits (too often).

unNamed
  • 660