前几天重庆大学研究生开学了,搬进宿舍把所有设备折腾好后,我的校园网账号就突然被踢下线了,显示账号不可使用路由器进行多设备共享,这给我搞得猝不及防。由于我有一台小主机在寝室做服务器,刚需内网环境,因此绕过这个多设备检测就是不得不做的了,本文便介绍一下绕过的方式。
1 检测原理
我本以为这个检测原理有多么高深,肯定用到了什么高级的计算机网络技术。但是查询资料后我发现这检测方式也太简单粗暴了吧,稍微接触过计算机网络的读者应该都能理解。
1.1 HTTP 数据包 User-Agent 检测
众所周知,客户端在发送 HTTP(S) 请求时,大多会在请求头中附带 User-Agent,用于辨识客户端类型。不同的客户端或者不同的操作系统发送的 User-Agent 是不同的,例如:
- Windows Chrome:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36
- iOS Safari:
Mozilla/5.0 (iPhone; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Mobile/15E148 Safari/604.1
通过 UA 中的操作系统信息,便可以辨别出该 HTTP 请求是电脑还是手机发出的,从而可以辨别出该 IP 是否存在多设备共享。
但这个检测的前提是,该请求是未经加密的 HTTP 协议发出的,HTTPS 对整个 HTTP 数据包进行了加密,包括请求头,因此这个检测是不可能对 HTTPS 完成的。回想起当时被踢下线,我就是用手机访问了学校的 HTTP 协议充值平台,证明该检测确实只能对 HTTP 完成。
1.2 TCP/IP 数据包 TTL 检测
在 IP 数据包的头部,存在 TTL(Time to Live) 字段,数据包每经过一跳,TTL 值便减一,以此来防止数据包路由时出现无限环回。不同的操作系统在发送 IP 数据包时,默认的初始 TTL 也是不同的:
- Windows: 128
- Unix-like(Android, iOS, macOS): 64
因此,通过识别 TCP/IP 数据包头部的 TTL 值,便可以辨别出该 IP 是否存在多设备共享。
同时,由于数据包每经过一跳 TTL 值便减一,如果校园网接入网关发现收到的 IP 数据包已经不是 128 或 64 而是 127 或 63,这也能够识别出在用户侧存在路由设备。
2 绕过方式
针对上述的两种检测方式,逐个击破进行绕过。
2.1 HTTP 数据包 User-Agent 统一
2.1.1 安装
该方法思路非常朴素,既然你识别我的 UA 头,那我就把所有设备发出的 UA 全改成一样的,你当然就分不清了。要实现该操作,我选择的是 UA2F 这个开源软件:
网上很多教程都要进行 OpenWrt 固件编译,这太麻烦了,而且作者已经有编译好的 ipk 二进制包,实际上没有必要把插件编译到固件里。
直接进入 GitHub 仓库的 release 里,下载自己架构的 ipk 包就行了。例如我的路由器是 GL-MT3000,cortex-a53 架构,因此就下载 ua2f_4.10.2-1_aarch64_cortex-a53-23.05.5.ipk
。下载后直接在 Web 后台安装软件包,或者直接 sftp 上传后 opkg install
就行了,根本不需要重新编译整个固件。我在安装后发现还有依赖缺失,需要补一下 opkg install iptables-mod-nfqueue
.
安装好后可以 SSH 到路由器上,执行一下 ua2f --version
指令,如果有正常回显则安装成功。
2.1.2 配置
安装后就可以进行配置了,配置方式可以参考 GitHub 仓库的文档,以下是我进行的配置:
# 启用 UA2F uci set ua2f.enabled.enabled=1 # 自动添加防火墙规则 uci set ua2f.firewall.handle_fw=1 # 处理内网流量,学校有内网网站,因此要开启 uci set ua2f.firewall.handle_intranet=1 # 自定义User-Agent,我选择统一为电脑端Chrome uci set ua2f.main.custom_ua="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.6.6.6 Safari/537.36" # 应用配置 uci commit ua2f # 开机自启 service ua2f enable # 启动UA2F service ua2f start
2.1.3 测试
可以使用 UA2F 提供的测试站点进行测试:http://ua-check.stagoh.com/。如果服务器端的 UA 为自己设定的 UA,并且显示运行状态正常,就说明配置无误。
2.1.4 LuCI 界面(可选)
该项目为 UA2F 制作了 LuCI 的网页界面,安装后就可以直接在网页管理 UA2F 了:
不过仓库里提供的 ipk 包不知道为什么装不上,不过我在这个软件包镜像找到了编译好的二进制包:src/gz openwrt_kiddin9 https://dl.openwrt.ai/packages-23.05/aarch64_cortex-a53/kiddin9
安装之后就能在 LuCI 网页的网络菜单中找到 UA2F 的管理界面了:
2.2 TCP/IP 数据包 TTL 统一
这个什么都不需要装,直接配置 iptabels 防火墙规则就行了。一行指令即可:
iptables -t mangle -A POSTROUTING -j TTL --ttl-set 64
配置好后随便 Ping 一个网站,可以发现 TTL 永远都是 64:
如果要撤销修改,使用以下指令:
iptables -t mangle -D POSTROUTING -j TTL --ttl-set 64
3 自动登录
为了防止校园网账号意外下线,导致宿舍的服务器断网,我也研究了下自动登录。学校的校园网登录非常朴素,F12 几分钟就研究出来 API 调用了,直接用 curl 请求下即可登录。
因此,流程就是使用 Crontab 每分钟运行指令,使用 curl 访问百度,如果 10s 内不能正常访问到则说明要登陆,通过 curl 访问学校的校园网登录接口进行登录。
写好的 Crontab 条目如下,记得把账号密码还有 WAN 口网卡号改成自己的:
* * * * * curl --connect-timeout 10 https://baidu.com || curl "http://10.254.7.4:801/eportal/portal/login?callback=dr1004&login_method=1&user_account=%2C0%2C【在这里填写账号】&user_password=【在这里填写密码】&wlan_user_ip=$(ifconfig 【在这里填写路由器的WAN口网卡号】 | grep 'inet addr:' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -n 1)&wlan_user_ipv6=&wlan_user_mac=000000000000&wlan_ac_ip=&wlan_ac_name=&ua=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F139.0.0.0%20Safari%2F537.36&term_type=1&jsVersion=4.2&terminal_type=1&lang=zh-cn&v=2992&lang=zh"
使用 crontab -e
,把这个条目加到 Crontab 计划任务的最后一行就行了。
发表回复