TREK 管理员插件面板完全指南:安装、审查、更新与安全治理

发布时间:2026/9/15 1:05:53
TREK 管理员插件面板完全指南:安装、审查、更新与安全治理 TREK 管理员插件面板完全指南安装、审查、更新与安全治理【免费下载链接】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 的插件系统允许任何人在不改动 TREK 源码的前提下扩展自托管实例的功能——仪表盘 widget、独立页面、行程页标签乃至照片/日历/通知渠道等集成。本篇技术指南以Admin → Plugins管理面板为主线完整讲解从注册表安装、预安装审查、依赖与权限治理、更新与签名校验到旁路加载与开发链接的完整运维流程并结合 服务端插件模块 的源码实现说明每个操作背后的隔离模型与安全边界。读完本文你将能安全、可控地在一个生产 TREK 实例上管理第三方插件。前置条件Admin 权限与运行时总开关Admin → Plugins整个面板仅对管理员开放且需要插件运行时处于开启状态。运行时由环境变量TREK_PLUGINS_ENABLED控制默认开启——但开启运行时与运行某个插件是两回事所有已安装插件必须逐个手动激活在激活之前不会有任何第三方代码执行。如果运行时被关闭面板会显示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.运行时开启时面板头部会出现绿色的Runtime on标识。环境变量的判定逻辑非常直接见 kill-switch.tsTREK_PLUGINS_ENABLED的取值只要不是false、0、off、no大小写不敏感即为开启且该判断在每次调用时实时读取改动环境变量并重启即可立即生效。关闭整个系统的方式来自 wiki/Plugins.md 与 wiki/Environment-Variables.mdenvironment: - TREK_PLUGINS_ENABLEDfalse运行时关闭时已安装的插件仍保留在磁盘上处于停用状态、无害重新打开总开关后即可恢复。相关的另外两个环境变量将在下文对应小节展开环境变量作用默认值TREK_PLUGINS_ENABLED插件系统总开关开启TREK_PLUGINS_DEV_LINK开发专用允许从本地构建目录注册插件并热重载仅当值恰为1关闭TREK_PLUGIN_ALLOW_PRIVATE_EGRESS设为on时允许插件出口访问私网/内网地址如 LAN 上的服务关闭默认拒绝私网出口TREK_PLUGIN_REGISTRY_URL覆盖 Discover 页浏览的注册表索引地址可指向自己的 fork/镜像TREK 官方注册表面板的两个视图与工具栏面板顶部是一个分段切换器segmented switch在两种视图间切换Installed已安装——当前实例上已安装的插件列表带数量统计。Discover发现——社区注册表以卡片形式浏览。两个视图共享同一套工具栏Search plugins…搜索框、Type类型筛选Widget / Page / Integration / Trip page、Sort排序菜单、Upload plugin上传按钮、Rescan重扫描按钮Installed视图额外多一个Status状态筛选Active / Off / Update available / Error。关于Rescan按钮值得重点说明它做两件事——重新发现磁盘上本地安装的插件对应discoverPlugins逻辑plugins.service.ts 目录并且强制拉取远程注册表绕过 30 分钟的服务器缓存和 GitHub 的 CDN。这样刚刚发布的插件可以立即出现而不是最长等待约 35 分钟。注册表缓存与下载逻辑见 registry.service.tsCACHE_TTL 30 * 60 * 100030 分钟拉取的是聚合的dist/index.json而非逐个插件的 GitHub API 调用避免速率限制并且注册表请求失败时软降级不影响面板使用。从注册表安装插件安装流程分为三步切换到Discover视图。每张卡片展示图标、名称、作者、描述、类型、Reviewed徽章如适用、Signed / Unsigned徽章、最新版本号和下载量。点击卡片打开预安装审查对话框详见下节。点击Install。一个关键的版本兼容逻辑如果最新版本要求比当前实例更新的 TREK安装按钮会变化——当存在仍兼容的旧版本时按钮变为Install {version}安装那个旧版本如果没有任何版本兼容按钮变为Incompatible并禁用。无论哪种情况对话框都会在琥珀色提示条中解释原因不会把原因藏在 tooltip 里。服务端的实现逻辑在PluginsController.install与registry.install中安装前通过assertHostCompatible/hostSatisfies校验插件声明的trek版本范围与当前宿主版本是否匹配见 host-compat.ts。刚安装的插件默认是**关闭off**状态。在手动启用之前它不会运行任何代码——安装流程只做下载、校验、安全解压、重新校验 manifest、注册inactive不执行任何内容参见 registry.service.ts 的注释说明。预安装审查对话框安装前必须仔细阅读以下各节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 生成预览ManifestPreviewregistry.service.ts其中包含权限列表、出口主机列表、operatorEgress标记、设置字段key/label/inputType/scope/required、许可证、图标、所需 addon 与插件依赖——预安装对话框里的信息正是来自这份预览而非插件作者自己写的介绍文字。操作者出口主机Operator egress hosts有一类插件会访问只有你才知道地址的服务——自托管的 Gotify、ntfy 等。这类插件的 manifest 无法预知主机名因此其 manifest 会声明operatorEgress审查对话框会额外出现一个 hosts you addchip 和如下提示This plugin talks to a service only you can name (a self-hosted server). After installing, add the hosts it may reach under ⋯ → Allowed hosts. It can reach no others.安装完成后打开该插件行的⋯ → Allowed hosts对话框逐个添加主机名。在添加至少一个主机之前该插件行会显示琥珀色的Add allowed hostchip——因为此时它一个主机也访问不到如果不提示会看起来像静默故障。一旦有了主机chip 变蓝并显示主机数量。保存后会重启插件使其加载新的出口白名单——运行中插件的白名单永远不能在原进程内热扩容。这一点在源码中有明确注释plugin-runtime.service.ts出口守卫在子进程初始化时安装一次且拒绝二次init因此唯一让新列表生效的方式就是重新拉起子进程。出口主机校验与 manifest 声明出口的规则一致不允许裸*、不允许整 TLD 通配、不允许带协议前缀校验正则见 plugin-runtime.service.ts。删除某个主机后插件会立即失去该出口并再次重启。卸载插件时这些主机一并删除避免后续复用同一 id 的插件继承前人的出口权限。两个安全边界需要记住见 wiki/Plugins.md 与 Plugin-Permissions.md未声明operatorEgress的插件永远无法被授予主机——安装时你同意的范围仍然是硬边界。只有管理员能添加主机。普通用户永远不能扩大插件出口即使该插件的凭据由用户自己提供。如果服务运行在与 TREK 同一台机器或同一局域网如localhost、192.168.x.x还需要设置TREK_PLUGIN_ALLOW_PRIVATE_EGRESSon——默认情况下插件不得访问私网地址。注意该变量会放宽所有已安装插件的私网出口策略只有当你信任全部插件时才应开启。启用、重启与停用每个已安装插件的行上都有一个开关Enable plugin并显示Active或Off状态。图标块上的彩色圆点反映运行时健康状态active绿、starting蓝闪烁、error红、inactive淡、disabled/incompatible琥珀。启用操作可能被拒绝每种拒绝原因都会给出对应的补救路径必需的 addon 未启用——toast 提示 addon 名称在 Admin-Addons 中开启后重试。插件依赖缺失或版本过旧——对话框逐条列出每个依赖提供一键Download / Update安装最新兼容版本后自动重试启用。更新拓宽了权限——弹出同意对话框见下文更新一节。已安装但处于停用状态的依赖会被自动级联启用并有 toast 告知你哪些依赖被顺带打开了。对应服务端逻辑见activate()的依赖优先排序plugin-runtime.service.ts启用一个插件前会先按依赖图计算enableOrder先拉起所有依赖再拉起目标。激活被拒的三类原因在服务端以结构化错误码返回见 plugin-runtime.service.ts 与assertActivatable检查链ADDON_DISABLED必需 addon 关闭、DEPENDENCY_MISSING插件依赖缺失/版本不匹配、TREK_VERSION_INCOMPATIBLE/TREK_VERSION_UNKNOWN宿主 TREK 版本不兼容/插件未声明支持范围。检查顺序是从最严重到最不严重版本兼容 → 权限再同意 → 必需 addon → 插件依赖且整个预检是只读的任何一项不满足都不会留下半激活状态。此外还有两个级联语义插件运行时若其依赖的 addon 被关闭该插件自动被停用deactivateForDisabledAddon会顺带停用所有传递依赖它的插件plugin-runtime.service.ts。停用一个被其他插件依赖的插件也会停用所有依赖它的插件——一个插件不能在依赖缺失的情况下继续运行deactivateWithDependents。每行的⋯菜单提供Restart仅活动插件、View error log查看错误日志、Allowed hosts出口主机、Source repository与Report an issue链接仅注册表插件以及Delete删除。更新插件当存在更新版本时插件行会出现Update → v{version}按钮列表上方会出现{count} updates available for your plugins.提示条和Update all批量更新按钮。如果新版本请求了尚未授予的权限TREK 会先安装新代码但保持插件关闭并显示{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暂不开启。批量更新多个插件时这些同意提示会排队依次出现不会跳过任何一个。如果被同意的新版本未签名对话框会额外说明没有任何机制把该版本与其作者绑定。服务端保证更新永不会静默扩大权限update()会对比新版本声明的权限与已授予权限的差集newGrants无新增权限时透明重启到新代码有任何新增权限或出口主机则保持 inactive 并返回差集plugin-runtime.service.ts。同时resolveUpdateTarget会挑选当前 TREK 能运行的最新版本而非简单取最新版避免新版本放弃对当前宿主的支持时把正常工作的插件更新坏。被阻塞的更新签名密钥变更如果作者的签名密钥与安装时钉住的密钥不再匹配更新会被拒绝插件行显示Update blocked — {reason}和Review链接。对话框会并排展示钉住的密钥指纹与当前提供的密钥指纹TREK cannot tell a legitimate key rotation apart from a takeover — both look identical from here. Confirm the new key with the author through a channel you already trust before you accept it.关键点在于覆盖范围只有密钥变更可以被覆盖Trust the new key update按钮。签名无效、缺失或半声明half-declared的情况只给出解释没有任何覆盖按钮——服务端同样拒绝这些情形。服务端在/retrust端点上强制了这一范围plugins.controller.ts 及 plugin-runtime.service.ts 中的assertRetrustable只有SIGNATURE_KEY_CHANGED这种错误码才允许覆盖且调用方必须回显对话框中展示的完整公钥防止对话框渲染后注册表条目又被换钥。重信任与更新在同一调用内完成——要么新密钥通过校验、插件落到新版本并钉住新密钥要么什么都不变杜绝钉住未验证密钥的窗口。卸载插件⋯ → Delete会弹出确认对话框Uninstall plugin?—This stops the plugin, removes its code, and deletes all of its data. This cannot be undone.卸载uninstallplugin-runtime.service.ts会执行停止插件进程、移除代码目录、删除plugins注册表行与设置字段deleteDatatrue时还会清除插件自己的数据目录、错误日志、实体元数据、每用户配置含加密的密钥、OAuth 令牌与状态、迁移台账、能力审计日志以及待处理的 GDPR 擦除队列。出口主机与定时任务无条件删除——否则后续复用同一 id 的插件会悄悄继承这些权限卸载时如选择保留数据则待处理的用户数据擦除义务也会保留待同 id 插件重装后继续兑现。徽章它们保证什么、不保证什么Reviewed已审查——Reviewed means a TREK maintainer scanned this plugin for malware on each version — not for quality or whether it works. It is not a guarantee that a plugin is harmless.即TREK 维护者对每一个版本做了恶意软件扫描但这不承诺质量或可用性也不是无害担保。Signed已签名——安装时文件已对照作者的签名密钥校验过且该密钥被钉住TOFU。校验和checksum已经证明文件是注册表所担保的字节签名则进一步证明这些字节来自作者。Unsigned未签名——The files match what the registry vouches for, but nothing ties them to the author. One guarantee fewer — not unsafe.目前注册表里大多数插件未签名因此这是琥珀色提示而非警报。需要反复强调的一点两个徽章都不说明代码做了什么。标签页底部有一个可折叠的How plugins are contained — and the limits插件如何被隔离——以及局限面板完整阐述隔离模型、权限真正约束什么、TREK 不能承诺什么、最坏情况是什么。隔离模型的核心事实wiki/Plugins.md 中总结并由 runtime/plugin-sdk.ts 与 supervisor/plugin-supervisor.ts 实现每个活动插件运行在独立 OS 子进程中由 Node 的权限模型--permission启动文件系统读取限定在其自身代码目录。插件无法访问JWT_SECRET、数据库连接或任何 TREK 机密——这些对其进程物理不可达。插件不能打开trek.db、写文件、派生子进程、使用 worker 线程或加载原生模块其自有数据存放在独立的 SQLite 文件中且只能通过 TREK 访问。插件只通过内部 RPC 通道与 TREK 通信TREK 只应答 manifest声明且你批准的能力——未授予的调用被拒绝而非忽略。RPC 通道本身对插件代码是封死的即使插件运行在 fork 进程中其原始 IPC 原语process.send、process.on(message)也在其代码加载前被吊销——插件既不能伪造宿主消息也不能窃听其他在途请求所有交互都被迫经过能力校验的 SDK。页面/组件的界面运行在密封的浏览器 frame中无法读取会话 cookie 或触碰外围 TREK 页面。插件崩溃、挂起或内存耗尽时只有它自己的进程死掉——TREK 继续运行并可重启或停用它。这意味着你批准的权限列表是真实边界而非标签。它界定了插件能触及什么但不约束它在授权范围内的意图一个被允许读取行程且连接某主机的插件完全可能把这些数据发送到那里。因此务必先读权限清单和出口主机再决定安装。旁路加载与开发链接Sideloading and dev-linking两条绕过注册表安装插件的路径Upload plugin上传插件——工具栏按钮或直接把.zip拖到面板上。安装的归档保持 inactive激活时仍需同意权限。该行标记为SideloadedUploaded manually — not from the registry, unsigned and unreviewed.服务端sideload()会先解压到 staging 并做与注册表安装相同的硬性防护防 zip-slip/炸弹的安全解压、严格 manifest 校验、拒绝原生二进制仅不适用注册表的 SHA-256/签名校验因为没有注册表条目。上传上限 50 MBregistry.service.ts 与 plugins.controller.ts 中50 * 1024 * 1024 4096。用相同 id 覆盖上传时旧代码会被先强制停止并停用替换代码绝不可能是未经重新激活仍在运行的状态。Link a local plugin链接本地插件——一个路径输入框从本地构建目录注册插件并针对真实数据热重载。仅限开发环境且仅当服务端设置TREK_PLUGINS_DEV_LINK1时该入口才出现。该行标记为Dev-Link。服务端实现见link()对插件代码目录创建符号链接不复制校验 manifest、拒绝原生二进制注册为 inactive并通过fs.watch监听构建输出重建后防抖 400ms 自动重新 forkplugin-runtime.service.ts。对自己诚实这两个徽章都只是卡片上的标签。它们记录代码来源——但不会因此做额外检查、不同沙箱或限制。旁路加载或 dev-link 的插件以它声明的权限原样运行与注册表插件完全一样且没有经过恶意软件扫描、没有签名。徽章的存在只是为了让你一眼看出除了你没有人为此代码背书。source 徽章会替换这些行上的 Signed/Unsigned 徽章因为它本身就是更强的声明。权限与审计面板上的每个端点都要求管理员账户且叠加TREK_PLUGINS_ENABLED运行时总开关dev-link 还额外要求TREK_PLUGINS_DEV_LINK。服务端所有路由挂在Controller(api/admin/plugins)并同时使用JwtAuthGuard与AdminGuardplugins.controller.ts运行时关闭时对应操作统一返回 503如install、upload、activate、update、rescan等。各权限的具体含义预安装审查与同意对话框中展示的每条权限完整记录在 Plugin-Permissions从只读的db:read:trips每个调用都对操作者做 membership 校验、到写入类的db:write:places叠加place_edit权限 写入审计、再到宿主中介的oauth:client宿主持有令牌插件只拿到短期 access token与notify:send收件人被强制限定为操作者本人或所属行程。插件做了什么也是可审计的。每个用户都能在Settings → Plugins的活动日志中查看插件以其名义执行的全部操作读取的行程/费用、写入的地点、TREK 代发的每次出站调用该视图不设管理员门槛——这是 TREK 基于哈希链的防篡改插件审计的用户侧管理员在Admin → Plugins看到按插件维度的视图。扩展阅读Plugins——插件系统全貌类型、隔离模型、依赖、活动日志Plugin-Permissions——每条权限的确切授予范围与http:outbound细节Plugin-Development——SDK 与 manifest 编写Plugin-Publishing——注册表提交流程与trek-pluginCLIAdmin-Addons——插件可能依赖的 addon 管理Admin-Panel-Overview——管理面板总览Environment-Variables——插件相关环境变量完整参考Security-Hardening——安全加固建议【免费下载链接】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),仅供参考