linux访问web服务(在Linux下通过WEB认证方式上网)
摘要
通过分析 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;
* document.all;
* element.innerHTML;
...详情请参阅 http://www.stopbadtherapy.com/standards.shtml
IE 对 JavaScripts 的这些扩充 ,Mozilla 是不支持的,实际上 Mozilla 对标准 JavaScripts 的支持比 IE 好 。所以 ,这些有 IE 特点的认证页面 Mozilla 等浏览器自然无法通过了 。
从用户浏览器的角度看 ,Web 认证除了通过 Web 页面输入用户名和密码外,还需要通过 http 协议传送客户由 DHCP 获得的 IP 。有些 ISP 在用户登录到认证页面时 ,由浏览器自动下载 .cab 文件 ,然后执行该文件获得用户的 IP ,再传给 Web Server 。还有些 ISP 在用户通过认证后 ,会在客户端弹出一个计时窗 ,定时向 ISP 发送 keep-alive 包 。当然 ,Web 认证是一个比较新的方式 ,还没有形成标准 ,所以各提供商的方法也不尽相同 ,所谓各村有各村的高招 ,你那里的方法就很有可能与我的不同 ,但道理应该是一样的。根据以上的分析 ,可以看出 Linux 用户自然不可能用非 IE 兼容的浏览器直接通过登录 Web 认证界面上网啦 。解决方法
好了,问题就在这些 Web 页面使用 IE 方言的 JavaScripts 上 ,有几种解决方法:
1 。使用 Linux 下 IE 兼容的浏览器 ,有吗?谁知道请告诉我。
2 。使用 wine + IE 的方法,有成功的吗?大家共同分享 。
3 。如果将这些鸟语改为普通话 ,我们就可以用 Mozilla 等非 IE 浏览器通过 Web 认证方式上网了 。
4 。要求 ISP 提供支持 W3C 标准的认证页面 。
5 。分析 web 认证的原理 ,编写认证程序 。最理想的方法四 ,可是我等不急 ,也不一定能等到 ,也许你比我幸运 。我采取第三种方法 ,对于方法三 ,你一定会问:认证页面在 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="https://www.jb51.net/ipError.jsp";
} else {
window.parent.location.href="https://www.jb51.net/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 联的网卡名 ,根据你的实际情况填写。
61.61.61.61 是我这 ISP 的认证地址 。
后面一段是获得 eth1 的 ip 地址 。
注意!一定要用非 IE 浏览器获得调试认证页面 ,因为 IE 可以执行认证页面的 JavaScripts,有些认证过程实际上是执行多个页面完成的 ,IE 最后停留的页面不一定是起始的认证页面 ,你有可能漏掉前面的重要信息 ,我这里就是这种情况。另外一种方法
如果你对方法 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 包也采用同样的方法 。
例子:
* 认证页面中的
用户名:
密 码:
<input name="lianjiewangluo" type="submit">* 用 curl 写的一个脚本:
说明:curl 是一个用 url 语法传输文件的命令行程序 ,支持 http,ftp 等协议 ,类似 wget。
上例中 ,curl 的命令行参数 -A 指明客户端的类型 ,这是服务器为了安全 ,需要指明 。Mozilla 或 IE 都可以 ,我更愿意用 Mozilla 。 -d 是必需的 ,表示用 POST 方法 。-d 后的内容就是用户名 、密码 IP 地址等信息,根据你的认证页面中 form 的 input 项目填写 ,内容与其保持一致 ,参数间用 & 分开 。后面是认证页面的地址 。执行这个脚本后,返回 200 OK ,表示认证成功 ,否则 ,仔细检查 -d 后的参数是否正常 ,地址是否正确 。
* 用 python 写的认证程序:
#!/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,所以比较罗嗦 。
最后 ,欢迎大家分享自己的成功经验 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!