# 沙盒

Agora 可以在你的设备本地运行轻量级 Alpine Linux 环境 — 无需网络连接。沙盒允许模型在隔离的 root 文件系统中安装软件包并执行命令。

!!! note "可用性"
    沙盒在启用 Shell 的构建版本中可用。从 **设置 → Shell → 沙盒管理** 进入。

## 工作原理

沙盒使用部署到设备应用私有存储的 Alpine Linux root 文件系统。基于 `apk` 的最小包管理器让你可以在该环境中安装软件，命令在基于 proot 的容器中执行。

这**不是**完整的虚拟机 — 而是一个共享主机内核的轻量级用户空间容器。它提供了足够的安全隔离，适合安全实验，同时保持较低的资源占用。

---

## VPN 干扰 — 重要

!!! danger "使用沙盒网络功能前请关闭 VPN"

    VPN 应用会干扰 proot 的 DNS 解析。原因如下：

    **根本原因 — PRoot 没有网络命名空间隔离。**

    PRoot 使用 `ptrace` 拦截系统调用并重定向文件路径，但它**不支持** `CLONE_NEWNET`（Linux 网络命名空间）。沙盒内的所有进程直接共享宿主 Android 系统的网络栈。没有虚拟网络接口、没有隔离的路由表、也没有独立的 DNS 配置。

    **Android VPN 如何在 proot 内部破坏 DNS：**

    1. Android VPN 应用使用 `VpnService` API，创建一个 **TUN 接口** — 一个虚拟网络设备，拦截**所有**设备流量，包括来自 proot 内部的流量
    2. 为防止 DNS 泄露到加密隧道之外，VPN 会**将所有端口 53（DNS）流量重定向**到自己的 DNS 服务器
    3. 在 proot 内部，当应用程序调用 `getaddrinfo()`（标准 libc DNS 解析器）时，请求经过 Android 系统解析器 — 而该解析器已被 VPN 拦截
    4. 在 Android 12+ 上，Google 重做了 DNS 解析器，使 proot 环境中的 `getaddrinfo()` 特别脆弱（[termux/proot#215](https://github.com/termux/proot/issues/215)）
    5. VPN 的 TUN 路由与系统解析器的 DNS 路径在 proot 内部产生冲突：解析器发出 DNS 查询，VPN TUN 拦截它，但响应无法通过 proot 的 `ptrace` 层返回

    **观察到的症状：**

    | 操作 | 结果 |
    |-----------|--------|
    | `ping 1.1.1.1` | ✅ 正常（直接 IP，无需 DNS） |
    | `ping google.com` | ❌ 失败 — "Temporary failure in name resolution" |
    | `apk add python3` | ❌ 失败 — 无法解析 `dl-cdn.alpinelinux.org` |
    | `curl https://example.com` | ❌ 失败 — 名称解析错误 |
    | `curl https://1.1.1.1` | ✅ 正常（IP 直连） |

    **解决方法：** 在沙盒中执行任何网络操作（安装软件包、`curl`、`wget` 等）之前，完全关闭 VPN。网络操作完成后可以重新开启 VPN。

    这是 proot 架构的根本限制 — 当 Android VPN 通过 TUN 接口覆盖系统 DNS 路由时，proot 无法虚拟化网络栈。

---

## 安装

### 安装 Root 文件系统

首次打开沙盒时，你会看到一个指示 rootfs 未安装的仪表板。点击 **安装** 下载并解压 Alpine root 文件系统。

!!! info "存储占用"
    基础 rootfs 大约占用 100–200 MB。安装的软件包会消耗额外空间。总磁盘使用量显示在仪表板上。

---

## 包管理

### 安装软件包

1. 在文本框中输入软件包名称（例如 `python3`）
2. 点击 **安装**
3. 在终端输出中查看安装进度

或者，点击任何**快速安装芯片**来安装常用软件包：

```
python3   git      curl      wget
openssh   nodejs   build-base   htop
```

### 已安装的包

在安装区域下方，所有已安装的软件包都会列出，包括：

- **名称** — Alpine 软件包名称
- **版本** — 已安装的版本
- **描述** — 简要说明（截断显示）

### 移除软件包

点击任何已安装软件包上的 :material-close: 图标即可移除。删除前会弹出确认对话框。

---

## 仪表板

当沙盒就绪时，仪表板显示：

- **磁盘使用量** — 进度条和数值显示（MB 或 GB）
- **已安装数量** — 软件包总数

---

## 终端输出

安装或移除软件包时，终端输出会显示在输入框下方的深色主题可滚动等宽文本区域中。输出会自动滚动跟随最新行。

用途：
- 监控安装进度
- 调试失败的软件包操作
- 查看软件包安装的文件

---

## 重置沙盒

底部的**危险区域**包含**重置沙盒**选项。这将完全删除 root 文件系统和所有已安装的软件包。

!!! danger "破坏性操作"
    重置沙盒会删除整个 Alpine 环境。之后你需要重新安装 rootfs 和所有软件包。重置前会弹出确认对话框以防止意外操作。
