Claude Code の Sandbox Runtime で使われている bubblewrap を試し外部との通信制限の仕組みを確認する

llmlinux

Claude Code にはエージェントに強い許可を与えながら安全に動かすためファイルシステムやネットワークを分離する Sandboxing の機能があり、Linux ではこれに bubblewrap を用いている。 bubblewrap は CLONE_NEWNET や CLONE_NEWPID などのフラグを渡して clone(2) システムコールを呼び出すことで 各 namespace を分離する。

$ sudo apt install bubblewrap
$ bwrap \
  --ro-bind /usr /usr \
  --ro-bind /lib /lib \
  --ro-bind /lib64 /lib64 \
  --unshare-net \
  ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever

 $ bwrap \
  --ro-bind /usr /usr \
  --ro-bind /lib /lib \
  --ro-bind /lib64 /lib64 \
  --proc /proc \
  --unshare-pid \
  ps aux

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
1000           1  0.0  0.0   3584  1420 ?        S+   07:14   0:00 bwrap --ro-bind /usr /usr --ro-bind /lib /lib --ro-bi
1000           2  0.0  0.0   8284  4096 ?        R+   07:14   0:00 ps aux

Docker と異なりデーモンを動かしてやり取りする必要がなく、小さいオーバーヘッドでプロセスを実行できる。

$ time for i in {1..100}; do
  echo "test" > /dev/null
done

real    0m0.022s
user    0m0.019s
sys     0m0.003s

$ time for i in {1..100}; do
  bwrap --ro-bind /usr /usr --ro-bind /lib /lib --ro-bind /lib64 /lib64 --unshare-all echo "test" > /dev/null
done

real    0m0.374s
user    0m0.125s
sys     0m0.095s

$ time for i in {1..100}; do
  docker run --rm alpine echo "test" > /dev/null
done

real    0m1.126s
user    0m0.254s
sys     0m0.158s

Sandbox Runtime (srt) は bwrap --unshare-net外部への通信を遮断しつつ、socat コマンドで Sandbox の localhost:{port} を socket に転送するようにして HTTP(S)_PROXY などに localhost:{port} を設定することで、ホストのプロキシサーバーを通って外に出られるようにする。このサーバーでallowed/deniedDomain によるフィルタを行う。

$ npm install -g @anthropic-ai/sandbox-runtime
$ sudo apt install ripgrep socat
$ srt --version
1.0.0

$ cat ~/.srt-settings.json
{
  "filesystem": {
    "denyRead": [],
    "allowWrite": ["."],
    "denyWrite": []
  },
  "network": {
    "allowedDomains": ["example.com"],
    "deniedDomains": []
  }
}

$ SRT_DEBUG=1 srt curl "sambaiz.net"
...
[SandboxDebug] HTTP proxy listening on localhost:44889
[SandboxDebug] SOCKS proxy listening on 127.0.0.1:44311
[SandboxDebug] Starting HTTP bridge: socat UNIX-LISTEN:/tmp/claude-http-59898d4a7ef502ee.sock,fork,reuseaddr TCP:localhost:44889,keepalive,keepidle=10,keepintvl=5,keepcnt=3
[SandboxDebug] Starting SOCKS bridge: socat UNIX-LISTEN:/tmp/claude-socks-59898d4a7ef502ee.sock,fork,reuseaddr TCP:localhost:44311,keepalive,keepidle=10,keepintvl=5,keepcnt=3
...
[SandboxDebug] No matching config rule, denying: sambaiz.net:80
[SandboxDebug] HTTP request blocked to sambaiz.net:80
Connection blocked by network allowlist[SandboxDebug] Sent SIGTERM to HTTP bridge process
[SandboxDebug] Sent SIGTERM to SOCKS bridge process

なお、Claude Code の /sandbox は現状 Windows 未対応で WSL2 でも動かない。

> /sandbox
  ⎿  Error: Sandboxing is currently only supported on macOS and Linux

ただ srt コマンドで動かすことはできる。Claude Code を動かすのに必要なドメインを許可する必要がある。

$ cat ~/.srt-settings.json
{
  "filesystem": {
    "denyRead": [
      "~/.ssh",
      "~/.aws"
    ],
    "allowWrite": [
      ".",
      "/tmp",
      "~/.claude.json",
      "~/.claude"
    ],
    "denyWrite": [
      ".env"
    ]
  },
  "network": {
    "allowedDomains": [
      "api.anthropic.com",
      "claude.ai",
      "statsig.anthropic.com",
      "sentry.io"
    ],
    "deniedDomains": []
  },
  "ignoreViolations": {
    "*": [
      "/usr/bin",
      "/System"
    ]
  }
}

$ srt "claude --dangerously-skip-permissions --print \"run a command: curl sambaiz.net\""
The curl command attempted to connect to sambaiz.net but the connection was blocked by a network allowlist. This means that network access to this domain is restricted in the current environment.

The response shows that only 39 bytes were received before the connection was blocked, suggesting some initial data was retrieved but the full content couldn't be fetched due to network restrictions.