我一直试图找出阻止访问我们的Rails 3应用程序的正确方法,除了少量的IP地址和几个IP子网。
在寻找方法时,我发现了question/answer。建议的代码如下:
应用程序控制器
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
这是有效的,所以我将其改为重定向到静态页面,而不仅仅是短信。
我想做的是允许从与Rails应用程序服务器相同的子网上的本地IP进行访问。子网只是192.168.1.0/24
。
将子网添加到接受的IP的最简单/最简洁的方法是什么?
答案 0 :(得分:4)
要测试给定的IP地址foo
是否在地址net
和掩码mask
指定的网络中,您可以将掩码应用于网络地址和测试地址,并查看结果是否相等:foo & mask == net & mask
。您必须先将IP地址和掩码转换为整数。 /24
的掩码是24位设置为1
,后跟8位设置为0
- 0xFFFFFF00
或255.255.255.0
的点分四位表示法。
before_filter :protect
def protect
@ips = ['127.0.0.1', '192.168.1.0/24'] #And so on ...]
allowed = false
# Convert remote IP to an integer.
bremote_ip = request.remote_ip.split('.').map(&:to_i).pack('C*').unpack('N').first
@ips.each do |ipstring|
ip, mask = ipstring.split '/'
# Convert tested IP to an integer.
bip = ip.split('.').map(&:to_i).pack('C*').unpack('N').first
# Convert mask to an integer, and assume /32 if not specified.
mask = mask ? mask.to_i : 32
bmask = ((1 << mask) - 1) << (32 - mask)
if bip & bmask == bremote_ip & bmask
allowed = true
break
end
end
if not allowed
render :text => "You are unauthorized"
return
end
end