如何配置Polkit规则:当指定文件存在时阻止系统关机?
这个方案思路挺清晰的,我帮你把各个环节的实现细节和注意事项梳理清楚,分三大部分来落地:
一、U盘插拔监控程序的实现
咱们的核心目标是通过监控U盘的插拔动作,维护一个锁文件的状态:
- U盘连接时:把它的唯一标识符(比如序列号)写入锁文件(推荐放在
/var/run/下,因为是临时文件目录,系统重启会自动清空) - U盘断开时:从锁文件中移除对应标识符,若文件为空则删除它
这里给你一个Python实现的示例(用pyudev库来监听系统设备事件,兼容性好):
import pyudev import os # 定义锁文件路径,建议放在/var/run下,系统重启自动清理 LOCK_FILE = '/var/run/usb_shutdown_lock' def update_lock_file(action, device_id): # 处理文件更新逻辑 if not os.path.exists(LOCK_FILE): if action == 'remove': return # 首次添加U盘,创建文件并写入标识符 with open(LOCK_FILE, 'w') as f: f.write(f"{device_id}\n") return # 读取现有内容,过滤掉当前要移除的标识符 with open(LOCK_FILE, 'r') as f: lines = [line.strip() for line in f if line.strip() != device_id] # 如果是添加动作,把标识符加回去 if action == 'add': lines.append(device_id) # 根据处理后的内容决定是写入还是删除文件 if lines: with open(LOCK_FILE, 'w') as f: f.write('\n'.join(lines) + '\n') else: os.remove(LOCK_FILE) # 初始化设备监控上下文 context = pyudev.Context() monitor = pyudev.Monitor.from_netlink(context) # 只监听块设备中的磁盘(U盘属于这类) monitor.filter_by(subsystem='block', device_type='disk') # 循环监听设备事件 for device in iter(monitor.poll, None): # 只处理有序列号的设备(排除内置磁盘) if 'ID_SERIAL_SHORT' in device: device_id = device['ID_SERIAL_SHORT'] if device.action == 'add': update_lock_file('add', device_id) elif device.action == 'remove': update_lock_file('remove', device_id)
二、Polkit规则配置
接下来要写Polkit规则,让系统在处理关机请求时检查锁文件的存在性:
- 在
/etc/polkit-1/rules.d/目录下创建规则文件,比如99-usb-shutdown.rules(文件名数字越大优先级越高) - 写入以下规则内容:
polkit.addRule(function(action, subject) { // 匹配所有关机、重启相关的动作 var shutdownActions = [ "org.freedesktop.login1.power-off", "org.freedesktop.login1.power-off-multiple-sessions", "org.freedesktop.login1.reboot", "org.freedesktop.login1.reboot-multiple-sessions" ]; if (shutdownActions.indexOf(action.id) !== -1) { // 检查锁文件是否存在 var lockFile = "/var/run/usb_shutdown_lock"; var fileExists = Polkit.File.exists(lockFile); if (fileExists) { // 锁文件存在,拒绝关机/重启请求 return polkit.Result.REJECT; } else { // 锁文件不存在,允许操作 return polkit.Result.ALLOW; } } });
三、额外注意事项和优化点
- 依赖安装:如果用上面的Python脚本,需要安装
pyudev库,Debian/Ubuntu系统可以用sudo apt install python3-pyudev,其他系统用pip install pyudev - 后台运行:把监控程序做成systemd守护进程,避免终端关闭就停止运行。创建
/etc/systemd/system/usb-shutdown-monitor.service文件:
然后执行[Unit] Description=USB Shutdown Monitor After=multi-user.target [Service] Type=simple User=root ExecStart=/usr/bin/python3 /path/to/your/monitor.py Restart=always [Install] WantedBy=multi-user.targetsudo systemctl daemon-reload && sudo systemctl enable --now usb-shutdown-monitor.service启用服务 - 权限问题:锁文件和Polkit规则文件都需要属于
root用户,确保普通用户无法篡改,规则文件权限设为644即可 - 测试验证:插U盘后尝试执行
systemctl poweroff,应该会被拒绝;拔掉U盘后再次尝试,就能正常关机了
内容的提问来源于stack exchange,提问作者AlmuHS
相关产品推荐
相关产品推荐

