外观
控制台 apps/control
DN42 控制平面的管理 Web 控制台,生产部署 https://console.natlan.io/。
基于 SvelteKit(adapter-static)的纯客户端 SPA,以 Authorization: Bearer 直连 控制服务器的 UI / Admin API。控制台把「节点应该跑什么配置」做成可视化闭环:在浏览器 里管理节点、peering、BGP 会话、路由策略、DNS 与令牌,后端合成新的 DesiredState 并 摇门铃,节点 Agent 拉取、渲染、对账、回报——控制台再把健康、路由、漂移、流量、BGP 抖动观测渲染出来。
安全模型:控制台本身不持有任何密钥。凭据(账号会话令牌或 admin token) 只存在于浏览器
localStorage,以 Bearer 头直连后端;控制面不提供远程 shell 或 任意命令执行接口。

1. 路由与功能
| 路由 | 模块 | 说明 |
|---|---|---|
/ | 总览四分屏 | 概述(世界地图拓扑:可平移缩放、区/国家/城市聚簇、WG 链路大圆弧 + 机群 KPI + peering 异常表) |
/traffic | 流量 | 本期 vs 上期相对变化、构成半环、按对端 AS 榜 |
/routing | 路由 | 全机群规模 / 协议族 / RPKI 验证 + 分家族趋势 + Top 起源 AS |
/flaps | BGP 抖动 | 会话 / 前缀 / 告警三层检测:fleet 速率仪表与活动时序、前缀 flap 榜(origin 归因 + MOAS 标红 + 根因区定位:近端/起源/路径/多源徽章、嫌疑点、AS 路径条)、对端烈度榜、告警事件流 |
/flaps/peers/[asn] | 单对端详情 | F6 行下钻:severity + 会话状态 + 前缀表 + 告警时间线 |
/nodes | 节点列表 | 卡片视图 + 可观测性 tab(CPU / RSS / 流量 / 对账失败四张 top-N 图) |
/nodes/[id] | 节点详情 | 五组页签,见下 |
/registrations | 注册审批 | 节点注册放行名单审批 |
/enrollment-tokens | 注册令牌 | enrollment token 的签发与管理 |
/provision | 导入下发 | 直接粘贴 / 从现有节点克隆 DesiredState JSON 整节点灌入 |
/dns-groups | DNS 组与 Anycast | DNS 组、zone、record 管理与节点订阅 |
/agent-releases | Agent 版本 | wheel 上传、全局目标版本、逐节点合规与活性表 |
/audit | 审计日志 | 管理动作审计流水(游标分页 + 服务端搜索) |
/account | 账号 | 改密 |
/login | 登录 | 双方式,见第 3 节 |
节点详情的五组页签:
| 页签 | 内容 |
|---|---|
| 概览 | 漂移表 / 趋势 / agent 自观测 |
| 互联 | peering / 接口 / BGP 会话 + flap 证据 / 内部拓扑 / 拨测(ping·mtr·traceroute 流式输出) |
| 路由 | 三视图:路由表 / 过滤前 / 调优 |
| DNS | 节点的 DNS 组订阅与记录 |
| 运维 | generation 历史 diff 回滚 / 状态事件 / 期望状态 / 令牌 |
处置(mitigation):从抖动板块一键发起的人工处置——拒收前缀 / 断开对端, 声明式可撤销、就地生效清单、全程审计。检测层只告警、绝不自动抑制。
一键互联向导:引导式 peer 表单,地址单一真相源(本端 LL 自动派生、对端只填一次、 复用节点钥),免手填原始 JSON,且提交是原子的。
体验:四语 i18n(简中 / 繁中 / 日 / 英)、亮 / 暗 / 跟随系统三档主题、35s 自动 刷新可暂停、URL 即状态(任意筛选/页签可分享)、骨架屏防跳动、可收缩侧栏、登录前防白闪。 这些行为背后的约定见 internals/interaction-contracts.md。
2. 界面
截图摄于生产实例,默认暗色主题。重截方式见 guides/capture-screenshots.md。
| 机群概览(暗色) | 抖动(flap 检测与根因定位) |
|---|---|
![]() | ![]() |
| 流量 | 路由 |
![]() | ![]() |
| 节点列表 | 节点详情 |
![]() | ![]() |
| 注册审批 | 注册令牌 |
![]() | ![]() |
| 导入下发 | DNS 组 |
![]() | ![]() |
| 审计日志 | 登录(双方式 + Cap 人机验证) |
![]() | ![]() |
3. 登录
两种方式并存,共用同一把 Bearer:
| 方式 | 凭据 | 人机验证 | 地址覆盖 |
|---|---|---|---|
| 管理员账号(默认) | 用户名 + 密码 | Cap(自托管,服务端硬校验) | 无,固定连默认控制面 |
| API Token | admin token | 无(机器凭据) | 有,可指向任意控制服务器 |
上次成功的方式记在 dn42.admin.loginMethod,决定默认页签。后端不支持账号体系时 (该路由返回 404/405),前端把它解释为「旧后端」并引导改走 API Token。
接口契约见 api/control.md。
4. 技术栈
- SvelteKit 2 + Svelte 5(runes 模式) + TypeScript
adapter-static——ssr=false/prerender=false,纯客户端 SPA,所有路由经index.html回退- bits-ui(无样式组件原语)、Chart.js(趋势 / 环形 / 火花线)、 Inter Variable
- Vite 8
- 共享层:
$ui(组件与设计令牌)
5. 部署
生产部署是 Cloudflare Git 关联 Worker(dn42-control-webui):push 到默认分支 即自动构建部署,本地不跑 wrangler deploy。
apps/control/wrangler.jsonc 是部署配置的事实源,必须保留——否则构建向导会改写 构建命令。其中:
| 配置 | 作用 |
|---|---|
main: ./worker/index.js | 薄壳 Worker,只为给每份 HTML 盖逐请求 CSP nonce |
assets.not_found_handling: "single-page-application" | SPA 回退(Pages 时代的 static/_redirects 已移除——Workers 资产会把它判成重定向死循环) |
assets.run_worker_first: ["/*", "!/_app/*"] | 文档过 Worker 拿 nonce,内容哈希产物直供 |
workers_dev: false | 关掉 *.workers.dev 第二入口 |
console.natlan.io 自定义域不在 wrangler.jsonc 里(与门户不同),由账号侧的 Workers 自定义域绑定承载。
完整步骤见 guides/deploy-workers.md,CSP 细节见 reference/csp.md。
自行托管
构建产物是 build/ 下的纯静态文件,可用任意静态服务器伺服。两点必须处理:
- SPA 回退:所有未知路径回退到
index.html(HTTP 200),否则刷新子路由会 404。 nginx:try_files $uri $uri/ /index.html; - CORS:后端需把该来源加入 CORS 白名单,浏览器才能跨域直连 Admin API。
6. 配置
见 reference/configuration.md。控制台相关的是 VITE_CONTROL_API、dn42.admin.* 存储键,以及登录页的运行时地址覆盖。
7. 许可证
apps/control/LICENSE —— GPL-3.0。











