Linux实现惠尔顿上网认证客户端

最近公司由于某些特殊原因,需要上一套惠尔顿的上网行为管理系统,局域网内的所有设备在连接互联网时都需要通过惠尔顿上网认证客户端进行登录,或者需要管理员在上网行为管理中设置免监控。

惠尔顿官方只提供了 Windows 上的客户端进行用户登录,也可以访问网页版进行临时登录,效果如下:

惠尔顿上网认证系统网页版

不过 Linux 服务器设备就没法登录了,为此我写了个 Python 程序模拟惠尔顿的网页版客户端实现 Linux / macOS 等系统下的上网认证功能。

Python 程序

我编写的 wholeton-auth.py Python 程序可以通过 Pastebin 分享链接 下载,写的很简单粗糙,这里贴出来说明一下:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import socket
from datetime import datetime
from uuid import getnode
import urllib
try:
    import urllib2
except Exception:
    from urllib import request as urllib2
try:
    import Cookie as cookies
except Exception:
    from http import cookies
import websocket
import json

wholeton_host = '192.168.1.254'
wholeton_user = 'test'
wholeton_pass = '123456'
wholeton_ip = ''
wholeton_mac = ''
update_secs = 28800

def url_encode(obj):
    try:
        return urllib.urlencode(obj)
    except Exception:
        return urllib.parse.urlencode(obj)

def get_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except Exception:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

def get_mac():
    return ':'.join(("%012x" % getnode())[i:i+2] for i in range(0, 12, 2))

if not wholeton_ip:
    wholeton_ip = get_ip()

if not wholeton_mac:
    wholeton_mac = get_mac()

uri_keys = { 'id' : 0, 'url' : 'mail.126.com', 'user' : wholeton_ip, 'mac' : wholeton_mac }
uri_data = url_encode(uri_keys).replace('%3A', ':')

auth_data = url_encode({ 'param[UserName]' : wholeton_user, 'param[UserPswd]' : wholeton_pass, 'uri' : uri_data, 'force' : 0 })
# convert for python 3
if sys.version_info[0] == 3:
    auth_data = auth_data.encode('ascii')

ws = None
loop = True

try:
    while loop:
        resp = urllib2.urlopen('http://' + wholeton_host + '/user-login-auth?' + uri_data, timeout = 5, data = auth_data)

        # get session cookie
        cookie = cookies.SimpleCookie()
        cookie.load(resp.info()['Set-Cookie'])

        resp_data = resp.read()
        if resp_data:
            print('Login response:')
            print(resp_data)

        ws = websocket.WebSocket()
        ws.connect('ws://' + wholeton_host + '/go-ws/user-auth', cookie = 'fms_session=' + cookie.get('fms_session').value, origin = 'http://' + wholeton_host)

        dt_start = datetime.now()
        while ws:
            try:
                ws_data = ws.recv()
            except KeyboardInterrupt:
                loop = False
                break
            except:
                break

            if ws_data:
                dt_now = datetime.now()
                if (dt_now - dt_start).seconds >= update_secs:
                    break

                print(dt_now)
                print(ws_data)

                ws_obj = json.loads(ws_data)
                if ws_obj and ws_obj["type"] == "logged-out":
                    break

        if ws:
            ws.close()
        ws = None
except KeyboardInterrupt:
    pass

if ws:
    ws.close()

为了支持比较老的服务器系统,此 Python 程序同时支持 Python 2 和 Python 3,在 Python 2.6 和 Python 3.6 版本上做了测试。为了减少依赖,本程序基本都是用的 Python 自带的模块,并针对 Python 2 和 Python 3 进行了区分处理。

程序首先通过惠尔顿网页版的 HTTP 登录接口进行登录,登录成功之后获取会话信息,然后建立 WebSocket 连接,并保持 WebSocket 连接状态,如果关闭了连接上网认证功能就会自动失效。

由于本程序需要建立 WebSocket 连接,也不需要任何 WebSocket 服务器的功能,所以没有用各种功能齐全的 WebSocket 库,只额外使用了 websocket-client 这个非常简单的 WebSocket 客户端库。

另外最新 1.3.2 版本的 websocket-client 库只支持 Python 3.7 及以上版本,为了能给 Python 2.6 版本使用,本程序使用的是 websocket-client 老一点的 0.59.0 版本,websocket-client 0.59.0 版本支持 Python 2.6 以上或 Python 3.4 以上版本,而且只依赖 six 这个 Python 兼容库,同时 six 库也使用 1.13.0 版本以兼容 Python 2.6 版本。

可以使用 pip 命令先安装 six 1.13.0 版本和 websocket-client 0.59.0 版本:

~$ pip install six==1.13.0
~$ pip install websocket-client==0.59.0

上网认证使用

上面依赖的库安装好之后,首先需要修改 wholeton-auth.py Python 程序中的配置(上面已经高亮显示了):

wholeton_host = '192.168.1.254'
wholeton_user = 'test'
wholeton_pass = '123456'
wholeton_ip = ''
wholeton_mac = ''
update_secs = 28800

简单说明如下:

  • wholeton_host 指定惠尔顿上网行为管理系统 IP 地址;
  • wholeton_userwholeton_pass 指定上网行为管理的用户名和密码;
  • wholeton_ip 为本机 IP 地址,默认为空,程序会自动获取,也可以自行修改覆盖;
  • wholeton_mac 为本机上网网卡(也就是连接上网行为管理系统的网卡)的 MAC 地址,默认为空,程序也会自动获取(这里为了图省事使用的 uuid 库的 getnode 函数获取网卡 MAC 地址),也可以自行修改覆盖;
  • update_secs 指定登录多长时间之后就强制断开连接进行重新登录,单位为秒,默认为 28800 秒也就是 8 个小时。

因为我这边使用本程序测试发现惠尔顿的上网认证系统即使在保持 WebSocket 连接打开的情况下,大概 9 ~ 10 个小时之后也会无法上网,所以大家可以根据实际情况测试确认之后,修改程序里的 update_secs 重新登录时间。

修改完配置之后,使用起来就很简单了,根据 Python 版本在终端里运行 python2 wholeton-auth.py 或者 python3 wholeton-auth.py 就可以了,程序运行之后会在标准输出中显示上网认证服务器返回的响应数据。

最后本程序还是需要一直保持运行的,大家可以根据自己的需要通过 screen 或者服务等方式来实现后台运行哦。

2 条评论 在此博文.
  1. tpu:

    握手!我做过类似的,在win上,用vbs写了个脚本,每隔8小时自动重连,并隐藏那个小窗口。
    另外你发现没,他这个认证系统,没登录时也是可以ping的。于是可以用udp2raw开个icmp通道,偷偷的上网

  2. Uranus Zhou:

    是呢,原来就发现不登录也可以 ping,不过公司里主要是因为某些特殊业务要求,必须上这套系统,管理员也从来不审计,不然全体人员都想把这个关了。

    现在写的 Python 的主要还是方便 Linux、Mac 系统上也能上网用起来。

发表评论





*