Skip to main content

苏州大学校园网认证脚本

·1338 words·3 mins
Work Web
葛世杰
Author
葛世杰
Student @ Soochow
Table of Contents

苏大校园网の小妙招 - 四叶草の博客 提供的脚本基础上进行修改调整,详细的原理和实现可点击 🔗 进一步了解

一、起因
#

众所周知,高校的校园网都需要进行认证才能访问网络,每次网络掉线再认证就比较麻烦。于是在网上看看有没有高手研究过相关的内容。果然有前人指路,但是博主写的脚本是网关设备直连校园网,与我要实现的情况不同。

办公室和机房的服务器网关的 ip 地址是上级路由器的 WAN口地址,而非本机 ip 地址。只有网关 ip地址和账户密码绑定才能正确访问外网,于是在原来的脚本基础上稍作修改。

二、需求实现
#

办公室有台群晖 NAS,机房服务器也是 Linux,将 Python 脚本挂载到后台每小时运行一次。简单说一下原理:校园网页面登录账号认证会发送链接请求,我们直接用脚本模拟网页请求实现网关认证。

关键是如何获取上级路由器 WAN 口的地址。要实现和路由器通信获取 WAN 口地址比较麻烦,也不能使用第三方工具获得公网 ip 地址作为网关地址。不过还好校园网认证页面会告诉你的网关地址是多少,可以直接使用 requests 模块抓取网页内容解析网关 ip 。

三、也可以直接看这
#

将脚本内容存为 auth_web.py,在终端中运行 python ./auth_web.py (已经配置好 Python 环境)不要忘记修改认证 ID ,PASSWORD 和 ISP(校园网、中国移动、中国联通、中国电信)

脚本内容:

import os
import urllib.request
import json
import requests
import re

def get_v4ip_from_webpage():
    url = "http://a.suda.edu.cn"
    try:
        # 发送HTTP GET请求
        response = requests.get(url, timeout=5)
        response.raise_for_status()  # 检查请求是否成功

        # 使用正则表达式查找v4ip的值
        match = re.search(r"v46ip\s*=\s*'([\d\.]+)'", response.text)
        if match:
            return match.group(1)
        else:
            print("未在网页中找到v4ip信息")
            return None
    except requests.exceptions.RequestException as e:
        print(f"请求网页时出错: {e}")
        return None

def check_network():
    # Ping百度,发送2个包,超时2秒
    response = os.system("ping -c 2 -W 2 www.baidu.com > /dev/null 2>&1")
    return response == 0  # 返回True如果能ping通

def campus_auth():
    # 用户配置
    user_name = "id"  # 替换为你的账号
    user_password = "password"  # 替换为你的密码
    ISP = ""  # 运营商:校园网(可选 @zgyd 中国移动 @cucc 联通、@ctc 电信)

    # 直接使用固定IP 10.9.1.3,不检测本机IP
    login_url = f"http://10.9.1.3:801/eportal/?c=Portal&a=login&callback=dr1003&login_method=1&user_account=%2C0%2C{user_name}{ISP}&user_password={user_password}&wlan_user_ip={target_ip}&wlan_user_ipv6=&wlan_user_mac=000000000000&wlan_ac_ip=&wlan_ac_name=&jsVersion=3.3.3"

    # 备用服务器(可选)
    backup_url = login_url.replace("10.9.1.3", "10.9.1.4")  # 替换为备用IP

    print("尝试登录,URL:", login_url)

    try:
        response = urllib.request.urlopen(login_url)
    except urllib.error.URLError:
        print("主服务器连接失败,尝试备用服务器...")
        try:
            response = urllib.request.urlopen(backup_url)
        except urllib.error.URLError:
            print("网络连接失败!请检查网络。")
            return False

    # 解析返回结果
    str_resp = response.read().decode('utf-8')
    str_json = str_resp[7:-1]  # 去除回调函数名(dr1003(...))
    data = json.loads(str_json)

    # 判断登录结果
    if data.get('result') == "1" and data.get('msg') == "\u8ba4\u8bc1\u6210\u529f":  # "认证成功"
        print("✅ 认证成功!")
        return True
    elif data.get('ret_code') == 2:
        print("⚠️ 已经登录!")
        return True
    elif data.get('ret_code') == 1:
        if data.get('msg') == "QXV0aGVudGljYXRpb24gZmFpbA==":  # "Authentication fail" (Base64)
            print("❌ 运营商错误!")
        elif data.get('msg') == "bGRhcCBhdXRoIGVycm9y":  # "ldap auth error" (Base64)
            print("❌ 密码错误!")
        elif data.get('msg') == "dXNlcmlkIGVycm9yMQ==":  # "userid error1" (Base64)
            print("❌ 用户名错误!")
        else:
            print("❌ 登录失败,未知错误:", data)
    else:
        print("❌ 未知响应:", data)
    return False

if __name__ == "__main__":
    if not check_network():
        print("网络不通,尝试校园网认证...")
        # 获取v4ip并赋值给target_ip
        target_ip = get_v4ip_from_webpage()
        if target_ip:
            print(f"成功获取v4ip: {target_ip}")
        else:
            print("未能获取v4ip")
        campus_auth()
    else:
        print("网络正常,无需认证")