锐捷校园网解限探索记录

黯绛 2026-09-12 10:29 1

https://linux.do/t/topic/2521942

在假期前,我测试了校园网对单线多拨没有限制(端口mac绑定),假期购买了一台瑞芯微rk3588的妖板BDY-G98 给rk3588小主机超频失败 ,如今回到学校使用就是个很大的问题。于是来研究这个。


可能你能看到的最全的(


0x00 前期梳理


梳理一下要求。




  1. 解除设备数限制 这个是最基本的要求了。




  2. 透明代理 我已经不想在每一天设备上安装mihomo,配置节点了,麻烦不说有些应用还不会遵循设置。




  3. 单线多拨 20M的宽带也是没谁了,不解限速太难受。虽然在AI下我们或许能对锐捷这套校园网管理系统做些攻击尝试,但是挨处分这些就免了,本人恰巧在网管中心工作,能接触一部分功能,恰巧有些账号是很久没人登录的,而且密码有规律进行了一波弱密码尝试(




  4. 宿舍使用 紧凑 耗电小 纯被动散热 满足上面要求所需的性能 当然价格也不能太高 100 出头最好。




综上所述,能做到上面要求的也就是能刷OpenWRT的硬路由了。从最后跑完整个流程得到的最低配置是要闪存256M 内存384M。如果你不需要上面的一些功能,可以继续往低选。




推荐首先选择联发科的设备,生态比高通好得多。


我最初的选择是RAX3000M的64G emmc 版本,但是价格就比较高了199元,我也没有在路由器跑docker的想法,纯被动散热下MT7981这颗芯片发热量是比较大的,不是很划算,观望了几天,恰巧之前玩过BDY-G98,从群友得知有 BDY-G56 这个硬件配置和RAX3000M一模一样,甚至有1G内存8G emmc,让老哥给我改改散热和外壳,得到了一个非常紧凑的大小,比RAX3000M优惠多的价格拿到,物有所值了。



缺点是这台设备存世量很少,不在openwrt的硬件列表上,虽然上面的老哥也给了一份可用的固件,但是还是需要自己编译固件,因为后面发现像单线多拨和其他的一些依赖需要自己增加内核模块,不过mt798x的生态比较完善,难度没有这么高,特别是现在有ai的支持之下。


如果你没有编译固件的能力,我更推荐你使用RAX3000M,可以在ImmortalWrt使用image builder在线构建固件,当然我更推荐你自行编译,自由度更高。


0x01 编译/刷入固件


推荐24.10版本,这个版本工具比较全,虽然像mwan3这种需要兼容层工作,而到了25.12上就需要使用重写的版本,而且不一定有mtk的闭源驱动。


采用 GitHub - padavanonly/immortalwrt-mt798x-6.6: An opensource OpenWrt variant for mainland China users. · GitHub 的源码。

如何进行固件编译/刷入,Uboot等就不多赘述,这部分openwrt社区教程已经非常丰富,主要说明一些注意点。源码大小30GB+,留意硬盘大小。


bdy-g56 需要自行修改源码支持,作为一个希望较为通用的教程这里就不说明了。


注意勾选一下软件包,依赖会自动勾选。


# 基础部分
kmod-nft-queue luci-app-mtwifi-cfg luci-app-eqos-mtk
# 单线多拨
kobs kmod-macvlan ip-full mwan3 luci-app-mwan3 iptables-nft
#工具
curl ethtool

由于我是在BDY-G98上进行的编译,在arm64上多线程编译时会有一些问题。如果是x86交叉编译则不需要。



  1. perl 需要单线程编译,否则会遇到依赖未被编译而报错终止。

  2. golong编译会遇到不支持arm64的问题,需要手动安装go 1.26 修改文件使用环境中的go来编译。


user@armbian:~/immortalwrt-mt798x-6.6/feeds/packages$ git diff lang/golang/golang/Makefile
diff --git a/lang/golang/golang/Makefile b/lang/golang/golang/Makefile
index c1eb93f..b26c8e9 100644
--- a/lang/golang/golang/Makefile
+++ b/lang/golang/golang/Makefile
@@ -83,7 +83,7 @@ BOOTSTRAP_GO_VALID_OS_ARCH:= \
darwin_386 darwin_amd64 \
dragonfly_386 dragonfly_amd64 \
freebsd_386 freebsd_amd64 freebsd_arm \
- linux_386 linux_amd64 linux_arm \
+ linux_386 linux_amd64 linux_arm linux_arm64 \
netbsd_386 netbsd_amd64 netbsd_arm \
openbsd_386 openbsd_amd64 \
plan9_386 plan9_amd64 \
@@ -266,26 +266,33 @@ define Host/Configure
endef

define Host/Compile
- $(call GoCompiler/Bootstrap/Make, \
- $(HOST_GO_VARS) \
- CC="$(HOSTCC_NOCACHE) -std=gnu17" \
- )
-
- $(call GoCompiler/Bootstrap-1.17/Make, \
- GOROOT_BOOTSTRAP="$(BOOTSTRAP_ROOT_DIR)" \
- $(HOST_GO_VARS) \
- )
-
- $(call GoCompiler/Bootstrap-1.20/Make, \
- GOROOT_BOOTSTRAP="$(BOOTSTRAP_1_17_BUILD_DIR)" \
- $(HOST_GO_VARS) \
- )
+# $(call GoCompiler/Bootstrap/Make, \
+# $(HOST_GO_VARS) \
+# CC="$(HOSTCC_NOCACHE) -std=gnu17" \
+# )
+#
+# $(call GoCompiler/Bootstrap-1.17/Make, \
+# GOROOT_BOOTSTRAP="$(BOOTSTRAP_ROOT_DIR)" \
+# $(HOST_GO_VARS) \
+# )
+#
+# $(call GoCompiler/Bootstrap-1.20/Make, \

0x02 解除设备数限制








大多数学校采用检查 TTL 和 追踪 HTTP UA 的方式,UA3F 是一个 HTTP(S) 重写代理,可用于透明改写请求/响应 Header、Body,也可按规则执行 URL 重定向、拒绝或丢弃请求。


如果不需要透明代理,可以直接参照此教程(依赖 kmod-nft-queue ):




我更推荐使用二进制版本,通过eBPF卸载来改写L3层数据(TTL等)性能会更好,同时不占用透明代理,可配合其本身的TPROXY透明代理http,或者其他代理核心透明代理模式进行分流给UA3F。配置方式可以直接参考UA3F文档。


可以先尝试只修改TTL,如果检查不严格可以直接使用nftables只改写ttl,就无需UA3F了。


root@ImmortalWrt:/etc/nftables.d# cat 12-mangle-ttl-64.nft 
# 1. 发出的包固定为 64(Android/Linux/macOS 标准初始值,如果偏好 Windows 可改 128)
chain mangle_postrouting_ttl64 {
type filter hook postrouting priority 300; policy accept;
counter ip ttl set 64
}
chain mangle_prerouting_ttl64 {
type filter hook prerouting priority 300; policy accept;
counter ip ttl set 64
}
# 2. 从 WAN 口进入的包:将 TTL 设为 2(防止外层探测穿透至局域网终端)
# 注意:wan替换为你实际的接口名(如 wan、eth0)
chain mangle_prerouting_ttl2 {
type filter hook prerouting priority 300; policy accept;
iifname "wan" counter ip ttl set 2
}
# 3. 防路由跟踪:直接丢弃发给路由及经路由转发的 TTL=1 探测包
chain filter_input_ttl {
type filter hook input priority 0; policy accept;
ip ttl 1 counter drop
}
chain filter_forward_ttl {
type filter hook forward priority 0; policy accept;
ip ttl 1 counter drop
}

sing-box可以根据协议类型分流http给UA3F(SOCKS5模式),降低UA3F处理压力。但是用mihomo的就比较难受了,总所周知sing-box的配置文件难写的很,而且大版本会引入破坏性修改,加之习惯了mihomo,只能牺牲一些性能让UA3F用REDIRECT模式在流量进入 Mihomo 之前先由防火墙截获 HTTP 流量修改 UA。


实话说UA检测在26年已经式微了。


0x03 单线多拨


在 ImmortalWrt 中,将 Macvlan 单线多拨源进源出 PBR(保障认证心跳)mwan3 负载均衡 结合,能够实现校园网多账号带宽链路聚合。


网络基础配置


进入系统后台 网络 → 接口 进行配置:




  1. 创建 Macvlan 设备



    • 进入 网络 → 接口 → 设备,添加设备类型为 MAC VLAN

    • 基础设备选择物理上行网口(如 eth0),命名为 wanmac0wanmac1 等。




  2. 创建逻辑接口



    • 在接口页面添加新接口,协议选择DHCP

    • 接口命名必须使用标准数字后缀:vwan0vwan1

    • 分别绑定对应的 wanmac0wanmac1 设备。


    推荐关闭ipv6




  3. 配置网关与跃点数(Metric)



    • 点击每个 vwan 接口的 修改 → 高级设置

    • 确保勾选 「使用默认网关」

    • 为每个接口设置不同的 「网关跃点」(如 vwan010vwan120),防止主表路由冲突。

    • 将所有虚拟 WAN 接口划入同一防火墙区域(通常为 wan 区域)。




部署源进源出 Hotplug 脚本


由于 mwan3 会在内核中插入基于数据包标记(fwmark)的策略路由(规则优先级通常在 2000 后),为了确保各认证客户端的心跳包绝对原路返回,必须将自定义的 PBR 优先级提升至 500 + num


在终端执行以下命令写入脚本:


Bash


cat << 'EOF' > /etc/hotplug.d/iface/95-wan-source-routing
#!/bin/sh
# 监听网络接口启动 (ifup)、重租 (ifupdate) 和关闭 (ifdown)
[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifupdate" ] || [ "$ACTION" = "ifdown" ] || exit 0

case "$INTERFACE" in
vwan*)
suffix="${INTERFACE#vwan}"
if [ -z "$suffix" ]; then
num=0
else
num=$((suffix + 1))
fi
table=$((200 + num))
# 优先级设为 500+,确保高于 mwan3 的默认捕获规则
pref=$((500 + num))

if [ "$ACTION" = "ifdown" ]; then
ip rule del pref "$pref" 2>/dev/null
ip route flush table "$table" 2>/dev/null
exit 0
fi

IP=$(ip -4 -o addr show dev "$DEVICE" 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -n1)
GW=$(ip -4 route show dev "$DEVICE" 2>/dev/null | awk '/default/ {print $3}' | head -n1)

if [ -n "$IP" ] && [ -n "$GW" ]; then
ip route replace default via "$GW" dev "$DEVICE" table "$table" 2>/dev/null
ip rule del pref "$pref" 2>/dev/null
ip rule add from "$IP" lookup "$table" pref "$pref"
fi
;;
esac
EOF

chmod +x /etc/hotplug.d/iface/95-wan-source-routing

路由规则碰撞警告


如果自定义的 pref 数值大于 mwan3 规则(如 2000 以上),认证心跳包将被 mwan3 的负载均衡规则强制劫持,造成心跳超时掉线。务必保持 pref 小于mwan3。


配置 mwan3 负载均衡


在 LuCI 界面进入 网络 → 负载均衡(mwan3)




  1. 配置接口(Interfaces)



    • 删除默认的 wan,添加 vwan0vwan1

    • 跟踪方式:勾选启用,跟踪的目标 IP 设置为公网通用 DNS(如 223.5.5.5119.29.29.29)。

    • 可靠度设为 2


    注意ipv6对应的wan6也要添加




  2. 配置成员(Members)



    • 创建 vwan0_m1_w1:接口绑定 vwan0,跃点数(Metric)填 1,权重(Weight)填 1

    • 创建 vwan1_m1_w1:接口绑定 vwan1,跃点数(Metric)填 1,权重(Weight)填 1




  3. 配置策略(Policies)



    • 创建策略 balanced:将上述成员(vwan0_m1_w1vwan1_m1_w1)全部加入,形成等权聚合。




  4. 配置规则(Rules)



    • 修改默认规则 default_rule:将目标策略设为 balanced,分配所有普通上网流量走聚合。




最终效果


Interface status:
interface wan is online and tracking is active (online 28h:44m:57s, uptime 31h:08m:46s)
interface wan6 is online and tracking is active (online 25h:24m:23s, uptime 50h:06m:19s)
interface vwan0 is online and tracking is active (online 28h:44m:57s, uptime 33h:45m:26s)
interface vwan1 is online and tracking is active (online 28h:44m:57s, uptime 31h:05m:30s)
interface vwan2 is online and tracking is active (online 28h:44m:57s, uptime 31h:05m:36s)

Current ipv4 policies:
load_blance:
vwan2 (25%)
vwan1 (25%)
vwan0 (25%)
wan (25%)

Current ipv6 policies:
load_blance:
unreachable

Directly connected ipv4 networks:
x.x.x.x

Directly connected ipv6 networks:
xxxx:xxxx:xxxx::/64
xxxx:xxxx:xxxx:xxxx::/64
xxxx::/64

Active ipv4 user rules:
224 14472 MARK 0 -- * * 0.0.0.0/0 172.16.0.0/12
10 670 MARK 0 -- * * 0.0.0.0/0 10.0.0.0/8
418K 35M - load_blance 0 -- * * 0.0.0.0/0 0.0.0.0/0
0 0 - load_blance 0 -- * * 0.0.0.0/0 0.0.0.0/0

Active ipv6 user rules:
175K 16M MARK 0 -- * * ::/0 ::/0
0 0 - load_blance 0 -- * * ::/0 ::/0

mihomo 配置


当 mwan3 重新加载策略或检测到某个接口掉线/重连时,会重构防火墙 mangle 链并刷新路由标记,这会导致 mihomo 的透明代理(Tproxy / Tun)连接中断或丢包。


校园网ipv6多不下发PD前缀,建议dns模块关闭ipv6,仅支持ipv6路由(可ping通ipv6),这样既可以用ipv6连接到HKIX的节点也不至于因为NAT6或多拨v6导致的问题。


放宽内核反向过滤(rp_filter)


多拨与负载均衡场景下,必须开启宽松模式,防止内核因非对称路由直接丢弃回包:


Bash


# 写入持久化配置
cat << 'EOF' > /etc/sysctl.d/99-multihoming.conf
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
EOF

# 立即应用配置
sysctl -p /etc/sysctl.d/99-multihoming.conf

系统验证与状态排查


按照顺序执行以下测试:




  1. 验证策略路由优先级与表项


    ip rule show

    确认 pref 位于 mwan3 规则之前,格式如下:


    1002:   from 10.90.80.61 lookup 201
    2001: from all fwmark 0x100/0xff00 lookup 100



  2. 验证源进源出可用性(单网卡绑定)


    curl --interface <vwan0分配的IP> http://ip.im -4
    curl --interface <vwan1分配的IP> http://ip.im -4

    两者均应成功返回公网响应,且即使网关不同也不会超时。




需要关闭硬件卸载/硬件加速吗?


实测无论是 HNAT / 全锥形 NAT / 防火墙硬件流量卸载都不需要关闭,很多教程都指出要关闭实测是没有影响的。


0x04 登录校园网


在GitHub上登录校园网的项目有很多,语言有python/bash/go/C++,但是没有对单线多拨这种情况的登录做的项目。

参考了以下下项目:


Iamtianyuyang/UPCnetworklogin: 这是一个基于c语言用于linux命令行登录中国石油大学(华东)校园网的代码。 | https://github.com/Iamtianyuyang/UPCnetworklogin
fjd2004711/ruijie_nxu: 对于宁夏大学(NXU)校园网锐捷认证的 Linux 通用登录脚本 | https://github.com/fjd2004711/ruijie_nxu
mapkkkk/single_login: 校园网自动登录 | https://github.com/mapkkkk/single_login
here200/Connect-School-Net: 一键登录校园网,针对网页认证 | https://github.com/here200/Connect-School-Net/tree/master
PengweeWang/campusnet_login | https://github.com/PengweeWang/campusnet_login
its-david-li/Ruijie-Campus-Auth: 帮你在路由器或 Linux 电脑上自动登录锐捷校园网的实用小脚本。配好之后扔在定时任务里就行,断网秒连。告别弹窗,让你的设备安安静静、稳稳当当地保持在线。 | https://github.com/its-david-li/Ruijie-Campus-Auth/tree/main
a76yyyy/HustWebAuth: HustWebAuth is a program used to implement Ruijie web authentication. | https://github.com/a76yyyy/HustWebAuth
Jun-maxs/CampusNetLogin: 校园网登录工具 + 远程控制系统 (ePortal认证/移动端Web/远程Agent) | https://github.com/Jun-maxs/CampusNetLogin
Redlnn/Ruijie-ePorta-Tool: 一个基于Python的自动登录锐捷ePorta网页认证的工具 | https://github.com/Redlnn/Ruijie-ePorta-Tool
huantuoshen-prog/ruijie-gdstvc-autologin: 锐捷Web认证自动登录 | OpenWrt路由器脚本 | 广科院校园网 | 支持电信联通 | Shell | https://github.com/huantuoshen-prog/ruijie-gdstvc-autologin#%E8%B7%AF%E7%94%B1%E5%99%A8%E9%83%A8%E7%BD%B2
Gloridust/RuijieWIFI-AutoLogin: 自动登录宜宾学院锐捷校园WiFi认证系统,防止意外掉线。理论上支持所有锐捷系统校园网。 | https://github.com/Gloridust/RuijieWIFI-AutoLogin

选择在a76yyyy/HustWebAuth的基础上fork增加支持单线多拨下指定接口,go语言编写占用低,性能好,二进制便于跨平台部署。



0x05 透明代理


推荐使用ShellCrash 相比openclash更原生,性能更好占用更低,缺点是没这么即开即用,推荐关闭本地配置文件覆写,会破坏你的配置文件中的规则。自己参考内置的配置文件去写适合路由器的配置。


这部分代理社区的教程也很多,在此就不赘述了。


0x06 总结


这篇只讲述了校园网相关,其实很多地方是研究了ImmortalWrt源码和mtk相关闭源驱动才得出相关的结论,像自编译后WiFi配置缩水,ipv6路由不可达,UA3F失效等等。放假之前在win上虚拟网口的操作我本以为实际上难度一般,但是最终难度超乎我的想象,花费了10天时间才完成整个流程。



考虑到学校内网不限速,下一步试试把这个通过内网shadowsocks共享给其他同学用。(二包运营商)

最新回复 (7)
  • IgniteRan 09-12 10:36
    1

    强啊佬,写的很细

  • Becod 09-12 10:41
    2

    之前用爱快测试了多拨绝对不是嫌mwan麻烦,学校的限制是每账号百兆,但是实测12拨只有五百多,有点奇怪

  • 3323232 09-12 10:45
    3

    佬,除了这个TTL=64,如果检测更严格,它还有什么可以检测?我热点改TTL可以用,但是我比较好奇 ^-^

  • cwxiaos 09-12 11:11
    4

    基本就是ttl,nat后面的设备除了ttl有明显的特征,再就是行为特征了,不过鬼才检测行为特征

  • 黯绛 楼主 09-12 12:09
    5

    检测方法还有很多,看相关章节的参考链接。

  • Elon Reeve Musk 09-12 12:13
    6

    我们学校是免费的 50m 校园网 目前接的万兆电信宽带 路由器似乎是h3c 这个有现成的项目吗

  • Jeremy Chen 09-12 14:14
    7

    还好我们学校不检测登录设备数量,中间跨一个路由器就行。流量直接ss到另一个服务器里,服务器是老师的流量随便花。

* 帖子来源Linux.do
返回