一套跑在 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
50 lines
2.9 KiB
Bash
50 lines
2.9 KiB
Bash
#!/bin/bash
|
|
# drouter 八模块回归自检(构建保护模式下应全部写成到磁盘,不启动服务)
|
|
B=http://127.0.0.1:8080
|
|
C="curl -s"
|
|
TOK=$($C $B/api/login -X POST -H 'Content-Type: application/json' \
|
|
-d '{"username":"admin","password":"admin123"}' \
|
|
| python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get("data") or {}).get("token",""))')
|
|
if [ -z "$TOK" ]; then echo "登录失败"; exit 1; fi
|
|
echo "token ok: ${TOK:0:12}..."
|
|
|
|
A(){ $C $B/api/apply -X POST -H "X-Token: $TOK" -H 'Content-Type: application/json' -d "$1" \
|
|
| python3 -c 'import sys,json;d=json.load(sys.stdin);print("ok=",d.get("ok"),"|",d.get("msg_cn") or d.get("code") or "")'; }
|
|
|
|
echo "--- 1 dnsmasq ---"
|
|
A '{"module":"dnsmasq","data":{"lan_iface":"ens18","lan_ip":"192.168.7.3","dhcp_enabled":false,"pool_start":"192.168.7.100","pool_end":"192.168.7.200","lease_time":43200,"dns_mode":"custom","dns_custom":"223.5.5.5,119.29.29.29","options":[{"enabled":true,"code":"6","value":"192.168.7.3"},{"enabled":true,"code":"3","value":"192.168.7.3"}]}}'
|
|
echo "--- 2 nft_v4 ---"
|
|
A '{"module":"nft_v4","data":{"wan_iface":"","lan_iface":"ens18","allow_estab":true,"icmp":true,"input_policy":"drop"}}'
|
|
echo "--- 3 nft_v6 ---"
|
|
A '{"module":"nft_v6","data":{"wan_iface":"","lan_iface":"ens18","allow_estab":true,"icmpv6":true,"input_policy":"drop"}}'
|
|
echo "--- 4 radvd ---"
|
|
A '{"module":"radvd","data":{"lan_iface":"ens18","prefix":"fd00:7::/64","adv_link_mtu":1500}}'
|
|
echo "--- 5 dhcpv6 ---"
|
|
A '{"module":"dhcpv6","data":{"wan_iface":"","lan_iface":"ens18","pd_len":60}}'
|
|
echo "--- 6 upnp ---"
|
|
A '{"module":"upnp","data":{"enable":false,"lan_iface":"ens18","wan_iface":""}}'
|
|
echo "--- 7 ntp ---"
|
|
A '{"module":"ntp","data":{"servers":["ntp.aliyun.com","time.cloudflare.com"]}}'
|
|
echo "--- 8 ppp ---"
|
|
A '{"module":"ppp","data":{"iface":"ens18","username":"test12345","password":"pass67890","isp":"ct","mtu":1492}}'
|
|
|
|
echo "=== 生成文件落盘检查 ==="
|
|
ls -la /etc/dnsmasq.d/drouter.conf /etc/nftables.d/drouter-v4.nft /etc/nftables.d/drouter-v6.nft \
|
|
/etc/radvd.conf /etc/dhcpcd.conf /etc/miniupnpd/miniupnpd.conf /etc/chrony/chrony.conf \
|
|
/etc/ppp/peers/drouter-wan 2>&1
|
|
|
|
echo "=== 安全不变量 ==="
|
|
echo -n "dnsmasq: "; systemctl is-active dnsmasq 2>&1
|
|
echo -n "radvd: "; systemctl is-active radvd 2>&1
|
|
echo -n "dhcpcd: "; systemctl is-active dhcpcd 2>&1
|
|
echo -n "miniupnpd:"; systemctl is-active miniupnpd 2>&1
|
|
echo -n "chrony: "; systemctl is-active chrony 2>&1
|
|
echo -n "53端口: "; ss -lnu | grep -c ':53 ' || true
|
|
echo -n "67端口: "; ss -lnu | grep -c ':67 ' || true
|
|
echo -n "VNC5900: "; ss -lnt | grep -c ':5900'
|
|
echo -n "BUILD_MODE: "; test -f /etc/drouter/BUILD_MODE && echo "存在(保护中)" || echo "不存在"
|
|
echo -n "ens18: "; ip -4 -o addr show ens18 | awk '{print $4}'
|
|
echo "=== nft 规则 ==="
|
|
nft list ruleset 2>/dev/null | head -5 || echo "nftables 表为空"
|
|
echo "REGRESSION_DONE"
|