Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More elegant way to block IPs? #111

Closed
pisaacs opened this issue Jan 18, 2015 · 7 comments
Closed

More elegant way to block IPs? #111

pisaacs opened this issue Jan 18, 2015 · 7 comments

Comments

@pisaacs
Copy link
Contributor

pisaacs commented Jan 18, 2015

The current documentation illustrates a static method to blocking/blacklisting an ip address:

# Block requests from 1.2.3.4
Rack::Attack.blacklist('block 1.2.3.4') do |req|
  # Requests are blocked if the return value is truthy
  '1.2.3.4' == req.ip
end

I've been thinking about a more "elegant" (i.e., dynamic really) solution to blocking/blacklisting IPs. How about the following approach?

Rack::Attack.blacklist('block <ip>') do |req|
  # if variable `block <ip>` exists in cache store, then we'll block the request
  Rails.cache.fetch("block #{req.ip}").blank?
end

In the case of ip 1.2.3.4, this snippet simply checks if the cache store has a variable called block 1.2.3.4, which can be managed by a site maintainer via Rails console:

rails c
Rails.cache.write('block 1.2.3.4', true, expires_in: 5.days)

Thoughts? I haven't tested this out. If you think the approach is good, we can update the docs.

Edit
Meant Rails.cache.fetch("block #{req.ip}").present? instead of Rails.cache.fetch("block #{req.ip}").blank?

@zmillman
Copy link
Contributor

In this block, blank? should be present?

Rack::Attack.blacklist('block <ip>') do |req|
  # if variable `block <ip>` exists in cache store, then we'll block the request
  Rails.cache.fetch("block #{req.ip}").blank?
end

And yep, this sounds like a reasonable way to manage a blacklist set by admins.

We could make an "Advanced Configuration" page in the project wiki to record these sorts of advanced techniques. We can link to that page from the README and "Example Configuration" to keep the README simple :)

Some other possible techniques for inclusion:

@zmillman
Copy link
Contributor

Also, if you're using a redis instance as your caching store, I believe you can use sets as values which would be an easier data structure to manage (otherwise how would you list the currently blacklisted IPs?)

@pisaacs
Copy link
Contributor Author

pisaacs commented Jan 29, 2015

Ahh, yes, I meant .present? instead of .blank?.

I like the idea of an "Advanced Configuration" page on the wiki...

@zmillman
Copy link
Contributor

@pisaacs
Copy link
Contributor Author

pisaacs commented Jan 30, 2015

👍 pure awesomeness. Thanks @zmillman!

@ktheory
Copy link
Collaborator

ktheory commented Feb 2, 2015

👏 Thanks @zmillman

@zmillman
Copy link
Contributor

zmillman commented Feb 2, 2015

Any time 😺

I think this can be closed now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants