
TREK 插件管理完整实战指南Admin Plugins 面板从安装、审查到签名治理【免费下载链接】TREKA self-hosted travel/trip planner with real-time collaboration, interactive maps, PWA support, SSO, budgets, packing lists, and more.项目地址: https://gitcode.com/GitHub_Trending/nomad22/TREKTREK 插件管理的全部动作都收敛在Admin → Plugins这一个面板里。本文以它为主线按总开关 → 三条获取通道 → 安装前信任评估 → 激活与依赖治理 → 出口主机 → 更新与签名 → 卸载 → 隔离与审计的顺序讲清 TREK Admin Plugins 每一步背后 plugins 模块 的隔离模型与安全边界。读者对象是负责自托管 TREK 实例的管理员与进阶用户。决策速查表我想做 X 该点哪里先定位再细读。表内入口均指 Admin → Plugins 面板除注明外。我想做入口关键注意从注册表装一个插件Discover视图 → 点卡片 →Install最新版本不兼容时按钮降为Install {version}装旧兼容版或Incompatible禁用装自己打包的插件工具栏Upload plugin或直接把.zip拖进面板上限 50 MB装完保持 inactive行上标记Sideloaded链接本地构建目录调试Link a local plugin路径框仅当服务端TREK_PLUGINS_DEV_LINK1时才显示标记Dev-Link启用一个插件行上的Enable plugin开关依赖会被级联拉起被拒时按错误码找补救见后文表格改某个插件可达的主机行⋯ → Allowed hosts仅operatorEgress插件可用保存后插件自动重启才生效更新插件 / 全部更新行按钮Update → v{version}提示条Update all新增权限/新出口时新代码保持关闭必须显式同意解除签名导致的更新阻塞行Update blocked→Review只有密钥变更可覆盖需回显完整公钥卸载插件行⋯ → Delete出口主机与定时任务无条件删除选择保留数据时擦除义务延续到同 id 重装让刚发布的插件立刻出现工具栏Rescan本地重发现 强制拉取注册表绕过 30 分钟缓存查插件以我名义做了什么用户Settings → Plugins管理员Admin → Plugins用户侧活动日志不设管理员门槛环境与总开关四个插件环境变量决定面板能做什么面板的所有端点都挂在Controller(api/admin/plugins)下同时叠加JwtAuthGuard与AdminGuardplugins.controller.ts在此之上才是运行时总开关。四个相关环境变量一次列齐变量作用默认值TREK_PLUGINS_ENABLED插件系统总开关取值只要不是false、0、off、no大小写不敏感即为开启且每次调用实时读取开启TREK_PLUGINS_DEV_LINK开发专用允许Link a local plugin注册本地构建目录并热重载值必须恰为1其余任何取值含不设置都关闭关闭TREK_PLUGIN_ALLOW_PRIVATE_EGRESS设为on才允许插件出口解析到私网/回环/链路本地/元数据地址默认拒绝关闭私网出口被阻断TREK_PLUGIN_REGISTRY_URL覆盖 Discover 视图浏览的注册表索引地址可指向自己的 fork/镜像TREK 官方注册表总开关关闭时面板显示Plugins are disabled原文是The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.此时install、upload、activate、update、rescan等操作统一返回 503而已安装插件仍留在磁盘上、处于停用状态重新打开即恢复。开关判定逻辑很短见 kill-switch.ts。要记住一个容易混淆的差别运行时开启不等于插件在跑。开启TREK_PLUGINS_ENABLED只是让面板与运行时可用面板头部出现绿色Runtime on标识每个已安装插件仍必须逐个手动激活激活之前不会执行任何第三方代码。整机关闭只需environment: - TREK_PLUGINS_ENABLEDfalse面板导览Installed 与 Discover 两个视图、工具栏和 Rescan 的双重作用面板顶部是分段切换器两个视图Installed当前实例已安装列表带数量统计与Discover社区注册表卡片浏览。共享工具栏包括Search plugins…、Type类型筛选Widget / Page / Integration / Trip page、Sort排序、Upload plugin、RescanInstalled 视图额外多一个Status状态筛选Active / Off / Update available / Error。Rescan 做两件事缺一不可。第一件是本地重发现重新扫描插件卷把磁盘上已有但注册表行里缺失的插件登记进来discoverPlugins逻辑。第二件是强制拉取远程注册表registry.service.ts 中fetchRegistry(forcetrue)会绕过服务端的 30 分钟内存缓存CACHE_TTL 30 * 60 * 1000并通过追加时间戳参数加no-cache头一并打穿 GitHub 的 CDN 边缘缓存max-age 300 秒——否则一个刚合并进注册表的条目最长要等约 35 分钟才可见。拉取的对象是聚合的单文件dist/index.json而不是逐个插件的 GitHub API 调用后者有速率限制问题拉取失败时软降级为空列表面板本身不受影响。三条获取通道注册表安装、上传旁路与 dev-link 本地链接怎么选代码进入实例只有三条路信任模型完全不同。先看差异再分述维度注册表安装上传旁路Uploaddev-link 本地链接代码来源聚合注册表索引中钉住的版本你上传的.zip/.tar.gz本地构建目录符号链接不复制完整性校验SHA-256 比对 防 zip-slip/炸弹解压同样的安全解压与 manifest 校验manifest 校验 原生二进制拒绝签名/审查可选作者签名TOFU 钉住密钥Reviewed 徽章无——未签名、未经审查无热重载无走更新流程无fs.watch监听构建输出防抖 400 ms 自动重新 fork版本兼容下载前预检 解压后按归档内 manifest 复验同一套assertHostCompatible检查同一套行上徽章Signed / UnsignedSideloadedDev-Link前置条件无归档 ≤ 50 MBTREK_PLUGINS_DEV_LINK1 管理员注册表安装字节先过三道关才落盘安装流水线PluginRegistryService.install是先验证、后落盘、最后注册的顺序且安装过程不执行任何内容SSRF 安全的受限下载 → SHA-256 与注册表条目比对 → 安全解压到 staging → 重新校验包内 manifestid 必须与安装目标一致、trek版本范围必须覆盖当前宿主→ 原生二进制扫描拒绝 → 原子移动进代码目录 → 以inactive状态登记并记录来源仓库、commit、sha256、审查时间。为什么解压后还要再验一次 manifest注册表索引里的版本元数据是较弱的一层过滤很多条目只有下限没有上限归档自带的 manifest 才是权威范围声明4.0.0这类独占上界只有在这一层才拦得住。首次成功安装签名插件时作者公钥以 TOFU信任首次使用方式钉入数据库行且只会被替换为刚刚验证过的新密钥、永不清空为 NULL——NULL 会重新打开从未签名的接受路径。上传旁路同一条防护线少一道签名用相同 id 覆盖上传时服务端先把旧插件强制停止并停用再替换代码保证替换后的代码绝不处于未经重新激活仍在运行的状态plugin-runtime.service.ts 的sideload()。防护上与注册表安装共用同一条硬线安全解压、严格 manifest、拒绝原生二进制唯一省略的是 SHA-256/签名校验因为旁路加载没有注册表条目可对照。上传上限 50 MB50 * 1024 * 1024 4096见 registry.service.ts 与 plugins.controller.ts。提交后该行来源记为local:upload同时清空旧的更新阻塞记录——它描述的是一次注册表更新的拒绝而代码已经脱离注册表信任模型留着会误导后续判断。激活时仍需照常同意权限。Dev-link符号链接加文件监听仅限开发机link()plugin-runtime.service.ts要求绝对路径校验trek-plugin.json与已构建的server/index.js存在、拒绝原生二进制然后在插件代码目录创建符号链接Windows 下为 junction卸载时也只断链、永不跟随删除作者源码登记为 inactive并对构建输出挂fs.watch重建后防抖 400 ms 自动重新 fork。它不会顶掉一个真实安装的插件——同 id 已存在时要求先卸载。为什么门槛叠得这么高管理员 总开关 TREK_PLUGINS_DEV_LINK1三层判定见 dev-link.tsdev-link 同时绕过了安装期签名/完整性模型、代码在重启间可变而无需重新同意且在npm run dev下 OS 权限围栏是关的数据访问仍走能力 RPC 网关但代码来源不受管控因此生产实例绝不应打开。安装前的信任评估审查对话框四块内容与版本兼容判定点 Discover 卡片先弹预安装审查对话框再谈 Install。对话框的四个内容块What it can access——逐条以平实语言渲染插件请求的权限如 Read the trips…、Create and edit places…未知权限代码原样显示不请求任何权限时显示Needs no special access.Connects to——manifest 声明的全部可访问主机等宽字体 chip 展示。Setup——插件要收集的设置项标注Instance-wide或Per user必要时标Required。Details——版本、体积、所需 TREK 版本范围、审查时间、总下载量。底部提供Source repository、Report an issue与插件Homepage链接。这里有个容易忽视的设计点对话框展示的不是作者写的介绍而是服务端在审查提交点实时拉取的 manifest 投影ManifestPreview权限、出口主机、operatorEgress标记、设置字段、许可证、图标、所需 addon 与插件依赖。作者文案与 manifest 声明不一致时你看到的是声明——这才是安装时会真正生效的东西。版本兼容由服务端计算客户端不持有 semver避免 UI 与安装门禁两套逻辑互相打架。三种按钮状态最新版本兼容 →Install最新版要求更新的 TREK 但存在仍兼容的旧版本 →Install {version}直接装那个旧版本没有任何版本兼容 →Incompatible并禁用。后两种情况对话框都会用琥珀色提示条解释具体原因而不是把理由藏在 tooltip 里。无论哪条路径指定版本、带约束、还是装最新registry.service.ts 的selectVersion都强制执行兼容断言不存在绕过检查的入口。徽章语义Reviewed、Signed、Unsigned 各自保证什么、不保证什么徽章保证不保证ReviewedTREK 维护者对该版本做过恶意软件扫描质量、可用性、无害——扫描只针对恶意软件Signed文件已对照作者签名密钥校验且密钥被 TOFU 钉住字节来自作者代码做了什么Unsigned文件字节与注册表担保的一致没有任何机制把字节绑定到作者——少一层担保不是危险警报注册表多数插件目前未签名故为琥珀色提示而非警报结论先行两个徽章都不说明代码做什么。面板底部有一个可折叠的How plugins are contained — and the limits面板完整阐述隔离模型与它不能承诺的边界安装决定必须基于权限清单与出口主机而不是徽章。激活与依赖治理插件开不动时按错误码找补救路径行上Enable plugin开关控制生命周期状态圆点反映运行时健康active 绿、starting 蓝闪烁、error 红、inactive 淡、disabled/incompatible 琥珀。激活前plugin-runtime.service.ts 的assertActivatable对整条依赖链做只读预检从最严重到最不严重宿主版本 → 权限再同意 → 必需 addon → 插件依赖任何一项不满足都不会留下半激活状态。被拒时分发的是结构化错误码而非一句散文按码找补救错误码含义补救动作TREK_VERSION_INCOMPATIBLE插件声明的trek范围不含当前宿主典型场景TREK 升级越过了插件声明的上限升级 TREK或装一个声明兼容的旧版本TREK_VERSION_UNKNOWN插件从未声明支持的 TREK 范围无法证明兼容要求作者补声明在此之前不能激活ADDON_DISABLED必需的 addon 未启用到 Admin → Addons 开启后重试toast 会提示具体 addon 名DEPENDENCY_MISSING插件依赖缺失或版本不匹配对话框逐条列出提供一键Download / Update装最新兼容版本后自动重试启用CONSENT_REQUIRED更新拓宽了权限/出口但尚未同意在同意对话框选Approve turn on或Keep off for now依赖级联有四个方向全部是自动行为触发激活一个插件其依赖已安装但停用 → 后果按依赖图计算启用顺序先拉起全部依赖再拉起目标被顺带打开的依赖会用 toast 告知。触发管理员停用某个被依赖的插件 → 后果deactivateWithDependents先停最远的传递依赖者、再停目标——依赖者的跨插件调用在依赖缺失时必然失败所以不能把它留在 enabled 状态。触发管理员在 Admin → Addons 关闭某 addon → 后果deactivateForDisabledAddon停用所有声明依赖该 addon 的插件以及传递依赖它们的全部插件。触发服务器重启 → 后果按依赖顺序自动拉起所有enabled插件启动时依赖不满足的会被对账回enabled 0UI 不显示虚假的 active。出口主机operatorEgress 插件的 Allowed hosts 配置与网络边界有一类插件访问只有你才知道地址的服务自托管 Gotify、ntfy 等manifest 无法预写主机名于是声明operatorEgress。审查对话框会因此多出一个 hosts you addchip 与提示该插件要连的服务只有你能命名安装后需在⋯ → Allowed hosts里逐个添加主机除此之外它一个主机都到不了。操作流程与为什么必须重启在 Allowed hosts 对话框逐个添加主机名校验规则与 manifest 声明出口一致不允许裸*、不允许整 TLD 通配、不允许带协议前缀正则见 plugin-runtime.service.ts。在添加至少一个主机之前该行显示琥珀色Add allowed hostchip——此时它实际上到不了任何主机不提示会像静默故障有了主机后 chip 变蓝并显示数量。保存时若插件正在运行服务端会重启它才生效出口守卫在子进程初始化时只安装一次且拒绝二次init运行中的白名单永远不能在原进程内热扩容重新 fork 是唯一路径。删除某个主机同理——立即失去该出口并再次重启。三条边界必须刻进肌肉记忆未声明operatorEgress的插件永远无法被授予主机——安装时你同意的 manifest 范围仍是硬边界setOperatorEgressHosts对未声明者直接拒绝。只有管理员能添加主机。普通用户不能扩大插件出口即使凭据由用户本人提供整个端点挂在 admin 守卫后。私网出口默认禁止。服务若与 TREK 同机或同局域网localhost、192.168.x.x需设TREK_PLUGIN_ALLOW_PRIVATE_EGRESSon。注意这个变量放宽的是所有已安装插件的私网出口策略——只有当你信任全部插件时才应开启。卸载插件时这些主机一并删除否则一个后续复用同一 id 的插件会悄悄继承前主人批准的出口权限。更新与签名什么时候静默重启什么时候必须停下来等同意有可用更新时行上出现Update → v{version}列表上方出现{count} updates available for your plugins.提示条与Update all。更新目标由resolveUpdateTarget选定当前 TREK 能运行的最新版而非绝对最新版——新版本放弃对当前宿主支持时盲目取最新会把一个能用的插件更新坏兼容但更旧的候选则视为降级直接报NO_COMPATIBLE_UPDATE拒绝update的名义下静默回滚比不动更糟。update()的核心是权限差集plugin-runtime.service.ts新代码装好后对比其声明权限与已授予权限。差集为空 → 插件被透明重启到新代码原本 active 的话。差集非空新权限或新出口主机→ 插件保持 inactive差集返回给 UI显示{name} v{version} is asking for rights you havent granted yet. The new version is installed but stays off until you approve it.对话框列出Newly requested permissions与New outbound connections管理员选Approve turn on或Keep off for now。批量更新时这些同意提示排队依次出现一个都不跳过若被同意的版本未签名对话框会额外说明没有任何机制把该版本与其作者绑定。签名密钥变更唯一的可覆盖场景且要回显完整公钥先讲后果覆盖签名密钥是把TOFU 钉住换到一把你刚批准的新钥匙上批准前 TREK 无法替你区分合法轮换与被接管——两者从面板里看完全一样。因此流程刻意加重更新被拒时行上显示Update blocked — {reason}与Review对话框并排展示钉住密钥的指纹与当前提供密钥的指纹并提示你在接受前通过你已信任的渠道向作者确认新密钥。硬约束有五条只有SIGNATURE_KEY_CHANGED这个错误码允许覆盖Trust the new key update。签名无效、缺失、半声明有密钥无签名或反之只给出解释没有任何覆盖按钮——服务端assertRetrustable同样独立拒绝这些情形直接调/retrust端点也绕不过UI 隐藏按钮只是便利而非控制。调用方必须回显对话框中展示的完整公钥。若注册表条目在你点按钮前又被换了一次钥服务端检测到指纹不符即拒绝——堵死批准了一把你没见过的钥匙的 TOCTOU 窗口。重信任与更新在同一次调用内原子完成要么新密钥验证通过、插件落到新版本并钉住新密钥要么什么都不变。拆成先重钉、后更新两步中间会存在钉住一把从未被任何安装验证过的密钥的窗口。被批准的新密钥仍须实际验证工件——retrustKey只解除换钥这一道闸门签名校验照跑一把签不了代码的钥匙和任何坏签名一样被拒。每次重信任写入管理员审计日志admin.plugin_retrust含新旧密钥指纹与 IP这是事故后必须能重建的事件。停用与卸载Delete 确认框背后到底删了什么⋯ → Delete弹出确认Uninstall plugin?—This stops the plugin, removes its code, and deletes all of its data. This cannot be undone.uninstall()plugin-runtime.service.ts分两档清理无条件删除无论是否勾选删除数据停止插件进程、移除代码目录dev-link 只断符号链接、plugins注册表行、设置字段定义、出口主机理由保留会让后续复用同一 id 的插件继承前人批准的出口、定时任务一个已不存在插件的回调绝不能开火、通知渠道登记否则所有用户的逐事件退订与管理员启用项会被同 id 新插件继承。勾选删除数据时额外清除插件自有数据目录、错误日志、plugin:{id}:%设置行、实体元数据、每用户配置含加密的密钥——不清理会留下可被同 id 重装收养的凭据、OAuth 令牌与状态、迁移台账、能力审计日志、待处理的 GDPR 擦除队列数据目录已不存在义务随之了结。选择保留数据时有一个容易被漏掉的语义擦除队列的行故意保留。数据目录里可能仍存着已注销用户的行GDPR 擦除义务必须活下去——同 id 插件重装后队列会被排空并继续兑现。只有当插件行消失且数据目录确实被删除真正的孤儿时清扫器才会清掉队列行。隔离模型速览插件进程物理上碰不到什么这是你批准的权限是真实边界这句话的底气所在实现见 supervisor/ 与 runtime/每个活动插件运行在独立 OS 子进程中生产编译子进程以 Node 权限模型--permission启动文件系统读取被限定在其自身代码目录。子进程环境是白名单NODE_ENV、TZ、PATH、插件 id 等没有继承任何东西——JWT_SECRET、数据库凭据对插件进程物理不可达。插件不能打开trek.db、写文件、派生子进程、使用 worker 线程或加载原生模块其自有数据在独立 SQLite 文件中只能经 TREK 访问。插件与宿主只通过内部 RPC 通道通信宿主只应答 manifest声明且你批准的能力——未授予的调用被拒绝而非忽略且每次调用对操作者做 membership 校验。RPC 通道本身对插件代码是封死的即便宿主用 fork 拉起原始 IPC 原语process.send、process.on(message)也在插件代码加载前被吊销plugin-host-entry.ts——插件不能伪造宿主消息假loaded/heartbeat也不能窃听其他在途请求一切交互被迫经过能力校验的 SDK。页面/组件界面运行在密封的浏览器 frame中读不到会话 cookie也碰不到外围 TREK 页面。崩溃、挂起或内存耗尽时只有它自己的进程死掉TREK 继续运行并可随时重启或停用它。一句话收尾权限清单约束的是插件能触及什么不约束它在授权范围内的意图——一个被允许读行程、且被允许连某主机的插件完全可能把行程发过去。先读权限与出口主机再点 Install。审计插件替你做了哪些事用户和管理员各看哪个日志插件行为分两条审计线回答两个不同的问题。用户侧——插件以我的名义做了什么。每个用户在Settings → Plugins的活动日志中可以看到插件以其名义执行的全部操作读取了哪些行程/费用、写入了哪些地点、TREK 代发的每一次出站调用。该视图不设管理员门槛基于哈希链防篡改管理员在 Admin → Plugins 看到的是按插件维度的对应视图audit端点。能力审计记录回答的是数据面问题用户有权自查。管理员侧——管理员自己做了什么。重信任签名密钥这类生命周期动作写入管理员审计日志动作admin.plugin_retrust含插件 id、版本、新旧密钥指纹、IP与用户侧的能力日志严格分开——管理员的操作不属于插件替用户做的事。延伸阅读源码模块与 wiki 页面索引Plugins——插件系统全貌类型、隔离模型、依赖、活动日志与整机关闭方式Plugin-Permissions——每条权限的确切授予范围与http:outbound细节Plugin-Development——SDK 与 manifest 编写、dev-link 的完整用法Plugin-Publishing——注册表提交流程与trek-pluginCLIAdmin-Addons——插件可能依赖的 addon 如何启用与停用Environment-Variables——四个插件环境变量的完整参考与默认值说明Security-Hardening——安全加固清单含 dev-link 为何必须保持关闭plugins.controller.ts——全部管理端点、守卫组合与 503 拒绝路径plugin-runtime.service.ts——激活预检、依赖级联、更新差集、retrust 原子性、卸载清理清单的实现registry.service.ts——注册表缓存与软降级、版本解析、安装流水线、旁路 stagingkill-switch.ts 与 dev-link.ts——两个开关的判定逻辑supervisor/ 与 runtime/——子进程监督、OS 权限模型启动、IPC 原语吊销plugin-sdk/——trek-pluginCLIcreate/dev/pack/sign/validate/publish 全套开发工具【免费下载链接】TREKA self-hosted travel/trip planner with real-time collaboration, interactive maps, PWA support, SSO, budgets, packing lists, and more.项目地址: https://gitcode.com/GitHub_Trending/nomad22/TREK创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考