34.2 沙箱隔离配置
约 1656 字大约 6 分钟
学习如何配置和使用 Claude Code 的沙箱隔离功能,为企业环境提供更安全的代理执行环境。
34.2.1 沙箱隔离概述
什么是沙箱隔离
沙箱隔离是 Claude Code 提供的一种安全机制,通过操作系统级原语强制执行文件系统和网络隔离。它允许 Claude Code 在预定义的安全边界内自主运行,减少对持续权限提示的依赖。
沙箱隔离的优势
- 减少批准疲劳:安全命令无需逐个批准
- 提高生产力:减少工作流中断
- 增强安全性:定义清晰的访问边界
- 启用自主性:Claude Code 可以更独立地工作
- 全面保护:文件系统和网络双重隔离
沙箱隔离的适用场景
- 企业开发环境
- 处理敏感数据的项目
- 需要高安全性的生产环境
- 自动化 CI/CD 流程
- 多租户开发环境
34.2.2 沙箱隔离工作原理
文件系统隔离
沙箱化 bash 工具通过以下方式限制文件系统访问:
沙箱文件系统访问规则示例
SANDBOX_FILESYSTEM_RULES = { "allowed_write_paths": [ "/workspace", # 当前工作目录 "/tmp", # 临时目录 "/home/developer/.cache" # 缓存目录 ], "allowed_read_paths": [ "/", # 整个系统(默认) "/usr/local/bin", # 系统工具 "/opt/tools" # 企业工具 ], "denied_paths": [ "/etc", # 系统配置 "/root", # root 用户目录 "/home/developer/.ssh", # SSH 密钥 "/home/developer/.aws", # AWS 凭证 "~/.config/claude-code" # Claude Code 配置 ] }
网络隔离
网络访问通过代理服务器控制:
34.2.3 快速入门
启用沙箱隔离
在 Claude Code 中运行斜杠命令:
这将使用默认设置激活沙箱化 bash 工具。
验证沙箱状态
检查沙箱是否启用
测试沙箱隔离
```bash
# 测试文件系统隔离 - 应该成功
echo "test" > /workspace/test.txt
# 测试文件系统隔离 - 应该失败
echo "test" > /etc/test.txt
# 测试网络隔离 - 应该成功
curl https://api.anthropic.com
# 测试网络隔离 - 应该失败
curl https://example.com
```## 34.2.4 基础配置
### settings.json 配置
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowedWritePaths": [
"${workspaceFolder}",
"/tmp"
],
"deniedPaths": [
"/etc",
"/root",
"~/.ssh",
"~/.aws"
]
},
"network": {
"allowedDomains": [
"api.anthropic.com",
"code.claude.com",
"github.com",
"npmjs.org"
],
"httpProxy": "http://proxy.company.com:8080",
"httpsProxy": "http://proxy.company.com:8080"
},
"excludedCommands": [
"docker",
"systemctl"
],
"allowUnsandboxedCommands": false
}
}环境变量配置
```bash
# 启用沙箱
export CLAUDE_SANDBOX_ENABLED=true
# 配置文件系统路径
export CLAUDE_SANDBOX_WRITE_PATHS="/workspace,/tmp"
export CLAUDE_SANDBOX_DENY_PATHS="/etc,/root,~/.ssh"
# 配置网络
export CLAUDE_SANDBOX_ALLOWED_DOMAINS="api.anthropic.com,code.claude.com,github.com"
export CLAUDE_SANDBOX_HTTP_PROXY="http://proxy.company.com:8080"
export CLAUDE_SANDBOX_HTTPS_PROXY="http://proxy.company.com:8080"
```## 34.2.5 企业级配置
### 多环境沙箱配置
> **开发环境配置:**
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowedWritePaths": [
"${workspaceFolder}",
"/tmp",
"/home/developer/.cache"
],
"deniedPaths": [
"/etc",
"/root",
"~/.ssh",
"~/.aws",
"~/.config/claude-code"
]
},
"network": {
"allowedDomains": [
"api.anthropic.com",
"code.claude.com",
"github.com",
"npmjs.org",
"*.dev.company.com"
],
"httpProxy": "http://proxy-dev.company.com:8080",
"httpsProxy": "http://proxy-dev.company.com:8080"
},
"excludedCommands": [
"docker",
"kubectl"
],
"allowUnsandboxedCommands": true
}
}生产环境配置:
```json
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowedWritePaths": [
"${workspaceFolder}/build",
"${workspaceFolder}/dist",
"/tmp"
],
"deniedPaths": [
"/etc",
"/root",
"~/.ssh",
"~/.aws",
"~/.config",
"${workspaceFolder}/src"
]
},
"network": {
"allowedDomains": [
"api.anthropic.com",
"code.claude.com",
"*.prod.company.com"
],
"httpProxy": "http://proxy-prod.company.com:8080",
"httpsProxy": "http://proxy-prod.company.com:8080"
},
"excludedCommands": [],
"allowUnsandboxedCommands": false,
"enableWeakerNestedSandbox": false
}
}
```### 项目级配置
为不同类型的项目创建专门的沙箱配置:
> **前端项目配置 (frontend-sandbox.json):**
{
"name": "Frontend Sandbox",
"sandbox": {
"filesystem": {
"allowedWritePaths": [
"${workspaceFolder}",
"/tmp",
"/home/developer/.npm"
],
"deniedPaths": [
"/etc",
"/root",
"~/.ssh",
"~/.aws"
]
},
"network": {
"allowedDomains": [
"api.anthropic.com",
"code.claude.com",
"github.com",
"npmjs.org",
"registry.npmjs.org",
"*.api.company.com"
]
},
"excludedCommands": [
"docker"
]
}
}后端项目配置 (backend-sandbox.json):
```json
{
"name": "Backend Sandbox",
"sandbox": {
"filesystem": {
"allowedWritePaths": [
"${workspaceFolder}",
"/tmp",
"/var/log/app"
],
"deniedPaths": [
"/etc",
"/root",
"~/.ssh",
"~/.aws",
"/var/lib"
]
},
"network": {
"allowedDomains": [
"api.anthropic.com",
"code.claude.com",
"github.com",
"*.api.company.com",Unix Socket 配置#
```json
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowedWritePaths": ["${workspaceFolder}"],
"allowedUnixSockets": [
"/var/run/docker.sock", # 警告:这可能授予主机访问权限
"/tmp/vscode-git.sock"
]
},
"network": {
"allowedDomains": ["api.anthropic.com", "code.claude.com"]
}
}
}
```### 嵌套沙箱配置
{
"sandbox": {
"enabled": true,
"enableWeakerNestedSandbox": true,
"filesystem": {
"allowedWritePaths": ["${workspaceFolder}"]
},
"network": {
"allowedDomains": ["api.anthropic.com", "code.claude.com"]
}
}
}34.2.7 安全最佳实践#
1. 最小权限原则#
从最严格的配置开始,根据需要逐步放宽:
```json
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowedWritePaths": ["${workspaceFolder}"],
"deniedPaths": [
"/etc",
"/root",
"~/.ssh",
"~/.aws",
"~/.config",
"/usr/local/bin",
"/opt"
]
},
"network": {
"allowedDomains": ["api.anthropic.com", "code.claude.com"]
},
"excludedCommands": [],
"allowUnsandboxedCommands": false
}
}
```### 2. 审计和监控
实现全面的审计日志记录:
import json
from datetime import datetime
from pathlib import Path
class SandboxAuditor:
def __init__(self, log_dir='/var/log/claude-sandbox'):
self.log_dir = Path(log_dir)
self.log_dir.mkdir(parents=True, exist_ok=True)
def log_filesystem_access(self, operation, path, allowed, user):
log_entry = {
"timestamp": datetime.now().isoformat(),
"type": "filesystem",
"operation": operation,
"path": path,
"allowed": allowed,
"user": user
}
self._write_log(log_entry)
def log_network_access(self, url, domain, allowed, user):
log_entry = {
"timestamp": datetime.now().isoformat(),
"type": "network",
"url": url,
"domain": domain,
"allowed": allowed,
"user": user
}
self._write_log(log_entry)
def log_command_execution(self, command, sandboxed, allowed, user):
log_entry = {
"timestamp": datetime.now().isoformat(),
"type": "command",
"command": command,
"sandboxed": sandboxed,
"allowed": allowed,
"user": user
}
self._write_log(log_entry)
def _write_log(self, log_entry):
log_file = self.log_dir / f"sandbox-{datetime.now().strftime('%Y-%m-%d')}.log"
with open(log_file, 'a') as f:
f.write(json.dumps(log_entry) + '\n')
def analyze_violations(self, days=7):
violations = []
for i in range(days):
date = (datetime.now() - timedelta(days=i)).strftime('%Y-%m-%d')
log_file = self.log_dir / f"sandbox-{date}.log"
if log_file.exists():
with open(log_file, 'r') as f:
for line in f:
entry = json.loads(line)
if not entry.get('allowed', True):
violations.append(entry)
return violations
# 使用示例
auditor = SandboxAuditor()
# 记录文件系统访问
auditor.log_filesystem_access('write', '/etc/config', False, 'developer')
# 记录网络访问
auditor.log_network_access('https://malicious.com', 'malicious.com', False, 'developer')
# 分析违规
violations = auditor.analyze_violations(days=7)
print(f"发现 {len(violations)} 个违规")3. 定期审查#
建立定期审查流程:
```bash
#!/bin/bash
# sandbox-audit.sh
LOG_DIR="/var/log/claude-sandbox"
REPORT_DIR="/var/reports/sandbox"
DATE=$(date +%Y-%m-%d)
# 创建报告目录
mkdir -p "$REPORT_DIR"
# 生成每日报告
echo "=== 沙箱审计报告 - $DATE ===" > "$REPORT_DIR/daily-$DATE.txt"
# 统计违规次数
VIOLATIONS=$(grep -r '"allowed": false' "$LOG_DIR" | wc -l)
echo "总违规次数: $VIOLATIONS" >> "$REPORT_DIR/daily-$DATE.txt"
# 统计文件系统违规
FS_VIOLATIONS=$(grep -r '"type": "filesystem"' "$LOG_DIR" | grep '"allowed": false' | wc -l)
echo "文件系统违规: $FS_VIOLATIONS" >> "$REPORT_DIR/daily-$DATE.txt"
# 统计网络违规
NET_VIOLATIONS=$(grep -r '"type": "network"' "$LOG_DIR" | grep '"allowed": false' | wc -l)
echo "网络违规: $NET_VIOLATIONS" >> "$REPORT_DIR/daily-$DATE.txt"
# 列出最活跃的用户
echo -e "\n最活跃的用户:" >> "$REPORT_DIR/daily-$DATE.txt"
grep -r '"user"' "$LOG_DIR" | jq -r '.user' | sort | uniq -c | sort -rn | head -10 >> "$REPORT_DIR/daily-$DATE.txt"
# 列出最常见的违规
echo -e "\n最常见的违规:" >> "$REPORT_DIR/daily-$DATE.txt"
grep -r '"allowed": false' "$LOG_DIR" | jq -r '.path // .domain // .command' | sort | uniq -c | sort -rn | head -10 >> "$REPORT_DIR/daily-$DATE.txt"
echo "报告已生成: $REPORT_DIR/daily-$DATE.txt"
```### 4. 环境隔离
为不同的环境使用不同的沙箱配置:
import json
from pathlib import Path
class SandboxConfigManager:
def __init__(self, config_dir='/etc/claude-sandbox'):
self.config_dir = Path(config_dir)
self.config_dir.mkdir(parents=True, exist_ok=True)
def create_config(self, environment, config):
config_file = self.config_dir / f"{environment}.json"
with open(config_file, 'w') as f:
json.dump(config, f, indent=2)
def get_config(self, environment):
config_file = self.config_dir / f"{environment}.json"
if config_file.exists():
with open(config_file, 'r') as f:
return json.load(f)
return None
def create_development_config(self):
return {
"sandbox": {
"enabled": True,
"filesystem": {
"allowedWritePaths": ["${workspaceFolder}", "/tmp"],
"deniedPaths": ["/etc", "/root", "~/.ssh", "~/.aws"]
},
"network": {
"allowedDomains": [
"api.anthropic.com",
"code.claude.com",
"github.com",
"npmjs.org",
"*.dev.company.com"
]
},
"allowUnsandboxedCommands": True
}
}
def create_production_config(self):
return {
"sandbox": {
"enabled": True,
"filesystem": {
"allowedWritePaths": ["${workspaceFolder}/build", "/tmp"],
"deniedPaths": [
"/etc",
"/root",
"~/.ssh",
"~/.aws",
"~/.config",
"${workspaceFolder}/src"
]
},
"network": {
"allowedDomains": [
"api.anthropic.com",
"code.claude.com",
"*.prod.company.com"
]
},
"allowUnsandboxedCommands": False,
"enableWeakerNestedSandbox": False
}
}
# 使用示例
manager = SandboxConfigManager()
# 创建开发环境配置
manager.create_config('development', manager.create_development_config())
# 创建生产环境配置
manager.create_config('production', manager.create_production_config())34.2.8 故障排查#
常见问题#
问题 1:沙箱阻止了合法操作
```bash
# 查看沙箱日志
tail -f /var/log/claude-sandbox/sandbox-$(date +%Y-%m-%d).log
# 临时禁用沙箱/sandbox disable
添加允许的路径或域名
在 settings.json 中更新配置
/sandbox config
将命令添加到排除列表
在 settings.json 中添加到 "excludedCommands"
34.2.9 与其他安全功能集成
与 IAM 策略集成
```json
{
"sandbox": {
"enabled": true,
"filesystem": {
"allowedWritePaths": ["${workspaceFolder}"],
"deniedPaths": ["/etc", "/root", "~/.ssh", "~/.aws"]
},
"network": {
"allowedDomains": ["api.anthropic.com", "code.claude.com"]
}
},
"permissions": {
"fileAccess": {
"allowedPaths": ["${workspaceFolder}"],
"deniedPaths": ["/etc", "/root", "~/.ssh", "~/.aws"]
},
"networkAccess": {
"allowedDomains": ["api.anthropic.com", "code.claude.com"]
}
}
}
```### 与开发容器集成
{
"name": "Claude Code Enterprise Dev Container",
"dockerFile": "Dockerfile",
"customizations": {
"vscode": {
"settings": {
"claude-code.sandbox.enabled": true,
"claude-code.sandbox.filesystem.allowedWritePaths": [
"${workspaceFolder}",
"/tmp"
],
"claude-code.sandbox.network.allowedDomains": [
"api.anthropic.com",
"code.claude.com",
"github.com"
]
}
}
},
"postCreateCommand": "bash .devcontainer/init-sandbox.sh"
}