Skip to content
返回

Claude Desktop 沙箱挡住了 github.com

上一篇填沙箱坑时,用 sandbox.excludedCommandsnpm run devcurl 放出了沙箱。那天我接着想让 Claude Desktop 帮我建个 PR,结果一口气又撞了两个沙箱的坑——先是 git push 直接连不上 github,放行之后又遇到 gh 的 TLS 问题。这篇先写前面这个:沙箱的网络出站白名单;后面那个 TLS 坑写在下篇

想直接拿走结论的话:最快的解法还是老朋友 excludedCommands,加一条 git * 把 git 放出沙箱就完事。下面先讲它,再讲不想一把放开 git 时该怎么按域名收敛地放行。

现象

让 Claude Desktop 走 /create-pr 建 PR,第一步 git push 就挂了:

fatal: unable to access 'https://github.com/lmk123/cvox.git/':
CONNECT tunnel failed, response 403

CONNECT tunnel failed 不是 git 的错、也不是网络断了——是有个代理在中间,对着 github.com 的 CONNECT 请求回了 403。换句话说,请求根本没出去,被就地拦了。

最快的解法:把 git * 放出沙箱

如果你只想赶紧把 git push 跑通,最省事的一招是直接让 git 整个绕开沙箱——在 sandbox.excludedCommands 里加一条 git *

{
  "sandbox": {
    "excludedCommands": ["git *"]
  }
}

git 在沙箱外跑,自然不受那层出站白名单管,403 当场消失。这招还有几个好处:

代价是放开了所有 git 命令的沙箱限制。 如果你不想给整个 git 开口子、只想精准放行 github 这一个主机,那就继续往下看——用「网络出站白名单」按域名加,是更收敛的办法。

是谁在拦:会话自己起的代理

沙箱里所有命令的网络都被强制走代理,环境变量里写得清清楚楚:

HTTP_PROXY=http://localhost:64310
HTTPS_PROXY=http://localhost:64310
ALL_PROXY=socks5h://localhost:64312

顺手查了下这俩端口是谁在监听:

lsof -nP -iTCP:64310 -sTCP:LISTEN
# claude  66175 mica ... TCP 127.0.0.1:64310 (LISTEN)

监听者就是 claude 进程本身——也就是当前这个 Claude Desktop 会话。所以这代理不是我装的什么网络工具,是会话运行环境自己注入的一层出站过滤:只放行白名单里的主机(api.anthropic.com、中转站、sentry 那几个),github.com 不在名单,于是 403。

这两个端口号每次会话都会变——我后来重启了几次,看到过 64310、也看到过 50351。要查当前值得自己 env | grep -i proxy

把我带偏的弯路:改错了配置文件

知道是白名单问题,接下来就是「往哪加 github.com」。我想当然地去翻 Claude Code 的 settings,查到字段是 sandbox.network.allowedDomains,于是在 ~/.claude/settings.json 里加了一段:

{
  "sandbox": {
    "network": {
      "allowedDomains": ["github.com", "*.githubusercontent.com"]
    }
  }
}

重启会话,再试——还是 403

这时,我想到我在 Claude Desktop 看到过一个设置项,位置是 Inference configuration -> Workspace restrictions -> Allowed egress hosts。我猜测是 Claude Desktop 用这个设置项覆盖了 settings.json 里的配置。

真正的开关:Allowed egress hosts

Allowed egress hosts(允许的出站主机)的说明文字把它的作用讲得很明白:

Hostnames the agent’s tools may reach from the Cowork and Code tabs. […] When unset, only the inference endpoint is reachable from the sandbox; the agent’s package installs (pip/npm) and web fetches will fail with a 403.

对上了——默认只放行推理(inference)那个端点,其余一律 403,所以连 github、装 npm 包都会挂。这才是真正拦我的那一层。

有个匹配规则的小坑,说明里特意点了出来:

Wildcards don’t cross schemes. *.corp.com matches docs.corp.com but not corp.com itself; add both if you need the apex.

通配符只匹配一级子域,不含顶级域本身。 所以不能只写 *.github.com 就完事——github.com 这个 apex 它不匹配,而 git push 走的恰恰是 apex。我加了这三条:

github.com
*.github.com
*.githubusercontent.com

设置里还有个 * Allow all 的选项,能一把放开所有出站。但那等于把这层过滤整个关掉,比需要的宽太多——加具体主机就够,没必要图省事。

改完重启 Claude Desktop,再 git ls-remote 测一下:

git ls-remote origin HEAD
# 24472e63...  HEAD   ← 通了
git push -u origin <branch>
# * [new branch] ...   ← push 成功

github 终于连上了。

一个小尾巴:push 成功但报 config 写入失败

push 那一下还顺带飘了两行红字:

error: could not write config file .git/config: Operation not permitted

看着吓人,其实无伤大雅。这是 git push -u 想往 .git/config 写 upstream tracking,被沙箱的文件写权限挡了——跟网络白名单是两码事。分支已经推上去了,tracking 也设上了,这行只是个没写成的副作用,忽略即可。

顺带一提:如果你走的是开头那条 git * 放出沙箱的路子,这个 config 写入失败也一并没了——git 不在沙箱里跑,.git/config 自然能写。这正是「一把放开 git」比「按域名加白名单」省心的地方:网络和文件写两层坑一次绕开。

收尾,以及那个 TLS 坑

github 一通,git push 就过了。然而 gh pr create 立刻又撞上 TLS 那道墙——那是另一层、另一个故事,留到下篇写

两个坑摞在一起,回头看是两层独立的过滤,得分开治:


分享这篇文章:

上一篇
Claude Desktop 里 gh 报 TLS 错的原因与解法
下一篇
Claude Desktop 踩坑后续