{"id":41270638,"url":"https://github.com/fl0w1nd/proxy-rule-manager","last_synced_at":"2026-05-27T19:00:38.874Z","repository":{"id":332821665,"uuid":"1135063011","full_name":"fl0w1nd/Proxy-Rule-Manager","owner":"fl0w1nd","description":"一个实现代理规则集编排管理的 WEBUI","archived":false,"fork":false,"pushed_at":"2026-05-23T23:06:29.000Z","size":11492,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-24T01:11:46.851Z","etag":null,"topics":["clash-meta","geosite","loon","mihomo","mihomo-config","mihomo-rules","shadowsocks","stash"],"latest_commit_sha":null,"homepage":"https://ruleset.zcsouls.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fl0w1nd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-15T15:33:13.000Z","updated_at":"2026-05-23T23:06:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fl0w1nd/Proxy-Rule-Manager","commit_stats":null,"previous_names":["fl0w1nd/proxy-rule-manager"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/fl0w1nd/Proxy-Rule-Manager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fl0w1nd%2FProxy-Rule-Manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fl0w1nd%2FProxy-Rule-Manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fl0w1nd%2FProxy-Rule-Manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fl0w1nd%2FProxy-Rule-Manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fl0w1nd","download_url":"https://codeload.github.com/fl0w1nd/Proxy-Rule-Manager/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fl0w1nd%2FProxy-Rule-Manager/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33579668,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clash-meta","geosite","loon","mihomo","mihomo-config","mihomo-rules","shadowsocks","stash"],"created_at":"2026-01-23T02:24:05.984Z","updated_at":"2026-05-27T19:00:38.865Z","avatar_url":"https://github.com/fl0w1nd.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"public/logo.svg\" width=\"100\" height=\"100\" alt=\"Proxy Rule Manager Logo\"\u003e\n\u003c/p\u003e\n\n# Proxy Rule Manager\n\n面向代理规则与客户端配置的管理平台，提供规则编辑、客户端管理与公开分发。\n\n## 预览\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"public/preview1.png\" width=\"90%\" alt=\"Dashboard Preview\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"public/preview2.png\" width=\"90%\" alt=\"Rules Manager Preview\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"public/preview3.png\" width=\"90%\" alt=\"Client Config Preview\"\u003e\n\u003c/p\u003e\n\n## 功能\n\n- 规则编排与自动化管理，支持本地 / 远程 / 引用 / Geosite 多种数据源混合\n- JS 自定义转换器（goja 沙箱执行，内置 `console` / `atob` / `btoa` /\n  `URL` / `URLSearchParams` / `TextEncoder` / `TextDecoder` / `helpers.*`）\n  + 内置 `replace` / `remove_lines`\n- 规则更新记录与差异追溯\n- 客户端配置文件编辑与管理\n- 公开分享与下载\n- 数据源定时同步（interval / cron）\n- WAF 速率限制 + IP 封禁\n- 完整数据库备份与恢复\n- 系统级参数（抓取超时 / 输出体积上限 / 速率限制等）可在 UI 调整并随备份保存\n\n---\n\n## ⚠️ 从 TypeScript 后端升级（≤ 0.3.x）\n\n本版本是 Node.js → Go 的完整重写，**数据库格式不兼容**。\n项目附带迁移脚本 `scripts/migrate-legacy-backup.sh`，可把旧版导出的备份 zip\n重写为新版可直接 restore 的格式。\n\n### 升级流程\n\n1. **在旧版**：管理面板 → 系统配置 → 数据库备份与恢复 → 备份数据库\n   会下载 `proxy-rule-manager-backup-YYYY-MM-DD.zip`。\n2. **本机**：跑迁移脚本（需要 `python3` / `unzip` / `zip`）：\n   ```bash\n   ./scripts/migrate-legacy-backup.sh proxy-rule-manager-backup-YYYY-MM-DD.zip\n   # 输出：proxy-rule-manager-backup-YYYY-MM-DD-migrated.zip\n   ```\n   脚本会同时打印迁移摘要（规则 / 客户端 / 转换器 / 数据源 / 客户端文件 / 同步元数据）。\n3. **部署新版**：替换镜像 / 二进制，启动新服务（admin token 会自动生成，见启动日志）。\n4. **新版**：管理面板 → 系统配置 → 数据库备份与恢复 → 恢复数据库\n   上传上一步生成的 `*-migrated.zip` 即可。\n5. **首次同步**：管理面板 → 触发一次全量同步以重新生成 `Rules/` 输出。\n\n### 迁移脚本会带过来什么\n\n- `config`：全部规则、转换器（含自定义 JS 脚本）、客户端覆盖、合并策略\n- `clients`：客户端 ID / 名称 / 全局 transforms\n- `artifacts` 元数据（dict → list，自动回填 `blobPath`）\n- `clientFiles` 元数据（dict → list，含 `displayName` / `description` / `isPublic`）\n- 同步元数据：`lastSyncInfo` / `cdnSettings` / `syncSchedule`\n- 资源目录：`client-files/` / `sources/` / `iconset/`\n\n### 不会自动迁移的内容\n\n- **WAF 封禁列表**：新版只读 SQLite，迁移脚本会把旧版 `waf/bans.json` 中仍处于\n  生效期的封禁导出到 `*-waf-bans.txt` 旁路文件，**需要你在新版重新封禁**。\n- **活动历史**（`data/records/`）：新版改用 SQLite，无逐文件迁移路径。\n- **Geosite 缓存**：新版首次访问时从上游重新拉取。\n- **Rules/ 输出**：恢复后由首次全量同步重新生成。\n- **任务历史 / 锁 / 每日统计 / configRev**：均不携带（jobs ID 格式由\n  `job_\u003cts\u003e_\u003crand\u003e` 改为 UUID v4，历史无意义）。\n\n### 已废弃的功能\n\n- **配置模板导入 / 导出**：新版统一通过\"数据库备份与恢复\"做配置迁移。\n\n---\n\n## 安装（Docker Compose）\n\n镜像：`ghcr.io/fl0w1nd/proxy-rule-manager`\n\n```yaml\nservices:\n  proxy-rule-manager:\n    image: ghcr.io/fl0w1nd/proxy-rule-manager:latest\n    container_name: proxy-rule-manager\n    restart: unless-stopped\n    ports:\n      - \"3000:3000\"\n    volumes:\n      - ./data:/app/data\n    environment:\n      - PORT=3000\n      # ADMIN_TOKEN 是可选的；不设时自动生成并持久化到 data/admin-token\n      # - ADMIN_TOKEN=your-secure-token-here\n      - ALLOWED_ORIGINS=__self\n```\n\n### 环境变量\n\n| 变量 | 说明 | 默认值 |\n| --- | --- | --- |\n| `PORT` | 服务端口 | `3000` |\n| `DATA_DIR` | 数据目录（SQLite + 产物） | `/app/data` |\n| `OUT_DIR` | 前端静态文件目录 | `/app/out` |\n| `ADMIN_TOKEN` | 管理员令牌。不设时自动从 `\u003cDATA_DIR\u003e/admin-token` 读取或生成 32 字节随机令牌（详见下方说明） | 空 |\n| `ALLOW_EMPTY_ADMIN_TOKEN` | 设为 `1` 时允许无令牌运行（完全开放模式），启动日志将持续打印安全警告。**切勿在不可信网络下启用** | 空 |\n| `INITIAL_CONFIG_PATH` | 首次初始化使用的模板 JSON 文件路径 | 自动探测 `out/templates/` 与 `public/templates/` |\n| `ALLOWED_ORIGINS` | 浏览器跨源白名单（逗号分隔，如 `https://rules.example.com`）。特殊值 `__self` 表示回显请求 Origin + 启用 credentials，效果为仅允许访问者自身域名（推荐默认值）。**不设**时默认 `Access-Control-Allow-Origin: *` 且不开启 credentials；管理认证使用 Bearer token，浏览器不会跨源自动携带，所以默认是安全的。仅当你需要在另一个域名下的前端通过 `credentials: include` 调用本服务时才需要显式设置域名列表。 | `__self`（推荐） |\n\n### 管理员令牌（Admin Token）\n\n启动时按以下顺序解析管理员令牌：\n\n1. **`ADMIN_TOKEN` 环境变量已设置** → 直接使用，不写入文件\n2. **读取 `\u003cDATA_DIR\u003e/admin-token`**（权限应为 `0600`）→ 使用文件中的令牌\n3. **以上都没有** → 自动生成 32 字节随机令牌，写入 `\u003cDATA_DIR\u003e/admin-token`（`0600`），并在启动 banner 中大字打印令牌值与文件路径\n4. **仅当显式设置 `ALLOW_EMPTY_ADMIN_TOKEN=1`** 时才保留\"无需认证\"的完全开放模式，启动日志将持续打印安全警告\n\n首次部署若不设置 `ADMIN_TOKEN`，请留意启动日志中的生成令牌，或查看 `data/admin-token` 文件。\n\n\u003e 所有可调的运行时参数（抓取超时、转换器执行上限、速率限制阈值等）都在\n\u003e 管理面板「系统配置」页中调整，存放在数据库 `kv_settings` 表里并随备份归档。\n\n### 健康检查\n\n运行时镜像为 distroless（无 `wget`/`curl`）。容器内置健康检查通过二进制自身实现：\n\n```\nCMD [\"/app/proxy-rule-manager\", \"--healthcheck\"]\n```\n\n执行时，程序向 `http://127.0.0.1:$PORT/api/status` 发出 HTTP GET 请求，成功返回 0，失败返回 1。\n\n---\n\n## 开发者\n\n### 环境要求\n\n- Node.js \u003e= 18\n- pnpm \u003e= 10\n- Go \u003e= 1.22\n\n### 项目结构\n\n```\nsrc/            # 前端（Next.js + React）\n  app/          # 页面 Shell\n  components/   # UI 组件\n  lib/          # API 客户端、Schema、工具函数\n  hooks/        # React Hooks\n\nbackend/        # 后端（Go）\n  cmd/server/   # 程序入口（main.go）\n  internal/\n    api/        # chi 路由与 HTTP 处理器\n    config/     # 环境变量加载\n    schema/     # 共享数据结构\n    store/      # SQLite 持久化层\n    syncengine/ # 同步引擎\n    geosite/    # Geosite 数据管理\n    diff/       # Diff 生成\n    transformer/# 内容转换器\n    util/       # 工具函数\n```\n\n### 开发\n\n```bash\npnpm install\n\n# 同时启动前端（Next.js dev :3000）和后端（go run :3001）\npnpm run dev\n\n# 或分别启动\npnpm run dev:fe   # 前端\npnpm run dev:be   # 后端\n```\n\n### 构建与运行\n\n```bash\n# 构建前端（静态输出到 ./out）+ 后端二进制（./bin/proxy-rule-manager）\nmake build\n\n# 或单独构建\nmake build-fe    # 前端\nmake build-be    # 后端\n\n# 启动生产服务\n./bin/proxy-rule-manager\n```\n\n### 检查与测试\n\n```bash\n# 一键跑完所有 CI 检查（lint + typecheck + test）\nmake check\n\n# 或单独运行\nmake lint        # 前端 ESLint + 后端 gofmt / go vet / staticcheck\nmake typecheck   # TypeScript 类型检查\nmake test        # Go 测试（-race）\n```\n\n### Docker\n\n```bash\n# 本地构建 + 运行（当前平台，数据挂载 ./data）\nmake docker-run\n\n# docker compose 部署\ndocker compose up -d    # 启动\ndocker compose down     # 停止\nmake logs               # 查看日志\n```\n\n### 其他\n\n```bash\nmake help       # 查看所有 make 目标\nmake version    # 显示版本号\nmake clean      # 清理构建产物\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffl0w1nd%2Fproxy-rule-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffl0w1nd%2Fproxy-rule-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffl0w1nd%2Fproxy-rule-manager/lists"}