news 2026/9/14 14:35:06

OpenClaw Tlon/Urbit 渠道插件:私网 Ship 接入、群组授权与 Owner 审批流完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenClaw Tlon/Urbit 渠道插件:私网 Ship 接入、群组授权与 Owner 审批流完整指南

OpenClaw Tlon/Urbit 渠道插件:私网 Ship 接入、群组授权与 Owner 审批流完整指南

【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 🦞项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw

本文基于 OpenClaw 仓库中的 Tlon 渠道文档 与 extensions/tlon 插件源码,完整覆盖 Tlon/Urbit 渠道的安装、登录认证、私网 SSRF 放行、群组发现与授权、Owner 审批系统与设置热重载的全部配置细节,并结合插件源码说明审批队列、SSRF 策略和设置存储的底层实现机制,帮助你在本地或私有网络中稳定运行一个带访问控制的 Tlon 机器人。

1. Tlon 渠道是什么,能力边界在哪

Tlon 是构建在 Urbit 上的去中心化即时通讯应用。OpenClaw 通过 Tlon 渠道插件连接到你的 Urbit ship(相当于一个去中心化主机实例),响应私聊(DM)和群组频道消息。群聊回复默认要求 @ mention,并在其上叠加了授权规则和 Owner 审批流。

能力现状(来自 docs/channels/tlon.md 的能力矩阵):

功能状态
私聊(DM)支持
群组/频道支持(默认需要 mention 才回复)
线程(Threads)支持(机器人一旦参与过该线程,后续消息免 mention 继续回复)
富文本Markdown 转换为 Tlon 原生格式(粗体、斜体、代码、标题、列表)
图片入站下载、出站上传
表情回应(Reactions)仅可通过捆绑的 skill 操作
投票(Polls)不支持
原生命令默认仅 Owner 可用

插件为随版本捆绑发布:当前 OpenClaw 的打包版本内置 Tlon,无需单独安装。在较旧版本或自定义安装中可通过 npm 安装:

openclaw plugins install @openclaw/tlon

建议使用裸包名以跟踪当前发布标签;只有需要可复现安装时才固定版本(@openclaw/tlon@x.y.z)。从本地检出目录安装:

openclaw plugins install ./path/to/local/tlon-plugin

从插件清单 openclaw.plugin.json 可以看到,插件声明了channels: ["tlon"]configRepair的 doctor 契约,并捆绑了@tloncorp/tlon-skill这个技能包。

2. 初始接入:channels add 与配置文件两种方式

最快的接入方式是 CLI 向导:

openclaw channels add --channel tlon --ship ~sampel-palnet --url https://your-ship-host --code lidlut-tabwed-pillex-ridrup

也可以直接编辑配置文件:

{ channels: { tlon: { enabled: true, ship: "~sampel-palnet", url: "https://your-ship-host", code: "lidlut-tabwed-pillex-ridrup", ownerShip: "~your-main-ship", // 推荐:你的 ship,始终被授权 }, }, }

登录 code 的获取与轮换code就是 ship 的 web 登录 code,在 ship 的 dojo 里执行+code打印当前值。code 会轮换,一旦认证开始失败就重新读取。

认证链路源码佐证:从 extensions/tlon/src/urbit/auth.ts 可以看到,认证实现就是向POST /~/login提交password=code表单,成功响应后从Set-Cookie头取出会话 cookie;拿不到 cookie 会抛出missing_cookie类型的UrbitAuthError。请求默认 15 秒超时、最多 3 次重定向,并携带tlon-urbit-login审计上下文——这正是文档中"认证失败就重新+code"的底层原因:code 过期时登录请求会直接失败。

配置修改遵循 Gateway 的 hot reload 机制。改完配置后执行openclaw channels status --probe验证(Gateway 离线时先启动),然后 DM 机器人或在群里 @ 它。

3. 私网 / 局域网 Ship:SSRF 防护的显式放行

OpenClaw 默认拦截私有/内网主机名和 IP 段以防 SSRF 攻击。如果你的 ship 运行在私有网络(localhost、局域网 IP、内网域名),必须显式声明信任:

{ channels: { tlon: { url: "http://localhost:8080", network: { dangerouslyAllowPrivateNetwork: true, }, }, }, }

该开关覆盖http://localhost:8080http://192.168.x.x:8080http://my-ship.local:8080这类目标。只对完全信任的 ship URL 开启——它会让该账号的 HTTP 请求失去 SSRF 保护。

注意:旧的扁平键channels.tlon.allowPrivateNetwork已废弃,openclaw doctor --fix会自动把它迁移到channels.tlon.network.dangerouslyAllowPrivateNetwork(插件通过 doctor.ts 注册的 legacy config 规则实现该迁移)。

源码层面的双重校验

  • extensions/tlon/src/urbit/base-url.ts 中,validateUrbitBaseUrl会拒绝非 http/https 协议、URL 内嵌凭据、把 base URL 归一化为纯 origin(防止夹带路径/查询参数),再调用isBlockedUrbitHostname→ 插件 SDK 的isBlockedHostnameOrIp判断主机名是否在拦截名单内;
  • 拦截判断发生在urbitFetch层,dangerouslyAllowPrivateNetwork: true最终转化为ssrfPolicy: { allowPrivateNetwork: true }透传给每次请求——extensions/tlon/src/urbit/auth.ssrf.test.ts 等测试专门验证了"默认拦截私网、开启后放行"的行为边界。

4. 群组频道:手动固定与自动发现

两种管理群组频道的方式,可并用:

{ channels: { tlon: { groupChannels: ["chat/~host-ship/general", "chat/~host-ship/support"], autoDiscoverChannels: true, }, }, }
  • groupChannels是手动固定的频道 nest 列表,格式为chat/~host-ship/channel
  • autoDiscoverChannels在配置文件未显式设置时默认为false;而 setup 向导会把该提示的默认回答设为 yes 并显式写入true。开启后,插件在启动时 scry 已加入的群组、监听随群组邀请被接受而新出现的频道,并且每 2 分钟复查一次。

频道 nest 的解析规则可以在 extensions/tlon/src/targets.ts 中确认:parseChannelNest用正则^chat\/([^/]+)\/([^/]+)$提取 host ship 与频道名,ship 名会自动补~前缀归一化。

5. 访问控制:DM 白名单与逐频道授权

DM 白名单(空 = 除ownerShip外任何 DM 都不允许):

{ channels: { tlon: { dmAllowlist: ["~zod", "~nec"], }, }, }

群组授权默认每个频道为restricted模式。用defaultAuthorizedShips设基线,再按频道 nest 覆盖:

{ channels: { tlon: { defaultAuthorizedShips: ["~zod"], authorization: { channelRules: { "chat/~host-ship/general": { mode: "restricted", allowedShips: ["~zod", "~nec"], }, "chat/~host-ship/announcements": { mode: "open", }, }, }, }, }, }

源码级解析逻辑:extensions/tlon/src/monitor/authorization.ts 的resolveChannelAuthorization实现了三级回退——

  1. 先取设置存储(settings store)中的channelRules,没有再取文件配置中的channelRules
  2. mode未匹配规则时回落到"restricted"(即文档说的"默认 restricted");
  3. allowedShips未指定时回落到defaultAuthorizedShips(同样是"设置存储优先、文件配置兜底"的顺序)。

线程续答与 mention 门控:机器人一旦在某个线程里回复过,后续该线程内的消息就无需再次 mention 也会继续响应。想强制每次显式 mention 时:

{ channels: { tlon: { implicitMentions: { threadParticipation: false }, }, }, }

多账号场景用channels.tlon.accounts.<id>.implicitMentions覆盖。另外 Tlon 目前不产生replyToBot/quotedBot事实,这两个 flag 在 Tlon 渠道上不生效。

6. Owner 与审批系统

配置ownerShip

{ channels: { tlon: { ownerShip: "~your-main-ship", }, }, }

Owner ship 处处被授权:DM 邀请总是自动接受、群组邀请总是自动接受、频道消息总是通过授权——它不需要出现在dmAllowlistdefaultAuthorizedShipsgroupInviteAllowlist里。

关键在于:设置ownerShip后,未授权请求不会被直接丢弃,而是排队等待审批并 DM 通知 Owner。会触发待审批请求的场景:

  • 来自不在dmAllowlist中的 ship 的 DM 请求;
  • 在发送者未通过授权的频道中的 mention;
  • 来自不在groupInviteAllowlist中的 ship 的群组邀请(在自动接受关闭、或开启但邀请人不在白名单时)。

Owner 在 DM 中回复即可处理请求:

Owner 回复效果
approve/deny/block作用于最近一条待审批请求
approve <id>/deny <id>按 id 处理指定请求
block同时以 Tlon 原生方式封禁该 ship,使其无法重连
unblock ~ship解除原生封禁
blocked列出当前被封禁的 ship
pending列出现有待审批请求

审批机制源码实现(extensions/tlon/src/monitor/approval.ts):

  • 待审批对象带唯一 id,格式为{type}-{timestamp}-{shortHash}generateApprovalId,L38-L42),typedm/channel/group三类;
  • parseApprovalResponse(L113-L126)用正则^(approve|deny|block)(?:\s+(.+))?$解析 Owner 回复,支持带 id 与不带 id(取最近一条,见findPendingApprovalL140-L149);
  • parseAdminCommand(L209-L229)解析unblock ~shipblockedpending三类管理命令,ship 名正则限定为~[\w-]+
  • 每个PendingApproval除了 id、类型、请求方 ship 外,还保留originalMessage完整上下文(消息 id、文本、内容、时间戳、父消息 id、是否线程回复),用于审批通过后的消息补发。

未配置ownerShip时,未授权 DM 和频道 mention 只会被丢弃并记日志,没有任何审批提示。

7. 自动接受(Auto-accept)策略

自动接受 DM 邀请(仅针对已在dmAllowlist中的 ship;Owner 无论该 flag 如何都总是自动接受):

{ channels: { tlon: { autoAcceptDmInvites: true, }, }, }

自动接受群组邀请(fails closed 语义:autoAcceptGroupInvites: truegroupInviteAllowlist为空时,任何非 Owner 邀请都不会被接受):

{ channels: { tlon: { autoAcceptGroupInvites: true, groupInviteAllowlist: ["~zod"], }, }, }

8. 入站持久化与投递语义

这部分常被忽略,但对生产部署很重要(来自 docs/channels/tlon.md 的 Inbound durability 一节):

  • OpenClaw 在把已接受的 Tlon DM/群事件派发给 agent 之前先持久化;pending 或可重试的轮次能扛过 Gateway 重启;
  • 工作按"群组频道"或"DM 对端"为单位串行处理;
  • 稳定的 Urbit 消息 id 会在队列记录或保留的完成记录存在时抑制重复投递的事件;
  • 从队列到 agent 的边界是at-least-once投递:handoff 期间崩溃可能重放一个轮次,因此产生外部副作用的 agent 动作应尽量保持幂等。

9. 通过 Urbit 设置存储实现配置热重载

上面大部分设置(dmAllowlistgroupInviteAllowlistgroupChannelsdefaultAuthorizedShipsautoDiscoverChannelsautoAcceptDmInvitesautoAcceptGroupInvitesownerShipshowModelSignature)首次运行时会被镜像写入 ship 的%settingsagent(deskmoltbot,buckettlon),之后从那里实时读取——所以经由 Landscape 客户端或捆绑 skill 的设置命令所做的修改无需重启 Gateway即生效。channelRules和待审批列表也作为 JSON 持久化在该处;文件配置对"从未写入设置存储的值"仍是唯一事实来源。

实现细节(extensions/tlon/src/settings.ts):

  • 初始加载通过scry("/settings/all.json"),响应形状为{ all: { [desk]: { [bucket]: { [key]: value } } } }(L332-L349);
  • 变更监听通过 SSE 订阅settings应用的/desk/moltbot路径,处理put-entry/del-entry两类事件(parseSettingsEvent,L200-L232),每次命中后增量更新本地状态并通知监听器;
  • 由于 Urbit settings store 不支持嵌套对象,channelRulespendingApprovals以 JSON 字符串形式存储,读回时做容错解析与逐条结构校验(parseChannelRules/parsePendingApprovals,L70-L95、L162-L195);
  • 设置 desk 尚不存在时load()静默回退为空设置——插件不会因此启动失败。

10. 出站投递目标(CLI / cron)

配合openclaw message send或 cron 投递使用:

  • DM:~sampel-palnetdm/~sampel-palnet
  • 群组:chat/~host-ship/channelgroup:~host-ship/channel

extensions/tlon/src/targets.ts 中的parseTlonTarget实际比文档列出的更多:还支持room:前缀、group:~host/channel两段式简写(自动拼成chat/~host/channelnest)、可选的tlon:渠道前缀,ship 名缺~前缀时自动补齐。出错时提示的标准写法为dm/~sampel-palnet | ~sampel-palnet | chat/~host-ship/channel | group:~host-ship/channel

11. 图片媒体限制(mediaMaxMb)

channels.tlon.mediaMaxMb以 MiB 为单位限制每张入站图片的下载和出站图片的加载。多账号下可用accounts.<id>.mediaMaxMb覆盖;未设置时依次回落渠道根、再回落agents.defaults.mediaMaxMb。图片下载与上传存在 6 MiB 的硬上限。行为差异:

  • 配置了 cap 时:尺寸检查失败或下载失败会让发送失败,而不是内嵌一个未经检查的 URL;有界下载成功后若上传失败,仍可使用原始 URL;
  • 未配置 cap 时:即使图片无法在限制内下载,仍保留原有的"直接发链接"回退。

12. 捆绑 Skill:tlon-skill

插件捆绑了@tloncorp/tlon-skill,一个用于直接 Urbit 操作的 CLI,安装插件后即可自动使用,能力覆盖:

  • Activity:mentions、replies、unreads
  • Channels:列出、创建、重命名
  • Contacts:列出/获取/更新 profile
  • Groups:创建、加入、邀请/请求流程、roles
  • Hooks:管理频道 hooks
  • Messages:历史、搜索
  • DMs:发送、react、接受/拒绝
  • Posts:react、删除
  • Notebook:向 diary 频道发帖
  • Settings:通过上文第 9 节的设置存储热重载插件配置

13. 完整配置参考表

含义
channels.tlon.enabled启用/禁用渠道启动
channels.tlon.ship机器人的 Urbit ship 名(如~sampel-palnet
channels.tlon.urlShip URL(如https://sampel-palnet.tlon.network
channels.tlon.codeShip 登录 code
channels.tlon.network.dangerouslyAllowPrivateNetwork允许 localhost/LAN ship URL(SSRF 显式放行)
channels.tlon.ownerShipOwner ship:处处被授权,接收审批请求
channels.tlon.dmAllowlist允许 DM 的 ship(空 = 除 Owner 外都不允许)
channels.tlon.autoAcceptDmInvites自动接受dmAllowlist中 ship 的 DM
channels.tlon.autoAcceptGroupInvites自动接受来自groupInviteAllowlist的群组邀请
channels.tlon.groupInviteAllowlist群组邀请可被自动接受的 ship 列表
channels.tlon.autoDiscoverChannels自动发现已加入的群组频道(默认false
channels.tlon.implicitMentions.threadParticipation允许已参与线程的后续消息绕过 mention 门控
channels.tlon.groupChannels手动固定的频道 nest 列表
channels.tlon.defaultAuthorizedShips所有频道默认授权的 ship(无规则匹配时使用)
channels.tlon.authorization.channelRules逐频道 nest 的授权模式 + 白名单
channels.tlon.showModelSignature在回复末尾追加_[Generated by <model>]_
channels.tlon.responsePrefix自动回复前缀:字面量、"auto""[{model}]"模板;账号覆盖优先,""禁用
channels.tlon.accounts.<id>额外命名账号(多 ship 部署)

完整的 Zod schema 定义见 extensions/tlon/src/config-schema.ts,其中network为 strict 对象(只接受dangerouslyAllowPrivateNetwork一个键),顶层还有文档表格未列出的historyLimit(整数 ≥ 0)、nameconfigWrites等字段。

14. 故障排查

常用诊断命令:

openclaw status openclaw gateway status openclaw logs --follow openclaw doctor

常见故障与定位方向:

  • DM 被忽略:发送者不在dmAllowlist且未配置ownerShip(没有审批流兜底);
  • 群消息被忽略:频道未被发现/固定,或发送者未通过授权且无ownerShip排队审批;
  • 连接错误:确认 ship URL 可达;本地 ship 需设置network.dangerouslyAllowPrivateNetwork
  • 认证错误:登录 code 会轮换——回 ship 重新+code获取当前值;
  • 旧配置迁移:出现allowPrivateNetwork扁平键时跑openclaw doctor --fix

15. 行为备注与相关文档

其他值得注意的行为约定:

  • 群回复需要 @ mention(如~your-bot-ship),除非机器人已加入该线程;
  • 线程回复落在线程内;agent 还会拿到线程最近 10 条消息作为上下文前缀;
  • 富文本(粗体、斜体、代码、标题、列表)自动转换为 Tlon 原生格式;
  • 入站消息若请求频道摘要(例如 "summarize this channel"),会触发内置的历史摘要流程而非普通回复;
  • Tlon 不属于声明 pairing 的渠道——它的 DM 认证用的是dmAllowlist+ownerShip审批流,而不是 Pairing 机制。

延伸阅读(仓库相对路径):

  • 渠道总览、群组行为
  • 插件机制
  • Gateway 热重载
  • Tlon 插件入口、SSE 客户端、审批测试

【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 🦞项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 14:34:15

AI技术如何驱动短剧出海全流程优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 14:32:37

经典ASP鲜花电商系统:IIS部署、数据库连接与安全加固实战

简介&#xff1a;本资源是一套完整的基于ASP技术开发的花店鲜花销售系统源码&#xff0c;面向计算机专业本科生、Web开发初学者及毕业设计选题学生&#xff0c;解决小型电商网站从用户浏览、商品管理到订单处理的全流程功能实现需求。压缩包共291个文件&#xff0c;含59个ASP核…

作者头像 李华
网站建设 2026/9/14 14:32:23

HLS 多 CDN 容灾与多域名切换调试,流媒体高可用业务实战

一、多 CDN 容灾业务开发痛点 对于高并发直播、付费点播业务&#xff0c;为了规避单一 CDN 节点故障、运营商网络异常&#xff0c;行业普遍采用多 CDN 容灾架构。一套 M3U8 资源同时部署在多家 CDN 厂商&#xff0c;当某一家 CDN 出现大面积故障、访问超时、大量 403/502&…

作者头像 李华
网站建设 2026/9/14 14:30:27

Django构建汽车美容行业网站:从项目搭建到业务建模实战

简介&#xff1a;这份源码包面向汽车美容行业线上转型需求&#xff0c;提供基于Django框架的完整网站设计与实现方案&#xff0c;适合Web开发学习者、行业从业者及需要快速搭建预约服务平台的开发者参考。项目涵盖车辆美容预约、服务套餐选择、技师团队展示、在线支付、会员管理…

作者头像 李华
网站建设 2026/9/14 14:29:49

Claude Code 配 TaoToken:GLM Coding Plan 的 Base URL 和 Key 这样改

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华