通过 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
2
Terminal sandbox could not start. This may be caused by an AppArmor configuration
on your Linux system (kernel 6.2+). See the documentation for how to resolve this.

沙箱无法启动后,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
2
3
4
5
6
uname -r                                                          # 内核版本
apparmor_parser --version # AppArmor parser 版本
sudo aa-status | head -5 # AppArmor 加载状态
sysctl kernel.apparmor_restrict_unprivileged_userns # userns 限制参数
ls /sys/kernel/security/apparmor/features/domain/userns # 内核 userns 特性
dpkg -l cursor-sandbox-apparmor # 包安装状态

排查结果汇总:

检查项 结果 判断
内核版本 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
2
3
apparmor="DENIED" operation="create" class="net" info="failed af match"
profile="cursor_sandbox_remote" comm="cursorsandbox"
family="unix" sock_type="dgram" protocol=0

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
2
curl -fsSL https://downloads.cursor.com/lab/enterprise/cursor-sandbox-apparmor_0.4.0_all.deb \
-o /tmp/cursor-sandbox-apparmor.deb

命令解释:

  • curl -fsSL:静默下载,失败时显示错误,跟随重定向
  • -o /tmp/...:保存到临时目录

安装时,包的 postinst 脚本会通过 debconf 询问是否添加 Cursor apt 仓库。根据需要选择不同方式:

方式 A:添加 apt 仓库(推荐)

1
2
3
echo "cursor-sandbox-apparmor cursor-sandbox-apparmor/add-cursor-repo boolean true" \
| sudo debconf-set-selections
sudo DEBIAN_FRONTEND=noninteractive apt install -y /tmp/cursor-sandbox-apparmor.deb

命令解释:

  • 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
2
3
echo "cursor-sandbox-apparmor cursor-sandbox-apparmor/add-cursor-repo boolean false" \
| sudo debconf-set-selections
sudo DEBIAN_FRONTEND=noninteractive apt install -y /tmp/cursor-sandbox-apparmor.deb

注意:如果不使用 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_remotecursor_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
2
3
  #kernel.apparmor_restrict_unprivileged_unconfined=0
- #kernel.apparmor_restrict_unprivileged_userns=0
+ kernel.apparmor_restrict_unprivileged_userns=0

或使用命令直接修改:

1
2
sudo sed -i 's/^#kernel.apparmor_restrict_unprivileged_userns=0$/kernel.apparmor_restrict_unprivileged_userns=0/' \
/etc/sysctl.d/50-cursor-remote-userns.conf

注意kernel.apparmor_restrict_unprivileged_unconfined=0 必须保持注释。该参数控制的是 unconfined 进程的用户命名空间权限,与本问题无关,放开会扩大攻击面。

加载配置并验证:

1
2
sudo sysctl --system
sysctl kernel.apparmor_restrict_unprivileged_userns

预期输出:

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
2
3
4
5
6
capability setpcap,

## Uncomment this on AppArmor 4.0
#userns,

mount,

修改后:

1
2
3
4
5
capability setpcap,

network,

mount,

或使用命令直接修改(同时处理两个 profile):

1
2
sudo sed -i '/## Uncomment this on AppArmor 4.0/{N;s/## Uncomment this on AppArmor 4.0\n  #userns,/network,/}' \
/etc/apparmor.d/cursor-sandbox-remote

重新加载 profile:

1
sudo apparmor_parser -r /etc/apparmor.d/cursor-sandbox-remote

命令解释:

  • apparmor_parser -r:重新加载指定的 AppArmor profile 文件,-r 表示 replace(替换已有 profile)

修改后的完整 profile 文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
profile cursor_sandbox_remote /home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox {
file,
/** ix,

capability sys_admin,
capability net_admin,
capability chown,
capability setuid,
capability setgid,
capability setpcap,

network,

mount,
remount,
umount,

/home/*/.cursor-server/bin/*/*/resources/helpers/cursorsandbox mr,
}

profile cursor_sandbox_agent_cli /home/*/.local/share/cursor-agent/versions/*/cursorsandbox {
file,
/** ix,

capability sys_admin,
capability net_admin,
capability chown,
capability setuid,
capability setgid,
capability setpcap,

network,

mount,
remount,
umount,

/home/*/.local/share/cursor-agent/versions/*/cursorsandbox mr,
}

六、一键修复脚本

将上述所有步骤合并为可直接执行的脚本(选择添加 apt 仓库的版本):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env bash
set -euo pipefail

# 1. 下载并安装 cursor-sandbox-apparmor 包(添加 apt 仓库)
curl -fsSL https://downloads.cursor.com/lab/enterprise/cursor-sandbox-apparmor_0.4.0_all.deb \
-o /tmp/cursor-sandbox-apparmor.deb
echo "cursor-sandbox-apparmor cursor-sandbox-apparmor/add-cursor-repo boolean true" \
| sudo debconf-set-selections
sudo DEBIAN_FRONTEND=noninteractive apt install -y /tmp/cursor-sandbox-apparmor.deb
rm -f /tmp/cursor-sandbox-apparmor.deb

# 2. 启用非特权用户命名空间
sudo sed -i 's/^#kernel.apparmor_restrict_unprivileged_userns=0$/kernel.apparmor_restrict_unprivileged_userns=0/' \
/etc/sysctl.d/50-cursor-remote-userns.conf
sudo sysctl --system >/dev/null 2>&1

# 3. 修复 AppArmor profile:替换 #userns 为 network
sudo sed -i '/## Uncomment this on AppArmor 4.0/{N;s/## Uncomment this on AppArmor 4.0\n #userns,/network,/}' \
/etc/apparmor.d/cursor-sandbox-remote
sudo apparmor_parser -r /etc/apparmor.d/cursor-sandbox-remote

echo "修复完成。请重新连接 Remote SSH 以验证。"

将脚本保存为 fix-cursor-sandbox.sh,然后执行:

1
2
chmod +x fix-cursor-sandbox.sh
./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
2
cursor_sandbox_agent_cli
cursor_sandbox_remote

两个 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
2
3
4
5
6
Types: deb
URIs: https://downloads.cursor.com/aptrepo
Suites: stable
Components: main
Architectures: amd64,arm64
Signed-By: /usr/share/keyrings/anysphere.gpg

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
2
sudo apt remove cursor-sandbox-apparmor
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=1

命令解释:

  • apt remove:删除配置文件(包括 AppArmor profile、sysctl 配置、apt 源)并卸载 AppArmor profile
  • sysctl -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 中的路径通配符是否仍然匹配。