前置为刷好 OpenWrt 的路由器,其 WAN 口接校园网并获取地址;校园网为门户认证,登录是带参数的认证请求,把这条请求搬到路由器上即可实现自动认证。
在浏览器中抓取认证请求,先在电脑上用 curl 验证,再把请求中的地址参数换成路由器 WAN 口地址在路由器上验证,最后写脚本自动取 WAN 口地址并认证,加入计划任务。
◆ 抓取认证请求
在校园网登录页按 F12 打开开发者工具,切到网络面板并勾选保留日志,正常登录一次,在请求列表中找到认证接口的请求状态码 200,右键复制为 cURL。
该接口为门户的 JSONP 形式,请求带 callback=dr1003,成功时返回 dr1003({"result":1,...}),判断成功看返回文本中的 result 是否为 1。
参数中与脚本相关的是几项:user_account 为门户生成的账号串,示例为 ,0,学号@telecom 的 URL 编码形式,带运营商后缀,原样保留而不手工拼接;user_password 为 URL 编码后的密码,密码含特殊字符时直接粘贴抓到的编码值;wlan_user_ip 为认证对象的地址,是需要替换的一项;wlan_user_mac、wlan_ac_ip、wlan_ac_name 与 wlan_user_ipv6 按抓到的固定值或空值保留;jsVersion、terminal_type、lang 与 v 为版本与随机参数,同样保留原值。
◆ 在电脑上验证
先在已连校园网的电脑上重放这条请求,Windows 10 与 11 自带 curl.exe,在 CMD 中执行并用双引号包裹整条 URL;PowerShell 中 curl 是 Invoke-WebRequest 的别名,需改用 curl.exe。
curl "http://门户地址/drcom/login?callback=dr1003&login_method=1&user_account=这里按照实际获取的数据&user_password=URL编码后的密码&wlan_user_ip=10.158.1.100(示例)&wlan_user_ipv6=&wlan_user_mac=000000000000&wlan_ac_ip=&wlan_ac_name=&jsVersion=4.2.1&terminal_type=1&lang=zh-cn&v=1253"
门户地址与路径以抓到的请求为准;地址、账号与密码均为示例值,替换为本机抓到的内容。返回文本中 result 为 1 表示认证成功,为 0 时按 msg 字段给出的原因排查,常见为密码错误与账号状态异常,也可能是学校网络抽风
◆ 在路由器上认证
路由器 WAN 口从校园网获取地址后,认证请求中的 wlan_user_ip 需换成该地址。先在路由器上查看 WAN 口地址,直接从接口页面查看即可。
接口名不为 wan 时换成实际名称,多 WAN 场景下每个 WAN 口各有地址,认证需按口分别进行。
把上一步的地址填入请求的 wlan_user_ip 后,在路由器上执行同一条 curl 命令,返回值判断与电脑上一致。
◆ 脚本与计划任务
脚本:读取 WAN 口当前地址,替换请求中的 wlan_user_ip,发起认证;地址在重启或租约变化后可能改变,每次执行时重新读取即可,不用改脚本。
wan_ip=$(ifstatus wan | jsonfilter -e '@["ipv4-address"][0].address')
curl -s "http://门户地址/drcom/login?callback=dr1003&login_method=1&user_account=实际值&user_password=URL编码后的密码&wlan_user_ip=${wan_ip}&wlan_user_ipv6=&wlan_user_mac=000000000000&wlan_ac_ip=&wlan_ac_name=&jsVersion=4.2.1&terminal_type=1&lang=zh-cn&v=1253"
脚本保存为文件并赋予执行权限,在 OpenWrt 的计划任务页面添加执行周期:
0 */6 * * * /root/hnu-login.sh
五个字段依次为分、时、日、月、周,*/6 表示每 6 小时一次;重新认证的实际需求并不频繁,约一个月一次,6 小时的间隔留出余量。需要更快恢复时,可在计划任务之外加一次连通性检测,请求 generate_204 返回非 204 时立即执行认证脚本。
◆ 验证与排错
认证成功以返回文本中的 result 为 1 为准;已在线时重复认证一般返回已登录,属正常结果。
认证失败按 msg 字段排查:密码错误核对编码后的密码;账号状态异常需在自助服务页面处理;地址为空或错误时确认 WAN 口是否已获取地址。
IPv6 侧的 NAT 方案在 OpenWrt 上已有支持,实际使用效果未达预期,本文不展开。