把 Grok Bot 的云主机变成 SSH 跳板:bore 内网穿透实战

Grok Bot 我是注册了随便玩玩的。玩到第三天翻它的”接管主机”按钮,才反应过来:它给每个 bot 配的不是聊天上下文,是一台真机器。有 shell,能出网,能 apt。

那就顺理成章想到下一件事——我能不能不走它的网页终端,直接从我 Mac 上 ssh 过去。

试了一下能。而且不用我自己动手,让住在里面的 Agent 把隧道打出来就行。最后本机敲这一行就进去了:

ssh -i tunnel_key -p 30950 box@bore.pub

下面把过程记一下,主要是给以后的自己看。

过程

先让它装个 pi。

新建 bot,第一句话就让它装 pi。倒不是我非要用 pi,随便装点什么都行——htop、curl、你顺手的任何东西。目的是探一下这台机器的底:包管理器通不通、有没有出网、能不能写文件系统。

装得下来,后面的事基本都能干。装不下来就别折腾了,那说明它给你的是个阉割过的壳。

接管主机。

装完之后界面上会出现”接管主机”,点进去就是个 web 终端,直连那台机器。

这一步是整件事的地基。有了 shell,它对你来说就不再是”bot 的运行环境”,而是一台你有权限的 Linux。

/login,换成自己的模型。

在终端里输入:

/login

然后选自己的大模型账号登进去。意思是:这台机器上跑的 Agent,脑子换成你的了。后面的活儿是它干,不是 Grok 那个默认助手干。

登完别退出。退了上下文就没了,得重来一遍。这一步我第一次做的时候手快关了标签页,白折腾十分钟。

发提示词。

保持在会话里,直接发:

用 bore 或者 cloudflared 把 SSH 隧道暴露出来,然后把连接信息发给我——地址、端口、密钥。
bore 应该会更省事一点。

最后那句”bore 应该会更省事一点”不是凑字数。不加的话它有挺大概率去搞 cloudflared,然后卡在 Cloudflare 的账号鉴权上——因为你没给它 token,它也没法给自己弄一个。bore 不需要账号,公共实例 bore.pub 拿来就用。

我没写具体步骤。装 bore、配 sshd、生成密钥对、往 authorized_keys 里塞公钥、起隧道、读出分到的端口——这些它自己会,我只是把它可能走的岔路堵掉一条。

等它回消息。

过一会儿三样东西就回来了:地址是 bore.pub,端口是个五位数(我这次是 30950),还有一段 -----BEGIN OPENSSH PRIVATE KEY----- 开头的私钥,以及用户名 box

端口是 bore 那边随机分的。隧道一断重连就换一个号,这点等会儿还得再说一次。

本机连。

私钥存成文件,改权限,连:

printf '%s\n' "$KEY_CONTENT" > tunnel_key
chmod 600 tunnel_key
ssh -i tunnel_key -p 30950 box@bore.pub

chmod 600 别省。权限不对 OpenSSH 直接拒绝加载,报这个:

Permissions 0644 for 'tunnel_key' are too open.
It is required that your private key files are NOT accessible by others.

我见过好几个人卡这儿,以为是密钥发错了,其实就是个权限位。

进去之后跟普通 Linux 没区别,scprsyncssh -L 端口转发都能用。

bore 干了什么

bore 是个几百行 Rust 写的 TCP 隧道,模型简单得有点朴素:客户端主动连出去,服务端把公网端口收到的字节原样转发回来。

你的 Mac  ──ssh──▶  bore.pub:30950
                        │
                        │ (bore server 手上那条控制连接)
                        ▼
                   云主机里的 bore client  ──▶  127.0.0.1:22

关键在方向。那台云主机没有公网 IP,也没能力在公网上监听端口,但它能往外连。bore client 从里往外把连接建起来,之后所有流量都在这条已经建好的连接上跑。防火墙管的是”谁能连进来”,管不了”谁连出去”,所以这条路走得通。

cloudflared、ngrok、frp 都是这个原理,不新鲜。bore 的区别只在于有个不用注册的公共实例,对一次性折腾来说启动成本低太多了。

这条路的边界

写到这儿得踩个刹车。能跑通不等于是个好方案,这套东西的问题挺明显的。

端口是明晃晃挂在公网上的。bore.pub:30950 谁都能连,你的防线就剩一层 SSH 密钥认证。这层其实够强,前提是别干蠢事:密码登录关掉,私钥别贴到聊天记录、Issue 或者任何会被爬到的地方。另外私钥是 Agent 生成完发给你的,它有没有在别处留副本,说实话我不知道。

bore.pub 是共享的公共实例,转发的是明文 TCP。SSH 本身端到端加密,中转方看不到内容,但它知道谁在什么时候连了哪个端口——你的信任边界里凭空多了个陌生人。

机器随时会没。端口重连就变,进程可能被回收,整台机器哪天不见了也正常。别在上面放唯一一份数据,别拿它当 CI runner,别指望它明天还在。

还有平台条款这一层。把 bot 的执行环境当通用 VPS 使,大概率不在 Grok Bot 的预期用法里。拿来做实验、搞明白原理没什么问题,真要长期跑东西的话,几块钱一个月的 VPS 省心得多,也不用担心哪天账号被处理掉。

所以我给它的定位很明确:这是个用来搞清楚”Agent 的执行环境到底有多真”的实验,不是基础设施。

顺带想到的

技术上真没什么新东西。bore 存在好几年了,SSH 反向隧道更是老手艺,这篇里所有命令都是十年前就有的。

让我多想了一会儿的是另外一件事。我给出去的是一句自然语言的目标——”把 SSH 隧道暴露出来,连接信息发我”。中间那七八个步骤,装包、配服务、生成密钥、注入公钥、起隧道、读端口、把结果拼成一条我能直接粘的命令,一步都不是我写的,但每一步都可能出错。

这跟我之前在目标驱动循环里聊的是一回事:交出去的是完成标准,不是指令序列。区别在于那篇讲的是写代码,验收多少还带点主观;这次硬得多,要么我的 ssh 连上了要么没连上,糊弄不过去。

而唯一真正需要我的地方,是”bore 应该会更省事一点”这半句。不是执行,是在岔路口指了一下。这个分工最近越来越明显了。

另外第三步”换成自己的模型”其实是最容易被跳过、但影响最大的一步。它决定了这台机器上跑的是谁的判断力。托管方给的默认助手不一定配合你干这种事——不是能力问题,是它的目标函数里压根没这一项。

要复现的话

  • 先随便装个包验证机器是真的
  • 接管主机拿 shell
  • /login 换自己的模型,别退出
  • 提示词里点名 bore,绕开 cloudflared 的账号问题
  • 私钥落盘 chmod 600
  • 端口是随机的,隧道重启就换

最后这行留个纪念:

ssh -i tunnel_key -p 30950 box@bore.pub