现充|junyu33

在 Android 的 Termux/Ubuntu 套娃环境里跑通 VSCode Remote+Codex

自从去年 12 月飞速入门 vibe coding 之后,我想尝试在任何能装 vscode 的机器中,都装上 codex 插件。于是我的下一步目标是——那台废弃的 android 手机。理论上 android(在 Google 坏事还没做尽前)是可以安装 termux 的,后者又有脚本来在里面套娃 ubuntu。因此我的那台 android 手机安装 remote SSH 和 codex 理论上是可行的。但实际上......

配置 SSH 直连 termux 内部的 ubuntu

问题的第一步,就是如何配置 SSH 直接连到里面的 Ubuntu,而不是通过 termux 再中转一层(因为 vscode server 并不支持 remote SSH 套娃)。这是整个流程最简单的一步,只需要在 Ubuntu 单独启一个 sshd,然后换一个和 termux 的 sshd 不冲突的端口即可。例如,在 Ubuntu 运行:

apt update
apt install -y openssh-server curl bash
mkdir -p /run/sshd
ssh-keygen -A
sed -i 's/^#\?Port .*/Port 2222/' /etc/ssh/sshd_config
/usr/sbin/sshd

也就是对应了 2222 端口。

这里我为了方便,使用默认的 root 用户,用 passwd 命令设一个密码,之后即可通过:

ssh -p 2222 root@手机IP

进行访问。

然后下一步是配好免密登录:

ssh-copy-id -p 2222 root@手机IP

本机 ~/.ssh/config 写一个代号,例如 phone-ubuntu

Host phone-ubuntu
    HostName 手机IP
    Port 2222
    User root
    ServerAliveInterval 30
    ServerAliveCountMax 6

测试 ssh phone-ubuntu 即可。如果没有问题,vscode 这边如果不出意外应该是可以正常使用 remote SSH 了。

Vscode 报错 Signature verification failed with 'UnknownError' error.

然后我便尝试去用 remote SSH 装 codex,诡异的事情便开始发生了。我收到了以下报错:

Signature verification failed with 'UnknownError' error.

我的直感是由于这个 ubuntu-in-termux 只是一个由 proot 搭起来的伪 linux 环境,但至少我得搞清楚这个 UnknownError 究竟具体是什么 error。于是我开始寻找这个报错的上下文:

对于前者直接点到那个位置,再 Ctrl+F 即可,后者的话路径在:

grep -niE 'signature|UnknownError' \
~/.vscode-server/data/logs/20260320T154741/remoteagent.log \
~/.vscode-server/data/logs/20260320T154741/exthost2/remoteexthost.log \
~/.vscode-server/data/logs/20260320T154741/exthost1/remoteexthost.log 2>/dev/null

(注意这里 logs 下面换成自己的时间路径)

可惜的是,当时这三个路径都没有结果。然后我又选择在本地查看最近 10 分钟的 log:

find ~/.config/Code/logs -type f \( -iname '*shared*' -o -iname '*window*' -o -iname '*renderer*' \) -mmin -10 -print0 2>/dev/null \ | xargs -0 grep -nEi 'Signature verification failed|UnknownError|signature|codex|openai|install' 2>/dev/null

这次倒是有了一些结果:

sharedprocess.log:122 Extension signature verification result for github.copilot-chat: Success
sharedprocess.log:134 Extension signature verification result for llvm-vs-code-extensions.vscode-clangd: Success
renderer.log:299 Remote Install Error Name SignatureVerificationInternal
renderer.log:301 Signature verification failed with 'UnknownError' error.

由此排除了本地 vscode 签名校验的问题(也就是失败点在远端安装 vscode server 这一步)。接下来有两个选择:

对于前者,首先我们得考虑 codex 这个插件是不是纯 js 写的,也就是运行:

find ~/.vscode/extensions/openai.chatgpt-* -type f | grep -E '\.node$|bin/|dist/.*(linux|arm64|x64)|\.(so|dll|exe)$'

我这里的返回结果为:

/home/junyu33/.vscode/extensions/openai.chatgpt-26.318.11754-linux-x64/bin/linux-x86_64/rg 
/home/junyu33/.vscode/extensions/openai.chatgpt-26.318.11754-linux-x64/bin/linux-x86_64/codex

这里区分了架构与平台,因此直接拷贝文件这条路可以放弃了。

接下来我们应该考虑如何搞到 codex 的 vsix 包,插件对应的商店页面没有找到对应的 vsix 下载链接,经过与 GPT 的一番斗智斗勇后,我获得了可以自由选择版本号的下载脚本:

for v in 26.318.11754 26.313.41514 26.313.41036 26.304.20706 0.4.79 0.4.60; do
  echo "=== $v ==="
  curl -sI "https://marketplace.visualstudio.com/_apis/public/gallery/publishers/openai/vsextensions/chatgpt/$v/vspackage?targetPlatform=linux-arm64" | sed -n '1,10p'
  echo
done

最新版本 26.318.11754 下下来是一个用 gzip 打包的 vsix(zip),看上去应该没有问题。接下来我尝试把 vsix 拷贝到服务器,然后另一个问题出现了:

SCP 传输失败

当我运行 scp openai-chatgpt-26.318.11754-linux-arm64.vsix phone-ubuntu: 后,我遇到了以下“报错”:

** WARNING: connection is not using a post-quantum key exchange algorithm. 
** This session may be vulnerable to "store now, decrypt later" attacks. 
** The server may need to be upgraded. See https://openssh.com/pq.html 
scp: Connection closed

我开始以为 openSSH 把非后量子密码协议给禁用了,然后意识到这只是一个 warning,重点是最后一句 scp: Connection closed。GPT 给出的解释是 Ubuntu 这边的 sshd 是手动启动的(也就是手动运行 /usr/sbin/sshd,而不是通过 systemctl 等方式启动),这会导致我的 SSH 仅能登录,没有 SFTP subsystem 进行文件传输,一个简单的 check 方式是:

sftp -P 2222 phone-ubuntu

我测试了一下,确实不行。GPT 提供了两种解决方案:

考虑到我的客户端 openSSH 版本是 10.2,服务器(Ubuntu)是 8.2,再加上服务器是非标准 linux 环境,使用后者可能会有其他兼容性问题,因此我选择每次记得加 -O 了事。


总之,给 scp 命令加上 -O 后,文件拷贝总算可以正常进行,最后便是离线安装 vsix:

code --install-extension ~/openai-chatgpt-26.318.11754-linux-arm64.vsix

然后便安装成功了。

codex 无法正常登录

由于国内特殊的网络原因,再加上我这种奇葩环境,我在浏览器输入账号密码,允许 vscode 客户端登录后,callback 似乎无法正确地传回到我的手机,从而我便卡在了 codex 登录这一步。

我便想登录应该是有认证 token 的,能否直接把我本地的凭据传到手机里呢?答案是肯定的,codex 在其官方文档中给了如下说明

If you can complete the login flow on a machine with a browser, you can copy your cached credentials to the headless machine.

  1. On a machine where you can use the browser-based login flow, run codex login.
  2. Confirm the login cache exists at ~/.codex/auth.json.
  3. Copy ~/.codex/auth.json to ~/.codex/auth.json on the headless machine.

为了保险,我也拷贝了对应的 config.toml,翻译到我这边就是:

ssh phone-ubuntu 'mkdir -p ~/.codex'
scp -O ~/.codex/auth.json phone-ubuntu:~/.codex/auth.json
scp -O ~/.codex/config.toml phone-ubuntu:~/.codex/config.toml
chmod 600 ~/.codex/auth.json ~/.codex/config.toml

注:这个操作对于 codex-cli 同样适用,也就是 vscode 的 codex 插件和 codex-cli 是同样的一套认证系统。

然后 vscode 这边 reload window,应该就没问题了。

代理问题

然后正当我打算愉快地与 codex 对话时,网络又出错了......

shell 没配好代理

首先检测 Ubuntu 这边有没有配好代理。结果我首先发现我忘了给代理的机器开启 Allow LAN,然后 ~/.bashrc 写的是:

http_proxy=http://主机ip:7897
https_proxy=http://主机ip:7897

而不是:

export http_proxy=http://主机ip:7897
export https_proxy=http://主机ip:7897

哎,真是个低级的错误......

开启局域网连接,并 source ~/.bashrc 后,curl google.com 就能正常返回了。

codex reconnecting 1/5 2/5 3/5 4/5 5/5

shell 代理解决之后,没想到 codex 仍然反复 reconnecting。我首先确认了 vscode 远端的代理设置为空(也就是默认走系统代理),这似乎没有问题。然后继续看 vscode server 的 log:

grep -RniE 'backend-api/codex/responses|Reconnecting|stream disconnected|proxy' ~/.vscode-server/data/logs ~/.config/Code/logs 2>/dev/null | tail -100

得到了以下结果:

/root/.vscode-server/data/logs/20260320T154741/exthost13/remoteexthost.log:1075:2026-03-20 17:44:52.997 [trace] ProxyResolver#tls.connect [{"highWaterMark":16384,"ca":"[290 certs]","servername":"chatgpt.com","session":"null","localAddress":"null","ALPNProtocols":"http/1.1","port":443,"host":"chatgpt.com"}] 
/root/.vscode-server/data/logs/20260320T154741/exthost13/remoteexthost.log:1076:2026-03-20 17:44:53.016 [trace] ProxyResolver#tls.connect [{"highWaterMark":16384,"ca":"[290 certs]","servername":"ab.chatgpt.com","session":"null","localAddress":"null","ALPNProtocols":"http/1.1","port":443,"host":"ab.chatgpt.com"}] 
/root/.vscode-server/data/logs/20260320T154741/exthost13/openai.chatgpt/Codex.log:38:2026-03-20 17:44:09.945 [error] [CodexMcpConnection] cli: message="codex_api::endpoint::responses_websocket: failed to connect to websocket: IO error: failed to lookup address information: Try again, url: wss://chatgpt.com/backend-api/codex/responses" 
/root/.vscode-server/data/logs/20260320T154741/exthost13/openai.chatgpt/Codex.log:39:2026-03-20 17:44:09.950 [warning] [CodexMcpConnection] cli: message="codex_core::session_startup_prewarm: startup websocket prewarm setup failed: stream disconnected before completion: failed to lookup address information: Try again" 
/root/.vscode-server/data/logs/20260320T154741/exthost13/openai.chatgpt/Codex.log:41:2026-03-20 17:44:14.994 [error] [CodexMcpConnection] cli: message="codex_api::endpoint::responses_websocket: failed to connect to websocket: IO error: failed to lookup address information: Try again, url: wss://chatgpt.com/backend-api/codex/responses" 
/root/.vscode-server/data/logs/20260320T154741/exthost13/openai.chatgpt/Codex.log:42:2026-03-20 17:44:14.997 [warning] [CodexMcpConnection] cli: message="codex_core::codex: stream disconnected - retrying sampling request (1/5 in 198ms)..." 
/root/.vscode-server/data/logs/20260320T154741/exthost13/openai.chatgpt/Codex.log:47:2026-03-20 17:44:20.214 [error] [CodexMcpConnection] cli: message="codex_api::endpoint::responses_websocket: failed to connect to websocket: IO error: failed to lookup address information: Try again, url: wss://chatgpt.com/backend-api/codex/responses" 
/root/.vscode-server/data/logs/20260320T154741/exthost13/openai.chatgpt/Codex.log:48:2026-03-20 17:44:20.216 [warning] [CodexMcpConnection] cli: message="codex_core::codex: stream disconnected - retrying sampling request (2/5 in 376ms)..."

结果是 扩展本身走了 vscode 的代理,但是 codex 本地的 websocket 貌似连接又出现了问题。那么问题就比较简单了,只需看 codex 是否接收到来自代理的环境变量即可:

首先还是更新一下 ~/.bashrc

export http_proxy=http://主机ip:7897
export https_proxy=http://主机ip:7897
export HTTP_PROXY=http://主机ip:7897
export HTTPS_PROXY=http://主机ip:7897
export all_proxy=http://主机ip:7897
export ALL_PROXY=http://主机ip:7897
unset no_proxy NO_PROXY

然后彻底重启 vscode server,并再更新一下环境变量:

pkill -f vscode-server
source ~/.bashrc

然后测试一下 codex-cli 本体能否正常工作:

~/.vscode-server/extensions/openai.chatgpt-26.318.11754/bin/linux-aarch64/codex exec "Say pong and nothing else."
OpenAI Codex v0.116.0-alpha.10 (research preview) 
-------- 
workdir: /root
model: gpt-5.4 
provider: openai 
approval: never 
sandbox: read-only 
reasoning effort: medium 
reasoning summaries: none 
session id: 019d0aa5-e037-7952-98b8-ded673f4d1ba 
-------- 
user 
Say pong and nothing else. 
warning: Codex could not find system bubblewrap at /usr/bin/bwrap. Please install bubblewrap with your package manager. Codex will use the vendored bubblewrap in the meantime. 
mcp startup: no servers 
codex 
pong 
tokens used 
1,101

看样子是正常了,然后重新打开 vscode server,codex 也终于恢复正常,完结撒花!