前言
我这里使用的是树莓派烧录的openwrt,本地编译我试了很多次,都失败了,我建议小白就去大神搭建的云编译平台openwrt。烧录固件的软件我用的树莓派官方的烧录器。
云编译
openwrt。填上我们需要的一些软件包,把后面的ipv6打上勾,之后就是下载->烧录->启动
1luci-app-ttyd mod-rkp-ipid iptables-mod-filter iptables-mod-ipopt iptables-mod-u32 iptables-nft kmod-ipt-ipopt ipset iptables-mod-conntrack-extra
联网
开机之后,用电脑连接上wifi名字叫Kwrt_5G,然后用网线让树莓派连接上校园网,增加一个wan口。wan口设备选择的是br-lan口,用的dhcp协议
之后会跳出认证界面,这个认证界面的mac地址是树莓派的地址,登录你的账号密码,就可以上网了
设置ntp服务器
1ntp.aliyun.com
2time1.cloud.tencent.com
3time.ustc.edu.cn
4cn.pool.ntp.org
添加开机启动脚本
1# 启动 UA3F
2uci set ua3f.enabled.enabled=1
3uci commit ua3f
4service ua3f enable
5service ua3f start
6
7#防火墙:
8iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53
9iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53
10
11# 防 IPID 检测
12iptables -t mangle -N IPID_MOD
13iptables -t mangle -A FORWARD -j IPID_MOD
14iptables -t mangle -A OUTPUT -j IPID_MOD
15iptables -t mangle -A IPID_MOD -d 0.0.0.0/8 -j RETURN
16iptables -t mangle -A IPID_MOD -d 127.0.0.0/8 -j RETURN
17# 由于本校局域网是 A 类网,所以我将这一条注释掉了,具体要不要注释结合你所在的校园网内网类型
18# iptables -t mangle -A IPID_MOD -d 10.0.0.0/8 -j RETURN
19iptables -t mangle -A IPID_MOD -d 172.16.0.0/12 -j RETURN
20iptables -t mangle -A IPID_MOD -d 192.168.0.0/16 -j RETURN
21iptables -t mangle -A IPID_MOD -d 255.0.0.0/8 -j RETURN
22iptables -t mangle -A IPID_MOD -j MARK --set-xmark 0x10/0x10
23
24# 防时钟偏移检测
25iptables -t nat -N ntp_force_local
26iptables -t nat -I PREROUTING -p udp --dport 123 -j ntp_force_local
27iptables -t nat -A ntp_force_local -d 0.0.0.0/8 -j RETURN
28iptables -t nat -A ntp_force_local -d 127.0.0.0/8 -j RETURN
29iptables -t nat -A ntp_force_local -d 192.168.0.0/16 -j RETURN
30iptables -t nat -A ntp_force_local -s 192.168.0.0/16 -j DNAT --to-destination 192.168.1.1
31
32# 通过 iptables 修改 TTL 值
33iptables -t mangle -A POSTROUTING -j TTL --ttl-set 64
34
35# iptables 拒绝 AC 进行 Flash 检测
36# iptables -I FORWARD -p tcp --sport 80 --tcp-flags ACK ACK -m string --algobm --string " src=\"http://1.1.1." -j DROP
37iptables -A FORWARD -p tcp --sport 80 --tcp-flags ACK ACK -m string --algo bm --string "src=\"http://1.1.1." -j DROP
安装ua3f和ShellClash
找到服务->终端
1#从URL安装ShellClash(以下链接三选一)
2#GitHub源(可能需要代理)
3export url='https://raw.githubusercontent.com/juewuy/ShellCrash/master' && sh -c "$(curl -kfsSl $url/install.sh)" && source /etc/profile &> /dev/null
4#jsDelivrCDN源
5export url='https://fastly.jsdelivr.net/gh/juewuy/ShellCrash@master' && sh -c "$(curl -kfsSl $url/install.sh)" && source /etc/profile &> /dev/null
6#私人源
7export url='https://gh.jwsc.eu.org/master' && sh -c "$(curl -kfsSl $url/install.sh)" && source /etc/profile &> /dev/null
1#用于UA3F的Clash配置(无外部代理)
2https://cdn.jsdelivr.net/gh/SunBK201/UA3F@master/clash/ua3f-cn.yaml






启动crash会出现两行报错,下面步骤是问了deepseek解决的
- 切换iptables后端的终极方法
如果系统同时安装了iptables-legacy
和iptables-nft
,直接通过符号链接强制指定:
1# 备份原有命令
2mv /usr/sbin/iptables /usr/sbin/iptables.bak
3mv /usr/sbin/ip6tables /usr/sbin/ip6tables.bak
4
5# 链接到legacy版本
6ln -s /usr/sbin/iptables-legacy /usr/sbin/iptables
7ln -s /usr/sbin/ip6tables-legacy /usr/sbin/ip6tables
8
9# 验证版本
10iptables --version
- 检查系统日志定位具体错误
1# 查看内核日志(重点关注nf_nat相关错误)
2dmesg | grep -i "nat\|conntrack\|iptables"
3
4# 查看ShellClash日志
5logread | grep "shellclash"
- 测试手动添加PREROUTING规则
1# 使用绝对路径强制操作
2/usr/sbin/iptables-legacy -t nat -N PREROUTING
3/usr/sbin/iptables-legacy -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 7890
4
5# 检查是否生效
6iptables-legacy -t nat -L PREROUTING
然后再启动crash -s start
或者crash然后输入1
安装UA3F
1#从URL安装UA3F
2opkg update
3opkg install curl libcurl luci-compat
4export url='https://blog.sunbk201.site/cdn' && sh -c "$(curl -kfsSl $url/install.sh)"
5service ua3f reload
启动UA3F
1#设置UA3F自动启动
2# 启动 UA3F
3uci set ua3f.enabled.enabled=1
4uci commit ua3f
5service ua3f start
1.配置静态IP(二选一)
如果你觉得方法2太麻烦,可以用这个方法
- 首先重启一下openwrt
- 手机或电脑连接openwrt的wifi,配置静态ip
- 比如:我的lan接口是192.168.1.1
- IP地址192.168.1.*(*表示2-254)
- 网关就是lanIP地址
- 子网掩码一般都是255.255.255.0
- dns配一个8.8.8.8就行
这样你就能访问openwrt后台了,然后直接去校园网认证界面,看到导航栏的mac地址是openwrt的地址,然后登录校园网,这样就是openwrt去获取到的校园网ip,在这个openwrt网段下的设备都可以上网。
2.安装python3配置认证脚本(二选一)
打开终端
1opkg update
2opkg install python3
3opkg install python3-yaml
在root目录下创建两个py文件
1touch ruijie.py
2touch config.py
下面是ruijie.py代码
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4import os
5import sys
6import fcntl # 文件锁
7import subprocess
8from datetime import datetime
9from json import loads as json_loads
10from os.path import dirname, join
11from urllib import parse, request
12from urllib.request import urlopen
13
14from config import read_cfg
15
16# 配置基础路径
17basedir = dirname(__file__) if not getattr(sys, 'frozen', False) else sys._MEIPASS
18
19cfg = read_cfg()
20
21headers = {
22 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
23 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
24 'Cookie': parse.quote(cfg['cookie']),
25 'Host': cfg['url']['server'].replace('http://', '').replace('https://', ''),
26 'Origin': cfg['url']['server'].replace('http://', '').replace('https://', ''),
27}
28
29headers.update(cfg['headers'])
30
31login_data = cfg['login_data']
32logout_data = cfg['logout_data']
33
34def notify(title: str, msg: str):
35 """命令行输出通知"""
36 print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {title}: {msg}")
37
38def test_internet(host: str = 'http://connect.rom.miui.com/generate_204', timeout: int = 1) -> bool:
39 """检测网络连通性(适配OpenWrt)"""
40 try:
41 # 使用ping检测基础网络
42 if subprocess.run(["ping", "-c", "1", "8.8.8.8"], timeout=2).returncode == 0:
43 return True
44 # 补充HTTP检测
45 resp = urlopen(host, timeout=timeout)
46 return resp.status == 204 if host.endswith('generate_204') else 200 <= resp.status <= 208
47 except Exception:
48 return False
49
50def connect():
51 """执行登录操作"""
52 req = request.Request(
53 cfg['url']['server'] + cfg['url']['login'],
54 data=parse.urlencode(login_data).encode() if login_data else None,
55 headers=headers,
56 method='POST'
57 )
58 try:
59 with request.urlopen(req, timeout=10) as res:
60 status = json_loads(res.read().decode())
61 if status['result'] == 'success':
62 notify('联网成功', status.get('message', '网络已连接!'))
63 else:
64 notify('联网失败', status.get('message', '未知错误'))
65 except Exception as e:
66 notify('错误', f'连接失败: {str(e)}')
67 sys.exit(1)
68
69def disconnect():
70 """执行注销操作"""
71 req = request.Request(
72 cfg['url']['server'] + cfg['url']['logout'],
73 data=parse.urlencode(logout_data).encode(),
74 headers=headers,
75 method='POST'
76 )
77 try:
78 with request.urlopen(req, timeout=10) as res:
79 status = json_loads(res.read().decode())
80 if status['result'] == 'success':
81 notify('断网成功', '已断开网络!')
82 else:
83 notify('断网失败', status.get('message', '未知错误'))
84 except Exception as e:
85 notify('错误', f'断网失败: {str(e)}')
86 sys.exit(1)
87
88def main():
89 # 单实例检测(文件锁)
90 lockfile = open('/tmp/ruijie.lock', 'w')
91 try:
92 fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
93 except BlockingIOError:
94 notify('警告', '程序已在运行,禁止多开!')
95 sys.exit(0)
96
97 # 网络检测逻辑
98 if cfg['funtion']['check_school_network']:
99 if not subprocess.run(["ping", "-c", "1", "172.31.0.3"], timeout=2).returncode == 0:
100 notify('环境检测', '未连接到校园网,程序退出')
101 sys.exit(0)
102
103 if test_internet():
104 if cfg['funtion']['disconnect_network']:
105 disconnect()
106 else:
107 notify('状态', '网络已连接,无需操作')
108 else:
109 connect()
110
111if __name__ == '__main__':
112 main()
找到"172.31.0.3"
改成你校园网的ip
下面是config.py的代码
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4import sys
5import os
6from os.path import dirname, join
7import yaml
8
9current_config_version = 3
10config_path = join(dirname(sys.argv[0]), 'config.yml')
11
12def str_value(target: dict):
13 """递归转换值为字符串(保持原有逻辑)"""
14 for k, v in target.items():
15 if isinstance(v, dict):
16 str_value(v)
17 elif isinstance(v, (int, bool)): # 处理整型和布尔值
18 target[k] = str(v).lower()
19 elif v is None:
20 target[k] = ''
21 return target
22
23def write_config():
24 """生成默认配置文件(移除GUI弹窗)"""
25 config_template = '''\
26# 本配置文件内容需要根据学校服务器设置动态调整
27main:
28 version: 3 # 配置文件版本号,请勿更改
29
30funtion:
31 check_school_network: true
32 disconnect_network: true
33
34url:
35 server: http://172.31.0.3
36 login: /eportal/InterFace.do?method=login
37 logout: /eportal/InterFace.do?method=logout
38
39# ...(其他配置项保持原样,此处省略)...
40'''
41 try:
42 with open(config_path, 'w', encoding='utf-8') as fp:
43 fp.write(config_template)
44 print(f"[INFO] 已生成新配置文件: {config_path}")
45 except Exception as e:
46 print(f"[ERROR] 配置文件创建失败: {str(e)}")
47 sys.exit(1)
48
49def read_cfg() -> dict:
50 """读取配置文件(命令行交互版)"""
51 # 检查配置文件是否存在
52 if not os.path.exists(config_path):
53 write_config()
54 print("[WARN] 配置文件不存在,已生成模板,请修改后重试!")
55 sys.exit(1)
56
57 # 读取配置内容
58 try:
59 with open(config_path, 'r', encoding='utf-8') as fp:
60 cfg = yaml.safe_load(fp)
61 except Exception as e:
62 print(f"[ERROR] 配置文件读取失败: {str(e)}")
63 sys.exit(1)
64
65 # 版本校验
66 config_version = cfg['main'].get('version', 0)
67 if config_version != current_config_version:
68 print(f"[ERROR] 配置文件版本不兼容(当前版本要求:{current_config_version})")
69 sys.exit(1)
70
71 # 数据预处理
72 for key in ['url', 'login_data', 'logout_data']:
73 if key in cfg and cfg[key] is not None:
74 cfg[key] = str_value(cfg[key])
75
76 # 基础校验
77 if cfg['login_data'].get('userId') == '00000000000':
78 print("[ERROR] 请修改配置文件中的userId字段")
79 sys.exit(1)
80
81 # URL格式修正
82 if cfg['url']['server'].endswith('/'):
83 cfg['url']['server'] = cfg['url']['server'][:-1]
84
85 return cfg
然后用命令python ruijie.py
运行,然后会多出来一个config.yml
文件
配置config.yaml文件
由于我们wifi连接的树莓派,mac地址是树莓派的地址,如果地址栏mac地址是你的电脑,那么你需要修改一下mac地址,然后再进行此操作。断开校园网,用电脑再次认证一遍,认证之前需要打开F12
我打####的地方都需要填,根据上面你获取的信息填
1# 本配置文件内容需要根据学校服务器设置动态调整
2main:
3 version: 3 # 配置文件版本号,请勿更改
4
5funtion:
6 check_school_network: true # 是否检查校园网环境
7 disconnect_network: true # 是否开启断网功能
8
9url:
10 #####改成你学校的ip地址
11 server: http://172.31.0.3 # 校园网登录服务器的地址,用于判断当前网络环境是否为校园网环境
12 login: /eportal/InterFace.do?method=login # 校园网登录地址,无需服务器地址
13 logout: /eportal/InterFace.do?method=logout # 校园网断线地址,无需服务器地址
14
15# 请根据抓包结果调整条目与内容
16cookie: '##########'
17
18# 请根据抓包结果调整条目与内容(?key1=value1&key2=value2)
19# 请不要在密码栏填入明文密码
20login_data:
21 userId: '##########'
22 password: ##########
23
24 service: '#######'
25 queryString: #########
26 operatorPwd:
27 operatorUserId:
28 validcode:
29 passwordEncrypt: true
30
31# 一般来说不填参数也能用,但请不要删除(?key1=value1&key2=value2)
32logout_data: {}
33
34headers:
35 Referer: ############
把改好的信息填入你的config.yaml
退出的校园网,终端运行python ruijie.py
看看是否能连接成功http://ua.233996.xyz/
打开这个网站,看看是否被修改成FFF
如果没有成功,可以看看是不是ShelClash没有运行,如果运行了,并且网络也能ping通,那么多刷新几遍试试,或者重启一下试试
定时断网重连
点开管控>任务设置>定时执行任务
自定义脚本写下面代码
1if ! ping -c 1 8.8.8.8 >/dev/null 2>&1; then
2 crash -s stop
3 sleep 10
4 /usr/bin/python3 /root/ruijie.py &
5 sleep 10
6 crash -s start
7fi
添加一条任务,记得打上对勾,最后面框框是1分钟执行一次,你可以按需更改,最后记得保存
我遇到过的问题
重启的话网络可能会没有自动连接上,那么就手动连接一下,再启动ShellClash。目前还没有找到100%可以自动启动的方法。
如果你的电脑连接上wifi并且可以上网,其他设备连接上会跳认证界面,你可以找到网络->接口把wan口删掉然后创建一个静态的wan口保存一下,然后再删了wan修改回去。然后电脑断掉wifi再连接,基本上就可以了。
有陌生设备连接时会断网,在终端再运行一遍
python ruijie.py
认证一下,目前没有找到更好的办法。把2做了一遍后手机连接还是跳认证界面,将wifi关掉再打开,或者切换一下网络,然后再重新连接就可以了。
终端不显示,
etc/init.d/ttyd
如果你让openwrt用wifi连接的校园网,你再开热点的话,会遇到打不开的情况,输入下面的代码
1rm /etc/config/wireless 2wifi config 3wifi down 4wifi up
参考
- https://www.bilibili.com/video/BV1yr4meeENt/?spm_id_from=333.1391.0.0
- https://www.bilibili.com/video/BV1qM411w7W5/?spm_id_from=333.1391.0.0&vd_source=bde3073c7fac1db05c5ea47eed6aa6a6
- https://github.com/IDeLoveYou/SGU-Script认证脚本是在这个作者代码的基础上更改的
吐槽
这玩意折磨了我两个星期,太难受了,走了好多弯路🥲