Floodww/RoutineOps
GitHub: Floodww/RoutineOps
RoutineOps 是一款自托管的跨平台设备管理(MDM/RMM)工具,通过 gRPC/mTLS 代理实现对 Windows、macOS、Linux 终端的远程运维、脚本执行、软件策略管控与合规监控。
Stars: 23 | Forks: 0
# RoutineOps
RoutineOps — 自托管的 MDM/RMM,用于管理 Windows、macOS 和 Linux 设备集群:代理程序保持与您的服务器的持久 gRPC/mTLS 连接,并可在没有 VPN 的情况下通过互联网工作。
版本 — 文件 [`VERSION`](./VERSION)。

## 安全性
任何对此类产品感兴趣的用户都会提出安全性问题,因为这是基础,也是首要关注的问题。与提供“付费才安全”的类似竞争产品不同,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)。
标签:EVTX分析, gRPC, MDM, mTLS, Python工具, RMM, 搜索引擎查询, 日志审计, 测试用例, 自托管, 设备管理, 请求拦截, 运维工具