解决星火应用商店无法在 Chrome OS 上安装应用
适用环境:ChromeOS 的 Linux 容器(Crostini),Debian 12/13。 星火应用商店版本:5.2.x(Electron 版) 现象:在星火商店里点"安装",进度条卡住、或弹不出授权框、或提示"没有找到提升权限的命令 pkexec"。
一、症状
在 ChromeOS 上用 Crostini 跑星火应用商店时,点击安装应用会出现:
- 能够下载,但是不能安装,一直转圈,甚至卡死;
- 终端里若手动跑会看到
找到提升权限命令:/usr/bin/pkexec; - 弹出
确认卸载的小窗口,但点了没窗口;
如果你在终端里手动敲一次:
pkexec id会看到类似报错:
Error creating textual authentication agent: Error opening current controlling terminal for the process (`/dev/tty'): No such device or address这就是星火商店装不了应用的根因。
二、解决方案:给 polkit 加一条免密放行规则
思路很简单:既然图形代理走不通,那就让 polkitd 在规则层直接放行,根本不去找代理。
ChromeOS 给 Crostini 预置的规则是同一种做法 —— 系统里其实已经有两条 garcon 规则:
$ ls /etc/polkit-1/rules.d/
50-garcon-packagekit.rules # 放行 PackageKit 装包
50-garcon-synaptic.rules # 放行 synaptic照着这个思路,加一条"对 sudo 组成员放行所有 polkit 鉴权"的规则即可。
2.1 创建规则文件
sudo tee /etc/polkit-1/rules.d/49-crostini-nopasswd.rules <<'EOF'
// Crostini: 对 sudo 组成员直接放行所有 polkit 鉴权
// 因为容器内没有图形座席,pkexec 的图形认证代理无法正常工作
// 此规则实现与免密 sudo 相同的效果,但作用在 polkit 层面
polkit.addRule(function(action, subject) {
if (subject.isInGroup("sudo")) {
return polkit.Result.YES;
}
});
EOF2.2 立即生效,无需重启
polkitd 会自动监测 rules.d 目录,文件写入后立刻生效,不用 systemctl reload,也不用重启。
2.3 验证
$ pkexec id
uid=0(root) gid=0(root) groups=0(root)返回 uid=0(root) 且退出码为 0,说明规则生效,pkexec 不再卡死。
然后回到星火商店重新点安装,应用就能正常装下了。
三、根因分析
3.1 星火商店硬编码了 pkexec
星火商店是 Electron 应用,其主程序 app.asar 内部写死了用 pkexec 来提权:
"/usr/bin/pkexec",
"/run/wrappers/bin/pkexec"
"[UpdateCenter] Running: pkexec shell-caller aptss ssupdate"也就是说,安装/更新应用时,星火商店会调用 pkexec 去执行 aptss(星火自己的 apt 包装器)。如果 pkexec 这一步走不通,整个安装流程就卡死。
3.2 为什么 pkexec 在 ChromeOS 上会卡死
pkexec 提权时,会去找 polkit 图形认证代理弹密码框。正常 Linux 桌面(GNOME/KDE)里,登录会话自带图形代理,所以能正常弹窗。
但 Crostini 容器不一样:
$ loginctl
SESSION UID USER SEAT LEADER CLASS TTY
1 1000 ktvheiheihei - 344 manager -
$ loginctl show-session 1 | grep -E 'Class|Type|Active'
Class=manager
Type=unspecified
Active=yes关键点:
SEAT是空的 —— 容器没有物理座席(键鼠屏);Class=manager—— 不是正常的user类会话;Type=unspecified—— 不是x11/wayland。
polkitd 在匹配认证代理时,需要把"发起提权的进程"和"注册的图形代理"对应到同一个会话。Crostini 这种"无座席、manager 类"的会话,polkitd 根本认不出图形代理,于是 pkexec 永远等不到那个弹窗,挂死;退而求其次走文本终端鉴权,又因为容器里 /dev/tty 不可用而报错。
Crostini 容器的会话基础设施不支持 polkit 图形授权流程,导致所有硬编码
pkexec的应用都会卡死。
四、附:为什么 ChromeOS 容器会"无座席"?
ChromeOS 把 Linux 容器(Crostini)当作一个"托管服务"运行,而非一个直接登录的桌面会话。容器内的 systemd-logind 创建的会话:
- 没有分配物理座席(
SEAT为空),因为键盘/鼠标/屏幕都由 ChromeOS 本体管理; - 会话类型是
manager(管理类)而非user(用户登录类); - 图形输出通过 Sommelier(Wayland 透传)桥接到 ChromeOS 桌面。
这套设计让 Linux 应用能在 ChromeOS 桌面上显示窗口,但绕过了传统 Linux 桌面那套"会话-座席-认证代理"的完整链路,于是 polkit 的图形鉴权成了无源之水。加一条规则直接放行,是最贴合 Crostini 架构的解法。
本文基于 ChromeOS M150 + Debian 13 (trixie) + 星火应用商店 5.2.1.0 (arm64) 实测整理。