This is a two part question. I\'m needing to restrict a rails site that I\'m throwing on development server to only a few IP addresses, so the public can\'t access it. (Basi
what about using NetAddr::CIDR?
and something like this?
class WhitelistConstraint
def initialize
@ips = []
@ips << NetAddr::CIDR.create('127.0.0.0/8')
@ips << NetAddr::CIDR.create('192.168.0.0/16')
end
def matches?(request)
valid = @ips.select {|cidr| cidr.contains?(request.remote_ip) }
!valid.empty?
end
end
MyProject::Application.routes.draw do
constraints WhitelistConstraint.new do
# all my routing stuff here
end
end
This way you can specify the blocks of IPs that should be whitelisted, and not have to worry about the partial matches?
>> require 'netaddr'
=> true
>> @ips = []
=> []
>> @ips << NetAddr::CIDR.create('127.0.0.0/8')
=> [127.0.0.08]
>> @ips << NetAddr::CIDR.create('192.168.0.0/16')
=> [127.0.0.08, 192.168.0.016]
>> @ips.select { |c| c.contains? '192.168.10.1' }
=> [192.168.0.016]
>> @ips.select { |c| c.contains? '192.169.10.1' }
=> []
I didn't know you could do this through routes, my approach would be to just have a before_filter
in the ApplicationController
and just have something that does:
before_filter :protect
def protect
@ips = ['127.0.0.1', '203.123.10.1'] #And so on ...]
if not @ips.include? request.remote_ip
# Check for your subnet stuff here, for example
# if not request.remote_ip.include?('127.0,0')
render :text => "You are unauthorized"
return
end
end
It is also possible to surround your route declaration with a scope like so:
scope :constraints => lambda{|req|%w(127.0.0.1).include? req.remote_addr} do
... your beautiful routes
end
Or simply use apache's .htaccess:
AllowOverride all
Allow from xxx.xxx.xxx.xxx Deny from all