开始
设计哲学
我们删掉的比加上的多。这一页说明为什么。
三个词:安全、极简、高效。顺序不是随便排的——冲突的时候,前面的赢。
安全
装完,面板不在公网上
一键脚本写死 --listen 127.0.0.1。这意味着装完那一刻你打不开面板,必须先配一段反向代理。
这是这个项目最容易被误认为是 bug 的设计。但代价很清楚:明文 HTTP 上,会话 cookie 和节点 token 在链路上全是明文,而任何一个中间人都能替换掉安装命令下载的那个二进制——那个二进制紧接着会以 root 跑起来。所以我们宁可让你多花五分钟配 nginx,也不给一个「先用着,回头再上 TLS」的默认值。
反向代理那一页把 nginx、caddy、Cloudflare 隧道三种配法都写好了,抄就行。
公开页永远不输出三个字段
IP、主机名、备注。过滤在序列化的时候做:匿名请求拿到的 JSON 里根本没有这几个 key, 不是设成空字符串,不是靠前端不渲染。
agent 上报的指标走的是白名单而不是黑名单——因为拿到任意一个节点 token 的人可以自己往上报里塞
一个 hostname 字段,黑名单会把它一路送到公开页上。
每一条匿名可达的路径都要说得出自己的上界
内存、占锁时长、出网字节。历史查询的窗口宽度、返回点数、agent 二进制转发的并发数,全部有硬上限, 而且上限是 hub 的,调用方只能往下调不能往上调。
极简
零配置文件
hub 只有四个命令行参数:--listen、--db、--themes、--site。其余全部存在 SQLite 里,在面板改。
少一个 TOML 解析器,少一类「配置文件在哪、权限对不对、和数据库不同步」的问题。
明确不做的
不是「还没做」,是不会做:
| 不做 | 为什么 |
|---|---|
| 通知与告警 | 探针的输出是数据,告警是另一个系统的事 |
| 远程 SSH / web terminal | 一个只读的观察者被攻破,和一个能执行命令的工具被攻破,代价差一个数量级 |
| 插件系统 | 等于把第三方代码请进 hub 的进程 |
| ICMP / HTTP 探测 | TCP 一种够用,三种要三套超时语义、三套图例 |
| agent 自动更新 | 自更新意味着 agent 能以 root 下载并执行任意二进制,这是整个探针最大的攻击面。升级方式是重跑一遍安装命令 |
| 跨平台 agent | 加 Windows / macOS 等于推翻整个采集实现 |
探针的职责是告诉你机器怎么样了,不是替你管机器。 一个东西同时是监控面板、告警中心、 远程终端和插件宿主的时候,它已经不是探针了。
如果这里面有一样是你必需的——那我们大概不合适。这不是遗憾,是选择。
功能压到最低的实际收益
源码 3,132 行,一个人一个下午读得完。没写的代码不占内存、不会慢、也不会有漏洞。
高效
同一台机器、同一套负载的实测数字(完整数据见性能):
| 可执行文件 | 5.4 MiB |
| 冷启动到能响应请求 | 63 ms |
| 空转内存 | 6.1 MiB |
| 200 个节点在线,每 2 秒上报 | 8.4 MiB,一颗核的 2.5% |
| 每秒 1000 次上报 | 8.6 MiB |
Rust 没有 GC 也没有语言运行时,所以负载上去内存基本不动。但光换语言只拿得到体积和内存的优势, 响应速度是一处一处调出来的——那几处改动也记在同一页里。
数字必须是对的
这一条单独拎出来,因为它是最容易错、错了又最不容易被发现的部分:错的读法永远给出一个看着合理的数字。
- 内存 用
MemTotal - MemAvailable,和free(1)的 used 列同一个算法。 流行的采集库把 page cache 算进已用内存,于是一台跑了几天的机器看起来内存快满了 - 硬盘 对齐
df(1)的 Used 列,用的是非特权用户可用的那个口径 - swap 不减
SwapCached——那些页确实还占着 swap 设备上的块
验收标准只有一条:面板上的数字,必须和你 ssh 上去敲 free -h / df -h 看到的对得上。
总流量永不回退
网卡计数器每次开机从 0 开始,照原样显示,VPS 一重启面板上的总流量就归零。
所以累加放在 hub 侧,agent 保持无状态:它只上报内核此刻给出的读数和一个 boot_id,
hub 负责算增量。只计入 hub 亲眼看着计数器涨过去的那部分字节——没有基线可减的时候就只对基线,
不计流量。
代价是 VPS 重启那一次会丢掉「开机到首次上报」之间的几百 KB。换来的是同一条安装命令误粘到第二台 机器上时,总流量不会一轮涨 180 GB。细节见流量统计。