Cursor Remote SSH 终端沙箱启动失败修复教程:AppArmor 配置与 userns 权限
通过 Remote SSH 连接 Ubuntu 服务器使用 Cursor 时,如果遇到”Terminal sandbox could not start”错误提示,Agent 会回退为每条命令都需要手动确认的模式,严重影响开发效率。本文将详细分析这个问题的三层根因,并提供完整的修复方案和一键修复脚本。
教程概述
本教程将带你完成 Cursor Remote SSH 终端沙箱启动失败的排查与修复过程。内容包括:
- 问题描述:沙箱失败的现象和影响
- 原理分析:Cursor 沙箱的工作机制与 AppArmor 的关系
- 根因定位:三层原因的逐步排查过程
- 修复操作:安装配置包、修复 profile、配置 sysctl 的详细步骤
- 一键脚本:可直接执行的自动化修复脚本
- 验证检查:修复后的完整验证清单
环境信息
| 项目 | 配置 |
|---|---|
| 操作系统 | Ubuntu 24.04.4 LTS |
| 内核版本 | 6.17.0-14-generic |
| AppArmor parser | 4.0.1 |
| Cursor 连接方式 | Remote SSH |
一、问题描述
通过 Remote SSH 连接 Ubuntu 服务器使用 Cursor 时,每次连接均弹出以下提示:
1 | Terminal sandbox could not start. This may be caused by an AppArmor configuration |
沙箱无法启动后,Cursor Agent 回退为每次执行终端命令前都需要手动确认的模式,严重影响使用效率。
二、工作原理
Cursor 终端沙箱机制
Cursor Agent 在执行终端命令时,会通过 cursorsandbox 辅助程序创建一个隔离的沙箱环境。该沙箱依赖 Linux 的非特权用户命名空间(unprivileged user namespaces) 技术实现进程隔离。
沙箱涉及的两个关键二进制路径(由 AppArmor profile 通配符匹配):
| 组件 | 二进制路径 |
|---|---|
| Remote SSH 服务端 | /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox |
| Agent CLI | /home/*/.local/share/cursor-agent/versions/*/cursorsandbox |
三、系统状态排查
使用以下命令逐项检查系统状态:
1 | uname -r # 内核版本 |
排查结果汇总:
| 检查项 | 结果 | 判断 |
|---|---|---|
| 内核版本 | 6.17.0-14-generic | 满足 ≥ 6.2 要求 |
| AppArmor | 已加载,170 个 profile | 正常 |
| AppArmor parser 版本 | 4.0.1 | 用户态工具已更新到 4.0 |
kernel.apparmor_restrict_unprivileged_userns |
= 1 | 限制已开启 |
| 内核 userns 特性文件 | 不存在 | 内核不支持 profile 级 userns 声明 |
cursor-sandbox-apparmor 包 |
未安装 | 缺失 |
四、根因分析
问题由三层原因叠加导致:
第一层:缺少 AppArmor 配置文件
服务器端仅有 .cursor-server(Remote SSH 服务端),没有 Cursor 桌面版。桌面版自带 AppArmor profile,而 Remote SSH 模式下需要手动安装 cursor-sandbox-apparmor 包来提供。
第二层:AppArmor profile 缺少 network 权限
安装官方包后问题仍然存在。通过 dmesg 查看内核审计日志发现关键线索:
1 | apparmor="DENIED" operation="create" class="net" info="failed af match" |
cursorsandbox 进程在创建 Unix domain socket 时被 AppArmor 拒绝。官方提供的 profile 声明了 file 权限但遗漏了 network 权限。
第三层:userns 规则不适用
官方 profile 中预留了注释 ## Uncomment this on AppArmor 4.0 和 #userns, 行。但经检查,虽然 AppArmor parser 版本为 4.0.1,内核却不支持 AppArmor 的 userns feature(特性文件不存在)。直接取消注释 userns 会导致 profile 解析异常。正确做法是通过 sysctl 全局放开 userns 限制。
五、修复操作
步骤 1:安装 cursor-sandbox-apparmor 包
首先下载官方提供的 AppArmor 配置包:
1 | curl -fsSL https://downloads.cursor.com/lab/enterprise/cursor-sandbox-apparmor_0.4.0_all.deb \ |
命令解释:
curl -fsSL:静默下载,失败时显示错误,跟随重定向-o /tmp/...:保存到临时目录
安装时,包的 postinst 脚本会通过 debconf 询问是否添加 Cursor apt 仓库。根据需要选择不同方式:
方式 A:添加 apt 仓库(推荐)
1 | echo "cursor-sandbox-apparmor cursor-sandbox-apparmor/add-cursor-repo boolean true" \ |
命令解释:
debconf-set-selections:预设 debconf 交互问题的答案,避免安装过程中弹出交互界面DEBIAN_FRONTEND=noninteractive:强制非交互模式安装
添加仓库后,会创建以下文件:
| 文件 | 用途 |
|---|---|
/etc/apt/sources.list.d/cursor-apparmor.sources |
DEB822 格式的 apt 源(指向 https://downloads.cursor.com/aptrepo) |
/usr/share/keyrings/anysphere.gpg |
GPG 签名密钥 |
后续可通过 sudo apt update && sudo apt upgrade 自动获取包更新。
方式 B:不添加 apt 仓库
1 | echo "cursor-sandbox-apparmor cursor-sandbox-apparmor/add-cursor-repo boolean false" \ |
注意:如果不使用
DEBIAN_FRONTEND=noninteractive且在非交互终端(如 Cursor Agent 的沙箱终端)中安装,debconf 会因无法打开交互界面而卡住。此时需要手动 kill 进程后执行sudo dpkg --configure -a恢复。
安装完成后清理临时文件:
1 | rm -f /tmp/cursor-sandbox-apparmor.deb |
该包释放了 2 个文件:
| 文件路径 | 用途 |
|---|---|
/etc/apparmor.d/cursor-sandbox-remote |
AppArmor 配置文件,包含 cursor_sandbox_remote 和 cursor_sandbox_agent_cli 两个 profile |
/etc/sysctl.d/50-cursor-remote-userns.conf |
sysctl 配置(默认全部注释,不生效) |
步骤 2:启用 sysctl 非特权用户命名空间
编辑 /etc/sysctl.d/50-cursor-remote-userns.conf,只取消注释 userns 一行:
1 | #kernel.apparmor_restrict_unprivileged_unconfined=0 |
或使用命令直接修改:
1 | sudo sed -i 's/^#kernel.apparmor_restrict_unprivileged_userns=0$/kernel.apparmor_restrict_unprivileged_userns=0/' \ |
注意:
kernel.apparmor_restrict_unprivileged_unconfined=0必须保持注释。该参数控制的是 unconfined 进程的用户命名空间权限,与本问题无关,放开会扩大攻击面。
加载配置并验证:
1 | sudo sysctl --system |
预期输出:
1 | kernel.apparmor_restrict_unprivileged_userns = 0 |
如果系统中存在其他 sysctl 配置(如
/etc/sysctl.d/10-apparmor.conf)将该值设为 1,不必担心——sysctl 按文件名数字顺序加载,50-cursor-remote-userns.conf的优先级更高,会覆盖之前的设置。
此操作后重新连接 SSH,问题仍然存在——需要继续修复 profile。
步骤 3:修复 AppArmor profile 的 network 权限
通过 dmesg 审计日志确认 cursorsandbox 创建 Unix socket 被 DENIED 后,需要在 profile 中添加 network 权限。
编辑 /etc/apparmor.d/cursor-sandbox-remote,在两个 profile 中各添加 network,(替换掉 #userns, 注释):
修改前(官方原始版本):
1 | capability setpcap, |
修改后:
1 | capability setpcap, |
或使用命令直接修改(同时处理两个 profile):
1 | sudo sed -i '/## Uncomment this on AppArmor 4.0/{N;s/## Uncomment this on AppArmor 4.0\n #userns,/network,/}' \ |
重新加载 profile:
1 | sudo apparmor_parser -r /etc/apparmor.d/cursor-sandbox-remote |
命令解释:
apparmor_parser -r:重新加载指定的 AppArmor profile 文件,-r表示 replace(替换已有 profile)
修改后的完整 profile 文件内容:
1 | profile cursor_sandbox_remote /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox { |
六、一键修复脚本
将上述所有步骤合并为可直接执行的脚本(选择添加 apt 仓库的版本):
1 |
|
将脚本保存为 fix-cursor-sandbox.sh,然后执行:
1 | chmod +x fix-cursor-sandbox.sh |
七、最终验证
修复完成后,逐项检查确认所有改动生效:
1. 包安装状态
1 | dpkg -l cursor-sandbox-apparmor |
预期输出:
1 | ii cursor-sandbox-apparmor 0.4.0 all AppArmor profile for Cursor sandbox helper (Enterprise) |
状态 ii 表示已正确安装。
2. AppArmor profile 加载状态
1 | sudo aa-status | grep cursor |
预期输出:
1 | cursor_sandbox_agent_cli |
两个 profile 均已加载到 enforce 模式。
3. sysctl 参数
1 | sysctl kernel.apparmor_restrict_unprivileged_userns |
预期输出:
1 | kernel.apparmor_restrict_unprivileged_userns = 0 |
通过配置文件持久化,重启后仍然生效。
4. apt 仓库(如选择添加)
1 | cat /etc/apt/sources.list.d/cursor-apparmor.sources |
预期输出:
1 | Types: deb |
5. 内核审计日志
修复后重新连接 SSH,确认 dmesg 中不再出现 cursorsandbox 相关的 DENIED 记录:
1 | sudo dmesg | grep -i "cursorsandbox.*DENIED" |
预期:无输出。
6. 功能验证
重新通过 Remote SSH 连接后,Cursor 不再弹出沙箱启动失败提示,Agent 可在沙箱中自动执行终端命令,无需手动确认。
八、改动文件清单
| 文件路径 | 操作 | 来源 |
|---|---|---|
/etc/apparmor.d/cursor-sandbox-remote |
由包安装 + 手动修改(替换 #userns, 为 network,) |
cursor-sandbox-apparmor 0.4.0 |
/etc/sysctl.d/50-cursor-remote-userns.conf |
由包安装 + 取消注释 userns 行 |
cursor-sandbox-apparmor 0.4.0 |
/etc/apt/sources.list.d/cursor-apparmor.sources |
由包 postinst 脚本自动创建(可选) | cursor-sandbox-apparmor 0.4.0 |
/usr/share/keyrings/anysphere.gpg |
由包 postinst 脚本自动创建(可选) | cursor-sandbox-apparmor 0.4.0 |
九、安全影响评估
| 改动 | 影响范围 | 风险等级 |
|---|---|---|
apparmor_restrict_unprivileged_userns=0 |
允许 confined 进程创建用户命名空间 | 低:仅放开 confined 状态下的限制,unconfined 限制未改动 |
profile 添加 network 权限 |
仅对 cursorsandbox 二进制文件生效 |
极低:仅允许沙箱辅助程序创建网络套接字,不影响其他进程 |
十、回滚方法
如需完整还原所有改动:
1 | sudo apt remove cursor-sandbox-apparmor |
命令解释:
apt remove:删除配置文件(包括 AppArmor profile、sysctl 配置、apt 源)并卸载 AppArmor profilesysctl -w:立即恢复内核参数。重启后因配置文件已删除,参数回到系统默认值
如果只想移除 apt 仓库而保留其他修复:
1 | sudo rm -f /etc/apt/sources.list.d/cursor-apparmor.sources |
备注
- 包重装会覆盖手动修改:
cursor-sandbox-apparmor包的重装或升级会覆盖/etc/apparmor.d/cursor-sandbox-remote文件,导致手动添加的network,权限丢失。每次包更新后需检查并重新修复 profile,然后执行sudo apparmor_parser -r /etc/apparmor.d/cursor-sandbox-remote重新加载。 - 官方包缺陷:官方
cursor-sandbox-apparmor 0.4.0包的 profile 缺少network权限声明,导致在 AppArmor 4.0 + 高版本内核环境下无法正常工作。后续 Cursor 更新该包时可能会修复此问题。 - 非交互安装:在自动化环境或 Cursor Agent 终端中安装此包时,必须使用
DEBIAN_FRONTEND=noninteractive并预设 debconf 选项,否则 postinst 脚本会因无法打开交互界面而挂起。 - 路径变化:如果 Cursor 更新后
cursorsandbox二进制路径发生变化,可能需要重新检查 profile 中的路径通配符是否仍然匹配。