65 lines
6.5 KiB
Markdown
65 lines
6.5 KiB
Markdown
# 23 · 实例内 AI 能力与权限限制核查(guest 对话记录)
|
||||
|
|
|
|||
|
|
- 日期:2026-09-11
|
|||
|
|
- 触发:用户提供 guest 账号在 AI 对话中遇到的 9 条"平台/环境限制"清单,要求判定**哪些正常、哪些不正常**
|
|||
|
|
- 结论一句话:**9 条中 1 条是真 bug(且是 P1,实例内 bash 工具被整体拒绝,已定位并已打补丁待重启生效)、3 条可优化、4 条属设计使然、1 条与平台无关**。
|
|||
|
|
- 状态:修复已编译(CI ✅),**待重启服务生效**;其余为建议项
|
|||
|
|
|
|||
|
|
> **TL;DR**|**结论**:guest 报的 9 条环境限制逐条判定:**1 条真 P1**(合成根缺 `/bin /sbin /lib` → dsh 沙箱探针失败 → **实例内 bash 工具被整体拒绝**,已修)+ 3 条可优化 + 4 条设计使然 + 1 条与平台无关。
|
|||
|
|
> **关键**:修复 = bwrap 补 3 个符号链接(不扩大可见面);另记一条安全点:统一 `DEEPSEEK_API_KEY` 注入实例 env 的外泄面。
|
|||
|
|
> **状态**:✅ 修复已上线(§五为建议项)
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、逐条判定
|
|||
|
|
|
|||
|
|
| # | 用户观察 | 判定 | 依据(实测) |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **1** | 🔴 沙箱后端缺失 → `sandbox mode "workspace-write" is requested but no sandbox backend is usable on this host; refusing to run the command unconfined`,**整个 bash 工具被拒**(2 轮) | 🔴 **真 bug(P1)—— 已修复待生效** | 见 §二 |
|
|||
|
|
| 2 | 只读根文件系统(`/etc`、DSH 安装目录、`ws` 上级 → Read-only file system,4 处) | ✅ **正常(设计)** | `spawnAsUser` 的 bwrap 参数:`--ro-bind /usr /lib64 /etc`,仅用户根目录 `--bind` 可写 → agent 写系统路径本就不该被允许 |
|
|||
|
|
| 3 | 无 sudo(`/etc/sudo.conf` 属主 uid 65534、sudo 未设 setuid) | ✅ **正常(且是安全特性)** | 宿主上 `/usr/bin/sudo` 实为 `---s--x--x`(setuid root)、`/etc/sudo.conf` 为 root:root;实例内失效是因为 **bwrap 默认 `no_new_privs`** → setuid 提权无效,且租户不在 sudoers |
|
|||
|
|
| 4 | 他人目录 `Permission denied`(`ls /var/lib/dshs/users/`) | ✅ **正常(隔离生效)** | `users/` 为 711(可穿越不可列),每用户目录 700;这正是多租户隔离,**探测被拒是预期结果** |
|
|||
|
|
| 5 | 工具缺失:`rg` `jq` **`ffmpeg`** MISSING | ⚠️ **可优化**(ffmpeg 影响视频业务) | 宿主实测三者皆缺;因 `/usr` 是 ro-bind,**宿主装好 → 实例立即可用**,无需改 bind/重启实例 |
|
|||
|
|
| 6 | 无浏览器(chromium/chrome/firefox 全 MISSING,无 playwright),抖音签名解不了 | ⚠️ **预期内,但影响抖音类任务** | 宿主确无浏览器;headless 浏览器需额外安装(体积/内存),而每实例有 **MemoryMax=512M** 上限 → 需评估 |
|
|||
|
|
| 7 | Python 过旧:3.6.8 + pip 9.0.3 | ⚠️ **可优化**(3.6 已 EOL,很多包装不了) | 宿主系统 python3 即 3.6.8(Alibaba Cloud Linux 8),实例经 ro-bind `/usr` 看到同一份 |
|
|||
|
|
| 8 | 无 DeepSeek 密钥:直接 curl → http=401(5 轮) | ⚠️ **半正常 + 一个安全点** | 实测实例进程 env **确实含 `DEEPSEEK_API_KEY`**(键名存在)→ 401 是因请求未带鉴权头。**但**:统一 key 注入实例意味着 **租户 agent 可读取并外泄平台 key**(P1 风险) |
|
|||
|
|
| 9 | `api.vvhan.com` → `curl: (6) Could not resolve host`(3 轮) | ✅ **与平台无关** | 公共 DNS 亦返回 **NXDOMAIN**(`vvhan.com` 本身可解析)→ 该子域不存在,第三方 API 地址已失效 |
|
|||
|
|
|
|||
|
|
## 二、第 1 条根因与修复(P1)
|
|||
|
|
|
|||
|
|
**现象**:实例内 bash 工具**完全不可用**(不是被拒某条命令,而是工具整体被拒)。
|
|||
|
|
|
|||
|
|
**根因链**:
|
|||
|
|
1. `dsh-sandbox-local` 在 Linux 的 runner 链 = **bwrap → Landlock**;两者探测都失败时抛 `SANDBOX_UNAVAILABLE`,上层 `dsh-sandbox` **拒绝无沙箱运行**("refusing to run the command unconfined")。
|
|||
|
|
2. **Landlock 不可用**:内核要求 ≥ 5.13,本机 Alibaba Cloud Linux 8 内核为 **4.19**。
|
|||
|
|
3. **bwrap 探针失败**:我们给实例构造的是**合成根**(只 bind `/usr`、`/lib64`、`/etc`、`/dev`、`/proc`、`/tmp` 与用户根),**缺 `/bin`、`/sbin`、`/lib`** → 探针要执行的 `/bin/sh` 之类 `execvp` 失败。
|
|||
|
|
> 对照实测:宿主 userns 正常(`kernel.unprivileged_userns_clone=1`、`user.max_namespaces=7322`),**嵌套 bwrap 本身可运行**(补上三个符号链接后 `NESTED-SHELL-OK`);因此问题不在"能不能嵌套",而在"根布局不标准"。
|
|||
|
|
|
|||
|
|
**修复(已实施,待重启服务生效)**:`src/supervisor/orchestrator.ts#spawnAsUser` 的 bwrap 参数补三个符号链接(**不扩大可见面**,仅三个链接):
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
'--symlink', 'usr/bin', '/bin',
|
|||
|
|
'--symlink', 'usr/sbin', '/sbin',
|
|||
|
|
'--symlink', 'usr/lib', '/lib',
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**验证**:`bash scripts/ci.sh`(typecheck + build + 单测)✅;ci 外还做了嵌套 bwrap 实测 ✅。生效需 `systemctl restart dshs`(会 drain 实例)。
|
|||
|
|
|
|||
|
|
## 三、建议项(按性价比)
|
|||
|
|
|
|||
|
|
| 项 | 建议 | 成本 | 影响 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| **ffmpeg** | 宿主 `dnf install ffmpeg`(或放一份静态构建到 `/usr/local/bin`) | 低(一次安装) | 解锁视频抽帧/转码(MCN 核心场景) |
|
|||
|
|
| **python** | 宿主装 python3.11/3.12(或引入 `uv` 供用户在 ws 内自建环境) | 中 | 解锁现代依赖(现 pip 9.0.3 基本装不了东西) |
|
|||
|
|
| **rg / jq** | 宿主 `dnf install ripgrep jq` | 极低 | 提升 agent 检索/JSON 处理效率与准确性 |
|
|||
|
|
| **headless 浏览器** | 评估 playwright + chromium(注意 512M 内存上限与体积) | 中高 | 抖音签名等重前端任务;**建议先只给需要的账号开** |
|
|||
|
|
| **统一 key 的外泄面** | 三选一:① per-user key ② 内网 LLM 代理网关(带记账/限流,实例只拿短期令牌)③ 接受现状并写进已知风险 | 中 | 现状下租户可用 agent 读出平台 key;属"设计层"取舍 |
|
|||
|
|
|
|||
|
|
## 四、不受影响/无需处理的项
|
|||
|
|
|
|||
|
|
- **第 2/3/4 条**:多租户隔离与该有的边界,**保持**。修复第 1 条后,实例内 bash 将恢复可用,但写权限仍受 `workspace-write` 限制(只在工作区内可写)、系统路径仍只读——这正是期望形态。
|
|||
|
|
- **第 9 条**:第三方域名失效,与平台无关(建议 agent 侧记录"该 API 已下线")。
|
|||
|
|
|
|||
|
|
## 五、红线遵守
|
|||
|
|
|
|||
|
|
- 核查全程**只读**(`ps` / `/proc/*/environ` 只取键名 / 公共 DNS 查询 / 官方包源码 grep),未读取任何密钥正文、未导出对话内容。
|
|||
|
|
- 修复只改编排器自身的 bwrap 参数(不碰官方 dsh 主程序与缓存,R2 满足)。
|