在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
摘要 通过分析 windoze 下 Web 认证过程,提出在 Linux 中用*脚本*实现通过 Web 认证方式上网的方法 问题由来 近来,随着宽带入户,越来越多的 ISP 采用 Web 认证这种接入认证技术。Web 认证从用户的角度看,是指用户在浏览器中通过 Web 页面输入用户名和密码的认证过程。多数 ISP 号称无需客户端软件,实际情况却是:Windoze 下用户可以顺利通过 Web 认证上网,但 Linux 用户却没有这么幸运。 分析原因 什么原因呢?解决问题还需从分析认证页面入手,下面的分析主要针对我这里的情况。在 Mozilla 中打开认证页面后,没有显示任何内容。仔细分析认证页面,发现认证页面采用 JavaScripts 编写,并且是针对 IE 编制的。IE 并未完全按照标准使用 JavaScripts。IE 对 JavaScripts 做了一些扩充,主要有以下几项: * .cab files for download of binaries; 详情请参阅 http://www.stopbadtherapy.com/standards.shtml IE 对 JavaScripts 的这些扩充,Mozilla 是不支持的,实际上 Mozilla 对标准 JavaScripts 的支持比 IE 好。所以,这些有 IE 特点的认证页面 Mozilla 等浏览器自然无法通过了。 解决方法 好了,问题就在这些 Web 页面使用 IE 方言的 JavaScripts 上,有几种解决方法: 1。使用 Linux 下 IE 兼容的浏览器,有吗?谁知道请告诉我。 最理想的方法四,可是我等不急,也不一定能等到,也许你比我幸运。我采取第三种方法,对于方法三,你一定会问:认证页面在 Web Server 上,我无权修改,行不通。确实如此,这里有个变通的办法:下载认证页面,按照 JavaScripts 标准修改并保存在本地,每次上网前用本地经过修改的 Web 认证页面而非 Web Server 的认证页面就可以了。具体修改方法,参照 http://www.stopbadtherapy.com/standards.shtml 中的对照表,找出认证页面使用 IE 方言的 JavaScritps,根据对照表提供的修改建议对你的认证页面作出相应修改。对于使用.cab 的认证页面,情况就比较复杂。需要分析这个.cab 在你的 JavaScripts 中的用法,判断它的功能,我这里是用它获得本地 IP。所以,我在本地执行脚本获得 IP 来模拟这个功能。似乎.cab 多与 IP 有关。 一个例子 * 以我这里为例,我的使用环境: ISP:铁通 ADSL 认证方式:Web 认证 ISP 的接入服务器:华为 Quidway MA5200E/F (具体型号不能完全确定) Linux:GENTOO 1.4 rc-3 Browser: Mozilla 1.4a/Phoenix 0.5 * 在 Linux 下用 mozilla (一定要用非 IE 浏览器获得认证页面,这话有点多余,但有的用户是在 Window$ 下调试的),访问 ISP 的 WEB 认证页面时,浏览器中没有显示任何内容,根本无法输入帐号和密码,更谈不上通过认证。这难不倒咱 linuxer, 查看认证页面(/index.jsp)源码,发现这两段 javascript: 复制代码 代码如下:id="PortalClient" codebase=http://61.61.61.61:80/PortalAX.cab#version=1,0,1,8 ... var clientIp = PortalClient.localIP; var languagetype = 0; if ((clientIp=="") (clientIp==null)) { window.parent.location.href="/ipError.jsp"; } else { window.parent.location.href="/queryPort.jsp?ip="+clientIp+"newbl="+languagetype; } 可以看出它用 PortalClient 获得本地的 IP,如果成功,转到 http://你的WEB认证页面/queryPort.jsp?ip=你当前的IP 。而 Mozilla 不支持它获取 IP (PortalClient,是针对IE的,唉,这个程序编得太短视),看来问题出在这里。既然如此,我们可以手工加上自己的 IP(这个 IP 是与 ADSL 相联的网卡从 ISP 的 DHCP 服务器获得的地址)。在 Mozilla 地址栏中输入: http://61.61.61.61/queryPort.jsp?ip=192.168.0.2 --------^^^^^^^^^^^------------------^^^^^^^^^^^ --------你的ISP认证服务器 ------------- 你当前的IP 嗒嗒,登录页面出来啦! 赶快输入帐号,密码,按登录按钮(期待中。。。)。 viva!!! ISP 的首页终于被揪出来啦,在终端中 ping www.gnu.org ,ping 通,没问题。 * 至此,在 Linux 下 web 认证方式已经完成。方法很简单,每次上网时,在 mozilla 的地址栏中输入: http://你的ISP认证服务器地址/queryPort.jsp?ip=你当前的IP 登录页面出来后,和 IE 中的操作过程完全一样。 * 当然你可以把这些步骤写成一个脚本,以后简单执行脚本就可以了。 复制代码 代码如下:#!/bin/bash dhcpcd eth1 phoenix http://61.61.61.61/queryPort.jsp?ip=`ifconfig eth1 grep inet sed 's/^ *//' sed 's/ /:/g' cut -f3 -d:` & 说明: eth1 是与 ADSL 联的网卡名,根据你的实际情况填写。 另外一种方法 如果你对方法 3 不满意,可以用方法 5,继续分析 web 认证的原理,编写自己的认证程序。其实搞清原理后,实现的方法更简单,更灵活,而且在 ISP 要求客户端定时发送 keep-alive 包的情况下,也只能采取这种方法。我是这样做的: 1。用网络分析软件(如:ethereal),抓取正常认证过程的通讯包; 在 windoze 下,用 ethereal 抓包。注意抓包时,除了 IE 不要启动其它产生网络通讯的程序,以免产生干扰数据;保存这些通讯包。 2。分析所抓包的内容; 只要看一眼 web 认证过程产生的通讯包,你就明白我为什么说这种方法更简单了。简单讲,web 认证方式实际是客户端用 http 协议向 ISP 发送用户名、密码和 IP 等内容的过程。客户端读取认证页面;将填写好认证页面表格发送到 ISP 的认证服务器。过程就这么简单。 3。编写生成这些包的程序; 用任意一个支持 http 协议的语言或工具,编写向认证服务器 POST 认证页面中 form 的程序即可,甚至读取认证页面都不需要。我用 curl 和 python 各做了一个。如果你略微了解 http 协议,只要找到认证页面中向服务器 POST 用户名、密码等数据的 form,然后转换为你采用语言的语法格式就可以了,根本不需要分析认证页面中繁杂的 Javascripts。对计时窗发出的 keep-alive 包也采用同样的方法。 例子: * 认证页面中的 复制代码 代码如下:<form id="mainform" name="mainform" method="post" action="http://61.61.61.61:80/secu/webLogin.jsp"> <input type="hidden" name="connectname" value=""> <input value="-1" name="connecttype" type="hidden"> <input value="0" name="consumeright" type="hidden"> <input value="0" name="separatecard" type="hidden"> <inputvalue="192.168.000.000" name="localip" type="hidden"> <input value="0" name="IsIndex" type="hidden"> 用户名:<input name="username"> 密 码:<inputname="password" type="password"> <input name="lianjiewangluo" type="submit"> * 用 curl 写的一个脚本: bash/shell Code复制内容到剪贴板
说明:curl 是一个用 url 语法传输文件的命令行程序,支持 http,ftp 等协议,类似 wget。 复制代码 代码如下:#!/usr/bin/env python import httplib, urllib params = urllib.urlencode({'connectname': '', 'connecttype': -1, 'consumeright': 0, 'separatecard': 0, 'localip': '192.168.000.000', 'IsIndex': 0, 'username': 88888888, 'password': 8888}) headers = {'Accept': 'text/html', 'User-Agent': 'Mozilla', 'Content-Type': 'application/x-www-form-urlencoded'} server = '61.61.61.61' path = '/secu/webLogin.jsp' conn = httplib.HTTPConnection(server) conn.request("POST", path, params, headers) r1 = conn.getresponse() print r1.status, r1.reason data1 = r1.read() print data1 conn.close() 产生 keep-alive 包的程序 复制代码 代码如下:#!/usr/bin/env python import httplib def testHttplib(server, path): req = httplib.HTTP(server) req.putrequest('GET', path) req.putheader('Accept', 'text/html') req.putheader('User-Agent', 'Mozilla') req.endheaders() ec, em, h = req.getreply() fd = req.getfile() return fd.read(), (ec, em) myip = '192.168.000.000' server = '61.61.61.61' path = '/ClientProcess.jsp?MsgType=1&ISNNO=1001&LocalIP=' + myip # print 'testing "%s%s"' % (server, path) dataHttplib, result = testHttplib(server, path) # print "data length (httplib):", len(dataHttplib), result # print dataHttplib 说明: python 是一个功能强大的脚本语言,与 Perl 类似。正如你看到的,它和 curl 完成同样的工作,但更优雅。这里要注意别漏掉'User-Agent' 和 'Content-Type' 内容,我在这个上面浪费了不少时间。其它与 curl 的说明一样。 最后,将下面内容加到 crontab 中,保证每 5 分钟向 ISP 发送一个 keep-alive 包,模拟计时窗功能。 */5 * * * * /home/zest/keepalive.py 方法 5 的总结: * 方法简单,思路清晰 * 适应性广 * 脚本实现,脱离浏览器和图形环境,更适于需要自动登录的环境(例如,自建的服务器) 一些成功的例子: * whz81 朋友 南京电信 * zest 就是我 西安铁通 * 你的位置 欢迎你与大家共同分享你的成功经验 相关的链接: * 从特有的 DOMs 和 Markup 转移到 W3C 标准。http://www.stopbadtherapy.com/standards.shtml 后记 这篇小文是我在解决 Linux 下 Web 认证方式上网问题时的一些文字总结。由于本人的能力有限以及环境的限制,文中的内容肯定相当粗浅,会存在一些错误,希望各位能够批评指正,共同完善这篇文字。这里,我希望尽量说明解决问题的思路和方法,而不是只给出结果。授人以鱼,不如授人以渔。另外,这篇文字是两个时期完成的,方法 3 是在四月完成的。最近,七月,我的 ISP 改变了 Web 认证页面,所以产生了方法 5。为了保持延续性,没有删除方法 3,所以比较罗嗦。 最后,欢迎大家分享自己的成功经验。 |
请发表评论