RubyRedGrapefruit
RubyRedGrapefruit

Reputation: 12214

How can I prevent access by a certain IP in Rails?

I would like to shut down people running screen scrapers against our site and mining the data. Or at least slow them down big time.

My idea is to write every IP address into a memory object and count how many requests they make per minute, then put them in some "no access" list if they exceed some number that I set.

I'm just looking for some community validation on whether this is a sound approach for a Rails application. Thanks for any help you can offer.

Upvotes: 1

Views: 271

Answers (2)

RubyRedGrapefruit
RubyRedGrapefruit

Reputation: 12214

I don't know guys, I came up with a pretty nice way to do this in the app. I just want to punish bad behavior in one app anyway. What I ended up doing was:

def log_ip
  # Initialize
  if IPLOG.include?(request.ip)
    IPLOG[request.ip][:count]+=1
  else
    IPLOG[request.ip] = {:time => Time.now, :count => 1}
  end
  # Reset the time if necessary
  IPLOG[request.ip][:time] = Time.now if IPLOG[request.ip][:time] < 1.minute.ago
  if IPLOG[request.ip][:count] > REQUESTS_PER_MINUTE_UNTIL_BLACKLIST
    Blacklist.create(:ip_address => request.ip, :count => IPLOG[request.ip][:count])
  end
  if Blacklist.where(:ip_address => request.ip).first
    IPLOG.delete(request.ip)
    redirect_to blocked_path
  end
end

I'm sure I can tighten this up so I'm not doing the db hit every time, but it appears to be working pretty well. It caught the GoogleBot last night. Plus, there's opportunity for whitelisting IP addresses in case a bunch of people are coming in through a known proxy.

Upvotes: 0

plang
plang

Reputation: 5646

I'm not sure it's a good idea to protect your site from these IPs at the application level. I would personally investigate if that would be possible to do that at the network level, for example in your firewall / router. If you have a Cisco router, check out the "rate-limit" command.

Upvotes: 3

Related Questions