Skip to content

Latest commit

 

History

179 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Server Monitor

English

基于 Web 的服务器监控平台,支持实时 SSH 终端。

使用 Claude Code & DeepSeek-v4-pro 构建


在线站点

公开探针每 15 秒刷新一次,只展示匿名节点编号、手动配置的公开位置、标签、可用性以及取整后的 CPU、内存和运行时间等健康指标。接口不会返回真实服务器名称、IP / 主机名、端口、SSH 用户、凭据、备注或数据库 ID。

安全提示: 管理功能涉及登录令牌和 SSH 凭据,请仅在域名已配置有效 HTTPS 证书并强制跳转 HTTPS 后使用。上面的链接仅指向匿名公开状态页。


技术栈

层级 技术
后端 Go + Gin + PostgreSQL
前端 React 19 + TypeScript + Vite + Ant Design
实时通信 WebSocket(SSH 终端)
状态管理 Zustand
图表 Recharts
容器化 Docker + Docker Compose
CI/CD GitHub Actions → GitHub Container Registry

主要功能

模块 能力
服务器面板 卡片 / 列表双视图(记忆选择)、搜索、按标签与在线状态筛选、按 CPU / 内存 / 磁盘 / 运行时长 / 到期时间排序
概览指标 总数、在线 / 离线、平均 CPU 与内存、按月折算并换算币种的支出汇总
机器详情 资源指标磁贴、CPU / 内存 / 网络 / 磁盘 I/O / 负载 / 延迟六组图表(自适应单位、随明暗主题切换)、时间范围预设与自定义区间、历史数据导出 CSV
告警中心 阈值规则 + 告警时间线,支持 Webhook 通知与连通性自测
批量操作 多选服务器后批量打/去标签、批量删除、导出资产清单 CSV、在最多 50 台上并发执行同一条命令并逐台查看结果
进程管理 详情页实时进程表,可按 PID / 用户 / CPU / 内存 / RSS / 运行时长排序,支持搜索、暂停自动刷新、结束进程(SIGTERM / SIGKILL)
可用性统计 24 小时 / 7 天 / 30 天观测可用率,30 天每日条带与中断记录,概览页展示全站均值,公开状态页展示 30 天 SLA
服务与端口 详情页 systemd 单元列表(失败优先)与启动/停止/重启/重载,以及监听端口表并按监听地址标注可达范围
运维操作 SSH 网页终端、Docker 容器管理(启停 / 日志 / 交互终端、CPU / 内存 / 磁盘占用)、SSH 凭据集中管理、备注
账号安全 修改密码,并即时登出其他设备上的会话
公开状态页 匿名化探针页,接口层面即排除身份与连接信息

文件管理与 Docker 自动加载

Web 新增主机/容器文件浏览、UTF-8 文本编辑及上传下载;Docker 页打开后自动分批加载容器。入口、支持范围、文件大小限制、外层代理配置见 文件管理说明

告警

告警规则在后端独立评估(默认每 30 秒一轮,ALERT_INTERVAL),只读取数据库中的最新采样,不会额外连接被监控主机。

  • 指标:CPU、内存、磁盘使用率(%),1 分钟负载、网络延迟(ms),以及主机离线。
  • 持续时长:阈值需连续满足设定时长才会开启告警,避免瞬时毛刺造成误报;离线规则最短 2 分钟,与面板的在线判定保持一致。
  • 作用范围:可指定单台服务器,或留空以覆盖全部服务器(含之后新增的)。
  • 通知:触发与恢复各向配置的 Webhook 地址 POST 一次 JSON(载荷格式见 docs/API.md),保存前可点「发送测试」验证链路。
  • 状态持久化:进行中的告警以数据库记录表示,服务重启既不会重复通知,也不会漏掉恢复通知;主机长时间失联时阈值类告警自动收敛为已恢复,不会永久挂起。

可用性统计

可用率按观测口径计算:窗口内实际落库的指标样本数 ÷ 应落库的样本数。它衡量的是"我们是否看得到这台主机", 而不是主机自身的 uptime 计数器——面板或其数据库不可用的时段,会同时计入所有服务器的不可用时间。界面上固定标注了这一口径。

  • 三个窗口:24 小时与 7 天读一分钟汇总层,30 天读 15 分钟层(一分钟层只保留 30 天,且逐台扫描它约是 20 倍的索引开销,而这点精度在一个月尺度上并不可见)。
  • 不冤枉新机器:窗口起点会夹到服务器的创建时刻,刚加入的主机不会因为"加入之前没有数据"而被判为不可用;此时界面标注实际统计区间比标签更短。窗口尚未跨过一个完整的桶时显示「—」而不是 0%。
  • 不永远差一个桶:窗口终点对齐到该汇总层的桶边界。正在填充中的桶还没有汇总落库,若把它算进应采集数,任何健康主机都永远到不了 100%。
  • 每日条带:30 天逐日着色,与旁边的 30 天百分比同层统计,两者的数字因此一致。全天中断的那一天在查询结果里根本没有行,会被显式补齐,不会从图上消失;条带高度固定、只用颜色表达高低,否则 0% 的那天会是一根看不见的零高度条。服务器尚不存在的日子画成斜纹留白,与「整天 0%」区分开。
  • 中断记录:由相邻汇总桶之间超过 2 分钟的间隔推导,最多列出最近 50 条,尚未恢复的一条会标为「进行中」。从未上报过任何样本的主机显示「暂无历史」,而不是「无中断」——没有样本可以作为中断的起点。

服务与端口

详情页新增「服务」与「端口」两个标签页,都走已有的 SSH 连接缓存,轮询只花一个 session。

服务

  • 读取:优先 systemctl list-units,再补一次 list-unit-files 拿开机启动状态;没有 systemd 的主机(多数容器、老式 sysvinit)回退到 service --status-all
  • 区分三种「问不到」:没装 systemd、装了但当前 SSH 用户问不到、以及主机根本没有任何服务管理器 —— 三者提示完全不同。特别地,在 systemd 主机上不会回退去读 init 脚本:无特权读取会把正在服务的 nginx 报成已停止,给出确定错误的数据比承认问不到更糟。
  • 排序:失败 → 运行中 → 启动中 → 其余,各组内按名称排序。列表上限 500 条,因此被截断掉的一定是最不需要关注的那些。
  • 状态显示active 旁边带上 sub 状态(running / exited / dead)—— 它才是区分「一次性任务已完成」和「守护进程已死」的字段。开机启动状态为空显示为 ,不会当作「已禁用」。
  • 控制:启动 / 停止 / 重启 / 重载。四个动词用文字而非图标 —— 重启和重载在小尺寸下都是「一圈箭头」,而选错不是无伤大雅的失误:重启会断开该服务上的所有连接。reload 单列一个动词正是因为它不断连接;Windows 没有对应语义,会直接拒绝而不是悄悄降级为重启。
  • 不提权:以服务器配置的 SSH 用户执行,不尝试 sudo。无权时把主机自身的拒绝信息原样展示。单元名经严格白名单校验(且在建立连接之前),shell 元字符一律拒绝。

端口

  • 读取ss -tulnp,失败回退 netstat -tulnp。两者格式差别不小,各有独立解析:UDP 在 ss 里的状态是 UNCONN 而非 LISTEN,按字面过滤会丢掉全部 UDP 监听;netstat 的进程列装的是被列宽截断的进程标题(sshd 显示为 sshd: /usr/sbin)。
  • 可达范围:由监听地址推导并着色 —— 通配监听(0.0.0.0 / ::)标为公网可达并单独提示,RFC1918 与 link-local 标为内网,127.0.0.0/8::1 标为仅本机。这是这个页面的主要价值:它直接回答「谁能连上这个端口」。
  • 常见端口会显示服务名(22 → ssh,5432 → postgres)。进程归属为空表示当前 SSH 用户无权查看,不代表没有归属进程。

批量操作

在服务器面板点击「批量选择」进入多选,卡片与列表视图均可勾选,底部浮出操作栏。

  • 批量标签 / 批量删除 / 导出清单:标签添加是幂等的;删除会级联清理历史指标、告警记录与标签关联;导出的清单不含任何密钥(接口本身就不返回)。
  • 批量执行命令:最多 50 台,8 台并发,单台限时 60 秒、输出上限 64 KB。执行前的确认弹窗会完整列出命令和全部目标主机;命令必须为单行,含 rm -rfreboot、写块设备等模式时会额外提示。
  • 逐台返回退出状态与合并输出(stdout + stderr),单台失败不影响其余主机。以服务器配置的 SSH 用户执行,不会尝试 sudo 提权。

安全设计

密码安全

  • 用户密码使用 bcrypt(cost factor 12)哈希存储,即使数据库泄露也无法还原明文密码
  • 密码要求最少 6 位,用户名 3-64 位,防止弱口令

SSH 凭据加密

  • 所有服务器的 SSH 密码和密钥在写入数据库前使用 AES-256-GCM 加密
  • 加密密钥独立于数据库存储(通过环境变量 ENCRYPTION_KEY 注入),数据库泄露也无法解密凭据
  • AES-256-GCM 提供认证加密(Authenticated Encryption),同时保证机密性和完整性

认证与授权

  • 基于 JWT(HS256) 的无状态认证,Token 有效期 72 小时
  • 修改密码会立即吊销该账号此前签发的全部 Token:用户表记录一个失效时间点,鉴权时拒绝 iat 更早的 Token。发起修改的那个会话会收到新签发的 Token,不会被自己的操作切断
  • 所有 API 请求通过 Bearer Token 认证,WebSocket 通过 Query Token 认证
  • 所有受保护的管理 API 查询强制按 user_id 过滤,用户之间数据完全隔离;公开探针使用独立的最小化数据模型,只返回匿名健康指标

接口防护

  • 登录和注册接口启用 令牌桶限流(5 次/分钟/IP),防止暴力破解和恶意注册
  • 注册接口默认开放;账号创建完毕后可用 ALLOW_REGISTRATION=false 关闭,此后 POST /api/auth/register 一律返回 403
  • 请求参数通过结构体绑定自动校验,防止非法输入
  • 支持配置 CORS 白名单,限制跨域请求来源
  • 告警 Webhook 默认拒绝内网目标:解析到 loopback / RFC1918 / link-local / CGNAT 地址的地址会在保存时被拒绝,且请求不跟随重定向,避免被当作 SSRF 跳板探测服务端内网(可用 ALLOW_PRIVATE_WEBHOOKS=true 显式放开)。Webhook 自测接口另有 6 次/分钟/IP 限流

传输安全

  • 支持 TLS/HTTPS(可配置证书和私钥文件)
  • 生产环境建议通过反向代理(Nginx)启用 HTTPS

部署安全

  • Docker 镜像基于 Alpine Linux 最小化构建,减少攻击面
  • 后端容器内进程以 非 root 用户 运行,仅 ping 二进制携带 CAP_NET_RAW 能力用于延迟探测
  • 敏感配置(数据库密码、JWT 密钥、加密密钥)通过 GitHub Secrets 管理,不写入代码
  • 数据库使用 ON DELETE CASCADE 外键约束,确保数据一致性

仓库结构

目录 内容
web/ 网页版:backend/(Go + Gin)、frontend/(React)与 docker-compose.yml,由 GitHub Actions 构建镜像并部署
macos/ macOS 原生客户端(SwiftUI,纯本地,不依赖服务端)
windows/ Windows 原生客户端(.NET 10 + WPF,纯本地,不依赖服务端)
docs/ 接口文档 API.md 与截图

三个客户端各有自己的工作流:改 web/ 触发网页版部署,改 macos/windows/ 只触发各自的构建,互不影响。

原生客户端

macos/ 下是一个纯本地的 SwiftUI 菜单栏应用,不依赖本项目的服务端:它直接用系统 ssh 连接各台主机采集指标(Linux 与 Windows),历史存在本机 SQLite,界面对标 SwiftServer——仪表板、机器详情卡片、Docker、SFTP、终端、代码片段、vnStat 流量统计,并常驻菜单栏在后台持续轮询与告警。构建、测试与打包见 macos/README.md

windows/ 是功能对等的 Windows 版(.NET 10 + WPF),同样纯本地、同样直连主机,托盘常驻:仪表板、机器详情、Docker 五表、SFTP、终端、代码片段、SSH 密钥、会话历史、Toast 告警与开机自启,界面文案与 macOS 端同源。默认走进程内的 SSH 长连接(相当于 macOS 端的 ControlMaster;Windows 自带的 ssh.exe 不支持连接复用),需要 Match 块、证书或真正的 ssh-agent 的主机可以逐台改用系统 ssh.exe。构建、测试、打包与已知缺口见 windows/README.md,技术决策与分阶段计划见 windows/PLAN.md

发布包是自包含单文件,目标机器不需要装 .NET;但没有代码签名,首次运行 SmartScreen 会拦一次。

快速开始

# 后端
cd web/backend
cp .env.example .env   # 编辑配置文件
go run ./cmd/server

# 前端
cd web/frontend
npm install && npm run dev

部署

项目通过 GitHub Actions 自动构建 Docker 镜像并部署到服务器。Push 到 main 分支或手动触发 workflow 即可。

发布前执行后端测试与前端浏览器回归,按本次 SHA 发布;部署后校验数据库就绪与生产页面,失败自动回滚。生产配置持久保存在 /opt/server-monitor/shared/.env,首次升级自动保留旧 web/.env,不再从 GitHub Secrets 重写应用配置。新部署须先配置 shared/.env;迁移、必要配置、手动回滚与保留策略见 Web 发布说明

前置条件

  • 服务器已安装 Docker 和 Docker Compose
  • 服务器已配置 PostgreSQL 数据库
  • 域名已解析到服务器 IP

配置 GitHub Secrets

在仓库的 Settings → Secrets and variables → actions 中添加以下 Secrets:

Secret 说明 示例
DEPLOY_HOST 服务器 IP 或域名 1.2.3.4
DEPLOY_USER SSH 登录用户名 root
DEPLOY_PASSWORD SSH 登录密码 -
DOMAIN 网站域名 svr.hmchxd.com
GHCR_PAT GitHub 个人访问令牌(read:packages 权限) 见下方说明

GITHUB_TOKEN 由 GitHub 自动提供,无需手动配置。

GHCR_PAT 说明:部署服务器需要从 GitHub Container Registry 拉取私有镜像,请到 GitHub Settings → Tokens 创建一个 Personal Access Token (classic),勾选 read:packages 权限,将生成的 token 填入此 Secret。


效果图

主页 / 仪表盘
dashboard
机器详情 SSH 终端
server-detail ssh-terminal

TODO

  • CI/CD 集成 — GitHub Actions 自动 lint / build / test / deploy
  • 修改机器信息 — 已添加的服务器支持修改 host / port / SSH 凭据等配置
  • 登录历史 — 登录成功后右下角弹窗显示上次登录的 IP、时间和地理位置
  • Docker 管理 — 机器详情页可查看 Docker 容器列表、状态及 CPU / 内存 / 磁盘占用
  • SSH 密钥管理 — 独立管理 SSH 密钥(创建、命名、关联服务器),避免重复粘贴
  • SSH 账号密码管理 — 像管理 SSH 密钥一样管理通用的账号密码
  • 账号密码管理 — 设置页可修改密码,并即时吊销其他设备上的会话
  • 机器组 / 批量操作 — 标签已承担分组职责,本项落地为批量操作:批量标签、批量删除、批量执行命令、导出清单
  • 可用性统计 — 观测口径的 24h / 7d / 30d 可用率、每日条带与中断记录,详见下文
  • 服务管理 / 端口检查 — systemd 单元列表与控制、监听端口及其可达范围,详见下文
  • 进程列表 — 详情页实时进程表,支持排序、搜索与结束进程
  • 磁盘占用 — 详情页展示当前磁盘使用占比
  • 告警通知 — 阈值规则(CPU / 内存 / 磁盘 / 负载 / 延迟 / 离线)+ Webhook 推送,详见下文
  • 公开探针 — 提供匿名化公开状态页和最小化状态 API,隐藏服务器身份与连接信息

About

Self-hosted server monitoring with real-time metrics, SSH terminal, Docker management, encrypted credentials, and an anonymized public status page.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages