anthropics / anthropics/claude-code
Linux/WSL2 sandbox: socat proxy bridge starts in the background, so the first network call in a command fails
- Ngôn ngữ chính
- Python
- Star
- 145k
- Fork
- 23.1k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
## Summary
In the Linux/WSL2 Bash sandbox, a command whose **first** action is a network call fails with connection refused on the proxy bridge. Later calls in the same command succeed. Cause: the two `socat` bridges are started in the background and the user command runs at once, with no wait for the listeners.
Same symptom as #62743 (closed as stale). This report adds the mechanism, measurements, and a suggested fix.
## Environment
- Claude Code 2.1.269 (native binary, `latest` channel)
- WSL2, NixOS 26.05, kernel 6.18.40.1-microsoft-standard-WSL2
- bubblewrap and socat from nixpkgs
- `sandbox`: `{ "enabled": true, "autoAllowBashIfSandboxed": true, "allowUnsandboxedCommands": true, "failIfUnavailable": true }`, no `network` block
## Reproduction
Any Bash tool command that starts with a network call, for example:
```
git ls-remote https://github.com//.git HEAD
```
```
fatal: unable to access 'https://github.com//.git/': Failed to connect to github.com:443 over proxy localhost after 0 ms: Could not connect to server
```
or
```
curl -sS -o /dev/null -w '%{http_code}' https://github.com
```
```
curl: (7) Failed to connect to localhost:3128 after 0 ms: Could not connect to server
```
4 of 4 probes failed. `ss -ltn` as the first action shows no listener on 3128 yet; the same command 100 ms later shows `0.0.0.0:3128` and `0.0.0.0:1080`.
## Mechanism
The bwrap command runs the shell with this script (from the 2.1.269 binary):
```sh
socat TCP-LISTEN:3128,fork,reuseaddr UNIX-CONNECT:/tmp/claude-http-.sock >/dev/null 2>&1 &
socat TCP-LISTEN:1080,fork,reuseaddr UNIX-CONNECT:/tmp/claude-socks-.sock >/dev/null 2>&1 &
trap "kill %1 %2 2>/dev/null; exit" EXIT
-c ''
```
Nothing waits for the listen sockets to bind. Measured inside the sandbox with a `/dev/tcp` poll loop: port 3128 accepts connections 15-30 ms after the inner shell starts, while the inner shell is ready in about 3 ms. So any immediate network call loses the race.
## Suggested fix
Wait for the bridge before running the user command, for example a bounded poll in the same script:
```sh
for _ in $(seq 1 50); do (exec 3<>/dev/tcp/127.0.0.1/3128) 2>/dev/null && break; sleep 0.01; done
```
or start `socat` with a readiness signal. A user-side workaround (a guarded poll in `~/.zshenv`) makes 3/3 first calls succeed with a 20-30 ms wait, which confirms the diagnosis.
## Related: `.gitmodules` mask
`.gitmodules` in the working tree is masked with a `/dev/null` bind mount. Inside the user namespace the device node cannot be opened (`EACCES`), so:
- `git fetch` prints `warning: unable to access '.../.gitmodules': Permission denied` twice (cosmetic), and
- libgit2 users fail: `nix flake check` gives `parsing .gitmodules file: failed open - '.../.gitmodules' is locked: Permission denied (libgit2 error code = 2)`.
Masking with an empty regular file instead of a device node would avoid both.
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Hướng nghiên cứu
Start by locating the Linux/WSL2 sandbox entry point that assembles the bwrap command and launches the two socat bridges, then reproduce with the first-action curl or git ls-remote examples. Verify that both listeners are usable before the user shell runs, and check the .gitmodules mask behavior separately; done means first network calls succeed without the race and libgit2 can read the masked path.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- bash, git, linux
- Lĩnh vực
- cli, infrastructure, networking, operating-systems, security
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Sôi nổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 52/100