一、核心原理
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 仍可关机 | 命令行绕过 Polkit | Polkit 仅管 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