Files
drouter/scripts/test-frontend-contract.sh
liuzhuohua 64df3cf331 feat: Drouter 1.0.0 —— Debian 13 软路由管理系统
一套跑在 Debian 13 (trixie) 上的软路由管理系统,提供 43 个功能页面的
Web 管理面板:WAN 接入、PPPoE 多拨、DHCP/DNS、IPv6、防火墙、QoS 限速、
访问控制、DDNS、文件共享、Docker 管理等。

核心设计原则:不重新实现任何协议
  PPPoE 交给 ppp,DHCP 交给 dnsmasq,IPv6 RA 交给 radvd,NAT 交给 nftables。
  Web 面板只做三件事:渲染原生配置文件 → 语法预检 → 原子写入并 reload。
  面板删掉后,系统仍是一台配置完好的 Debian 路由器。

安全默认值
  · 安装后不接管网络:不改默认路由、不开 IP 转发、不启动 DHCP 服务
  · 所有改网络的动作都需要用户在面板上亲手点「应用」
  · 避开 5900 端口,不触碰 VNC / X 会话
  · 配置写入前先做语法预检,失败则回滚

架构
  · backend/  Python 3 标准库,零第三方依赖(9 个模块)
  · web/      原生 JS/CSS,无构建步骤
  · 常驻 helper 通过 Unix socket 提供 75 个动作,socket 不可用时回退 subprocess
  · 鉴权走 X-Token 请求头

打包
  · packaging/build-deb.sh            → drouter_1.0.0_all.deb(含 6 个 systemd 单元)
  · scripts/make-offline-deps.sh      → 236 个依赖 .deb + 本地仓库索引
  · packaging/build-offline-bundle.sh → 自包含离线包,目标机零外网可装
  · packaging/build-docker.sh         → 容器镜像(体验用)

测试
  40 套单元测试 + 3 个前端检查脚本(菜单映射 / 离线渲染 / 手机适配),
  全部挂在 devtools/sync.sh 的预检链里。

许可:MIT
2026-09-30 19:26:24 +08:00

85 lines
3.6 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 前端契约回归:验证登录能拿到 token,且每个前端页面依赖的接口都返回 200
B=http://127.0.0.1:8080
echo "=== 1. 登录应返回真实 token ==="
RESP=$(curl -s $B/api/login -X POST -H 'Content-Type: application/json' \
-d '{"username":"admin","password":"admin123"}')
echo "$RESP" | python3 -m json.tool --no-ensure-ascii
TOK=$(echo "$RESP" | python3 -c 'import sys,json;print((json.load(sys.stdin).get("data") or {}).get("token") or "")')
if [ -z "$TOK" ]; then echo "❌ token 为空 —— 登录仍坏"; exit 1; fi
echo "✅ token = ${TOK:0:16}..."
echo
echo "=== 2. 用该 token 请求各页面依赖接口 ==="
FAIL=0
check() {
local ep="$1" m="${2:-GET}" body="${3:-}"
local args=(-s -o /tmp/o.json -w '%{http_code}' "$B$ep" -H "X-Token: $TOK")
[ "$m" = POST ] && args+=(-X POST -H 'Content-Type: application/json' -d "${body:-{\}}")
local code=$(curl "${args[@]}")
local ok=$(python3 -c 'import json;print(json.load(open("/tmp/o.json")).get("ok"))' 2>/dev/null)
printf " %-22s %-5s HTTP=%-4s ok=%-6s %s\n" "$ep" "$m" "$code" "$ok" \
"$( [ "$code" = 200 ] && [ "$ok" = True ] && echo ✔ || { echo ✘; FAIL=1; } )"
}
# 概览页
check /api/sysinfo; check /api/services; check /api/ifaces
check /api/ipv6; check /api/routes
# 网卡/WAN/LAN
check /api/iface/meta; check /api/config
# 防火墙/日志/诊断/电源/用户/升级
check /api/nft; check /api/leases; check /api/users; check /api/ntp
check /api/logs; check /api/journal; check /api/audit
check /api/snapshot/list; check /api/upgrade/info
# 构建保护模式(前端用 GET)
check /api/buildmode GET
check /api/pppoe/saved
# 新增:Web 端口 / 网卡配置方式 / 拨号实时日志
check /api/webport
check /api/iface_method
check /api/ppp/log
# 新增:IPv6 连通性测试工具
check /api/diag POST '{"tool":"ipv6test","which":"cn"}'
# 新增:自动快照策略 / 紧急救援通道
check /api/snapshot/auto
check /api/rescue
# 新增批次(#17–#22):通用 API / 依赖自检 / NAT / 软加速 / VLAN / WOL / 文件管理
check /api/openapi
check /api/examples
check /api/deps/check
check /api/vlan
check /api/wol
check /api/nat/last
check /api/accel POST '{"op":"get"}'
# 新增批次(#23–#25):PPPoE 多拨 / QoS 智能限速 / DPI 应用识别
check /api/pppoe-multi
check /api/pppoe-multi POST '{"op":"get"}'
check /api/pppoe-multi/log POST '{"idx":1}'
check /api/qos
check /api/qos POST '{"op":"get"}'
check /api/dpi
check /api/dpi POST '{"op":"get"}'
check /api/dpi POST '{"op":"plan","which":"apt"}'
check /api/dpi/log
check '/api/files/list?path=/etc/drouter'
check '/api/files/read?path=/etc/drouter/snapshot.conf'
# 写操作:只保存(不应用)
check /api/config POST '{"module":"system","data":{"hostname":"debian-primaryrouter"}}'
echo
echo "=== 3. 关键字段核对 ==="
curl -s $B/api/buildmode -H "X-Token: $TOK" | python3 -c '
import sys,json;d=json.load(sys.stdin)
print(" buildmode.data.enabled =", d["data"]["enabled"], "(解除后应为 False)")'
curl -s $B/api/ifaces -H "X-Token: $TOK" | python3 -c '
import sys,json;d=json.load(sys.stdin)
for i in d["data"]:
if i["name"]=="lo": continue
n=i.get("name"); m=i.get("mac"); st=i.get("oper") or i.get("operstate") or ""
print(" %-8s mac=%s state=%s" % (n, m, st))'
curl -s $B/api/routes -H "X-Token: $TOK" | python3 -c '
import sys,json;d=json.load(sys.stdin)
print(" 默认路由:", [(r["gateway"], r["dev"]) for r in d["data"]["v4"] if r["dst"]=="default"])'
echo
[ $FAIL = 0 ] && echo "FRONTEND_CONTRACT_OK ✔ 全部接口正常" || echo "FRONTEND_CONTRACT_FAIL ❌ 存在异常接口"