技术实践 ·

我开源了 Fleetd:把 Linux 服务器和软路由放到一个后台里

我开源了 Fleetd,用一个后台管理 Linux 服务器、OpenWrt 和 iStoreOS 软路由。介绍监控告警、客户端主动连接、签名命令与权限设计,以及 v0.3.0 的 Docker Compose 试用方法。

服务器和软路由数量不多的时候,管理它们看起来没什么难度。想看状态就连 SSH,服务出了问题就查日志,需要更新软件就执行几条命令。

麻烦在于,这些动作分散在不同的地方。看服务器是一套入口,进软路由又是一套入口。发现异常以后,还要重新找到那台机器,确认环境,再开始处理。

我想把这些日常操作放到一起:打开一个页面,知道哪些机器在线、哪里有告警;点进机器,查看状态,必要时执行命令或者打开终端。

于是做了 Fleetd,一个可以自己部署的服务器和软路由管理工具。现在代码已经按 MIT 协议开源,首个公开版本是 v0.3.0,中英文使用文档也一起上线了。

这篇先介绍它解决什么问题、目前能做什么,以及几个决定了项目方向的设计选择。后面的文章再展开实现。

我需要一个从“看到问题”走到“处理问题”的入口

监控能告诉我磁盘快满了,但接下来还得查哪个目录在增长;知道一个服务失败了,也得继续看日志、检查配置,决定是否重启。

对自己维护少量机器的人来说,这些动作经常连在一起。我希望后台能够保留这种连续性,尽量减少在几个工具之间来回找机器的过程。

Fleetd 目前把功能分成了几块:

功能 可以做什么
机器监控 查看 CPU、内存、负载、磁盘和网络速率,保留 7 天历史
运行状态 查看失败的 systemd 服务、Docker 容器和 WireGuard 对端等信息
告警 提醒机器离线、资源持续超限、磁盘空间不足及相关服务异常,可配置邮件通知
远程命令 对一台或多台机器执行经过签名、且符合客户端权限的命令
网页终端 在允许完整操作权限的机器上打开交互终端
客户端管理 批准新机器接入,并分发经过签名的客户端更新包

Fleetd 机器总览表格,展示资源占用与在线状态

项目文档中的总览界面局部,展示字段和布局。图中数值不代表性能测试结果。

这些信息也需要结合机器环境理解。例如 systemd 服务状态适用于运行 systemd 的系统,不能拿同一套服务列表要求 OpenWrt。WireGuard 的握手时间也是排查线索,不能脱离流量和配置,直接等同于线路已经故障。

我更关心的是让异常有一个可以继续查下去的入口。至于复杂的监控规则、长期数据分析或者完整的配置编排,仍然可以交给擅长这些工作的工具。

一台服务端,每台机器一个客户端

Fleetd 的结构比较直接。

服务端负责管理页面、机器记录、监控数据和操作记录,数据放在 PostgreSQL。被管理的 Linux 机器上运行一个客户端,负责采集状态、接收请求,并决定是否执行。

后台用 Vue 3 编写,构建后嵌入 Go 服务端程序。客户端也是 Go 程序,发布了 Linux amd64 和 arm64 两种架构的版本。实际安装时仍要核对设备架构,不能因为一台路由器运行 OpenWrt,就认为现成的二进制一定能用。

对部署者来说,这个结构的好处是边界容易理解:服务端是一处,数据库是一处,每台被管理的机器上有自己的客户端和配置。

日后排查问题,也可以顺着这些边界看:客户端有没有连上,数据有没有上报,请求有没有到达,客户端为什么接受或拒绝了它。

软路由接入,先解决连接方向

云服务器和家里的软路由,网络条件常常不一样。服务器可能有公网地址,软路由通常在 NAT 后面。为了管理一台机器,就给它额外开放一个公网入口,会增加配置和维护工作。

Fleetd 采用客户端主动连接服务端的方式。只要被管理机器能访问服务端的连接地址,就不需要专门为客户端开放入站管理端口。

这很适合把不同网络里的 Linux 服务器、OpenWrt 或 iStoreOS 设备接到一个后台。服务端本身仍然需要一个客户端能够访问的地址,正式使用也需要按文档配置 HTTPS 和 WebSocket 转发。

连接建立以后,新机器不会立即成为可操作对象。它先出现在“等待批准”里,管理员核对安装端和后台显示的指纹,再决定批准还是拒绝。

这个步骤保留了一个明确的判断:连接到后台的那台机器,是不是我刚刚准备接入的机器? 主机名可以起得一样,界面上多出一个条目也不能代替身份核对。

具体的接入、指纹和重连流程,下一篇再展开。

能看到机器,不代表可以随意操作机器

把远程命令放进监控后台之后,权限问题就变得很实际。

一台机器可能只需要上报状态;另一台机器可以接受几个固定的维护动作;只有部分机器才需要完整的命令和终端能力。它们不应该因为出现在同一个后台里,就默认拥有相同的操作范围。

Fleetd 把这个决定放在客户端本地配置里,分为三级:

权限 允许的操作
monitor 只监控,不执行远程命令
allowlist 只执行本地预先定义的动作
full 允许任意命令和网页终端

命令还需要在管理员浏览器里签名,客户端使用自己信任的公钥验证,并检查目标、有效期和本地权限。服务端负责转发,不能仅凭一条普通请求就让客户端执行。

这套设计希望减少客户端对服务端指令的盲目信任。不过,安全结论需要把前提说完整:浏览器和它运行的前端代码也必须可信。

管理页面由服务端提供,如果服务端被篡改,后续打开的页面也可能被替换。私钥不可导出,并不等于恶意页面无法尝试调用签名。因此,不能只因为加了命令签名,就宣称服务器失陷后整套系统仍然绝对安全。

我会单独写一篇讲这条信任链。对使用者来说,初期最有价值的做法很简单:只需要监控的机器就保持 monitor,能用固定动作解决的事情优先使用 allowlist,需要完整终端时再开放 full。

更新客户端,也要有自己的信任依据

设备分散之后,更新客户端会成为另一项日常工作。每台机器手动复制程序,很快就会变得繁琐;让客户端下载一个文件就直接运行,又把更新来源的问题留了下来。

Fleetd 使用签名发布包。发布者在自己的环境中生成更新包并签名,客户端依据预先配置的发布公钥进行校验。命令签名和程序发布签名是两个用途不同的机制,不应混在一起管理。

这也意味着,GitHub Releases 里的文件要分清用途。普通客户端二进制可以用于相应架构的手动部署,而带签名的 .release 包只有在客户端信任对应发布公钥时才适用。

自行部署的人应当按照文档建立自己的发布密钥和更新流程。上传了作者的签名包,不代表它就会被任意一套自建环境接受。

自动更新的细节,包括版本判断、校验失败和更新过程中的恢复,会在后面的文章里结合代码说明。

想先看一下,可以从 Docker Compose 开始

如果已经安装 Docker 和 Compose 插件,可以先在自己的电脑上试用服务端:

git clone https://github.com/weiyi0/fleetd
cd fleetd
git checkout v0.3.0
docker compose up -d
docker compose run --rm fleetd admin-add admin

创建管理员时按提示设置密码,然后访问 http://localhost:8480。后台支持中文和英文。

这里固定到 v0.3.0,便于和本文的版本范围对应。当前 Compose 配置会从源码构建服务端,并启动 PostgreSQL,因此首次运行需要下载依赖、构建程序,耗时取决于本机和网络环境。

做到这一步,只是把后台启动起来,还没有接入任何机器。 Docker 镜像也不会顺便为你生成签名客户端发布包。

接下来可以按快速开始文档,先编译并手动运行一个客户端,体验机器接入;准备长期使用时,再配置自己的发布密钥、上传签名客户端包,通过后台提供的安装方式接入设备。

默认 Compose 示例面向试用,包含示例数据库凭据,8480 端口也不只绑定回环地址。在本机体验时应限制网络访问;准备通过网络使用前,按部署文档修改凭据、配置 HTTPS,并做好数据库和密钥备份。

先接一台便于维护的测试机器,核对指纹、查看状态,再试验它允许执行的操作。完整流程跑通以后,再逐步接入其他机器,会更容易发现配置差异。

为什么从 v0.3.0 开始公开

第一个公开版本是 v0.3.0,是因为此前使用环境中的客户端已经到了 0.2.0。项目的更新机制要求目标版本比当前版本更新,因此公开发版沿用了这个版本序列。

版本号说明的是演进顺序,成熟度仍然要靠使用和验证积累。

目前最适合 Fleetd 的,是希望自己掌握数据、维护少量 Linux 服务器和软路由,也愿意理解基本部署和权限配置的人。公开仓库、可下载程序和文档,让大家可以看清它如何工作,再判断是否适合自己的环境。

我也不想仅凭一个功能表,就把它描述成各种现有运维工具的替代品。监控、自动化、配置管理都有各自成熟的方案。Fleetd 先把自己的场景做扎实:让机器状态、告警和必要的维护操作连起来,并让每台机器保留清楚的权限边界。

后面会继续写什么

这个系列会接着写主动连接和设备批准、浏览器签名、本地权限、OpenWrt 适配、告警与客户端更新,也会复盘使用 AI 开发这个项目的过程。

我更想留下具体的取舍:为什么这样设计,解决了什么问题,又带来了哪些限制。真实遇到的问题和验证记录,也会随着项目往前推进继续补充。

如果你也在维护服务器或软路由,欢迎先看代码和文档。一般使用问题可以到仓库提 Issue;涉及安全漏洞时,请通过仓库的私密漏洞报告入口反馈。

希望这个工具能让日常维护少一些来回切换,也希望后面的开发记录,能给正在做类似项目的人提供一点可复用的经验。