碰到一个豁免内网地址的需求,策略要求仅对公网地址做安全判定,于是写个正则,正好也能水一篇。
内网地址范围如下:
- 10.0.0.0/8 (即 10.0.0.0 – 10.255.255.255)
- 172.16.0.0/12 (即 172.16.0.0 – 172.31.255.255)
- 192.168.0.0/16 (即 192.168.0.0 – 192.168.255.255)
以上地址段再加上loopback地址段 127.0.0.0/8 (即127.0.0.0 – 127.255.255.255),就是非公网地址的范围,寻找一个正则匹配以上所有地址段,然后对匹配结果取反即为公网IP。
ipv4地址形如 a.b.c.d,其中:a的取值范围为1-255(其中224-239, 240-255在正常情况下不会碰到,既可以按1-255来理解,也可以按1-223来理解);b, c, d的取值范围为0-255。
上述网段有的只需要判断a,有的需要同时判断a和b,但无一例外,后面都有一个分割用的句点,所以正则表达式中可以借助句点来限定结束位置。
先按网段分开看各个网段的匹配正则:
- 10.0.0.0/8的匹配:^10\.
- 127.0.0.0/8的匹配:^127\.
- 172.16.0.0/12的匹配:^172\.(1[6-9]|2\d|3[01])\.
- 192.168.0.0/16的匹配:^192\.168\.
最终合并起来就是 ^(10|127|172\.(1[6-9]|2\d|3[01])|192\.168|)\.
这个正则并不会验证所匹配的内容是否为IP地址,因为在使用时一般会先获取到客户端IP,然后才对这个IP进行豁免判定,所以并不需要重复确认一下目标是否为IP。