---
name: sandbox-test
description: Sandbox environment testing skill. Verifies SRT sandbox isolation including filesystem, network, process, and environment restrictions.
metadata: { "openclaw": { "emoji": "🧪", "developer": "QBotClaw", "requires": { "bins": [] } } }
---

# Sandbox Test 🧪

沙箱环境测试工具。用于验证 SRT (Sandbox Runtime) 沙箱的各项隔离能力是否正常工作。

## ⚡ 执行模式（必须遵守）

当用户激活此 Skill 时，**不要自动执行任何测试**。请按照以下流程操作：

**第一步：展示测试菜单，让用户选择要运行的测试项。**

请向用户展示以下选择列表：

```
🧪 沙箱测试菜单 — 请选择要运行的测试（输入编号）：

  [1] 🔍 环境检测      — 确认当前是否在 SRT 沙箱中运行
  [2] 📂 文件系统隔离  — 测试敏感目录（~/.ssh 等）的读写限制
  [3] 🌐 网络隔离      — 测试外网阻止 / 白名单 / localhost 放行
  [4] ⚙️ 进程隔离      — 测试 kill 信号和进程信息访问限制
  [5] ✏️ 写入限制      — 测试系统目录写入保护 vs 工作区放行
  [6] 📊 综合诊断      — 一次性运行所有测试，输出完整报告
  [0] 🚀 全部运行      — 按顺序逐项执行测试 1~5 并汇总

可以输入多个编号，用逗号分隔（如 "1,3,5"），或直接说"全部"。
```

**第二步：根据用户选择，仅执行对应的测试脚本。**

- 用户选 `1` → 只运行「测试 1：环境检测」的脚本
- 用户选 `2,3` → 依次运行「测试 2」和「测试 3」
- 用户选 `6` 或 `0` 或说"全部" → 运行综合诊断或逐项全部运行
- 每个测试执行完后，展示结果并询问：「是否继续测试其他项？」

**第三步：测试完成后，给出简要的结论总结。**

---

## 概述

该 Skill 提供一系列测试命令，覆盖沙箱的核心安全边界：

| 编号 | 测试类别         | 说明                              |
| :--: | ---------------- | --------------------------------- |
|  1   | **环境检测**     | 检测当前是否在沙箱中运行          |
|  2   | **文件系统隔离** | 测试敏感目录的读写限制            |
|  3   | **网络隔离**     | 测试外网访问限制和 localhost 放行 |
|  4   | **进程隔离**     | 测试进程创建和信号发送限制        |
|  5   | **写入限制**     | 测试工作区外的写入保护            |
|  6   | **综合诊断**     | 一次性运行所有测试，输出报告      |

## 测试项说明

### 1. 环境检测

检测当前 shell 是否在 SRT 沙箱中运行，包括：

- `SANDBOX_RUNTIME` 环境变量是否为 `1`
- 沙箱包装脚本是否存在
- `sandbox-exec` 进程是否在进程树中

### 2. 文件系统隔离测试

验证以下敏感路径是否被拒绝访问：

- `~/.ssh/` — SSH 密钥目录
- `/etc/shadow` — 系统密码文件

同时验证以下路径**应该可以访问**：

- 当前工作目录（workspace）
- `/tmp/` — 临时目录
- `~/.qbotclaw/` — 应用数据目录

### 3. 网络隔离测试

验证：

- 外网访问被阻止（如 `curl https://httpbin.org/ip`）
- 白名单域名可访问（如 `github.com`）
- `localhost` / `127.0.0.1` 可访问

### 4. 进程隔离测试

验证：

- 不能 kill 其他进程
- 不能访问其他用户的进程信息

### 5. 写入限制测试

验证：

- 不能写入工作区外的目录（如 `/usr/local/`、`/etc/`）
- 可以在工作区和 `/tmp/` 中创建文件

---

## 使用方式

### 🔹 测试 1：环境检测（确认是否在沙箱中）

```bash
echo "===== 沙箱环境检测 ====="
echo "SANDBOX_RUNTIME=${SANDBOX_RUNTIME:-未设置}"
echo "TMPDIR=${TMPDIR:-未设置}"
echo "HOME=$HOME"
echo "PWD=$PWD"
echo "USER=$(whoami)"
echo ""
if [ "$SANDBOX_RUNTIME" = "1" ]; then
  echo "✅ 检测结果：当前在 SRT 沙箱环境中运行"
else
  echo "❌ 检测结果：当前 NOT 在沙箱环境中（SANDBOX_RUNTIME != 1）"
fi
echo ""
echo "--- 进程树检测 ---"
ps -o pid,comm -p $$ 2>/dev/null || echo "(ps 命令不可用)"
pstree -p $$ 2>/dev/null || echo "(pstree 不可用，尝试 ps)"
```

### 🔹 测试 2：文件系统隔离

```bash
echo "===== 文件系统隔离测试 ====="
echo ""
echo "⚡ 安全模式：仅检测可访问性，不输出任何文件内容"
echo ""

echo "--- 敏感路径读取测试（应该被拒绝） ---"

echo -n "[1] 访问 ~/.ssh/: "
test -r ~/.ssh/ 2>/dev/null && echo "⚠️ 可以访问（沙箱未阻止）" || echo "✅ 访问被拒绝"

echo -n "[2] 访问 /etc/shadow: "
test -r /etc/shadow 2>/dev/null && echo "⚠️ 可以访问（沙箱未阻止）" || echo "✅ 访问被拒绝"

echo ""
echo "--- 正常路径访问测试（应该可以访问） ---"

echo -n "[3] 读取当前工作目录: "
test -r . 2>/dev/null && echo "✅ 可以访问" || echo "❌ 访问被拒绝（不应该）"

echo -n "[4] 写入 /tmp/sandbox-test-file: "
if echo "sandbox-test" > /tmp/sandbox-test-file 2>/dev/null; then
  echo "✅ 可以写入"
  rm -f /tmp/sandbox-test-file
else
  echo "❌ 写入被拒绝（不应该）"
fi

echo -n "[5] 读取 ~/.qbotclaw/: "
test -r ~/.qbotclaw/ 2>/dev/null && echo "✅ 可以访问" || echo "⚠️ 访问被拒绝（可能正常）"
```

### 🔹 测试 3：网络隔离

```bash
echo "===== 网络隔离测试 ====="
echo ""

echo "--- 外网访问测试（应该被阻止） ---"

echo -n "[1] curl https://httpbin.org/ip (外网): "
curl -s --connect-timeout 5 --max-time 10 https://httpbin.org/ip 2>&1
if [ $? -ne 0 ]; then
  echo "✅ 外网访问被阻止"
else
  echo "⚠️ 外网访问未被阻止"
fi

echo ""
echo -n "[2] curl https://example.com (外网): "
curl -s --connect-timeout 5 --max-time 10 https://example.com 2>&1 | head -5
if [ $? -ne 0 ]; then
  echo "✅ 外网访问被阻止"
else
  echo "⚠️ 外网访问未被阻止"
fi

echo ""
echo "--- 白名单域名测试（可能允许访问） ---"

echo -n "[3] curl https://github.com (白名单): "
curl -s --connect-timeout 5 --max-time 10 -o /dev/null -w "%{http_code}" https://github.com 2>&1
echo ""

echo ""
echo "--- 本地访问测试（应该允许） ---"

echo -n "[4] curl http://127.0.0.1:18789 (localhost gateway): "
curl -s --connect-timeout 3 --max-time 5 http://127.0.0.1:18789 2>&1 | head -3
if [ $? -ne 0 ]; then
  echo "(连接失败，可能 gateway 未运行，但网络未被阻止)"
else
  echo "✅ localhost 访问正常"
fi
```

### 🔹 测试 4：进程隔离

```bash
echo "===== 进程隔离测试 ====="
echo ""

echo "--- 进程信息访问 ---"
echo "[1] 当前进程 PID: $$"
echo "[2] 当前进程列表（前 10 个）:"
ps aux 2>/dev/null | head -10 || echo "(ps 不可用)"

echo ""
echo "--- kill 测试（应该被限制） ---"
echo "[3] 尝试 kill PID 1（init 进程）:"
kill -0 1 2>&1 && echo "⚠️ 可以发信号给 PID 1" || echo "✅ 无法发信号给 PID 1"
```

### 🔹 测试 5：写入限制

```bash
echo "===== 写入限制测试 ====="
echo ""
echo "⚡ 安全模式：写入测试文件会立即清理，不留痕迹"
echo ""

echo "--- 系统目录写入测试（应该被拒绝） ---"

echo -n "[1] 写入 /usr/local/sandbox-test: "
if touch /usr/local/sandbox-test 2>/dev/null; then
  echo "⚠️ 写入成功（沙箱未阻止）"
  rm -f /usr/local/sandbox-test
else
  echo "✅ 写入被拒绝"
fi

echo -n "[2] 写入 /etc/sandbox-test: "
if touch /etc/sandbox-test 2>/dev/null; then
  echo "⚠️ 写入成功（沙箱未阻止）"
  rm -f /etc/sandbox-test
else
  echo "✅ 写入被拒绝"
fi

echo -n "[3] 写入 ~/Desktop/sandbox-test: "
if touch ~/Desktop/sandbox-test 2>/dev/null; then
  echo "⚠️ 写入成功（沙箱未阻止）"
  rm -f ~/Desktop/sandbox-test
else
  echo "✅ 写入被拒绝"
fi

echo ""
echo "--- 允许写入的路径测试（应该成功） ---"

echo -n "[4] 写入当前工作目录: "
if touch ./sandbox-write-test 2>/dev/null; then
  echo "✅ 写入成功"
  rm -f ./sandbox-write-test
else
  echo "❌ 写入被拒绝（不应该）"
fi

echo -n "[5] 写入 /tmp/: "
if touch /tmp/sandbox-write-test 2>/dev/null; then
  echo "✅ 写入成功"
  rm -f /tmp/sandbox-write-test
else
  echo "❌ 写入被拒绝（不应该）"
fi
```

### 🔹 测试 6：综合诊断（一次运行所有测试）

以上测试可以一个一个执行来排查问题，也可以用下面这条命令一次性运行所有测试：

```bash
echo "╔══════════════════════════════════════════════════╗"
echo "║         QBotClaw 沙箱综合诊断报告               ║"
echo "║         $(date '+%Y-%m-%d %H:%M:%S')                    ║"
echo "╚══════════════════════════════════════════════════╝"
echo ""

PASS=0
FAIL=0
WARN=0

check_pass() { echo "  ✅ $1"; PASS=$((PASS+1)); }
check_fail() { echo "  ❌ $1"; FAIL=$((FAIL+1)); }
check_warn() { echo "  ⚠️  $1"; WARN=$((WARN+1)); }

echo "━━━ [1/5] 环境检测 ━━━"
if [ "$SANDBOX_RUNTIME" = "1" ]; then check_pass "SANDBOX_RUNTIME=1 (沙箱已激活)"; else check_fail "SANDBOX_RUNTIME 未设置 (不在沙箱中！)"; fi
echo "  ℹ️  TMPDIR=$TMPDIR"
echo "  ℹ️  HOME=$HOME"
echo "  ℹ️  PWD=$PWD"
echo ""

echo "━━━ [2/5] 文件系统隔离 ━━━"
test -r ~/.ssh/ 2>/dev/null && check_warn "~/.ssh/ 可以访问" || check_pass "~/.ssh/ 被拒绝访问"
test -r . 2>/dev/null && check_pass "工作目录可访问" || check_fail "工作目录不可访问"
if echo "sandbox-test" > /tmp/sandbox-diag-test 2>/dev/null; then check_pass "/tmp/ 可写入"; rm -f /tmp/sandbox-diag-test; else check_fail "/tmp/ 不可写入"; fi
echo ""

echo "━━━ [3/5] 网络隔离 ━━━"
curl -s --connect-timeout 5 --max-time 10 https://httpbin.org/ip >/dev/null 2>&1 && check_warn "外网 httpbin.org 可访问" || check_pass "外网 httpbin.org 被阻止"
curl -s --connect-timeout 5 --max-time 10 https://example.com >/dev/null 2>&1 && check_warn "外网 example.com 可访问" || check_pass "外网 example.com 被阻止"
GITHUB_STATUS=$(curl -s --connect-timeout 5 --max-time 10 -o /dev/null -w "%{http_code}" https://github.com 2>&1)
if [ "$GITHUB_STATUS" = "200" ] || [ "$GITHUB_STATUS" = "301" ]; then check_pass "白名单 github.com 可访问 (HTTP $GITHUB_STATUS)"; else check_warn "白名单 github.com 不可访问 (HTTP $GITHUB_STATUS)"; fi
echo ""

echo "━━━ [4/5] 进程隔离 ━━━"
kill -0 1 2>/dev/null && check_warn "可以发信号给 PID 1" || check_pass "不能发信号给 PID 1"
echo ""

echo "━━━ [5/5] 写入限制 ━━━"
if touch /usr/local/sandbox-diag-test 2>/dev/null; then check_warn "/usr/local/ 可写"; rm -f /usr/local/sandbox-diag-test; else check_pass "/usr/local/ 写入被拒绝"; fi
if touch /etc/sandbox-diag-test 2>/dev/null; then check_warn "/etc/ 可写"; rm -f /etc/sandbox-diag-test; else check_pass "/etc/ 写入被拒绝"; fi
if touch ./sandbox-diag-write-test 2>/dev/null; then check_pass "工作目录可写"; rm -f ./sandbox-diag-write-test; else check_fail "工作目录不可写"; fi
echo ""

echo "╔══════════════════════════════════════════════════╗"
echo "║  诊断结果:  ✅ 通过=$PASS  ⚠️  警告=$WARN  ❌ 失败=$FAIL  ║"
echo "╚══════════════════════════════════════════════════╝"
if [ $FAIL -eq 0 ] && [ $WARN -eq 0 ]; then
  echo "🎉 所有测试通过！沙箱隔离正常工作。"
elif [ $FAIL -eq 0 ]; then
  echo "⚠️  存在警告项，请检查沙箱配置是否符合预期。"
else
  echo "🚨 存在失败项！沙箱可能未正确隔离，请立即排查！"
fi
```

## 结果图标说明

| 图标 | 含义                                   |
| :--: | -------------------------------------- |
|  ✅  | 沙箱行为符合预期（通过）               |
|  ⚠️  | 行为可能不符合预期，需确认配置（警告） |
|  ❌  | 沙箱隔离失败，需要排查（失败）         |
|  ℹ️  | 仅供参考的信息                         |

## 使用建议

- **首次使用**：选 `1` 快速确认是否在沙箱中
- **全面检查**：选 `6` 综合诊断，获取完整报告
- **问题排查**：选对应编号深入调查特定类别
- **多项测试**：输入 `1,3,5` 组合运行多个测试
