跳转到内容
GitHub

远程访问与 MCP

borg mcp 让 Claude 等 AI 智能体在你已打开的 borg 中工作,无论 borg 运行在你自己的机器上,还是运行在你通过 SSH 访问的服务器上。除了 borg 之外无需安装任何东西:智能体会自行启动 borg mcp(对于服务器则通过 SSH 启动),然后连接到在那里运行的 borg 会话。服务器无需开放任何端口,也无需访问互联网。

按 F1 再按 C(或选择 F9 → 远程 → 将此 Borg 共享为主机…)。Borg 会显示两条命令,供你粘贴到自己计算机上的终端中:一条会启动已连接到此 borg 的 Claude Code,另一条则把该连接添加到 Claude Code 中,供所有会话使用。按 Tab 选择其中一条,按 Enter 通过终端将其复制到你的计算机的剪贴板。通过 SSH 使用 iTerm2、Ghostty、kitty、WezTerm 和 Alacritty 时均可如此复制(在 tmux 中需添加 set -g set-clipboard on)。如果终端不支持(许多浏览器终端都是如此),按 F3 会单独以纯文本显示该命令,方便你用鼠标选中;按任意键返回 borg。

通过 SSH 连接时,borg 会自动填入你所连接的地址。如果你的计算机需要用另一个名称访问该服务器(例如 SSH 别名,或通过跳板机访问),请改为输入该名称。SSH 必须能够免密码登录,即使用密钥或 SSH agent。borg mcp setup prod 会在命令行中输出同样的 Claude Code 和 Claude Desktop 配置方法。

连接后,智能体看到的和你一样:以文本形式呈现的屏幕本身、你当前处于面板还是控制台、两个面板、高亮和已标记的文件、命令行在哪里运行以及其中输入了什么。它用“位置”来指代各个地方:borg 所在机器上的绝对路径或 ~/…、容器内的 docker://web/etc/nginx,或相对于当前面板的路径。无需询问,它就可以读取文件夹和文件(可按行范围读取,或只读取包含特定文本的行),查看最繁忙的进程和容器,以及在你的另一个面板中显示某个文件或文件夹。它还能列出开放的端口、连接和网络接口及其流量,这些数据在一秒内测得,并可用与网络屏幕筛选相同的词语缩小范围(参见筛选)。它还能列出启动项,最近改动的排在最前,附带各自的程序和所匹配的规则,并可用与该屏幕筛选相同的词语缩小范围(参见启动项)。

任何会更改机器的操作,都会在一个对话框中等待你确认,对话框会完整展示更改内容:要运行的命令及其运行位置、新建的文件,或以 diff 形式呈现的编辑。内容较长时,可用方向键、PgUp 和 PgDn 或鼠标滚轮滚动,按 F3 可全屏查看对话框。在你选择“是”之前,默认选中的始终是“否”;对话框出现后的前半秒内不接受“是”,以免原本用于别处的按键或点击批准它。如果在你决定期间文件发生了变化,编辑会被拒绝。包含制表符、转义序列或其他控制字符的命令同样会被拒绝,因为对话框无法显示这些字符。该对话框会显示在所有内容之上,包括编辑器、查看器、其他对话框和屏幕保护程序;在你作出回答之前,它会接收所有按键。回答后,被它遮住的内容会重新显示。如果智能体先停止等待,对话框会关闭,并有通知说明。对于已配对的计算机,approval_mode 会在为该会话开启“全部批准”之前先询问你一次。开启期间会一直显示一个标记;点击它或按 Ctrl+Alt+A 可立即关闭。该配对连接断开时,它也会自动关闭。配对时的批准与此相互独立。

如果你自己电脑上的远程面板正显示请求所在的会话,该请求也会送达你的电脑(参见远程面板)。你的 borg 会用同样的对话框显示它,标题注明服务器名称,并显示在你正在进行的任何操作之上,然后通过加密连接把你的答复发回去。服务器也会保持自己的对话框打开。无论答复来自哪里,都以最先到达的为准,其他对话框会关闭,并有通知说明在哪里作出了答复。智能体撤回的请求会在所有地方关闭。如果另一台计算机正通过镜像控制该会话,你的对话框会显示请求,但不提供“是”和“否”,按 Esc 只会在你的屏幕上关闭它。当该会话处于全部批准状态时,你的 borg 会显示一个带有服务器名称的标记;点击它或按 Ctrl+Alt+A 可立即在那里关闭“全部批准”。只有你的按键和点击才能答复这些对话框:智能体的工具(包括 type)都无法在其中按下任何按钮。

命令会输入到一个你可以看到的 Shell 中,并且不会记入其历史。针对本机的命令会进入 borg 自己的控制台,命令运行期间控制台会显示出来,以便你回应 sudo 之类的提示;针对容器的命令则会进入 Docker 视图中该容器的 Shell。Shell 会在命令之间保留当前文件夹和变量。

智能体还可以替你输入文本供你检查:在提示符处输入一条命令,或在控制台中打开的 vim 或 nano 里输入一段脚本。这些文本不会被执行:永远不会按下 Enter,多行文本会以粘贴的方式输入,Shell 和编辑器只会插入而不会运行它。

智能体还能以与内存搜索相同的方式搜索进程内存,查找字符串、指标、文本或字节。内存中可能保存着密码、密钥和私密消息,而搜索到的任何内容都会发送给智能体,因此对每个进程的首次搜索都需要你在对话框中批准,对话框会列出进程、其程序以及搜索内容。批准之后,在 borg 退出之前,智能体都可以再次搜索和扫描该进程。它可以请求以管理员身份读取,这会弹出系统自身的密码提示。

智能体还可以用 YARA 规则扫描并检查代码完整性,就像 Ctrl-F 对话框中的 规则匹配 以及内存映射中的 Y 和 I 一样(参见 用规则扫描文件、代码完整性检查 和 用规则扫描内存)。扫描 borg 所在机器上的文件或文件夹无需询问,与读取相同。扫描文件夹时会读取该文件夹下同一文件系统中的每个文件,包括隐藏文件。超过 64 MiB 的文件不会被读取,扫描在读取 20,000 个文件、找到 2,000 个匹配或经过 45 秒后停止。容器中的文件不会被扫描。

进程则不同,因为扫描会读取它的内存。对每个进程的首次扫描都会在 远程请求扫描进程内存 对话框中等待你批准,对话框会列出进程、其程序以及检查项:完整性检查、规则,或两者都有。一次批准就涵盖该进程的扫描和内存搜索,直到 borg 退出,无论智能体先请求的是哪一种。每项检查在 45 秒、读取 1 GiB 内存或 2,000 项发现后停止。智能体可以请求以管理员身份读取,这会弹出系统自身的密码提示,两项检查只询问一次。

规则是 Borg 自带的规则和你规则文件夹中的规则,除非智能体带来自己的规则文本,最多 64 KiB。这样它就能根据发现的内容起草规则,在文件夹或进程上试用,再加以完善。这段文本单独运行,不带 Borg 的规则和你的规则,不能使用 include,也从不保存。无法编译的文本会连同编译器的消息退回给智能体,此时不会弹出任何对话框。扫描进程时,对话框会在检查项下方显示智能体的规则文本,让你看到它要找什么。

智能体会按严重程度从高到低收到每项发现:严重程度、类型、规则及其来源、文件和偏移量或地址和内存区域、最多 64 字节的匹配内容(文本或十六进制),以及其他可能的解释。随后是读取了多少、哪些无法读取、扫描是否完成,以及被排除的规则文件。证据按原样发送给智能体,包括密钥和令牌,与内存搜索相同。

智能体还可以像网络屏幕上的 R 一样抓取流量(参见抓取流量)。它指定要录制的内容:一个端口、一条连接、按 PID 指定的进程,或接口上的全部流量。对于进程,Borg 会录制整个接口,再汇总该进程的会话。一次抓包持续 1 到 60 秒,智能体未指定时长时为 5 秒。如果智能体没有指定接口,Borg 会测量一秒,然后选择 抓取流量 对话框会选的那个接口。每次抓包都会在一个对话框中等待你确认,对话框标题为 远程请求抓取流量,其中显示流量、接口、时长、每个数据包保留多少以及文件夹。抓包期间,页脚会显示它;结束后,一条通知会说明 Borg 把它保存在哪里:当前面板的文件夹或智能体指定的文件夹,只有你可以读取。智能体的抓包始终以你的身份运行,从不索要管理员密码,所以没有权限时,抓包会结束,通知会说明没有在该接口上抓包的权限,并写出接口名称。

智能体会收到一份摘要:先是 Borg 识别出的协议,然后是每个进程、主机和连接及其数据包和字节数,主机名来自抓包自身的 DNS 应答和 TLS 服务器名称。抓包期间 Borg 会监视套接字,所以即使网络屏幕没有打开,会话也能归到各自的进程。摘要不包含数据包携带的内容。读取 .pcap、.pcapng 或 .cap 文件会得到同样的摘要,并可用流量查看器筛选中的词缩小范围;智能体还可以按编号请求某一个数据包,获取它的各层信息和十六进制转储形式的字节。Borg 会记住最近 16 次智能体抓包的进程,直到退出;其他文件中的会话显示为 未知进程,除非其中的数据包带有进程信息。

智能体连接后,快捷键栏开头会出现 ◈ 远程。点击它,或随时选择 F9 → 远程 → 远程日志…,可查看智能体的操作日志:它查看、读取、扫描、显示和输入了什么,以及每条命令和每项更改,无论被批准还是被拒绝。每个会话都把自己的日志保存在磁盘上,只有你能读取。这样,即使 Borg 已经退出,你回到一个让它继续运行的会话时,也能看到其中发生了什么。日志变大后,Borg 会丢弃最旧的记录。保存记录之前,Borg 会隐藏它能识别的密码、令牌和密钥,并且不记录命令的输出。作为普通参数传入的密码看起来和其他词没有区别,因此 Borg 无法隐藏它。如果完全不想保留日志,可在 选项 → 插件 中关闭 远程:记录它所做的操作,这也会删除已保存的日志。

借助 borg cloud,Claude 可以访问没有 SSH 路径可达的 borg:在浏览器终端中打开的服务器、容器,或位于 NAT 之后的机器。双方都主动向外连接到一个中继,由中继将它们连接起来。

  1. 在服务器上的 borg 中按 F1 再按 C。第一个选项是带链接的 borg pair;按 Enter 即可复制。该链接只能使用一次,有效期十分钟。下方是中继:如果要使用其他中继,把它的地址粘贴到那里并按 Enter,即可保存该地址并获取经由它的链接。
  2. 在你的计算机上的终端中运行该命令(你的计算机上也需要安装 borg)。它会输出一个配对码:六个 emoji,每个都附有名称,例如 🐱 Cat · 🦁 Lion · 🐎 Horse。
  3. 服务器上的 borg 会询问是否配对,并显示你的计算机的名称和配对码。即使 F3 正以纯文本显示命令,这个询问也会立即出现。如果两边的配对码一致,选择“是”。随后,borg pair 会提议把该服务器添加到 Claude Code 中,即 claude mcp add borg-NAME -- borg mcp remote NAME。它会等待你回答 5 分钟;如果它放弃等待或被你中止,询问会关闭,链接也随之失效。

配对码来自两个 borg 刚刚完成的加密握手,因此只有当与服务器通信的确实是你的计算机时,两边屏幕上的配对码才会一致。如果有人拿到了链接并抢先使用,服务器上显示的将是另一个配对码,而且对方无法让它与你的配对码相同。如果你的终端绘制的 emoji 比 borg 预期的窄,borg 只会显示名称;这时请比对名称。

此后,只要那台机器上的 borg 在运行,Claude 就能访问它。单独运行 borg pair 会列出已配对的服务器,borg pair --forget NAME 可忘记其中一个;在服务器上,在远程访问对话框中按 F8 会忘记所有已配对的计算机。通过 borg cloud,Claude 还能使用 download 和 upload 在服务器和你的计算机之间复制文件;在你的终端中,borg get NAME:PATH [TO] 和 borg put FROM NAME:PATH 可完成同样的操作。Claude 下载的文件会保存到你的“下载”文件夹中,且不会替换其中已有的文件。上传需要你在 borg 中批准,批准对话框会显示要发送的文件,每次批准请求都会注明是哪台计算机发出的。

连接采用端到端加密。每个 borg 都保存一个服务器密钥,已配对的计算机凭它识别该 borg;需要访问服务器的计算机还会另外保存一个自己的计算机密钥。两者都只有你能读取。服务器密钥是状态文件夹的 link 文件夹中的一个文件。计算机密钥同样是那里的一个文件。在 Mac 上它保存在你的登录钥匙串中,在 Linux 上该文件用密码封存(见计算机密钥)。配对时双方交换公钥,每次连接都以绑定这些公钥的 Noise IK 握手开始,因此中继转发的始终只是密文,也无法冒充任何一方的 borg 作出应答。来自另一台计算机的调用与本地调用一样,可以无需询问直接读取;在 选项 → 插件 中开启“另一台计算机读取前先询问”,可让这些读取同样需要批准。除非已经配对或正在显示配对链接,否则 borg 不会与中继保持连接;在 选项 → 插件 中关闭 borg cloud 后,则完全不会连接。

Borg 会将中继以 relay = "wss://relay.example.com" 的形式保存在配置中。计算机通过配对时所用的中继访问服务器,因此服务器更换中继后,需要重新配对计算机。同一台机器上的所有 borg 共用这些密钥,由后台服务将它们全部连接到中继。关闭后台服务时,只有最先打开的 borg 会连接到中继,其他 borg 会告诉你是哪一个在使用 borg cloud。

计算机密钥向每台已配对的服务器证明连接来自你的计算机。如果某台服务器仍按另一个密钥(例如本机的服务器密钥)识别这台计算机,Borg 会在下次在那里打开会话时把它换成计算机密钥。Borg 向服务器证明自己持有新密钥,服务器随后替换该计算机条目中的密钥,并保留其名称。仍在使用旧密钥的连接会在下一次调用时结束。服务器会显示一条通知,并把两个指纹写入智能体日志;它的 客户端 列表会显示密钥何时更换以及原来的指纹。运行旧版 Borg 的服务器会继续使用旧密钥,直到它被更新。

在 Mac 上,Borg 把计算机密钥保存在你的登录钥匙串中,作为名为 Borg Commander 的项目,只有 Borg 可以不经询问读取它。Borg 进程第一次需要该密钥时,macOS 会请求 Touch ID 或你的密码,因此即使是自行启动 borg 的程序也会暴露出来。每次 Borg 更新后,macOS 还会询问一次新的 Borg 能否使用该项目;请选择 始终允许。旧版 Borg 留下的计算机密钥文件会在 Borg 第一次使用时移入钥匙串,随后该文件会被删除。在没有 Mac 屏幕的环境中运行的 Borg,例如通过 SSH 或在后台服务中,无法显示该请求,也无法连接服务器。当 $BORG_STATE_DIR 指向常用位置以外的状态文件夹时,Borg 会把计算机密钥作为文件保存在该文件夹的 link 文件夹中。Borg 的 macOS 版本使用 Hardened Runtime 签名,因此其他程序无法读取 Borg 的内存,也无法向其中加载代码。

在 Linux 上,Borg 用你选择的密码封存计算机密钥,保存在文件 computer-key.sealed 中,该文件位于 link 文件夹。在终端中运行 borg unlock 来选择密码:Borg 会建议四个随机单词,它们容易输入又难以猜中,并要求你输入两次密码。Borg 使用 Argon2id 加固密码,这需要几秒钟和 1 GiB 内存,在内存少于 8 GiB 的机器上则使用八分之一的内存,因此用文件副本猜测密码会很慢。旧版 Borg 留下的计算机密钥文件会在你第一次运行 borg unlock 时被封存,随后该文件会被删除;在此之前,Borg 会提示你运行该命令。当 $BORG_STATE_DIR 指向常用位置以外的状态文件夹时,Borg 在 Linux 上同样把计算机密钥保存为不设密码的普通文件。

解锁后,密钥会保存在你的用户的内核密钥环中,直到 Borg 连续 12 小时没有使用它,每次使用都会重新开始计算这 12 小时。重启会锁定它,borg lock 会立即锁定它。在 Borg 无法使用内核密钥环的环境中,例如许多容器和系统服务中,会由一个小型 Borg 进程保管密钥,它在 link 文件夹中一个只有你能打开的套接字上应答,连续 12 小时未被使用后便会退出。密钥被锁定时,Borg 会询问密码:面板会打开 解锁密钥 对话框,borg pair、borg get、borg put 和 borg mirror 会在终端中询问。Claude 在没有终端的情况下启动的 borg mcp remote 会提示你运行 borg unlock。

borg unlock --ssh-agent 还允许你的 ssh-agent 解锁该密钥。Borg 会请求代理用 Ed25519 密钥签署一个固定的质询,没有 Ed25519 密钥时则使用 RSA 密钥,并用该签名再封存一次密钥。此后,只要能连接到该代理,Borg 就会直接解锁密钥而不再询问,密码也依然有效。Borg 会检查代理两次签名是否相同,并拒绝签名会变化的密钥。任何能使用你的代理的人都能生成同样的签名:如果你用 ssh -A 转发代理,远程机器上的 root 在你连接期间就能使用它,再加上一份封存文件的副本即可解锁此密钥。只把代理转发到你信任的机器,否则就不要开启此功能。borg unlock --no-ssh-agent 会再次关闭它。

borg pair --new-key 会为这台计算机生成新密钥,每台服务器会在 Borg 下次连接时接受它。在所有服务器都接受之前,Borg 也会保留旧密钥,borg pair 会标出仍接受旧密钥的每台服务器。一周后,它还会建议用 borg pair --forget NAME 忘记你不再使用的服务器。

如果某台服务器拒绝这台计算机持有的所有密钥,Borg 会告诉你。要么有人在那台服务器上忘记了这台计算机,要么有人持有其密钥的副本,并抢先把服务器换成了他自己的密钥。更换密钥属于日常防护,无法撤销泄露。如果你怀疑有人复制了密钥,请在每台服务器的远程访问中按 F8 忘记已配对的计算机,重新配对,并检查这些服务器。

使用命名工作区时,borg sessions list 显示它们的 ID 和名称,borg sessions create NAME 新建一个,borg --session NAME 打开它。通过 MCP,智能体可以调用 list_sessions、list_remote_sessions 和 use_session 来选择该连接所使用的会话。单次工具调用也可以传入 session ID,仅这一次针对另一个会话。所选会话只对该 MCP 连接有效。

有多个会话时,或者唯一的会话已在另一个终端中打开时,borg 启动后会先打开 Borg 会话 窗口。窗口开头说明会话是什么,列表中列出每个会话及其上次使用的时间。当前处于活动状态的会话会标出其状态:已在另一个终端中打开,或在后台服务运行它时显示 由后台服务保持运行。默认选中上次使用的会话,除非它已在另一个终端中打开。按 Enter 会回到你上次离开所选会话时的样子;由服务保持运行的会话会以连接方式打开,与 borg service attach NAME 相同。单击可选中会话,再次单击即可打开。F7 为新会话命名并打开它,按 Esc 或 F10 则退出,不打开任何会话。窗口打开期间,每 2 秒检查一次哪些会话处于活动状态。

按 F8 或 Delete 可删除所选会话,确认对话框默认选中 否。这会删除该会话保存的面板和终端历史;你的文件和文件夹会保留。默认会话始终保留,当前处于活动状态的会话也是如此:请先在另一个终端中退出 Borg。要删除由服务保持运行的会话,请用 borg service attach NAME 打开它,再按 F10 退出。

如果用 borg --session NAME 指定的会话已由另一个 Borg 在终端中打开,borg 会停止并指出是哪个 Borg:它的进程号、ps 所显示的终端,以及它启动了多久。在那个 Borg 所在的终端按 F10 退出它。如果已经无法回到它的终端,用 kill 加上进程号结束它。

同一台机器上你的所有 Borg 共用一个后台服务。你打开的第一个 borg 会启动它,无需任何安装;最后一个会话关闭 30 秒后,服务会自行停止。如需关闭此功能,请在配置中设置 start-service = false。

服务为你的所有 Borg 保持 borg cloud 连接,因此配对的计算机可以访问每个已打开的会话。它会在自己指定的会话中工作,未指定时则在你最后使用的会话中工作,并在那里等待你的批准。你可以从任何一个 Borg 发起配对。

要让会话在没有终端的情况下保持运行,请运行 borg service keep NAME。用 borg service attach NAME 或在 Borg 会话 窗口中打开它,按 Ctrl-] 可分离。在其中按 F10 退出 Borg 会结束该会话。当配对的计算机请求一个未在运行的会话时,服务会在后台启动它。

要让服务开机启动,请运行 borg service install、enable 和 start。这些命令通过 sudo 运行,sudo 会询问你的密码;以 root 身份运行时则无需 sudo。borg service stop、disable 和 uninstall 可撤销这些设置。也可以选择 F9 → 远程 → 后台服务…:对话框会显示下一步的命令,按 Enter 即可在 Borg 的 Shell 中运行它。在没有 systemd 的容器中,请让容器的进程管理器运行 borg service run。

borg update 会安装新版本,然后让后台服务切换到新版本,并在服务运行新版本后告诉你。服务会在自己的进程中重新启动,因此它保持运行的会话会保留各自的 Shell 以及其中运行的程序。每个打开的 Borg 会在空闲时跟进:它会等待正在运行的任务完成、已编辑的文件保存或关闭,以及智能体的请求处理完毕。然后它会在同一个终端中重新启动,保留自己的 Shell,并告诉你它现在运行的版本。

更新会把被替换的版本保留在程序文件旁边,名为 .borg.previous。如果新版本在 60 秒内没有接管,Borg 会把之前的版本放回原处,服务也会用它重新启动。此时服务保持运行的会话会以新的 Shell 启动。

由旧版 Borg 启动的服务无法自行切换。borg update 会说明这一点,服务会在下次启动时使用新版本。

要更新已配对的机器,请在远程主机中选中它并按 U。确认后,主机会像 borg update 一样获取最新版本,其服务也会切换过去。更新进行期间,按 Esc 可关闭选择器。之后 Borg 会告诉你主机现在运行的版本,或者告诉你新版本未能启动、主机已回到原来的版本。该主机上会话的镜像会等待它,并在它恢复后重新显示主机(参见镜像会话)。如果主机上的 Borg 较旧,或者没有使用后台服务运行,请改为在主机上运行 borg update。主机上通过 Homebrew 或 cargo 安装的 Borg 需要在主机上用相应的工具更新,Borg 会给出该命令。

配对后,borg --remote MACHINE:SESSION 会在左侧面板中打开该会话的文件。按 Enter 或 F3 会下载一份临时的本地副本来预览远程文件。F5 可在本地面板和远程面板之间,或在两台已配对主机之间复制已标记的文件和文件夹,目标对话框会注明两侧分别是哪个客户端或主机。复制以后台任务的形式运行,显示字节进度,支持暂停和取消,遇到同名文件时可选择覆盖、跳过或保留两者。复制文件夹时会一并复制其中的空子文件夹和符号链接,普通文件会保留可执行权限和修改时间。文件只有在全部内容到达后才会出现在目标位置。远程面板中不提供 F6(移动)和 F8(删除)。

右侧面板始终显示你本机的内容。开启 选项 → 插件 → 跟随 后,命令行和 Ctrl-O 会使用远程主机上的交互式 Shell。其终端在本地绘制,而按键、粘贴的内容、Ctrl-C 和终端程序都在远程主机上运行。切换面板时,每个远程会话都会保留各自的 Shell 和未完成的命令行;选中客户端面板则会切回本地 Shell。

全屏程序以及 top 这类读取原始键盘输入的程序,在运行期间会接收所有按键(包括 Ctrl-O),调整终端大小也会同步调整远程 PTY 的大小。请使用程序自己的按键退出(例如按 q 退出 top)。如果程序是从面板命令行启动的,退出后 Borg 会返回面板;如果是在远程控制台中启动的,控制台会保持打开。远程 Borg 自身的面板和 Shell 与此控制台相互独立。要在命令行中传输文件,请使用 borg get MACHINE/SESSION:PATH [TO] 和 borg put FROM MACHINE/SESSION:PATH。

在 Borg 的主 Bash、Zsh 或 Fish Shell 中输入 exit 时会请求确认。默认选中 否,即保持同一个 Shell、变量、文件夹和镜像继续运行。在远程控制台中,exit 会询问是否关闭主机上的 Shell;选择“是”之后,可按 Alt-H 重新选择该会话,以获得一个新的 Shell。

远程文件夹分块加载,期间会显示加载动画和已接收的条目数;切换到其他文件夹会取消该请求。

远程面板显示某个会话时,在那里等待的智能体请求也会显示在你的屏幕上,你可以在这里答复(参见智能体能做什么)。

在本地 Borg 中,按 Alt-H、点击快捷键栏中的 远程主机,或选择 F9 → 远程 → 浏览主机和会话,即可查看已配对的机器及其命名会话。按 Enter 会在你打开选择器的那个面板中打开所选会话的文件,替换该面板原有的内容。按 M 镜像该会话的屏幕,按 U 更新该主机(参见在会话打开时更新),按 R 刷新列表。

Tab 在 主机(本 Borg 能访问的计算机)和 客户端(能访问本 Borg 的计算机)之间切换。客户端列表显示与本 Borg 配对的计算机、它们的公钥指纹、是否已连接,以及各自的连接数。某台计算机更换密钥后,指纹一行还会显示更换的日期以及之前的指纹。即使一个镜像使用了多个连接,同一台计算机也只列出一次。选择器打开期间状态会实时更新,包括连接由后台服务持有的会话。配对是单向的:被允许的客户端并不会自动成为本 Borg 可以浏览其文件的主机。如果连接的持有者无法报告连接状态,已配对的客户端仍会列出,并显示 连接状态不可用。同一个 Borg 可以同时是主机和客户端。“远程”菜单还提供 镜像已挂载的主机、将此 Borg 共享为主机…、远程日志… 和 后台服务…。

选择器会显示每台主机的 Borg 版本。选中某个会话后,会显示其操作系统和架构、是以后台服务还是在终端中运行、请求延迟以及中继地址。各主机会并行检查,因此一台主机不可用不会拖慢其他主机。无法报告版本的主机会显示 版本不可用;显示的版本始终是主机的版本,与中继无关。请在两台计算机上都保持 Borg 为最新版本:如果主机缺少某项远程功能,会显示提示信息,要求你升级。

镜像连接期间,选择器会显示动态状态,按 Esc 可立即取消。每个连接步骤限时 10 秒,整个连接尝试限时 30 秒。如果尝试失败,选择器会保持打开,并指出哪一步失败;按 M 可再次尝试连接所选会话。

在选择器中,F2 为所选主机重命名(作用于该主机上的所有会话),Shift-F2 为所选会话重命名。这些名称保存在当前客户端上,并显示在选择器、面板标题和控制台页脚中。将名称留空即可恢复原名。详细信息中仍会显示原始的主机名和会话名。名称与已配对主机的密钥和会话 ID 绑定;命令目标以及远程主机上的名称都不会改变。

在不可用的主机上按 F8,会在当前客户端上忘记其配对;按 Shift-F8 则即使所选主机在线也会将其忘记。确认对话框默认选中“否”。忘记主机会关闭当前客户端为该主机打开的面板和控制台;主机上的会话和文件都会保留,当前客户端的身份及其他配对也不受影响。重新配对即可再次连接。

在主机会话上按 F8 或 Delete 可将其移除,确认对话框默认选中 否。这会关闭该会话及其远程控制台,并删除其保存的 Borg 面板和终端历史;主机上的文件和文件夹会保留。默认会话无法移除。当前正在承载连接的独立会话不能移除自身;请先在主机上关闭它,并在另一个会话中运行 Borg。如果移除失败,该会话仍会保留在列表中,方便你重试。正在运行的会话会先被停止,服务也不会再启动它。

borg mirror MACHINE:SESSION 会在本地终端中显示远程会话的实时屏幕;在带有远程面板的本地 Borg 中,按 Alt+Shift+M 可打开同样的镜像。按 Ctrl-G(按住 Control 再按 G)可离开镜像并返回本地面板,点击底部的横幅也可以。横幅上方的一行显示当前由谁控制;按 Ctrl-] 也可以退出。

普通的 borg 或 borg --session NAME 在运行时即可被镜像,无需后台服务。它自己的终端仍然可见,在那里进行任何键盘或鼠标输入,都会从镜像手中收回控制权。你拥有控制权时,主机上的 Borg 会按你的窗口排布界面:如果横幅上方的区域比主机终端小,Borg 就按你的尺寸绘制在主机终端的左上角,其余部分留空。控制权回到主机终端或你离开镜像后,Borg 会重新占满整个终端。没有控制权的镜像沿用主机终端的布局,窗口较小时会截断显示;把窗口调大即可看到其余部分。由后台服务保持运行的会话在其终端关闭后仍会继续运行,其大小由拥有控制权的计算机决定。

如果另一个终端正控制着远程会话,镜像会以只读模式打开,你的按键不会传到该会话。按 Ctrl-T 或点击状态行可夺取控制权并断开另一个终端,也可以直接用 borg mirror MACHINE:SESSION --take 启动;--take 总会从其他查看者手中夺取控制权。获得控制权后,第一次按键会唤醒处于休眠状态的远程屏幕,之后的按键和鼠标输入都会传到该屏幕。跟不上进度的查看者会跳过过时的动画帧,直接显示当前屏幕。

当主机停止响应时(例如在更新期间),镜像会保留最后的画面,在状态行中说明这一点,并每 2 秒重试一次,最多持续 100 秒。在此期间按 Ctrl-G 可离开镜像。主机恢复后,镜像会重新显示它的屏幕,右下角显示它现在运行的版本。如果主机在此之后仍未恢复,镜像会结束并显示一条消息。

智能体的请求会按服务器上的样子显示在镜像中,获得控制权后即可在镜像里答复。如果你是从远程面板打开的镜像,离开镜像时请求仍在等待,该面板所在的 borg 会再次显示它。

borg-relay 是各个 borg 相互连接所经由的中继。在一台有域名指向、且 443 端口空闲的 Linux 服务器上,一条命令就能将其安装为服务,并自动获取 Let’s Encrypt 签发的 TLS 证书:

终端窗口
curl -fsSL https://raw.githubusercontent.com/0xcd21h/borg-commander/main/scripts/install-relay.sh | sudo sh -s -- relay.example.com you@example.com

再次运行同一条命令即可更新。

在 Dokploy、Coolify 或其他由代理处理 TLS 的 Docker 主机上,运行镜像 ghcr.io/0xcd21h/borg-relay:latest,并为其 8080 端口配置域名。在 Dokploy 中,基于该 Docker 镜像创建一个应用,为容器的 8080 端口配置域名并开启 HTTPS;在 Coolify 中,基于该 Docker 镜像创建一个资源,暴露 8080 端口并配置域名。两者也都可以将 packaging/relay/docker-compose.yml 作为 Compose 服务使用。该镜像运行 borg-relay --behind-proxy:由代理提供 HTTPS 并透传 WebSocket,中继则按代理在 X-Forwarded-For 中报告的客户端地址实施各项限制。它以非特权用户身份运行,并带有健康检查(GET /health)。

在没有此类代理的 Docker 主机上,同一个镜像可以自行提供 TLS:

终端窗口
docker run -d --restart unless-stopped -p 443:443 -v borg-relay:/data ghcr.io/0xcd21h/borg-relay --domain relay.example.com --cache /data

如果位于其他处理 TLS 的代理之后,请运行 borg-relay --behind-proxy --listen 127.0.0.1:8080。只有在代理之后才能这样运行,因为中继会信任代理报告的客户端地址。中继会按地址限制服务器和会话的数量、帧大小、带宽、每个会话的字节数、空闲时间和会话时长。除了证书之外,它不存储任何内容。

中继的日志只记录计数:如果有变化,每分钟写入一行,例如:

stats: connections=3 servers=2 sessions=1 joined=14 carried=3.2MiB limited=0

这一行显示它当前持有的连接数、已注册的服务器数和已打开的会话数,以及自启动以来加入的会话数、这些会话传输的字节数,以及因触发限制而被拒绝或终止的连接和会话数。调试时,使用 --log(对于镜像则设置环境变量 BORG_RELAY_LOG=1),还会记录每台服务器的注册情况(以其密钥的开头部分标识)、每个会话及其传输的字节数,以及每次触发限制时的客户端地址。

本指南跟随 main 分支更新 · Borg 0.11.0 · 1f6bce6
最新发布版本可能尚未包含此处介绍的全部功能。 发布说明

译自英文指南,欢迎指正。命令和键盘快捷键不作翻译。