步骤/目录:
1.需求分析
2.解决方案
    (1)电脑wifi共享
    (2)手机热点法
    (3)路由器更改MAC法
        a.配置路由器
        b.更改路由器上网方式及MAC地址
        c.注意事项及改进
    (4)路由器刷机法
        a.购买路由器
        b.路由器刷breed
        c.路由器刷机
        d.刷机后设置
        e.通过wget网页登录校园网
        f.mentohust锐捷认证
        g.后续
    附:openwrt设置路由器无线桥接

本文首发于个人博客https://lisper517.top/index.php/archives/14/,转载请注明出处。
实验日期为2022年2月13日。

1.需求分析

校园网限制登录设备,但是有多台设备(电脑和手机)需要在寝室中同时连入一个校园网账号,并且暂时不需要在寝室外连校园网。

2.解决方案

背景介绍:电脑连接上网线后,校园网可网页登录或客户端登录。校园网账号可以绑定 电信/联通/移动 的宽带,可以从使用校园网套餐切换到使用运营商宽带。校园网客户端为锐捷。

(1)电脑wifi共享

思路是win10电脑连接网线,然后wifi共享,如果是台式机需要确定装有无线网卡。市面上有很多wifi热点软件声称可绕过校园网检测,但可能通用性不是太好。下面是在cmd中设置电脑wifi的命令(按win+R,输入cmd,点击确定即可打开cmd):

netsh wlan set hostednetwork mode=allow ssid=wifi名称 key=wifi密码
netsh wlan start hostednetwork #打开wifi热点的命令
netsh wlan stop hostednetwork #关闭wifi热点

另外还要设置共享网络:win10电脑连上校园网后,在 Windows设置-网络和Internet-状态 中找到 更改适配器选项 ,选中校园网连接,右键选择属性,选择 共享 分页,点击 允许其他网络用户通过此计算机的Internet连接来连接
如果运行顺利,此时其他设备就能连接到电脑的wifi下。但是锐捷客户端可识别网卡,同时使用有线和无线网卡时锐捷客户端会自动断开连接,除非在设备管理器禁用其中一张。网页登录时不知道有无同样的问题,可以试一试。

(2)手机热点法

前往运营商处办理一张新卡后可选择套餐。如果是流量较多的套餐,可以选择用一部旧手机插上电源、SIM卡开热点来联网,如果是新手机不建议长时间开启热点(7x24h那种)。另外有的路由器支持插上SIM卡开启wifi,如华为就有移动路由(又名插卡路由),价格300-350¥。但校园中有些寝室手机信号不好,此法就只能用于应急。

(3)路由器更改MAC法

粗略地理解,MAC地址就是网卡的身份证,每张网卡的身份证都不一样。如果更改路由器的MAC地址,也许能让路由器伪装成普通电脑连接校园网,其余设备再通过wifi或网线连接到路由器。另外,更改MAC法也有殊途同归的简单版,就是路由器直接使用DHCP而不是静态IP模式上网,然后电脑连路由器wifi进行网页认证,不过有的学校可能行不通。

a.配置路由器

购买能更改MAC地址的路由器(注意有些路由器可能不支持改MAC地址。这里推荐小米路由器4C,69¥)并配置好路由器热点。这里简单提一下新买的路由器如何配置:插上路由器电源,电脑连上路由器wifi(看路由器说明书上的wifi名称和wifi密码,大多数路由器第一次配置时没有wifi密码),浏览器输入路由器ip地址(看路由器说明书,如华为路由器是192.168.8.1,小米是192.168.31.1,其他的大致都是192.168.x.x的格式)即可开始配置路由器。具体的操作还是要参考路由器说明书。

b.更改路由器上网方式及MAC地址

配置完路由器后,下面介绍如何更改路由器上网方式。
首先在win10电脑上连接到校园网(网页登录或客户端皆可),然后打开cmd(按win+R,输入cmd,点击确定即可打开cmd),输入以下命令:

ipconfig -all

如果有多张网卡,可能会输出多个配置。需要找到其中一条,大致如下:

   连接特定的 DNS 后缀 . . . . . . . :
   描述. . . . . . . . . . . . . . . : (这里是网卡名称)
   物理地址. . . . . . . . . . . . . : (重要)网卡MAC地址,格式为XX-XX-XX-XX-XX-XX
   DHCP 已启用 . . . . . . . . . . . : 是
   自动配置已启用. . . . . . . . . . : 是
   本地链接 IPv6 地址. . . . . . . . : xxxx::xxxx:xxxx:xxxx:xxxx(首选)
   IPv4 地址 . . . . . . . . . . . . : (重要)xxx.xxx.xxx.xxx(首选)
   子网掩码  . . . . . . . . . . . . : (重要)255.255.252.0
   获得租约的时间  . . . . . . . . . : xxxx年x月x日 xx:xx:xx
   租约过期的时间  . . . . . . . . . : xxxx年x月x日 xx:xx:xx
   默认网关. . . . . . . . . . . . . : (重要)xxx.xxx.xxx.xxx
   DHCP 服务器 . . . . . . . . . . . : xxx.xxx.xxx.xxx
   DHCPv6 IAID . . . . . . . . . . . : xxxxxxx
   DHCPv6 客户端 DUID  . . . . . . . : xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx
   DNS 服务器  . . . . . . . . . . . : (重要)xxx.xxx.xx.x
   TCPIP 上的 NetBIOS  . . . . . . . : 已启用

锐捷客户端写的再复杂,底层是不会变的。接下来需要按照上面标记为 (重要) 的条目配置路由器(注意不要填汉字,要填自己cmd中显示的):

上网方式(或者其他名字,上网设置等) 改为 静态IP
IP地址 填 IPv4 地址(xxx.xxx.xxx.xxx,只填数字和小数点)
子网掩码 填 子网掩码(同上)
网关 填 默认网关(同上)
DNS1 填 DNS 服务器(同上)
DNS2(又名备用DNS)可以不填

这里填完后找到 MAC地址克隆 ,填上电脑网卡的MAC地址,注意把 - 改为 : 。比如 1A-2B-3C-4D-5E-6F 改为 1A:2B:3C:4D:5E:6F 。
然后拔掉电脑的网线,路由器连上网线,电脑连上路由器的wifi,随便访问一个网页试试。如果出现网页登录的界面,就用自己的校园网账号登录(注意选择校园网套餐或运营商宽带)。其他设备也可以连上看看。

c.注意事项及改进

首先,这种方法是把路由器的网卡伪装成电脑的网卡;手机使用一些app时可能出现手机上有些网页可能打不开或app功能无法使用,笔者不知道二者有无关联。好在这方面的需求一般不是太强烈,而且手机用b站等视频app大多还是正常的。

其次,校园网长时间不用一般会自动退出登录,所以即使路由器一直开着,但是睡一觉起来打开电脑可能又需要网页登录一次。这种情况的解决方法较多,可以在电脑上使用python的selenium或requests库自动网页登录,或者购买微电脑(如树莓派)24h小时开机、自动检测断网并进行网页登录。下面的内容是使用selenium网页登录的例子(无法直接运行,需要一定python基础):

from selenium.webdriver import Chrome
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions

if __name__ == "__main__":
    username = '123456'  #用户名,一般是学号
    password = '123456'  #密码
    service_type = '中国电信'  #宽带类型。可选 校园网、中国移动、中国电信
    url = "http://xxx.xxx.xxx.xxx/..."  #每次网页认证时弹出来的网址复制到此处
    bro = Chrome(executable_path=r'D:\chromedriver')

    bro.get(url=url)
    locater = (By.ID, 'loginLink_div')
    WebDriverWait(bro, 5).until(
        expected_conditions.presence_of_element_located(locater))

    tag_username = bro.find_element_by_xpath('//*[@id="username"]')
    tag_password = bro.find_element_by_xpath('//*[@id="pwd"]')
    tag_service_type = None
    if service_type == '校园网':
        tag_service_type = bro.find_element_by_xpath('//*[@id="_service_0"]')
    elif service_type == '中国移动':
        tag_service_type = bro.find_element_by_xpath('//*[@id="_service_1"]')
    elif service_type == '中国电信':
        tag_service_type = bro.find_element_by_xpath('//*[@id="_service_2"]')
    tag_button = bro.find_element_by_xpath('//*[@id="loginLink_div"]')

    tag_username.send_keys(username)
    if bro.find_element_by_xpath('//*[@id="deleteDiv"]').get_attribute(
            'style') == 'float: left; display: block;':
        bro.find_element_by_xpath('//*[@id="deletepwd"]').click()
    bro.find_element_by_xpath('//*[@id="pwd_hk_posi"]').click()
    #填完用户名后密码框会失去焦点,需要点一下密码输入框,否则出现element not interactable
    tag_password.send_keys(password)
    bro.find_element_by_xpath('//*[@id="xiala"]').click()
    tag_service_type.click()
    tag_button.click()

    locater = (By.ID, 'userMessage')
    try:
        WebDriverWait(bro, 3).until(
            expected_conditions.presence_of_element_located(locater))
        print('登录成功')
    except Exception as e:
        print('登录失败')

用requests库应该也可以,但是可能比较复杂,感兴趣的可以自行尝试。

(4)路由器刷机法

上文提到,路由器更改MAC法 的一个不足就是路由器不能自动进行网页登录,需要在电脑上进行登录认证。接下来介绍的路由器刷机法可以使路由器能够自动登录认证;缺点是比较复杂,需要一定基础。操作前注意:

首先,不一定要自己刷机,贴吧或其他平台可以交易刷好的路由器(破解版路由器,大多是代代相传的),之后跳过购买和刷机这两步直接看后面的。但如果怕别人留后门就自己刷吧;
其次,有些机器用的系统是openwrt改的或可以通过其他方式开启ssh,比如小米路由器。这种情况下开启ssh即可(小米路由器开启ssh需要用官方提供的工具刷机成开发版,然后路由器绑定小米账号,最后到官网的 开放 中下载 开启ssh工具,根据提示操作。部分小米路由器如4C就没有开发版,而且路由器的root密码也要绑定后才能看,比较坑)。当然嫌麻烦的也可以直接开刷。
最后,刷机前树立一些概念:大多数路由器就是一个使用linux系统的微电脑,很多操作也能对路由器进行(比如连ssh),只是官方系统可能关闭了sshd这些服务;或者其他使用linux系统的电脑(如树莓派)也可以装openwrt后再搭配其他硬件当路由器用。系统也不止openwrt,Padavan(老毛子)、Asuswrt-merlin等也可以用,主要取决于路由器的芯片。最后,刷机(路由器或手机甚至手环等)是一项历史悠久的运动,刷完后能做的远不止登录校园网,刷机的内容也远非一篇文章能讲完的。

a.购买路由器

许多路由器是一个WAN口进,多个LAN口出;有的路由器进口是epon或gpon(光纤);有的路由器能插SIM卡,所有LAN口都可出;有的路由器能插USB;还有的路由器不能开wifi或没有LAN口。但最重要的区别是路由器芯片,购买时要看好参数,比对openwrt支持的路由器型号(右上角可切换语言)。另外,路由器最好能开wifi热点。下面就使用较便宜的小米路由器4C(69¥)进行演示。

b.路由器刷breed

breed又称不死鸟,给路由器刷上breed后备份和进一步刷机更简单了,可有效放止机器变砖(变砖即无法连接上机器),想进一步了解可参考breed发布原址。另外提一下,由于涉及开机引导分区,有的路由器可能还需要物理操作(拆机卸芯片等)刷入breed,下面提到的OpenWRTInvasion是专门给小米系列路由器用的,不适用其他型号。

以下的操作主要参考了这篇教程

首先开启win10机器的telnet功能:在windows设置中搜索 启用或关闭windows功能 ,在下面的框中勾选 Telnet 客户端 后确定。有PuTTY或者用win10自带的ssh命令也可以不用Telnet。
然后去小米路由器官网固件下载页面下载小米路由器4C对应的固件(下文提到的固件可以解释为linux的发行版)做备份,以后可以刷回官方系统。接下来下载OpenWRTInvasion,首先介绍一下,OpenWRTInvasion是大神写的python刷小米路由器脚本,下载地址有3个:GitHub源仓库地址(速度可能较慢),我复制的Gitee仓库,和网友提供的蓝奏云盘。最后小米路由器4C使用路由模式连接网络(使用 更改MAC法 ,或者直接DHCP+网页认证。也可以不连网,因为联网是为了下breed,不过小米路由器不联网时电脑连它有点问题),电脑连接上4C的网络,开始刷breed。注意,下面的操作需要知道路由器的管理页面密码,需要下载python及requests库(pip install requests,不会的话请参考刚才提到的教程)。

打开OpenWRTInvasion-master.zip解压出来的OpenWRTInvasion-master文件夹,在该文件夹的文件路径框中输入cmd打开命令行界面,输入:

python remote_command_execution_vulnerability.py

会显示:

Router IP address [press enter for using the default 'miwifi.com']:

这里输入路由器地址:192.168.31.1 。然后显示:

Enter router admin password:

这里输入路由器管理页面密码。然后显示:

There two options to provide the files needed for invasion:
   1. Use a local TCP file server runing on random port to provide files in local directory `script_tools`.
   2. Download needed files from remote github repository. (choose this option only if github is accessable inside router device.)

这是问使用本地刷机模式还是联网刷机模式(联网模式要从github下文件,经常失败)。输入 1 后回车,等待刷机完毕。脚本的所有输出文字:

Router IP address [press enter for using the default 'miwifi.com']: 192.168.31.1
Enter router admin password: 12345678
There two options to provide the files needed for invasion:
   1. Use a local TCP file server runing on random port to provide files in local directory `script_tools`.
   2. Download needed files from remote github repository. (choose this option only if github is accessable inside router device.)
Which option do you prefer? (default: 1)1
****************
router_ip_address: 192.168.31.1
stok: 235c60efe641083025e6e30efc47a9d9
file provider: local file server
****************
start uploading config file...
start exec command...
local file server is runing on 0.0.0.0:49961. root='script_tools'
local file server is getting 'busybox-mipsel' for 192.168.31.1.
local file server is getting 'dropbearStaticMipsel.tar.bz2' for 192.168.31.1.
done! Now you can connect to the router using several options: (user: root, password: root)
* telnet 192.168.31.1
* ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 -c 3des-cbc -o UserKnownHostsFile=/dev/null root@192.168.31.1
* ftp: using a program like cyberduck

此时路由器的root用户密码就是root。另外,如果只是想开启4C的ssh,到这里就已经可以了。脚本最后还输出了几行,提示如何连接到小米路由器,此处用Telnet演示,用PuTTY或者win10自带的ssh命令也是一样的。cmd中输入:

telnet 192.168.31.1

然后输入root,回车后输入密码root即可成功连接到路由器,欢迎界面如下:

BusyBox v1.19.4 (2019-11-26 08:38:00 UTC) built-in shell (ash)
Enter 'help' for a list of built-in commands.

 -----------------------------------------------------
       Welcome to XiaoQiang!
 -----------------------------------------------------
  $$$$$$\  $$$$$$$\  $$$$$$$$\      $$\      $$\        $$$$$$\  $$\   $$\
 $$  __$$\ $$  __$$\ $$  _____|     $$ |     $$ |      $$  __$$\ $$ | $$  |
 $$ /  $$ |$$ |  $$ |$$ |           $$ |     $$ |      $$ /  $$ |$$ |$$  /
 $$$$$$$$ |$$$$$$$  |$$$$$\         $$ |     $$ |      $$ |  $$ |$$$$$  /
 $$  __$$ |$$  __$$< $$  __|        $$ |     $$ |      $$ |  $$ |$$  $$<
 $$ |  $$ |$$ |  $$ |$$ |           $$ |     $$ |      $$ |  $$ |$$ |\$$\
 $$ |  $$ |$$ |  $$ |$$$$$$$$\       $$$$$$$$$  |       $$$$$$  |$$ | \$$\
 \__|  \__|\__|  \__|\________|      \_________/        \______/ \__|  \__|

接下来备份eeprom到tmp文件夹下(后面解释eeprom):

dd if=/dev/mtd3 of=/tmp/eeprom.bin

然后获取路由器对应的breed。这里要看一下路由器的CPU,在小米路由器官网查看得知4C的芯片是MT7628DA,在breed下载页面找到了breed-mt7628-hiwifi-hc5661a.binbreed-mt7628-oye-0006.bin。一般过程就是这样,找路由器CPU->找对应breed型号下载。但是这里对4C建议选择breed-mt7688-reset38.bin,其他小米路由器型号建议对应的breed:

4A千兆版:https://breed.hackpascal.net/breed-mt7621-pbr-m1.bin
3G 和 4:https://breed.hackpascal.net/breed-mt7621-xiaomi-r3g.bin
3A,3C,4A百兆版,4C:https://breed.hackpascal.net/breed-mt7688-reset38.bin

然后浏览器输入https://breed.hackpascal.net/breed-mt7688-reset38.bin下载breed。慎重起见,顺便下载md5sum.txt,找到breed-mt7688-reset38.bin对应的md5值是cc80874b1b7363929661616b333b6f53,cmd中使用命令certutil -hashfile breed-mt7688-reset38.bin MD5得到下载到文件的md5值,若不一样就重复下载并校验到一样为止。

接着用WinSCP(WinSCP下载地址)传breed到路由器:WinSCP新建一个站点,协议为FTP、不加密,地址192.168.31.1,用户名root,登录,到tmp文件夹下,把breed包改名为breed.bin后拖过去,顺便把tmp里的eeprom.bin(大多数路由器的这个文件大小应该是64kb,不对就重新备份eeprom文件)拖过来做个备份。最后刷breed,在ssh里,进入tmp文件夹后输入以下命令:

mtd write breed.bin Bootloader

显示如下:

Unlocking Bootloader ...

Writing from breed.bin to Bootloader ...

完了之后关掉telnet界面及其他连接到路由器的软件(WinSCP、PuTTY等),进入breed:拔掉路由器电源,用取卡针顶住reset键后不松,再插上电源,等路由器上的灯(4C上是网络灯和电源灯)闪烁几下后松开reset即可(插上电源到松开reset大概3-7s),再到浏览器进入breed默认的路由器地址(192.168.1.1),显示 Breed Web 恢复控制台 (如果打不开也可能是电脑的问题,换一台电脑试试)。第一次进入breed后最重要的是先把备份的eeprom刷好,操作是在 breed页面中-固件更新 处选择勾选eeprom,选择文件就是刚才备份的eeprom.bin。这个文件是路由器的MAC等重要参数,如果这个丢了再刷其他固件,就好比猪的灵魂进了狗的躯壳,会不适应新的身体。

刷完breed、刷上eeprom后就好比上了一道保险,以后刷错了其他固件可以随时救回来。方法就是刚才的 拔电源-顶住reset-插电源-等待3-7s ,就又可以在192.168.1.1中重刷。当然,有些路由器没有对应breed,或者艺高人胆大,也可以直接从下一步开始。

c.路由器刷机

这一步要为路由器刷上openwrt(在breed界面下)。没有刷breed、直接刷openwrt的操作也和上面差不多,可以参考这篇文章

先进入breed界面:192.168.1.1,在 恢复出厂设置-固件类型 中选择 OpenWrt ,点击执行,一段时间后完成。接着去openwrt官网找固件:点击左侧 下载,点击 下载您设备专用的OpenWrt/LEDE固件 下面的 硬件列表,这里可以筛选;找到4C对应的安装固件(不是升级固件),下载下来。文件名为openwrt-21.02.1-ramips-mt76x8-xiaomi_mi-router-4c-squashfs-sysupgrade.bin,MD5值为ea235366cb821012e804af9c270d8b6f。在 breed页面-固件更新 里勾选 固件,选择刚刚下载的文件,点击 上传-更新 ,路由器会自动重启。过一会儿进入固件的本地ip地址(openwrt是192.168.1.1)即可。但是前面下的breed是通用版,对4C不太匹配,还有些工作要做。这里参考了Mi-Router-4C刷openwrt需要注意的地方,详细介绍请参考原链接,以下不做解释。

回到breed刚刷好、备份完eeprom时。在 breed页面-恢复出厂设置 中 固件类型 选择OpenWRT;在 环境变量设置 中选择 启用,位置为 Breed 内部,其他不用管,点击 设置 ,然后重启路由器。这时路由器可能会出现问题,表现为192.168.1.1页面的连接断断续续,进行breed式reset重新进入页面,环境变量设置 中 位置 被改为了自定义,其余未变,不用管。在 环境变量编辑 中添加一条,字段 为 autoboot.command,值 为 boot flash 0x160000,暂不保存。
进入bin文件存放目录,在该目录下开启cmd,先输入ipconfig查看得知本机ip地址为192.168.1.3(arp -a看到该网段下有192.168.1.1动态地址,对应路由器);然后输入py -m http.server开启本地ftp服务器。
在浏览器中输入http://192.168.1.3:8000/,复制下面的bin文件链接。
使用telnet连接到breed:

telnet 192.168.1.1

然后在telnet界面输入:

wget http://192.168.1.3:8000/openwrt-21.02.1-ramips-mt76x8-xiaomi_mi-router-4c-squashfs-sysupgrade.bin

此时wget拿到bin文件并存入了内存。屏幕显示如下:

breed> wget http://192.168.1.3:8000/openwrt-21.02.1-ramips-mt76x8-xiaomi_mi-router-4c-squashfs-sysupgrade.bin
Connecting to 192.168.1.3:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5243193/0x500139 (5MB) []
Saving to address 0x80000000

[========================================================================] 100%

Transmission completed in 1.2s.

其中0x80000000为存放bin文件的内存起始位置,0x500139为bin文件大小,需要记住。接着擦除需要写入的系统分区位置(这里擦除得到的空间大小为0xD40000):

flash erase 0x160000 0xea0000

把内存中的bin文件写到断电存储中(0x80000000和0x500139注意更换):

flash write 0x160000 0x80000000 0x500139

回到breed页面,保存刚才新增的一条环境变量。在 重启 中重启路由器,4C的黄灯会闪一会儿,然后变为蓝灯;访问192.168.1.1,出现OpenWRT页面,成功刷机。

d.刷机后设置

第一次登录,openwrt的root默认是无密码的,下面通过PuTTY连接进行一些设置。
PuTTY连接到192.168.1.1,用户为root。登录后输入passwd root为root设置密码。
在设置页面中,System-Administration 下,设置Router Password(管理页面密码),添加一个SSH-Keys(公钥),SSH Access取消密码认证、root密码登录;System-system 设置一下;Network里设置无线网(默认关闭)。System-Software-Configure opkg里换一下国内源(/etc/opkg/distfeeds.conf里所有https://downloads.openwrt.org/换成清华源mirrors.tuna.tsinghua.edu.cn/openwrt。不过此时清华源最新版openwrt是21.02.0,我的是21.02.1,就没换。也可以不换)。

另外需要说明,openwrt下没有shutdown now,关机命令是poweroff

更多设置可以自行更改。另外,对OpenWrt有兴趣的可以看看OpenWrt.pro

最后需要补充说明一点:路由器每次用breed或其他途径刷上新的固件后,需要进行一次双清。笔者目前对双清还不太了解,下面提供搜集的信息:
双清指的是清理nvram和/etc/storage文件夹,双清的目的是彻底清理上一个固件的残留脚本(/etc/storage)和路由器配置(nvram),每次刚刷好新的固件后都应该双清一下。若刷好新固件后,wifi名称显示为之前的,就可能是未双清(配置未清空)。在老毛子(padavan)系统或miwifi中,在 恢复/导出/上传设置 里,有 路由器参数(NVRAM)路由器内部存储(/etc/storage) 两项,点击下面的 恢复出厂设置 对应的 重置(先/etc/storage后NVRAM)即可双清。但是在openwrt官网下的固件并没有这么方便的双清,笔者只在 System 下的 backup/flash firmware 的 Restore 里找到一个 Perform reset 的选项,这应该是清空配置文件,下面提示若想清空脚本文件,点这个之前应该先恢复出厂设置。所以官网openwrt的双清估计是路由器开机后按reset(若固件不支持reset键或硬件上没有reset键的,使用firstboot命令后reboot;另外在openwrt路由管理网页,未登录时Login旁有个Reset,可能也是factory-reset),然后到这里按 Perform reset。但此猜想未经证实,读者可谨慎实验。

清空nvram:ssh登录后,输入mtd -r erase nvram(此时路由器会因为找不到nvram表,而重启系统建立新的nvram表,ssh连接会断开,这时候千万别切断电源,静等几分钟,再重新连上路由器即可,如果切断了电源,路由会变砖);然后输入nvram commit(将内存中新建的nvram保存),最后reboot即可。
但是出现了nvram: not found,据说nvram的可执行文件在/usr/sbin/nvram,但用find命令也找不到。

e.通过wget网页登录校园网

下面写的脚本太过复杂,其实可以不用脚本登录校园网,而是自己手动在电脑上登录,路由器隔10min访问一次登录页面保持在线就行了。详见 g.后续

这里主要参考了一种在openwrt路由器突破校园网web认证设备限制的方法(对swu校园网的一次实践)。按照本流程走时请到参考文章中看看自己学校的登录页面是否相似,不相似的可能需要自力更生。

先用PuTTY或其他工具连上路由器ssh。输入wget,弹出帮助信息,可以看到其中有--user-agent(带请求头)、--post-data(带载荷)和-O(指定输出文件) 的选项。但是wget发送post的载荷太复杂时会出问题,所以安装curl代替:4C连上网(学校可能比较麻烦,可以用一个改MAC法的路由器LAN连到4C的WAN),用opkg update && opkg install curl即可;路由器连不上网就到openwrt官网按固件版本和CPU型号(本例中为21.02.1,芯片MT7628)查找安装包(本例中为https://archive.openwrt.org/releases/21.02.1/packages/mipsel_24kc/packages/),这里的curl需要curl、libcurl、libnghttp、libwolfssl(不同版本的固件需要的包也可能不同)。一般来说网页登录校园网时随便进一个网站都会跳到登录界面,用wget连接认证界面的ip试试(之前先把校园网接到路由器的WAN口,并且校园网账号下线):

mkdir /tmp/test
cd /tmp/test
wget 192.168.xxx.xxx # xxx.xxx要改成自己学校的
#输出结果
Downloading '192.168.xxx.xxx'
Failed to allocate context

这是因为没有指定http或https。输入:

wget http://192.168.xxx.xxx
#输出结果
Downloading 'http://192.168.xxx.xxx'
Connecting to 192.168.xxx.xxx:80
Redirected to /eportal/redirectortosuccess.jsp on 192.168.xxx.xxx
Redirected to / on xxx.xxx.xxx.xxx
Writing to 'index.html'
index.html           100% |*******************************|   480   0:00:00 ETA
Download completed (480 bytes)

打开index.html,发现只包含一个跳转到登录页面的js脚本:

<script>top.self.location.href='http://192.168.xxx.xxx/eportal/index.jsp?wlanuserip=1&wlanacname=2&ssid=&nasip=3&snmpagentip=&mac=4&t=5&url=6&apmac=&nasid=7&vid=8&port=9&nasportid=10'</script>

这个网址就是普通网页登录时的页面。经过几次实验,在同一个寝室中,用不同电脑联网,其中只有wlanuserip,url和mac不一样。mac应该是加密后的网卡MAC,wlanuserip的前16个字符应该也是从mac生成的,后16个字符可能是用时间生成的,url也和mac异同一致,所以这里网卡MAC可能需要认证(不过大多数学校应该不会认证MAC,否则新生入学或者买了新设备还得去网络管理的地方登记MAC)。接下来分析网页登录页面,在电脑打开认证页面,输入账号密码,通过F12开发者选项(勾上保留日志)发现,认证的账号密码等信息通过post方法发给了另一个网址:

http://192.168.xxx.xxx/eportal/InterFace.do?method=login
#各种载荷
userId: 校园网账号,一般是学号,明码
password: 加密过的密码,网页的js对原密码使用RSA算法加密。也可为明码
service: 服务类型,如电信、移动、校园网(被js的中的encodeURLComponent()过两次)
queryString: 登录页面的载荷,把所有 = 、&、% 换成了对应的URL编码(同上)
operatorPwd:空值
operatorUserId:空值
validcode:空值
passwordEncrypt: true,表示密码经过加密了;false时密码则以明文发送。阅读js得知判断是否加密是看密码长度是否超过150

登录使用curl模拟post方法,带上载荷(主要是userId,password,service,queryString)即可。但是如果路由器网页认证登录上校园网后,再想下线就比较难,必须等一段时间自动下线,所以不着急登录、先看看下线操作。认证成功后会跳转到一个认证成功的界面,并且以json格式发送来一个userIndex,其长度较长、应该加密过;已在线时访问根页面也会跳转到认证成功页面。在认证成功的界面点击下线,发现下线的操作是通过post发送userIndex到http://192.168.xxx.xxx/eportal/InterFace.do?method=logout。那么上下线的操作都有了,接下来开始写脚本(附带注释。所有的192.168.xxx.xxx请改成自己学校的):

#!/bin/ash
#进入工作目录
cd ~/school_net
#~/school_net/account是用来存放账号密码服务类型的,后面会附上格式
account_file=`find -name "account" | wc -l`
if [ $account_file -eq 0 ]; then
    echo "~/school_net/account file not exist. Please establish one!"
    exit 0
fi
userId=`tail ./account | grep "userId" | awk '{print $1}' | awk 'BEGIN{FS="="} {print $2}'`
password=`tail ./account | grep "password" | awk '{print $1}' | awk 'BEGIN{FS="="} {print $2}'`
service=`tail ./account | grep "service" | awk '{print $1}' | awk 'BEGIN{FS="="} {print $2}'`
if [ $service -eq 1 ]; then
    service_1="internet" #对应 校园网 服务类型
elif [ $service -eq 2 ]; then
    service_1="%E7%A7%BB%E5%8A%A8%E5%87%BA%E5%8F%A3" #对应 中国移动
elif [ $service -eq 3 ]; then
    service_1="%E7%94%B5%E4%BF%A1%E5%87%BA%E5%8F%A3" #电信
fi
#没有试过不加UA,保险起见都加上
UserAgent=`tail ./account | grep "User-Agent" | awk 'BEGIN{FS="="} {print $2}' | awk 'BEGIN{FS="#"} {print $1}'`

encodeURLComponent() # 转换=,&,%
{
    s0=$1
    s1=${s0//=/%3D}
    s2=${s1//&/%26}
    s3=${s2//%/%25} # %在最后,所以过一次本函数等于js的同名函数两次
    echo $s3
}
get_queryString()
{
    info=$(wget -O - -U "$UserAgent" http://192.168.xxx.xxx)
    already_login=`echo "$info" | grep "DOCTYPE" | wc -l` #已在线时,访问该网页会返回html而非json
    if [ $already_login -gt 0 ]; then
        echo "1"
        exit 0
    fi
    s1=`echo $info | awk 'BEGIN{FS="?"} {print $2}' | awk 'BEGIN{FS="\047"} {print $1}'` #\047为单引号
    s2=$(encodeURLComponent $s1)
    echo $s2 > ./queryString
    echo $s2
}
login()
{
    queryString=$(get_queryString)
    if [ "$queryString" == "1" ];  then
        echo "Reloginning... already online, exit"
        exit 0
    fi
    service_2=$(encodeURLComponent $service_1) #service_1是汉字转一次码,这里只转了一次
    echo $service_2 > ./service
    payload="userId=${userId}&password=${password}&service=${service_2}&queryString=${queryString}&operatorPwd=&operatorUserId=&validcode=&passwordEncrypt=false"
    echo $payload > ./login_payload
    curl -o ./login_info -A "$UserAgent" -d "$payload" "http://192.168.xxx.xxx/eportal/InterFace.do?method=login" #wget的--post-data在载荷太长时一直不能生效。也可能是特殊标点的问题
    s0=`cat ./login_info`
    s1=${s0#*:\"}
    s2=${s1%%\"*}
    echo $s2 > ./userIndex
    echo $s2
}
logout()
{
    userIndex=`cat ./userIndex`
    wget -O ./logout_info -U "$UserAgent" --post-data="userIndex=${userIndex}" http://192.168.xxx.xxx/eportal/InterFace.do?method=logout
}

login
#logout

exit 0

account文件的格式如下(不要随便增删空格和#):

userId=123456 #student ID
password=123456 #password
service=1 #type of service. 1=school internet, 2=Mobile, 3=Telecom
User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36#fake User-Agent. Dont fix unless experienced

然后在路由器的/root下新建school_net文件夹,使用WinSCP上传脚本文件(命名为school_net.sh)和account文件。修改权限(chmod 755 school_net.sh),开始测试,脚本文件改一下:

login
#logout

改为

login
wget http://bing.com
sleep 5s
logout

运行脚本,在/root/school_net下生成各种临时文件,查看login_info和logout_info可以得知上线下线是否成功。其中的index.html打开,显示bing首页,脚本成功实现了路由器自动上下线。之后把脚本最后改回去。
在openwrt里,System-Scheduled Tasks 提供了crontab的GUI文本输入。可以让脚本10min运行一次,在文本框中添加:

0 5 * * 1 sleep 1m && reboot #若不添加sleep 1m则路由器会在这一分钟一直重启
*/10 * * * * /root/school_net/school_net.sh

顺便加上每周一5点重启的命令。另外,脚本不能太频繁运行,否则登录界面会带验证码,以4C路由器的性能恐怕不能识别验证码。
最后,需要让脚本能开机自启动。openwrt有/etc/rc.local,直接在其中添加:

/root/school_net/school_net.sh

或者在 System-Startup-Local Startup 里也可以快捷修改rc.local。

如果只是单纯想连校园网、保持24h在线,到这一步已经基本完成了,只是没有下线功能。下面的内容属于拓展,增加了下线功能,不生成各种测试文件。
openwrt上添加到serivce和普通发行版不太一样(官网范例),在/etc/init.d中编写一个脚本school_net:

#!/bin/sh /etc/rc.common
# "new(er)" style init script
# Look at /lib/functions/service.sh on a running system for explanations of what other SERVICE_
# options you can use, and when you might want them.

START=99 #越小表示开机时越先执行
STOP=1 #越小表示关机时越先被关闭
SERVICE_USE_PID=1
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1

start() {
        /root/school_net/school_net_login.sh > /root/school_net/school_net.log
}

stop() {
        /root/school_net/school_net_logout.sh > /root/school_net/school_net.log
}

因为想控制断网,所以把school_net.sh分成了两个,还加了log文件,另外把debug性质的输出都注释了。下面是login和logout修改后的完整版(所有的192.168.xxx.xxx同样要改成自己学校的):
school_net_login.sh:

#!/bin/ash
cd ~/school_net
account_file=`find -name "account" | wc -l`
if [ $account_file -eq 0 ]; then
    echo "~/school_net/account file not exist. Please establish one!"
    exit 0
fi
userId=`tail ./account | grep "userId" | awk '{print $1}' | awk 'BEGIN{FS="="} {print $2}'`
password=`tail ./account | grep "password" | awk '{print $1}' | awk 'BEGIN{FS="="} {print $2}'`
service=`tail ./account | grep "service" | awk '{print $1}' | awk 'BEGIN{FS="="} {print $2}'`
if [ $service -eq 1 ]; then
    service_1="internet"
elif [ $service -eq 2 ]; then
    service_1="%E7%A7%BB%E5%8A%A8%E5%87%BA%E5%8F%A3"
elif [ $service -eq 3 ]; then
    service_1="%E7%94%B5%E4%BF%A1%E5%87%BA%E5%8F%A3"
fi
UserAgent=`tail ./account | grep "User-Agent" | awk 'BEGIN{FS="="} {print $2}' | awk 'BEGIN{FS="#"} {print $1}'`

encodeURLComponent() # convert =,&,% to url encode
{
    s0=$1
    s1=${s0//=/%3D}
    s2=${s1//&/%26}
    s3=${s2//%/%25} # % replaced last, meaning this func actually encodes twice
    echo $s3
}
get_queryString()
{
    info=$(wget -O - -U "$UserAgent" http://192.168.xxx.xxx)
    already_login=`echo "$info" | grep "DOCTYPE" | wc -l`
    if [ $already_login -gt 0 ]; then
        echo "1"
        exit 0
    fi
    s1=`echo $info | awk 'BEGIN{FS="?"} {print $2}' | awk 'BEGIN{FS="\047"} {print $1}'`
    s2=$(encodeURLComponent $s1)
    #echo $s2 > ./queryString
    echo $s2
}
login()
{
    queryString=$(get_queryString)
    if [ "$queryString" == "1" ];  then
        echo "Reloginning... already online, exit"
        exit 0
    fi
    service_2=$(encodeURLComponent $service_1) # as for $service_1, encodeURLComponent works only once
    #echo $service_2 > ./service
    payload="userId=${userId}&password=${password}&service=${service_2}&queryString=${queryString}&operatorPwd=&operatorUserId=&validcode=&passwordEncrypt=false"
    #echo $payload > ./login_payload
    s0=$(curl -A "$UserAgent" -d "$payload" "http://192.168.xxx.xxx/eportal/InterFace.do?method=login")
    s1=${s0#*:\"}
    s2=${s1%%\"*}
    echo $s2 > ./userIndex
    echo $s2
    echo "login success"
}

login

exit 0

school_net_logout.sh:

#!/bin/ash
cd ~/school_net
UserAgent=`tail ./account | grep "User-Agent" | awk 'BEGIN{FS="="} {print $2}' | awk 'BEGIN{FS="#"} {print $1}'`

logout()
{
    userIndex=`cat ./userIndex`
    logout_info=$(wget -O - -U "$UserAgent" --post-data="userIndex=${userIndex}" http://192.168.xxx.xxx/eportal/InterFace.do?method=logout)
    #echo $logout_info > ./logout_info
    echo "logout success"
}

logout

exit 0

最后做一些收尾:

chmod 755 /etc/init.d/school_net
chmod 755 /root/school_net/school_net_login.sh
chmod 755 /root/school_net/school_net_logout.sh
touch /root/school_net/school_net.log
chmod 766 /root/school_net/school_net.log
/etc/init.d/school_net enable

另外把crontab里改成:

*/10 * * * * /etc/init.d/school_net start

现在自连校园网的路由器就配置完成了。工作目录在/root/school_net,可以通过/etc/init.d/school_net startstop控制上下线,开机和每次分钟数为10的倍数时自连校园网,账号信息在/root/school_net/account中配置,log为/root/school_net/school_net.log。

f.mentohust锐捷认证

如果所在学校不能网页登录、只能用锐捷客户端登录,可以试试mentohust,这是华中大人开发的可在linux、macos及windows下运行的锐捷认证程序。笔者没用过,也不太清楚如何切换运营商,故不做详细介绍。感兴趣的可以参考教你利用MentoHUST在路由器上挂锐捷认证。另外,最好不要乱下别人分享的mentohust,可从github仓库地址下载。

g.后续

从openwrt网页能看到,4C上一共有2个不同的MAC地址,一个是4D结尾,一个是4C结尾(Devices里一共有5个设备,br-lan、eth0、eth0.1是同一个MAC,wlan0、eth0.2是另一个)。用了几天后无线突然连不上了,于是把所有MAC改成一样,又可以快乐上网了。估计是网页端登录时,后台人工发现设备使用了2个MAC地址,于是封了一个,但是所有的都一样,就分不出来了。

又过了一段时间,校园网维护了一次,自动登录的脚本用不了了,笔者也懒得改。于是目前是用电脑网页登录,然后通过4C路由器每10min访问一次登录页保持在线。总结一下感觉这个方法更简单,4C只需要负责访问登录界面就行了,目的就是保持活跃。总结如下:
一样的需要路由器刷机,比如刷成openwrt,然后把网口的MAC地址都改成一样的,直接在crontab里加上*/10 * * * * wget -U "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36" http://192.168.xxx.xxx即可。以后使用的时候只要电脑连路由器、手动网页登录校园网,之后路由器自动访问登录页保持在线。

附:openwrt设置路由器无线桥接

以下内容参考 这篇文章

如果宿舍里没有网线、只能wifi连校园网,可以试试openwrt的无线桥接。如果有一些个性化设置,建议reset重置一下(重置路由器的方法见前文)。比如之前MAC地址都改成一样的了,设置桥接前可能就需要reset。

reset后打开路由器,用电脑有线连接路由器,并且电脑断开所有其它网络(注意不要连到wifi),浏览器访问 192.168.1.1 登录openwrt后台。到 Network - Interfaces (中文openwrt一般译为接口)里, Edit 第一个绿色的 LAN ,在它的 General Settings - IPv4 address 里,把 192.168.1.1 改成 192.168.5.1 或者其它地址,以防与一级路由冲突(即主路由。一级路由一般用192.168.1.1地址,小米则用192.168.31.1)。更改后,该路由的openwrt后台会改为 192.168.5.1 ,需要在浏览器换到此地址访问;该路由下的子网也会换到 192.168.5.1/24192.168.5.x )。

然后在 Network - Wireless 里选一张无线网卡。小米路由器4C只有一张2.4G无线网卡,其它路由器可能还有5G或者其它网卡。点击 Scan 搜索一级wifi(需要中继的wifi),选中 Join Network 并输入wifi密码,此时openwrt路由器就连接上了主路由的wifi,该网卡下会多出来一个 SSID: 一级wifi名 | 模式: Client 的条目,点进去后可以看到 General Setup - ESSID 是一级wifi的名字, Wireless Security - Key 是一级wifi的密码。

然后设置二级wiFi。该网卡下面自带了一个 SSID: Openwrt | 模式: Master 的wifi,是openwrt自己发出的, Edit 一下,在 General Setup - ESSID 修改二级wifi的名称, Wireless Security - Key 设置二级wifi的密码(选择WPA2-PSK即可,最常用的加密方式)。

现在就已经设置完成了。主路由发出wifi-1(一级wifi),二级路由器通过密码连接一级wifi,二级路由器发出自己的wifi-2(二级wifi)。像wifi放大器这样的设备应该可以同时沿用一级wifi的名称、密码,笔者没有把二级wifi的名字改成和一级wifi一样,感觉会冲突(像小米原生的mesh组网,有线网络是一致的,但wifi还是不同的名称)。总之,到这里就设置成功了。

设置网络这里可能会有一些不同,总之最后需要达成的效果如下:该网卡下面有 SSID: 二级wifi名 | Mode: MasterSSID: 一级wifi名 | Mode: Client 的2个条目,Master的意思为该wifi是二级路由器自己发出的;Client则是二级路由器接受一级路由器的wifi。Master网络的 General Setup - Mode 可看到为 Access Point 即AP(AP就是桥接)。这时可以连接二级路由器的有线、无线网络,都会桥接到一级路由器,但是网段还是 192.168.5.x (如果是小米原生的mesh组网,客户端连接子路由后,也会在主路由的 192.168.31.x 下)。

标签: 校园网, 路由器刷机, OpenWrt, 锐捷, mentohust

已有 6 条评论

  1. 睡眠

    作者你好,本人小白,我们学校使用的锐捷认证是通过web端进行认证的,但是会检测ua,如果苹果,安卓,windows同时连接路由器,极大概率会导致被检测到,然后被封禁一定时间。我看到老毛子的shadowsocks插件里可以搭建ss服务器。能否通过第一个路由器进行认证并搭建服务器,给第二个路由器代理进行加密,防ua检测?还有有办法只通过一个路由器既搭建服务器,又使其自己代理自己吗?

    1. 我这里是在认证的时候已经伪装过UA了,你的意思是你们学校不光认证的时候,后面访问其他网页也要检查UA?
      酸酸乳方面的东西我完全没试过也搞不懂,但是我初步想可以手动更改浏览器默认UA,参考https://jingyan.baidu.com/article/4ae03de34b9fb87fff9e6bfc.html(chrome更改UA)。

  2. 青春

    老哥 我这个是通过mac克隆实现的多设备公用,但是确实会一天一掉,所以这个自动登录的脚本具体咋写,大佬可以代写或者细交一下吗,因为我小白没有编程基础,可以有偿,还有这个自动登录的脚本要配合啥固件用,目前用的是斐讯的官改固件,之前抓过包知道是post命令。感谢

    1. 我远程帮你写太难了,你最好是找一下学校有没有计算机专业的同学帮你写一个吧。要不就去恩山无线上看看有没有其他大佬。

  3. 兰亭梦

    大佬 我们学校没网线 用无线桥接的话怎么个操作嘞

    1. 我猜你的意思是宿舍没有网线,想用路由器连学校wifi,然后路由器分享出来网络。
      可以看一下这篇文章https://www.3kjs.com/topic/15700.html,用的openwrt固件。

添加新评论