IP白名单校验之包含网络地址和广播地址
her0kings1ey
很久没有打字总结了,趁着今天脑抽了(大雾=='|),刚好总结下最近遇到的一个问题,其实问题本身完全没有复杂性,记录下来主要是总结出一种解决问题的思路吧。那么,我们开始吧。
问题背景
在最近的开发工作中,有一个地方使用了IP白名单的校验,即在白名单范围内的ip才能够对某些资源进行访问或操作。
但是作为一个公司或者团队来说,访问ip不可能只有一个,如果一个个ip来进行记录和配置的话,往往过于麻烦,业界一般都是采用ip段的方式进行配置,即提供一个ip子网段,如:192.168.1.0/24 来表示一个网段的ip。
在ip白名单配置中只需要配置一个网段,认为该网段下面的ip都是合法的ip。
那么问题来了,有些ip白名单的实现里面,认为该网段的网络地址和广播地址不属于该网段的可用地址。比如commons-net下面的SubNetUtils实现,默认的isInRange方法就不包含网络地址和广播地址。
但是呢,在某种情况下,是可能使用网络地址和广播地址作为ip地址的(毕竟这两个地址还是属于那个网段的),那么,怎么办呢?
解决思路
讲真,这是个特别容易解决的问题,主要看你愿不愿意解决。
在解决问题前,先提供一个原有的通过SubNetUtils的ip白名单校验实现:
通过new 一个SubNetUtils,构造参数是子网段字符串,如:192.168.1.0/24
然后getSubInfo().isInRange(xxx)的方式来获取ip是否属于该网段。
简单的实现代码如下
public static void main(String [] args){
SubnetUtils utils = new SubnetUtils("192.168.1.0/24");
System.out.println(utils.getInfo().isInRange("192.168.1.0"));
}
刚刚说到了,这个默认是不包含网络地址和广播地址的,所以会打印false。
怎么解决呢?
一种直接的方式,把网络地址和广播地址单独作为一个ip添加到配置文件中。这样的方式虽然能解决问题,但显然没有道理,不符合我们工程师解决问题的方式。
于是,只要稍微动动脑筋,我们会猜测,这种普遍的需求,作为一个设计良好的底层包,应该会提供相应的实现。
于是我们查看相应的代码。
我们发现有一个属性:
/** Whether the broadcast/network address are included in host count */
private boolean inclusiveHostCount = false;
我们尝试设置这个属性为true,ok,问题bingo!
很多问题只要尝试看下源码实现,其实就立马解决了。从使用这个类实现到解决这个问题,五分钟都不用。
那么延伸一下,如果没有这个属性,我们可以怎么样呢?
一种思路:
通过子网段算出网络地址和广播地址,在代码里isInRange后面手段比较一下即可。
计算的方法也很简单,网络地址就是网段,广播地址则是网络地址加上 232-x -1, x是掩码位数,也就是192.168.1.0/24的位数。
总结
基础知识和耐心真的很重要,今天在cat交流群上看到一个伸手党不用礼貌用语地问来问去,都想呵斥他了。搞技术还是不能太浮躁,自勉自勉。