4

I'm running a large WordPress multiuser site. I have a varnish cache in front of the WordPress application server. As it makes no sense to cache POST requests, I am vulnerable to DDoS using lots of POSTs against the varnish cache server.

I have tried setting op a firewall rules that only accepted 20 simultaneously connections from each client, but that had impact on the users sitting behind shared proxies and on schools with lots of users behind the same gateway.

Varnish does not have the option to rate-limit the numbers of POSTs, and I want to do the rate-limit BEFORE it hits the application server. Is there a small transparent proxy that would do the job?

Currently Varnish is receiving about 100-150 hits/second, the proxy should at least be able to handle this load.

the
  • 468
  • 8
  • 23

2 Answers2

2

I am going to put this down as an answer only because it's going to be long. As you quite accurately said blocking more than 20 concurrent requests from 1 IP won't do the trick. You have to set "smarter" criteria. I will go as far as to say that putting another proxy between a proxy and an application server is not elegant nor useful.

I don't know why you want to do the rate-limit before hitting apache because you are missing out on fail2ban, mod_qos, mod-antiloris (highly specific) and other solutions. Moreover I don't know if POST requests are your only problem in terms of a DDoS.

Caching POST request replies is possible and makes sense as well. Unless you are serving dynamic content every single time. That of course doesn't mean that you can cache authenticated pages.

You can apply request time-outs for POST if the request has taken more that 5s. Although users with slow connections won't be able to POST anything. You can also apply a rule on a per URL basis combined with the above rule. This makes sense, since it is reasonable for a user to POST 1000kb on a file uploading page but not on the login page. As I said create "smarter" criteria. They might be long and it might take some time to formulate them but they will provide you with a sustainable solution as I don't know of a one-size fits all in this kind of situation.

Another solution which you can combine is an application firewall. Might be more than you need but it can as well keep you safe from many other things. Here is a owasp page with recommendations and the relevant wiki

EDIT: I have to admit, I don't have any experience with that configuration (varnish and antiloris). Sooner or later there's so much that varnish can cache (although it is highly "programmable"). The main thing you can do is know the pattern of use and when it deviates from the norm. If you just want to prevent that very specific type of attack then writing better rules for Varnish should do it. However requests hitting apache is not a bad thing, as long as you have the proper mods/confs in place, Apache can tell when a request is legit and thus process it and when not to. Blocking X number of connections from each client is NOT a good thing to do, unless you can definitely blacklist that IP. You can do that on apache either through fail2ban(regex) or mod_qos

the
  • 468
  • 8
  • 23
user
  • 1,418
  • 8
  • 10
  • I was not aware of the http://sourceforge.net/projects/mod-antiloris/ solution. I will investigate that solution. The reason for not wanting to have the requests hitting apache is that, i am convinced that apache does not handle tons of requests as elegant as varnish or a small proxy would do. Also im a bit worried about the ram usage on the appliation server if all requests from a dos would actually hit apache. But thx for the reply, i will look into your suggestions :-) – Tonny Jørgensen Jan 27 '12 at 09:06
  • One more thing, when using mod_slowloris, this give issues as apache sees all connections comming from varnish server and not from the enduser client. So the purpose of blocking X number of connections per client in the apache is not possible ? – Tonny Jørgensen Jan 27 '12 at 12:39
0

I think Varnish, correctly configured will do this fine.

I don't know much about wordpress, but I take it a valid post will have a session variable either in a cookie or the form params. If so, what you want to limit is either repeated POSTs for the same value, or POSTs with no such value.

I've done a blog post here: http://blog.dansingerman.com/post/4604532761/how-to-block-rate-limited-traffic-with-varnish on rate-limiting based on IP address or a URL param; it should be straightforward to customise it for POSTs and based around a form variable or a cookie variable.

DanSingerman
  • 131
  • 1
  • 4