I'm writing an api using nodejs and express and my app is hosted by openshift free plan. I want to protect my routes from brute force. For example if an IP sends more than 5 requests /sec then block it for 5 minutes. :)
-
1This is called "Rate Limiting" and there have been many articles and some previous StackOverflow posts written about it. I'd suggest you start with what has already been written. Here's one: [What's a good rate limiting algorithm](http://stackoverflow.com/questions/667508/whats-a-good-rate-limiting-algorithm). – jfriend00 Sep 19 '15 at 16:02
-
@jfriend00 thanks for the name, I'm searching for it + it's very cool to write something from scratch :) – Ameer Mousavi Sep 19 '15 at 16:04
-
1Here's a good reference on the [Leaky Bucket Algorithm](https://en.wikipedia.org/wiki/Leaky_bucket) which is one common algorithm used for rate limiting. – jfriend00 Sep 19 '15 at 16:07
3 Answers
There's nothing stopping you from implementing this in Node.js/express directly, but this sort of thing is typically (and almost certainly more easily) handled by using something like nginx
or Apache httpd
to handle traffic to your app.
This has the added benefit of allowing you to run the app entirely as an unprivileged user because nginx (or whatever) will be binding to ports 80 and 443 (which requires administrative/superuser/whatever privileges) rather than your app. Plus you can easily get a bunch of other desirable features, like caching for static contents.
nginx has a module specifically for this:
The ngx_http_limit_req_module module (0.7.21) is used to limit the request processing rate per a defined key, in particular, the processing rate of requests coming from a single IP address.

- 66,479
- 23
- 173
- 212
-
Thanks for reply. But I think that I didn't get your point. I'm using nodejs and don't want to using another webserver :) – Ameer Mousavi Sep 19 '15 at 16:08
-
5
It is better to limit rates on reverse-proxy, load balancer or any other entry point to your node.js app.
However, it doesn't fit requirements sometimes.
rate-limiter-flexible package has block option you need
const { RateLimiterMemory } = require('rate-limiter-flexible');
const opts = {
points: 5, // 5 points
duration: 1, // Per second
blockDuration: 300, // block for 5 minutes if more than points consumed
};
const rateLimiter = new RateLimiterMemory(opts);
const rateLimiterMiddleware = (req, res, next) => {
// Consume 1 point for each request
rateLimiter.consume(req.connection.remoteAddress)
.then(() => {
next();
})
.catch((rejRes) => {
res.status(429).send('Too Many Requests');
});
};
app.use(rateLimiterMiddleware);
You can configure rate-limiter-flexible
for any exact route. See official express docs about using middlwares
There are also options for Cluster or distributed apps and many others useful

- 1,121
- 10
- 23