IP白名單校驗之包含網(wǎng)絡地址和廣播地址
her0kings1ey
很久沒有打字總結了,趁著今天腦抽了(大霧=='|)伐憾,剛好總結下最近遇到的一個問題篙螟,其實問題本身完全沒有復雜性芹扭,記錄下來主要是總結出一種解決問題的思路吧。那么脓匿,我們開始吧舌菜。
問題背景
在最近的開發(fā)工作中,有一個地方使用了IP白名單的校驗亦镶,即在白名單范圍內(nèi)的ip才能夠對某些資源進行訪問或操作日月。
但是作為一個公司或者團隊來說,訪問ip不可能只有一個缤骨,如果一個個ip來進行記錄和配置的話爱咬,往往過于麻煩,業(yè)界一般都是采用ip段的方式進行配置绊起,即提供一個ip子網(wǎng)段精拟,如:192.168.1.0/24 來表示一個網(wǎng)段的ip。
在ip白名單配置中只需要配置一個網(wǎng)段虱歪,認為該網(wǎng)段下面的ip都是合法的ip蜂绎。
那么問題來了,有些ip白名單的實現(xiàn)里面笋鄙,認為該網(wǎng)段的網(wǎng)絡地址和廣播地址不屬于該網(wǎng)段的可用地址师枣。比如commons-net下面的SubNetUtils實現(xiàn),默認的isInRange方法就不包含網(wǎng)絡地址和廣播地址萧落。
但是呢践美,在某種情況下洗贰,是可能使用網(wǎng)絡地址和廣播地址作為ip地址的(畢竟這兩個地址還是屬于那個網(wǎng)段的),那么陨倡,怎么辦呢敛滋?
解決思路
講真,這是個特別容易解決的問題兴革,主要看你愿不愿意解決犁柜。
在解決問題前顶掉,先提供一個原有的通過SubNetUtils的ip白名單校驗實現(xiàn):
通過new 一個SubNetUtils就轧,構造參數(shù)是子網(wǎng)段字符串刽锤,如:192.168.1.0/24
然后getSubInfo().isInRange(xxx)的方式來獲取ip是否屬于該網(wǎng)段蹋盆。
簡單的實現(xiàn)代碼如下
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"));
}
剛剛說到了宿礁,這個默認是不包含網(wǎng)絡地址和廣播地址的墩衙,所以會打印false闸氮。
怎么解決呢泌霍?
一種直接的方式货抄,把網(wǎng)絡地址和廣播地址單獨作為一個ip添加到配置文件中。這樣的方式雖然能解決問題朱转,但顯然沒有道理蟹地,不符合我們工程師解決問題的方式。
于是藤为,只要稍微動動腦筋怪与,我們會猜測,這種普遍的需求缅疟,作為一個設計良好的底層包分别,應該會提供相應的實現(xiàn)。
于是我們查看相應的代碼存淫。
我們發(fā)現(xiàn)有一個屬性:
/** Whether the broadcast/network address are included in host count */
private boolean inclusiveHostCount = false;
我們嘗試設置這個屬性為true耘斩,ok,問題bingo桅咆!
很多問題只要嘗試看下源碼實現(xiàn)括授,其實就立馬解決了。從使用這個類實現(xiàn)到解決這個問題岩饼,五分鐘都不用荚虚。
那么延伸一下,如果沒有這個屬性籍茧,我們可以怎么樣呢版述?
一種思路:
通過子網(wǎng)段算出網(wǎng)絡地址和廣播地址,在代碼里isInRange后面手段比較一下即可寞冯。
計算的方法也很簡單院水,網(wǎng)絡地址就是網(wǎng)段腊徙,廣播地址則是網(wǎng)絡地址加上 232-x -1, x是掩碼位數(shù),也就是192.168.1.0/24的位數(shù)檬某。
總結
基礎知識和耐心真的很重要撬腾,今天在cat交流群上看到一個伸手黨不用禮貌用語地問來問去,都想呵斥他了恢恼。搞技術還是不能太浮躁民傻,自勉自勉。