A gem we use in some of our apps to add rate-limiting capabilities is rack-ratelimit
. This gem is not too complex and quite flexible but lacks a feature that could be useful for people using it: the possiblity of banning a client completely for a period of time when they expose some undesirable behaviour.
The idea is that users of this gem could specify a number of requests after which a particular client would get banned for a given time interval, for all requests, rather than just rate-limited for a particular kind of requests. A new config option, ban
, could be introduced to support this, working as follows:
ban: an array of [max requests, period in seconds, ban time]: [500, 5.minutes, 3.hours]
ban
could be provided instead of rate
, so this one wouldn't be required anymore (but one of them would be always necessary). Here is an example of how it could be used:
# Ban IPs that are hammering our sign in page with login requests for 24 hours
use(Rack::Ratelimit, name: 'login_brute_force',
conditions: ->(env) { env['REQUEST_METHOD'] == 'POST' && env['PATH_INFO'] =~ /\A\/sessions/ },
ban: [10, 5.minutes, 24.hours],
cache: Dalli::Client.new,
logger: Rails.logger) { |env| Rack::Request.new(env).ip }
That is: if we see over 10 POST
requests to /sessions
in 5 minutes, we want that IP address to be banned completely for 24 hours, for all requests.
- The described way
ban
could be used and configured is just a suggestion that can be changed if you decide so, no problem about that! - The change should be backwards-compatible with existing usages of
Rack::Ratelimit
. - Tests and updating the
README
to describe this feature are expected.
- Don't fork the
rack-ratelimit
repository on Github or submit a pull request directly there, as that would make your solution public for others to see. Instead, just clone the repository and work locally on it. - When you're done, squash your work into a single commit and use
git format-patch
to generate a patch file. Email the patch file to us as your work sample submission. If you prefer to provide a GitHub's private gist or even do your work in a private repo and add us to it, that's also totally fine.