Skip to content
FunCoding

Search

Search docs, agents, posts, Skills and MCP servers

沙箱

用沙箱化的 Bash 工具获得文件系统和网络隔离:启用、两种模式、配置文件系统路径、工作原理与限制。

Bash 沙箱让 Claude 无需停下来请求权限就能运行大多数 shell 命令。你不再逐个批准命令,而是定义命令能触碰哪些文件和网络域名,然后由操作系统对每个 Bash、PowerShell 或 Monitor 命令及其子进程强制执行这个边界。

想比较其他隔离方式(dev container、自定义容器、虚拟机),见官方的 Sandbox environments;想减少 Bash 之外其他工具的权限提示,见权限模式。

开始使用

沙箱内置于 Claude Code,运行在 macOS、Linux 和 WSL2 上,不支持原生 Windows(在 Windows 上,请在 WSL2 发行版里运行 Claude Code)。macOS 上无需安装任何东西:沙箱使用内置的 Seatbelt 框架。Linux 和 WSL2 上,沙箱依赖两个包:

  • bubblewrap:强制文件系统隔离的无特权沙箱工具
  • socat:用于把网络流量路由经过沙箱代理的中继

用发行版的包管理器安装:

sudo apt-get install bubblewrap socat
# 或
sudo dnf install bubblewrap socat

步骤:

  1. 启动 Claude Code 会话并运行 /sandbox。它会打开沙箱面板,有三个标签页:Mode(选择沙箱化命令如何被批准)、Overrides(选择在沙箱下失败的命令能否回退到非沙箱运行,即 allowUnsandboxedCommands 设置)、Config(查看解析后的沙箱设置)。如果面板只显示 Dependencies 标签页,说明缺少必需的包,安装后重启 Claude Code 再运行 /sandbox
  2. 在 Mode 标签页选 auto-allow 或 regular permissions
  3. 让 Claude 运行一条命令,比如构建或测试套件。默认情况下,沙箱内的命令可以写入工作目录、每用户临时目录和你添加的目录;命令第一次需要新的网络域名时,Claude Code 会提示批准
  4. 无法在沙箱里运行的命令回退到常规权限流程,其权限提示的标题是「Bash command (unsandboxed)」而不是「Bash command」,这样你能分辨哪些命令在沙箱之外运行

你在面板里选定模式后,Claude Code 会把它保存到项目的本地设置 .claude/settings.local.json。想不写设置文件、只为一个会话改变沙箱,用 --settings 启动,例如启动一个 Claude 无法在沙箱之外重试被阻止命令的会话:

claude --settings '{"sandbox": {"enabled": true, "allowUnsandboxedCommands": false}}'

默认情况下,如果沙箱因缺少依赖或平台不受支持而无法启动,Claude Code 显示警告并在没有沙箱的情况下运行命令;想让它变成硬性失败,设置 sandbox.failIfUnavailable。

沙箱模式

两种模式下沙箱强制执行相同的文件系统和网络限制,区别只是沙箱化的命令是被自动批准,还是需要显式许可。

Auto-allow 模式:命令可以被沙箱化时,Claude Code 在沙箱内运行并自动批准,无需询问你。无法沙箱化的命令(如需要访问非允许主机的网络)回退到常规权限流程。即使在这个模式下,以下仍然适用:显式 deny 规则始终被遵守;针对关键路径的 rm 或 rmdir 仍走常规权限流程;内容限定的 ask 规则(如 Bash(git push *))即使对沙箱化命令仍强制提示。

Regular permissions 模式:所有 Bash 命令都走常规权限流程,即使被沙箱化。这提供更多控制,但需要更多批准。

未沙箱重试的逃生口:有些命令根本无法在沙箱里运行,比如与沙箱不兼容的工具,或需要你没允许的主机。Claude Code 在被阻止命令的结果里报告沙箱违规,指出沙箱拒绝的路径或主机,Claude 会看到沙箱挡住了什么,并可以用 dangerouslyDisableSandbox 参数在沙箱之外重试。重试的命令走常规权限流程:Manual 模式下你会得到确认提示。你可以在沙箱设置里设置 "allowUnsandboxedCommands": false 禁用这个逃生口,这样每个命令都必须沙箱运行。注意严格沙箱模式只适用于 Claude 运行的命令;你在 ! shell 模式提示里自己输入的命令在沙箱之外运行(后台会话除外)。

临时目录:每用户临时目录默认和工作目录一起可在沙箱内写入。除非禁用文件系统隔离,Claude Code 会为沙箱化命令把 $TMPDIR 设为该目录。

配置沙箱

通过 settings.json 定制沙箱行为。默认情况下,沙箱化命令可以写入当前工作目录、每用户临时目录,以及用 --add-dir、/add-dir 或 permissions.additionalDirectories 添加的目录。如果子进程需要写这些位置之外的路径,用 sandbox.filesystem.allowWrite 添加:

{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "allowWrite": ["~/.kube", "/tmp/build"]
    }
  }
}

这些路径在 OS 级别强制执行,所以沙箱内运行的所有命令(包括子进程)都遵守它们。当某个工具需要对特定位置的写权限时,推荐这种做法,而不是用 excludedCommands 把工具完全排除在沙箱之外。同一个文件系统数组在多个设置范围里定义时,Claude Code 会合并它们,而不是用一个范围的数组替换另一个。会话期间编辑这些列表,Claude Code 会把改动应用到运行中的会话。

路径前缀如何解析:

前缀含义示例
/从文件系统根开始的绝对路径/tmp/build 保持为 /tmp/build
~/相对于家目录~/.kube 变成 $HOME/.kube
./ 或无前缀项目设置里相对于项目根,用户设置里相对于 ~/.claude.claude/settings.json 里的 ./output 解析为 <project-root>/output

这个语法不同于 Read 和 Edit 权限规则(后者用 //path 表示绝对路径、/path 表示项目相对路径),沙箱文件系统路径采用标准约定。你也可以用 sandbox.filesystem.denyWrite 和 sandbox.filesystem.denyRead 拒绝写或读访问,用 sandbox.filesystem.allowRead 在被拒绝区域内重新允许特定路径;读规则重叠时,路径更窄的规则生效。下面的例子阻止读取整个家目录,同时仍允许读取当前项目(放在项目的 .claude/settings.json 里,因为相对路径 . 只有当配置在项目设置里时才解析为项目根):

{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "denyRead": ["~/"],
      "allowRead": ["."]
    }
  }
}

想在保留工作目录可读的同时拒绝沙箱化命令读取家目录和挂载卷,设置 permissions.blockReadsOutsideWorkingDirectories,而不是自己写路径规则。把 sandbox.filesystem.disabled 设为 true 可以跳过文件系统隔离但保留网络隔离。

沙箱如何工作

文件系统隔离

沙箱化的 Bash 工具把文件系统访问限制在特定目录:

  • 默认写行为:对当前工作目录及其子目录、你添加的目录、再加上每用户临时目录有读写权限
  • 默认读行为:对整台电脑有读权限,除了某些被拒绝的目录。注意这个默认仍然允许读取 ~/.aws/credentials 和 ~/.ssh/ 这样的凭据文件;用 sandbox.credentials 阻止读取这些文件
  • 被阻止的访问:没有显式权限,不能修改工作目录、添加的目录和每用户临时目录之外的文件,包括 ~/.bashrc 这样的 shell 配置文件和 /bin/ 里的系统二进制文件
  • Git worktree:当工作目录是链接的 git worktree 时,沙箱还允许写入主仓库共享的 .git 目录,让 git commit 这类命令能更新引用和索引(其中的 hooks/ 和 config 仍受保护)

受保护路径

在沙箱化命令可写的目录内,沙箱仍然拒绝写入 Claude Code 从中加载配置和代码的文件。能编辑这些文件的命令可以授予自己权限,或添加 Claude Code 在沙箱之外运行的 Hook 或 MCP 服务器。受保护的有:工作目录及其上级目录里的 .claude 设置文件、.claude/skills、.claude/agents、.claude/commands、.claude/hooks 目录和 .mcp.json;仅工作目录里的 shell 启动文件(.bashrc、.zshrc)、.gitconfig、.vscode 和 .idea 目录,以及 .git 里的 hooks 和 config;~/.claude(或 CLAUDE_CONFIG_DIR 指向的目录)里的大部分内容,加上 ~/.claude.json 和 .credentials.json 凭据存储。没有办法豁免这些路径之一:allowWrite 条目或覆盖该路径的 Edit allow 规则不会解除保护。

网络隔离

网络访问通过运行在沙箱之外的代理服务器控制:

  • 域名限制:Claude Code 默认不预先允许任何域名。命令第一次需要新域名时,Claude Code 会提示批准
  • 批准选择:选 Yes,Claude Code 在当前会话的剩余时间里允许该主机,不再为之后对同一主机的连接提示;选「Yes, and don't ask again」会把 WebFetch(domain:...) allow 规则保存到你的本地设置
  • 预先允许域名:用 allowedDomains 预先允许域名以完全避免提示
  • 严格白名单:在用户、托管或 CLI --settings 设置里把 strictAllowlist 设为 true,Claude Code 会拒绝沙箱化命令访问白名单之外的任何主机,而不是提示
  • 托管锁定:托管设置里设置 allowManagedDomainsOnly,未允许的域名被自动阻止而不是提示
  • 企业代理:当网络要求出站流量经过企业代理时,在设置的 env 块里设置 HTTPS_PROXY、HTTP_PROXY 和 NO_PROXY
  • 全面覆盖:限制适用于命令派生的所有脚本、程序和子进程

内置代理根据请求的主机名强制执行白名单,默认不终止或检查 TLS 流量。

限制

沙箱降低风险,但不是完整的隔离边界。依赖它作为硬性安全控制之前,请审阅这些限制:

  • 网络过滤:沙箱限制进程能连接哪些域名,但默认不检查加密连接的内容。允许 github.com 这类宽泛的域名可能产生数据外泄路径(代理基于客户端提供的主机名做决定,沙箱内运行的代码可能利用域前置绕过过滤)
  • 通过 Unix socket 提权:allowUnixSockets 配置可能无意中授予对系统服务的访问,导致沙箱绕过。例如允许访问 /var/run/docker.sock 实际上授予了通过 Docker socket 访问主机系统的权限
  • 文件系统权限升级:过于宽泛的文件系统写权限可能导致提权攻击。允许写入包含 $PATH 里可执行文件的目录、系统配置目录或用户 shell 配置文件(如 .bashrc、.zshrc)都可能带来风险
  • Linux 沙箱强度:Linux 实现提供强的文件系统和网络隔离,但包含一个 enableWeakerNestedSandbox 模式,让它能在没有特权命名空间的 Docker 环境里工作,会大大削弱安全性
  • macOS 的 Apple Events:macOS 沙箱默认阻止 Apple Events;allowAppleEvents 设置解除限制,让 open、osascript 这类工具能工作,但会移除代码执行隔离

平台:支持 macOS、Linux 和 WSL2;不支持 WSL1 和原生 Windows。范围:沙箱隔离 Bash 子进程,其他工具在不同边界下运行:内置文件工具(Read、Edit、Write)直接使用权限系统而不经过沙箱;computer use 在你真实的桌面上运行;沙箱化的 Bash 命令默认继承父进程环境(包括其中设置的任何凭据),可以用 sandbox.credentials 取消设置或遮蔽特定变量;子智能体与父会话在同一进程里运行并使用相同的沙箱配置。

有效的沙箱需要同时有文件系统隔离和网络隔离。没有网络隔离,被攻陷的智能体可能外泄 SSH 密钥等敏感文件;没有文件系统隔离,则可能逃出沙箱并获得网络访问。

与权限的关系

沙箱和权限互补:权限控制 Claude Code 能使用哪些工具、访问哪些文件或域名,沙箱提供 OS 级强制。两者一起用提供纵深防御,两处来源的路径和域名会合并进最终的沙箱配置。