# KDE 桌面禁用 GUI 电源操作(Polkit 规则)

4 阅读2分钟

一、核心原理

Polkit(PolicyKit)是 Linux 系统权限管理框架。当 KDE 中点击关机/重启按钮时,系统通过 D-Bus 向 systemd-logind 发送请求,Polkit 会介入检查预定义规则,决定是否放行。

本方案通过编写 JavaScript 规则文件,返回 polkit.Result.NO 直接拒绝所有电源相关请求。


二、快速部署

1. 创建规则文件

sudo nano /etc/polkit-1/rules.d/99-disable-all-power-actions.rules

2. 写入规则内容

polkit.addRule(function(action, subject) {
    var powerActions = [
        // 关机
        "org.freedesktop.login1.power-off",
        "org.freedesktop.login1.power-off-multiple-sessions",
        "org.freedesktop.login1.power-off-ignore",
        "org.freedesktop.login1.power-off-inhibit",
        "org.freedesktop.login1.power-off-active",
        "org.freedesktop.login1.power-off-force",
        // 重启
        "org.freedesktop.login1.reboot",
        "org.freedesktop.login1.reboot-multiple-sessions",
        "org.freedesktop.login1.reboot-ignore",
        "org.freedesktop.login1.reboot-inhibit",
        "org.freedesktop.login1.reboot-active",
        "org.freedesktop.login1.reboot-force",
        // 睡眠
        "org.freedesktop.login1.suspend",
        "org.freedesktop.login1.suspend-multiple-sessions",
        "org.freedesktop.login1.suspend-ignore",
        "org.freedesktop.login1.suspend-inhibit",
        "org.freedesktop.login1.suspend-active",
        // 休眠
        "org.freedesktop.login1.hibernate",
        "org.freedesktop.login1.hibernate-multiple-sessions",
        "org.freedesktop.login1.hibernate-ignore",
        "org.freedesktop.login1.hibernate-inhibit",
        "org.freedesktop.login1.hibernate-active",
        // 混合睡眠
        "org.freedesktop.login1.hybrid-sleep",
        "org.freedesktop.login1.hybrid-sleep-multiple-sessions",
        "org.freedesktop.login1.suspend-then-hibernate",
        // systemd 直接调用
        "org.freedesktop.systemd1.power-off",
        "org.freedesktop.systemd1.reboot",
        "org.freedesktop.systemd1.suspend",
        "org.freedesktop.systemd1.hibernate",
        "org.freedesktop.systemd1.hybrid-sleep"
    ];

    // 精确匹配
    if (powerActions.indexOf(action.id) !== -1) {
        return polkit.Result.NO;
    }

    // 模式匹配(防遗漏新变体)
    if (action.id.indexOf("power-off") !== -1 ||
        action.id.indexOf("reboot") !== -1 ||
        action.id.indexOf("suspend") !== -1 ||
        action.id.indexOf("hibernate") !== -1 ||
        action.id.indexOf("hybrid-sleep") !== -1 ||
        action.id.indexOf("ksmserver") !== -1) {
        return polkit.Result.NO;
    }
});

3. 设置权限并生效

sudo chmod 644 /etc/polkit-1/rules.d/99-disable-all-power-actions.rules
sudo systemctl restart polkit

💡 建议文件名使用 99- 前缀,确保最高加载优先级,覆盖其他可能允许电源操作的规则。


三、验证与测试

# 1. 确认文件存在
ls -la /etc/polkit-1/rules.d/99-disable-all-power-actions.rules

# 2. 检查服务状态
systemctl status polkit

# 3. 测试拦截效果(应被拒绝)
systemctl reboot

四、常见需求变体

▶ 只允许管理员组执行

if (powerActions.indexOf(action.id) !== -1) {
    if (subject.isInGroup("sudo") || subject.isInGroup("wheel")) {
        return polkit.Result.YES;
    }
    return polkit.Result.NO;
}

▶ 禁用特定用户

if (powerActions.indexOf(action.id) !== -1) {
    if (subject.user == "restricted_user") {
        return polkit.Result.NO;
    }
}

▶ 部分操作需认证

if (action.id == "org.freedesktop.login1.reboot") {
    return polkit.Result.AUTH_ADMIN;  // 重启需管理员密码
}
if (action.id.indexOf("power-off") !== -1) {
    return polkit.Result.NO;          // 关机直接禁止
}

五、故障排查

问题可能原因解决方案
规则未生效Polkit 未重载sudo systemctl restart polkit
菜单仍显示但点击无效正常现象,规则仅拦截请求如需隐藏菜单项需额外配置 KDE(本文不涉及)
root 仍可关机命令行绕过 PolkitPolkit 仅管 GUI/DBus,root 需用 systemd 配置或 shell 限制
与其他规则冲突加载顺序问题确保文件名 99- 开头,优先级最高

六、卸载规则

sudo rm /etc/polkit-1/rules.d/99-disable-all-power-actions.rules
sudo systemctl restart polkit

本文为我原创,未经授权禁止转载 | bilibili UID1319899187 | 掘金 ID1048290992076985