Floodww/RoutineOps

GitHub: Floodww/RoutineOps

RoutineOps 是一款自托管的跨平台设备管理(MDM/RMM)工具,通过 gRPC/mTLS 代理实现对 Windows、macOS、Linux 终端的远程运维、脚本执行、软件策略管控与合规监控。

Stars: 23 | Forks: 0

RoutineOps

# RoutineOps RoutineOps — 自托管的 MDM/RMM,用于管理 Windows、macOS 和 Linux 设备集群:代理程序保持与您的服务器的持久 gRPC/mTLS 连接,并可在没有 VPN 的情况下通过互联网工作。 版本 — 文件 [`VERSION`](./VERSION)。 2026-07-16 18 05 28 ## 安全性 任何对此类产品感兴趣的用户都会提出安全性问题,因为这是基础,也是首要关注的问题。与提供“付费才安全”的类似竞争产品不同,RoutineOps 并非如此。我们在开发时坚持的第一条原则是:“安全不出售”。 您可以在以下文件中详细了解其运作方式和安全模型:[`ARCHITECTURE.md`](./ARCHITECTURE.md) 和 [`SECURITY.md`](./SECURITY.md)。 我在此简要列出我们的安全技术栈:全程代理通道采用 **mTLS (TLS 1.3) 并固定私有 CA**,并基于证书进行身份识别(`device_id` = CN,服务器不信任消息体);**RBAC**;基于 **JWT 的管理员会话**以及 **IP 和账户锁定机制**;**一次性 enroll token**;带有 sha256 验证和防回滚的 **Ed25519 签名的代理自更新**;所有管理员操作的**审计日志**;**secure-by-default(默认安全)** — 强制要求强 `JWT_SECRET`,安全标头(HSTS/CSP),rate-limit 和请求大小限制。在我看来,这是自托管产品的最高配置。但为了全面理解,我强烈建议您阅读上述文件。 ## 功能 - **Windows、macOS 和 Linux 代理** — Windows 通过通用 MSI 安装,macOS 通过 `.pkg` 安装,Linux 通过生成的 installer 脚本以 systemd-unit 安装(软件清单取自 dpkg/rpm/pacman/apk)。 - **请求管理员权限** — 用户可以直接在其设备的系统托盘中发送管理员权限申请。 - **资产清点** — hostname、OS、CPU/RAM/磁盘、IP、序列号、代理版本、已安装软件列表、进程事件。 - **脚本** — 在单台设备或群组上一次性运行;按计划进行策略调度,或在代理连接和触发事件时运行;脚本库及结果查看。 - **设备群组** — 成员管理、群组颜色、按群组筛选设备列表、绑定脚本和软件策略、在整个群组上运行脚本。 - **软件策略** — 针对单台设备、群组或平台的 allowed/forbidden 规则。 - **策略合规性** — 对于每个软件和脚本策略,可以看到其覆盖的设备数量以及其中 Pass / Fail 的数量。 - **设备锁定** — 带有密码的全屏 overlay(Windows 和 macOS),支持在离线状态下解锁。 - **事件和告警** — `agent_unreachable`(设备失联)、禁止的软件、未经授权的安装/设置更改;按类型分组并带有未确认事件计数器;通过 Telegram 发送通知。 - **审计日志** — 记录管理员的所有操作,retention 可配置(`AUDIT_RETENTION_DAYS`,默认为 365 天)。 - **RBAC** — 角色 `it_admin`(完全访问权限)和 `viewer`(只读权限);通过电子邮件邀请用户。 - **代理自更新** — 签名的 ed25519 版本发布,校验 sha256 和 manifest 签名,提供版本防回滚保护。 - **mTLS** — 代理通过客户端证书进行身份验证,服务器在 enrollment 阶段为其颁发证书。 ## 快速开始 1. **服务器。** Linux(Ubuntu 22.04+ / Debian 12+),Docker + Compose v2,开放端口 80/443(Web、enrollment、下载)和 50051(代理的 gRPC)。对于最多 50 台设备,1 vCPU / 2 GB RAM / 20 GB SSD 就足够了。只需静态 IP,域名不是必需的。详情请参阅:[`docs/install.md`](./docs/install.md)。 2. **安装。** 复制配置模板,填写并运行 — 这样所有参数都会立即并确切地应用于安装: cp install.env.example install.env nano install.env # PUBLIC_ADDR (外部 IP/域名) + ADMIN_EMAIL / ADMIN_PASSWORD ./install.sh 该脚本将生成 TLS 证书、带有密钥的 `.env.prod`、版本发布签名密钥,启动 compose stack(数据库迁移会自动执行),并为 Windows/Linux/macOS 构建并发布代理。**`PUBLIC_ADDR`** 是外部代理和浏览器访问服务器的地址(外部 IP 或域名):如果在 NAT/VPN 后,请明确指定,否则通过外部地址的 enroll 将在 TLS 阶段失败(该地址必须包含在证书的 SAN 中;主机的内部 IP 会自动添加到 SAN 中)。请**不要使用 `sudo`** 运行,请使用属于 `docker` 群组的用户执行 — 否则属于 root 的 `.git` 和 `.env.prod` 会破坏后续的 `./update.sh` 命令([`docs/install.md`](./docs/install.md))。详情请参阅:[`docs/self-hosted-deploy.md`](./docs/self-hosted-deploy.md)。 3. **首次登录:** 访问 `https://` 并使用凭据 `ADMIN_EMAIL`/`ADMIN_PASSWORD`。密码必须符合复杂度策略(至少 8 个字符,包含 4 种字符类中的 3 种) — 如果密码较弱,将无法创建管理员(在服务器日志中将显示 `seed admin failed`)。 4. **代理已在步骤 2 中发布**,并可在服务器上访问(`/downloads/...`)。后续更新:运行 `./update.sh` — 它将拉取新版本(`git pull`),重新构建服务器并重新发布代理,而设备集群将自动拉取新版本(默认为每 6 小时一次)。详情请参阅:[`docs/self-update.md`](./docs/self-update.md)。 5. **连接设备:** 在 Web 界面中转到“设备” -> “添加设备” — 您将获得一个一次性 token(TTL 24 小时)和现成的安装命令。Windows 使用通用 MSI:`msiexec /i RoutineOps-agent.msi /qn ENROLL_URL=... ENROLL_TOKEN=... CA_URL=... CA_SHA256=... SERVER_ADDR=...`(这五个属性均为必填:MSI 内部不内置 CA,代理通过 `CA_URL` 下载它并使用 `CA_SHA256` 进行固定)。macOS 使用来自服务器的 `.pkg`(`sudo installer -pkg RoutineOps-agent.pkg -target /`,由于安装包未签名 — 双击会被 Gatekeeper 拦截)。Linux/macOS 使用生成的 installer `sudo bash install-mdm.sh`。详情请参阅:[`docs/install.md`](./docs/install.md) 和 [`docs/enrollment.md`](./docs/enrollment.md)。 ## 文档 - [`ARCHITECTURE.md`](./ARCHITECTURE.md) — 系统组件、通信通道、信任边界。 - [`docs/install.md`](./docs/install.md) — 完整安装:要求、证书、端口、代理发布。 - [`docs/self-hosted-deploy.md`](./docs/self-hosted-deploy.md) — `install.sh` / `update.sh`,备份,迁移,回滚。 - [`docs/enrollment.md`](./docs/enrollment.md) — 连接设备:一次性 token,颁发证书。 - [`docs/agent-cli.md`](./docs/agent-cli.md) — 代理二进制文件的命令、flags 和 env 变量。 - [`docs/self-update.md`](./docs/self-update.md) — 代理自更新:签名发布,发布版本,anti-rollback。 - [`docs/operations.md`](./docs/operations.md) — 运维:备份与恢复,常规操作。 - [`docs/field-troubleshooting.md`](./docs/field-troubleshooting.md) — 设备上的代理诊断(`agent diag`),“代理无法连接”的常见原因。 - [`docs/tamper-protection.md`](./docs/tamper-protection.md) — 保护代理免受用户删除(Windows: SafeBoot + 注册表;macOS: `schg` 标志;Linux 不支持),标准卸载流程。 - [`docs/jwt-secret-rotation.md`](./docs/jwt-secret-rotation.md) — 轮换 `JWT_SECRET`(管理员会话的信任根)。 - [`SECURITY.md`](./SECURITY.md) — 信任模型以及自托管部署中操作员的责任。 必须备份的内容:PostgreSQL dump,`certs/` 目录(特别是 `ca.key`), `release_ed25519.pem`(如果丢失 = 设备集群将无法再获得更新),`.env.prod`。 详情请见 [`docs/self-hosted-deploy.md`](./docs/self-hosted-deploy.md)。 ## 技术栈 | 组件 | 技术 | |---|---| | 代理 | Go | | 服务器 | Go (单体应用) | | 代理 ↔ 服务器通信 | gRPC + Protocol Buffers + mTLS | | 数据库 | PostgreSQL 16 | | 代理任务投递队列 | Redis + Asynq | | Web 界面 | React + TypeScript (Vite),由 nginx 容器提供服务(compose 中的 `web`) | ## 本地开发 ``` # 启动 Postgres + Redis docker compose up -d # 运行测试 TEST_POSTGRES_DSN="postgres://mdm:mdm@localhost:55432/mdm?sslmode=disable" go test ./... # 使用 race detector 运行测试 TEST_POSTGRES_DSN="postgres://mdm:mdm@localhost:55432/mdm?sslmode=disable" go test -race ./... ``` ## 企业版 企业版在上述功能的基础上增加了: | 功能 | 状态 | |---|---| | FileVault 恢复密钥托管 (macOS) | ✅ | | 强制设备进行 FileVault 锁定 | ✅ | | 从界面中卸载设备的软件 | 开发中 | | 多租户 (具有独立策略的独立租户) | 开发中 | | SSO/OIDC, MFA, SCIM, 导出到 SIEM | 开发中 | | 远程桌面连接 | 计划中 | 当前构建中物理上不存在企业版功能(例如, `lock_mode=filevault` 将返回 409)。完整列表和计划请见 [`docs/ROADMAP.md`](./docs/ROADMAP.md)。 **有关企业版授权、Bug 和建议的问题** — 请发送邮件至 [charmander020104@gmail.com](mailto:charmander020104@gmail.com) 或通过 Telegram [@flood_j](https://t.me/flood_j) 联系,或者在此存储库中 提交 [Issue](https://github.com/Floodww/RoutineOps/issues)。

      RoutineOps

标签:EVTX分析, gRPC, MDM, mTLS, Python工具, RMM, 搜索引擎查询, 日志审计, 测试用例, 自托管, 设备管理, 请求拦截, 运维工具