自托管服务器监控面板 —— 无 Agent 采集、毛玻璃(glassmorphism)界面、带功耗计量、WireGuard 组网管理与内网穿透平台托管。 通过 SSH 直连被监控机采集真实指标,Docker 单容器部署,公开页永不暴露 IP 等敏感信息。
- 双主题前端架构(v2.8 新增):默认主题 Toy Neubrutalism(
/,玩具积木风)与经典 Sky Glass · 天空玻璃拟态(/classic/)两套独立 Vue 应用打包进同一镜像,侧栏主题中心一键互切、偏好存 LocalStorage(beacontower_preferred_theme);架构预留主题注册表,未来新主题即插即用(设计见 doc/18) - 零 Agent 采集:面板定时 SSH 连接各节点执行只读命令(
/proc、df、sysfs),被监控机不装任何东西;面板自身自动作为「本机」节点展示(本地进程采集,免 SSH) - 系统画像自动回读:添加节点只需 SSH 地址 + 账号,主机名 / 系统 / CPU / 内存 / 磁盘 / 虚拟化 / 公网 IP 归属自动探测(v2.7.3 修复定位不可用时把「未定位」占位写进节点的问题:在线多源兜底 + 可选离线库,定位失败可随时「重新定位」)
- 面板代管密钥(v2.7 新增):添加节点默认「自动密钥」——填一次密码引导,面板生成节点专属 Ed25519 密钥装机并验证,之后 SSH 全走密钥、面板不再存储密码;密钥失联(重装系统等)在节点详情「修复密钥」重输一次密码即可重建,见下文
- RAPL 功耗监控(Intel 机型 / 含电池笔记本):实时整机功率、CPU/内存分项、温度、频率;电池放电自动校准基础功耗,月度 kWh 与电费估算
- 实时总览:KPI 玻璃条 + 全网吞吐趋势 + 节点卡片网格,SSE 推送 + 10 秒保底轮询;节点详情页 1h/6h/24h/7d 历史曲线
- WG 组网管理(v2.0 新增):在面板里一键完成 WireGuard 星型组网——密钥生成、conf 渲染推送、防火墙放行、成员增删全部自动化,见下文
- 内网穿透平台托管(v2.1 新增):接入 Sakura 与 ChmlFrp 两个国内内网穿透平台——账号用量与余额、隧道在线状态与今日/累计流量、节点负载与倍率一览;支持新建/改参/启停/锁定/迁移隧道、下载 frpc 配置、ChmlFrp 子域名管理;OAuth 令牌自动续期,失效时面板内弹窗重新授权,见下文
- Cloudflare Tunnel 接入(v2.6 新增):第三穿透平台补足海外链路——粘贴一个 API Token 即完成绑定(Account/Zone ID 自动发现),隧道以「统一容器」模型管理:面板专属一条 cloudflared 隧道,新增/删除节点(域名路由)即挂进/移出该容器,托管只需一个 cloudflared 容器且改配置免重启;独立专线(自行建的隧道)同步只读展示绝不改动;今日流量经 GraphQL Analytics 按域名回填,运维手工建的隧道同步展示为只读,见下文
- 穿透客户端托管(v2.3 新增):隧道建好后不必再登录节点跑 frpc——面板经 SSH 在任意节点上探测/自动安装 Docker、拉镜像、下发配置(0600)并起容器,隧道增删改后一键「同步配置」,移除时连同节点上的容器与配置一起清理;同一隧道只允许一个客户端,部署时会禁选已被托管的隧道,隧道行也能一眼看出「面板托管」并「释放占用」
- 穿透状态(游客版):公开页多一个
/tunnels——今日流量消耗、隧道在线数与在用节点健康度(名称/分组/负载/在线时长)。账号画像、套餐余量与节点域名不在白名单内,公开页永不渲染(设计见 doc/13 §12) - 组网状态(游客版,v2.4 新增):公开页多一个
/mesh——中心/备援巡检健康度、网内服务器成员在线数、在网设备数与全网今日/本月 WG 中转流量。网段拓扑、成员 WG IP、中心端点/端口、公钥指纹与巡检错误原文均不下发,设备成员只报数量(设计见 doc/12 §17) - 管理面板:初始化向导 → 登录 → 节点管理(试连回读画像、排序/隐藏/暂停、功耗校准)、采集展示设置、安全与账号(会话管理 / 改密踢会话)、审计日志
- 安全设计:SSH 凭据 AES-256-GCM 加密存储、Argon2id 密码哈希、CSRF 双提交、登录限速封禁、TOFU 主机指纹(可选严格模式)、公开 API 字段白名单
- 视觉:毛玻璃(glassmorphism)设计语言 —— v3 视觉全量重构进行中(旧「天空信标」配色已废弃),动效尊重
prefers-reduced-motion/prefers-reduced-transparency
| 总览(默认主题 · Toy Neubrutalism) | 总览(Sky Glass · /classic/) |
|---|---|
| 节点详情 · 资源/功耗一屏尽览 | 历史曲线 · 功耗与每日流量 |
|---|---|
toy 主题总览截图来自合成数据的演示实例(
docs/img/overview-toy.png),节点名/流量数字均为演示值,非真实环境。
面向「多台 VPS + 家庭 NAT」场景的 WireGuard 控制面:利用节点管理中已录入的 SSH 凭据,
把手工逐台 wg genkey / 手写 conf / 敲防火墙规则的过程,压缩成面板里的几次点击。
- 一键组网:选中心 + 勾成员 → 面板生成密钥、渲染 conf、经 SSH 推送、自动放行 UDP、拉起接口、逐节点验证
- 热操作不断连:hub 增删 peer 走
wg set+ conf 追加;成员变更用wg syncconf,存量隧道零中断 - 主备中心(A/B 轮换):现役 + 温备援随时一键切换;新机接管可继承现役身份(成员只改 Endpoint 一行)
- 新机一键变备援(v2.7.2):网外节点卡片一个「配置为备援」把整条链路跑完(生成密钥 → 全量 conf → 装包/放行/拉起 → 真握手实测),进度落任务弹窗; 不需要预先在机器上手工配 WG,唯一人工项是到云控制台放行 UDP。(机器上已有手工 WG 的走「只读登记」,只读不写。)
- 任务全过程日志(v2.7.3):组网任务每个节点的执行日志边跑边写(预检/装机/放行/配置/自检逐段带耗时戳),失败现场保留原文、重试不再互相覆盖;UDP 实测补「第几次尝试成功 + 单次 RTT」明细
- 凭证中心:使用端(Mac/Win/iPhone)conf 在线预览、二维码扫码、打包下载(zip 内按平台命名);每台设备一个 peer,PSK 可选; 新增使用端后直接出二维码;导入成员(面板无私钥)可「生成二维码」——同 IP 同 PSK 换面板托管密钥并在所有中心整体替换
- 巡检:每 5 分钟读
wg dump判活、按日累计中心转发流量(月度额度提醒)、公钥漂移/配置外部改动告警 - 面板宿主可入网:本机节点经宿主 SSH 接入组网(容器无 NET_ADMIN 时走宿主管理)
面板只写 WG 相关状态(conf / 防火墙 / sysctl),其余一律只读。设计细节见 doc/12。 组网页截图来自合成数据的演示实例(IP 均为文档保留段 203.0.113.x / 10.66.66.x),非真实环境。
接入 Sakura 与 ChmlFrp 两个国内内网穿透平台,两平台数据归一化展示在同一份视图里: 平台卡(配额/剩余流量/签到)→ 账号用量 → 流量历史曲线 → 隧道统一列表(跨平台新建/改参/启停/锁定/迁移、下载 frpc 配置)→ 客户端托管 → 在用节点负载;ChmlFrp 免费二级域名管理。OAuth 令牌自动续期,失效时面板内弹窗重新授权。
v2.6 新增 Cloudflare Tunnel(第三平台,海外链路):绑定只需粘贴一个 API Token(Account/Zone ID 自动发现,「?」帮助弹窗带中英双语获取指引)。
Cloudflare 的模型是「一个 Tunnel = 一个连接器容器」,面板据此用统一容器管理:所有面板新建的节点(域名路由)都挂进面板专属的一条物理隧道(beacontower-managed),托管时也只需要一个 cloudflared 容器,增删节点云端即生效、无需重启;你在 CF 后台手工建的独立专线(一服务一线)同步为只读展示,面板绝不改动。今日流量经 Cloudflare GraphQL Analytics 按域名聚合回填。设计细节与 E2E 记录见 doc/16。
隧道建好后,客户端也能交给面板托管:选平台 + 选节点 + 勾隧道,面板经 SSH 完成 Docker 探测/自动安装、
拉镜像、配置下发(0600,仅经 stdin 落盘)、起容器,并回读状态与日志;隧道增删改后列表点「同步配置」,
移除时连带清理节点上的容器与 /etc/beacontower-frpc/(只碰带 beacontower.managed=frpc 标签的自建容器)。
游客版公开页多一个 /tunnels——今日流量消耗、隧道在线数与在用节点健康度(名称/分组/负载/在线时长)。账号画像、套餐余量与节点域名不在白名单内,公开页永不渲染(设计见 doc/13 §12)。
截图来自合成数据的演示实例(隧道/节点名与流量均为演示值,节点域名统一为
*.demo.example保留样式域),非真实环境。
# Docker 单容器(推荐)
cp .env.example .env # 填入 BEACON_MASTER_KEY(openssl rand -hex 32)
docker compose up -d --build
# 打开 http://127.0.0.1:8080,首次访问 /admin 完成管理员初始化
# 本地开发(前后端分离)
cd web && npm install && npm run dev # http://localhost:5173(/api 代理到 8080)
BEACON_DATA_DIR=./data go run . # http://127.0.0.1:8080| 层 | 选型 |
|---|---|
| 后端 | Go 1.26 + Gin + SQLite(modernc.org/sqlite 纯 Go,无 CGO) |
| 前端 | Vue 3 + Vite + Pinia + ECharts(按需引入),构建产物 go:embed 进单二进制 |
| 采集 | SSH(golang.org/x/crypto)执行只读脚本;本机节点走本地进程 |
| 组网 | WireGuard 内核态 + wg-quick,面板经 SSH 全程托管 |
| 部署 | 多阶段 Dockerfile 单镜像(~35MB)+ docker-compose |
镜像由 GitHub Actions 自动构建并发布到 GHCR(push 到 main 即触发,linux/amd64):
# 服务器上
mkdir -p /data/appdata/beacontower && cd /data/appdata/beacontower
cat > docker-compose.yml <<'EOF'
services:
beacontower:
image: ghcr.io/yoahoug/beacontower:latest
container_name: beacontower
restart: unless-stopped
ports:
- "127.0.0.1:8091:8080" # 只绑本机回环,走反代对外
environment:
- BEACON_MASTER_KEY=<openssl rand -hex 32>
- TZ=Asia/Shanghai
volumes:
- ./data:/app/data
EOF
echo "BEACON_MASTER_KEY=$(openssl rand -hex 32)" >> .env
docker compose up -d建议前置反向代理提供 HTTPS(Caddy 示例见 doc/07-Docker部署方案.md)。
隧道建完后,还需要一台跑 frpc 的机器把流量接到本机服务。两个穿透平台的客户端都打成了本仓库镜像,
不跟随 main 推送构建(Actions 页手动触发 FRP client images (manual),可传版本号)。
v2.3 起这件事可以完全交给面板:只要目标机器在「节点管理」里录了 SSH 凭据,隧道页的「客户端托管」会替你把 它做完——探测/(按需)自动安装 Docker、拉镜像、生成并下发配置(权限 0600)、起容器、回读状态与日志; 隧道增删改后点「同步配置」即可,不用再登录那台机器。
# 手工兜底(目标机器没有 SSH 凭据时):在面板「内网穿透 → 隧道 → 配置」下载 ini,传到服务器,然后:
FRPC_CONFIG_FILE=./natfrp-ssh.conf docker compose up -d # compose 文件在 deploy/frpc-natfrp/镜像 ghcr.io/yoahoug/beacontower-frpc-natfrp(樱花分支 0.51.0-sakura-14,含官方环境变量模式)与
ghcr.io/yoahoug/beacontower-frpc-chmlfrp(上游 frp 0.61.2),都默认 host 网络、配置文件只读挂载;
为什么要 host 网络、配置格式和镜像版本怎么耦合,见 deploy/ 下的说明。
- 公开页与公开 API 走字段白名单:不输出公网 IP、内网地址、主机名等敏感字段,隐藏节点对外统一「不存在」
- SSH 密码/私钥、WG 私钥/PSK 全部 AES-256-GCM 加密落库,主密钥来自环境变量或
data/master.key(0600) - 面板代管密钥(v2.7 新增):添加节点默认自动生成节点专属 Ed25519 密钥——一次性密码只作引导(装机 + 独立重拨验证通过才启用),面板落库后即清除密码,后续采集/组网/穿透托管全走密钥;密钥失联(节点重装等)在节点详情「修复密钥」重输一次密码重建,密码同样不落库;面板不改节点 sshd 配置,公钥行注释
beacontower-panel-server-*便于辨识清理 - 登录限速 + 连续失败递增封禁;审计日志中来源 IP 只存哈希
- 建议部署在反向代理(HTTPS)之后,管理端仅自己访问
- 归属解析优先用本地离线库(
data/geolite2-city.mmdb,可选放 DB-IP Lite / GeoLite2 City);使用 DB-IP Lite 时按 CC-BY 4.0 署名 —— IP Geolocation by DB-IP
完整开发方案(需求 / 架构 / 数据库 / API / 安全 / 部署 / 功耗算法 / WG 组网 / 穿透 / PWA)见 doc/README.md:
- 01-需求分析 · 02-总体架构与技术选型 · 03-数据库与数据模型
- 04-API接口设计 · 05-安全设计 · 15-PWA移动端
- 07-Docker部署方案 · 09-功耗监控设计 · 11-服务器部署SOP
- 12-WG组网模块设计
采集到的指标均为被监控机真实数据(SSH 只读命令),面板不写目标机任何状态(WG 组网除外,且仅限 WG 配置)。
- LINUX DO —— 中文技术社区(AI / 开发 / 自托管),Where possible begins.