这项任务是从米老师(米新江的博客)那里接手的。目的是给考试系统加上限制,在局域网内,防止同学从考试以外的地点登录。
过滤IP听起来比较容易,最终的效果就是验证一下IP,再决定是否有权限访问考试系统。但是要做的好就不那么容易了。接下来总结一下开发历程。
一、工程根基:数据库设计。
设计工程首先要从需求开始,需求出界面,界面出数据库。由于需求比较简单,我直接设计了数据库。
设计数据库的时候,考虑到IP过滤相当于防火墙,和手机上来电防火墙很相似,顺便取其精华了。在IP过滤中,加上规则功能,有三个预定义的规则:不使用、只拦截黑名单、只允许白名单。经过数次的设计改进,最终数据库结构如下:
![](https://img-my.csdn.net/uploads/201207/15/1342314271_8189.png)
简要说明一下设计思路:
当前规则表用来存放正在使用的规则,根据规则不同,进行不同的验证,读不同的表(黑名单表或者白名单表)
黑名单表、白名单表用来存放被禁止的IP、被允许的IP,仅仅放一个IP。同时支持IP段过滤,比如192.167.25.*。
IP-MAC对应信息表相当于信息库,当某个IP通过了黑白名单的验证,还要检查IP和MAC是否对应,因为很可能有人修改了IP来伪造,但这时IP和MAC就不再对应。
最后说明一下,一般要IP和MAC同时验证,如果只验证IP,太不安全,局域网内非常容易伪造。如果是外网,只验证IP就够了,外网的IP是唯一的。
二、代码工之路:尝试Web获取访问者IP、MAC。
在没有查阅相应技术之前,就隐隐感觉到这是一项艰巨的任务,因为MAC信息非常敏感。果然,经过调查,发现在Web端获取访问者的IP很容易,但是获取MAC就几乎是幻想,因为它太敏感了。
获取客户端MAC共有三种方法(只做概述):
l 通过ActiveX控件获取。缺点:只兼容IE浏览器,而且要把IE浏览器的安全性设置的很低,先别说用户是否同意,微软第一个不同意,疯狂的弹出安全警告。优点:速度快,结果准确可靠,内网、外网通用。
l 通过调用WindowsAPI基于ARP发包原理获取。缺点:只能在局域网内使用,外网无效。就算是局域网,网段还要一样,否则获取不到。优点:速度快,与浏览器无关,兼容性好。
l 通过调用CMD命令获取。缺点:速度及其慢,慢的像网页假死一样,而且结果不太可靠。优点:浏览器无关,兼容性好,而且内网、外网均可以使用。
说明一下,以上所有方法都是针对javascript说的,因为只有它是运行在客户端的。可以看出,以上每种方法的缺点都是致命的,经过分析思考,最终放弃了使用Web获取访问者的IP信息。
三、代码工之路:用客户端获取访问者IP、MAC。
通过征求米老师的意见,最终决定用客户端获取访问者IP、MAC。也就是说,用户想使用考试系统,必须先下载安装客户端。这样设计一来可以很方便的获取访问者的IP和MAC,二来可以让我们更加主动,能更好的控制用户。
核心问题:
这样做又引出一个新问题:安全问题。由于信息是由客户端获取,然后以参数的形式传递给Web网站,这样很可能被手动伪造。
首先想到的解决方案是对传递的参数进行加密,加密以后由于外人不知道加密算法,无法对参数进行修改、构造。
本来以为这样就可以了,过了几天,才突然意识到这样是不行的。假如A电脑允许访问网站,而B电脑不允许访问,那么A电脑上的客户端构造的参数是一个有效的参数,B电脑上的客户端构造的参数是无效参数。如果有人截获了A电脑上的有效参数,手动复制到B电脑上,那么B电脑凭借有效参数可以成功登入系统,我们完全不知道被欺骗了。以上的参数,都是经过加密的,无论怎么加密,都是徒劳的。
这个问题的中心是如何区分传递给Web网站的参数是客户端构造的,还是手动伪造的。答案是:无法区分!
既然无法区分,可以换另外一个角度。受到网盘下载地址的启发,可以给客户端构造的参数加上一个时效。在客户端生成参数时,加入一个有效期,假设是2秒,Web网站接受参数时,判断是否过期。参数是加密的,因此外界无法修改参数有效期,除非他知道加密算法。
这样一来,手动伪造几乎不可能,因为参数的有效期仅仅2秒,参数构造、传递、接受、有效期判断等过程基本上就把2秒消耗的差不多了,即使是复制到别处,那时候早就失效了。
Web端职责:
为了使程序尽量灵活,Web端有如下职责:
l 提供规则、黑名单、白名单管理页面,也就是整个IP过滤系统的后台控制。
l 提供出错页面。诸如:未安装客户端、禁止该IP访问、参数异常等错误提示,灵活的显示在出错页面上,并且根据错误类型不同,来显示或隐藏客户端下载提示。
l 提供IP扫描接口。受到深信服网络监控的启发,提供扫描模式,只要电脑安装了客户端,即可向客户端发送命令,让客户端访问扫描接口,自动添加电脑IP-MAC对应信息到数据库中,如果存在,则修改,不存在则添加,无需手动干预。
l 提供服务器时间接口。客户端构造参数的有效期,必须依赖于服务器时间。
l 提供客户端参数接口。客户端几乎所有的参数都是从服务器获取的,这样可以更加灵活的控制客户端,以后有什么改动,完全不用修改客户端,达到一次编译,永久运行。
客户端职责:
l 从服务器获取配置信息。
l 监视浏览器网址。
l 获取访问者IP、MAC,构造参数。
简单的说,客户端就是按照服务器的意愿办事。
至此,一个IP过滤功能就完成了。这里总结的仅仅是理论,代码就不贴了。希望大家多多和我交流,互相促进。
最后感谢米老师的大爱!