polkit
来自 polkit 主页
- polkit 是一个应用程序级别的工具包,用于定义和处理策略,该策略允许非特权进程与特权进程对话:它是一个框架,用于集中决策过程,关于授予非特权应用程序访问特权操作的权限。
Polkit 用于控制系统范围的权限。它为非特权进程与特权进程通信提供了一种有组织的方式。与 sudo 等系统相比,它不会授予整个进程 root 权限,而是允许对集中式系统策略进行更精细的控制。
Polkit 的工作原理是划定不同的动作,例如运行 GParted,并通过组或名称划定用户,例如 wheel 组的成员。然后它定义了这些用户如何(如果允许)执行这些动作,例如通过输入密码来验证其组成员身份。
安装
认证代理
认证代理用于使会话用户证明他们确实是该用户(通过作为用户进行身份验证)或管理用户(通过作为管理员进行身份验证)。polkit 软件包包含 pkttyagent,这是一个文本认证代理,用作通用回退。
如果您正在使用图形环境,请确保已安装图形认证代理并在登录时自动启动(例如,通过 xinitrc)。
Cinnamon、Deepin、Hyprland、GNOME、GNOME Flashback、KDE、LXDE、LXQt、MATE 和 Xfce 已经有认证代理。在其他桌面环境中,您必须选择以下实现之一
- hyprpolkitagent,它提供
/usr/lib/hyprpolkitagent
- lxqt-policykit,它提供
/usr/bin/lxqt-policykit-agent
- lxsession 或 lxsession-gtk3,它提供
/usr/bin/lxpolkit
- mate-polkit,它提供
/usr/lib/mate-polkit/polkit-mate-authentication-agent-1
- polkit-gnome,它提供
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
- polkit-kde-agent,它提供
/usr/lib/polkit-kde-authentication-agent-1
- ts-polkitagentAUR,它提供
/usr/lib/ts-polkitagent
- xfce-polkitAUR 或 xfce-polkit-gitAUR,它提供
/usr/lib/xfce-polkit/xfce-polkit
- pantheon-polkit-agent,它提供
/usr/lib/policykit-1-pantheon/io.elementary.desktop.agent-polkit
pgrep -af polkit-gnome
。配置
Polkit 定义可以分为两种
- 动作 在位于
/usr/share/polkit-1/actions
中的 XML.policy
文件中定义。每个动作都附加了一组默认权限(例如,您需要以管理员身份验证才能使用 GParted 动作)。默认值可以被否决,但编辑动作文件不是正确的方法。 - 授权规则 在 JavaScript
.rules
文件中定义。它们可以在两个位置找到- 第三方软件包可以使用
/usr/share/polkit-1/rules.d
。 /etc/polkit-1/rules.d
用于本地配置。
- 第三方软件包可以使用
Polkit 在 Linux 中现有的权限系统(组成员身份、管理员状态)之上运行——它不会取代它们。.rules 文件指定用户子集,引用动作文件中指定的一个(或多个)动作,并确定这些用户可以在哪些限制下执行这些动作。例如,规则文件可以否决所有用户在使用 GParted 时以管理员身份进行身份验证的默认要求,从而确定某些特定用户不需要这样做。另一个例子:某些用户完全不允许使用 GParted。
动作
您可以通过 polkit 使用的动作将取决于您已安装的软件包。有些在多个桌面环境中使用(org.freedesktop.*),有些是 DE 特定的(org.gnome.*),有些是特定于单个程序的(org.gnome.gparted.policy)。命令 pkaction
列出 /usr/share/polkit-1/actions
中定义的所有动作,以供快速参考。
为了了解 polkit 可以做什么,这里有一些常用的动作组
- systemd-logind (org.freedesktop.login1.policy) 由 polkit 监管的动作包括关闭电源、重启、挂起和休眠系统,包括当其他用户可能仍在登录时。
- udisks (org.freedesktop.udisks2.policy) 由 polkit 监管的动作包括挂载文件系统和解锁加密设备。
- NetworkManager (org.freedesktop.NetworkManager.policy) 由 polkit 监管的动作包括打开和关闭网络、Wi-Fi 或移动宽带。
每个动作都在 .policy 文件中的 <action>
标签中定义。org.gnome.gparted.policy
包含单个动作,看起来像这样
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/software/polkit/policyconfig-1.dtd"> <policyconfig> <action id="org.gnome.gparted"> <message>Authentication is required to run the GParted Partition Editor</message> <icon_name>gparted</icon_name> <defaults> <allow_any>auth_admin</allow_any> <allow_inactive>auth_admin</allow_inactive> <allow_active>auth_admin</allow_active> </defaults> <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/gparted</annotate> <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate> </action> </policyconfig>
属性 id 是发送到 D-Bus 的实际命令,message 标签是需要身份验证时向用户的解释,icon_name 顾名思义。
defaults 标签是权限(或缺乏权限)所在的位置。它包含三个设置:allow_any、allow_inactive 和 allow_active。inactive 和 active 在这里都指的是本地控制台或显示器上的本地会话,而 allow_any 设置用于所有其他会话,包括远程会话(SSH、VNC 等)。
对于这些设置中的每一个,以下选项可用
- no:用户未被授权执行该动作。因此,不需要身份验证。
- yes:用户被授权执行该动作,无需任何身份验证。
- auth_self:需要身份验证,但用户不必是管理用户。
- auth_admin:需要以管理用户身份进行身份验证。
- auth_self_keep:与 auth_self 相同,但与 sudo 类似,授权持续几分钟。
- auth_admin_keep:与 auth_admin 相同,但与 sudo 类似,授权持续几分钟。
这些是默认设置,除非在以后的配置中被否决,否则对所有用户都有效。
有关详细说明,请参阅 polkit(8) 手册页。
从 GParted 动作可以看出,无论会话是活动的还是非活动的,用户都需要以管理员身份进行身份验证才能使用 GParted。
授权规则
否决默认设置的授权规则布局在如上所述的一组目录中。对于与单个系统的个人配置相关的所有目的,应仅使用 /etc/polkit-1/rules.d
。
addRule()
方法用于添加一个函数,该函数可以在每次执行动作和主体的授权检查时调用。函数按照添加的顺序调用,直到其中一个函数返回值。因此,要添加在其他规则之前处理的授权规则,请将其放在 /etc/polkit-1/rules.d
中的文件中,文件名在其他规则文件之前排序,例如 00-early-checks.rules
。
.rules 文件的布局非常不言自明
/* Allow users in admin group to run GParted without authentication */ polkit.addRule(function(action, subject) { if (action.id == "org.gnome.gparted" && subject.isInGroup("admin")) { return polkit.Result.YES; } });
在函数内部,我们检查指定的动作 ID (org.gnome.gparted) 和用户的组 (admin),然后返回一个值“yes”。
管理员身份
addAdminRule()
方法用于添加一个函数,该函数可以在需要管理员身份验证时调用。该函数用于指定哪些身份可以用于动作和主体标识的授权检查的管理员身份验证。添加的函数按照添加的顺序调用,直到其中一个函数返回值。
管理员身份的默认配置包含在文件 /usr/share/polkit-1/rules.d/50-default.rules
中,因此对该配置的任何更改都应通过将文件复制到 /etc/polkit-1/rules.d
目录并编辑该文件来进行
/etc/polkit-1/rules.d/50-default.rules
polkit.addAdminRule(function(action, subject) { return ["unix-group:wheel"]; });
唯一要编辑的部分(复制后)是函数的返回数组:当被要求以管理员身份验证时,用户应该以谁的身份进行身份验证?如果他们是指定为管理员的组的成员,他们只需要输入自己的密码。如果某个其他用户(例如 root)是唯一的管理员身份,他们将需要输入 root 密码。用户身份识别的格式与指定权限的格式相同。
Arch 默认设置是将 wheel 组的所有成员设置为管理员。像下面这样的规则将使 polkit 要求输入 root 密码而不是用户密码来进行管理员身份验证。
/etc/polkit-1/rules.d/49-rootpw_global.rules
/* Always authenticate Admins by prompting for the root * password, similar to the rootpw option in sudo */ polkit.addAdminRule(function(action, subject) { return ["unix-user:root"]; });
示例
允许用户使用 org.freedesktop.timedate1.set-timezone 动作
要允许名为 archie
的用户在没有身份验证的情况下使用 org.freedesktop.timedate1.set-timezone
动作,请以 root 身份创建以下 polkit 规则文件
/etc/polkit-1/rules.d/49-allow-archie-set-timezone.rules
polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.timedate1.set-timezone" && subject.user == "archie") { return polkit.Result.YES; } });
保存规则文件后,策略应立即生效。您可以使用 timedatectl
设置时区来测试它
[archie]$ timedatectl set-timezone America/New_York
如果操作完成时没有要求身份验证,则规则按预期工作。如果动作似乎不允许,请确保 /etc/polkit-1/rules.d/
中没有具有更高优先级(前缀编号较低)的冲突规则。
调试/日志
要使用 polkit.log()
函数启用日志记录,请从 /usr/lib/systemd/system/polkit.service
文件中的 ExecStart
命令中删除 --no-debug
标志。
以下规则记录有关任何请求访问的详细信息
/etc/polkit-1/rules.d/00-log-access.rules
polkit.addRule(function(action, subject) { polkit.log("action=" + action); polkit.log("subject=" + subject); });
要手动测试规则,请使用 pkcheck
:[1]
$ pkcheck -u -p $$ --enable-internal-agent -a action
禁用挂起和休眠
以下规则禁用所有用户的挂起和休眠。
/etc/polkit-1/rules.d/10-disable-suspend.rules
polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.login1.suspend" || action.id == "org.freedesktop.login1.suspend-multiple-sessions" || action.id == "org.freedesktop.login1.hibernate" || action.id == "org.freedesktop.login1.hibernate-multiple-sessions") { return polkit.Result.NO; } });
绕过密码提示
要实现类似于 sudo NOPASSWD
选项的功能,并仅基于用户/组身份获得授权,您可以在 /etc/polkit-1/rules.d/
中创建自定义规则。这允许您覆盖密码身份验证,可以仅针对特定动作或全局地。有关示例规则集,请参见[2]。
全局地
以 root 身份创建以下文件
/etc/polkit-1/rules.d/49-nopasswd_global.rules
/* Allow members of the wheel group to execute any actions * without password authentication, similar to "sudo NOPASSWD:" */ polkit.addRule(function(action, subject) { if (subject.isInGroup("wheel")) { return polkit.Result.YES; } });
将 wheel
替换为您喜欢的任何组。
这将导致通过 Polkit 为任何需要管理员权限的操作进行自动身份验证。 因此,请谨慎选择您授予此类权限的组。
还有 AUTH_ADMIN_KEEP
,它允许保持授权 5 分钟。 然而,授权是基于进程的,因此如果一个新进程在 5 分钟内请求授权,新进程仍然会再次请求密码。
对于特定操作
以 root 身份创建以下文件
/etc/polkit-1/rules.d/49-nopasswd_limited.rules
/* Allow members of the wheel group to execute the defined actions * without password authentication, similar to "sudo NOPASSWD:" */ polkit.addRule(function(action, subject) { if ((action.id == "org.gnome.gparted" || action.id == "org.libvirt.unix.manage") && subject.isInGroup("wheel")) { return polkit.Result.YES; } });
此处选择的 action.id
只是 GParted 和 Libvirt 的(工作)示例,但您可以将它们替换为您喜欢的任何其他存在的(自定义或由软件包提供)操作,并且您可以定义任何组而不是 wheel
。
||
运算符用于分隔操作(逻辑 OR),&&
表示逻辑 AND,并且必须保留为最后一个运算符。
Udisks
文件管理器在尝试挂载存储设备时可能会要求输入密码,或者产生未授权或类似的错误。 有关详细信息,请参阅 Udisks#配置。
允许普通用户管理单个 systemd 单元
通过检查传递给 polkit 策略检查的某些值,您可以授予特定用户或组管理特定单元的能力。 例如,您可能希望普通用户启动和停止 wpa_supplicant
/etc/polkit-1/rules.d/10-wifimanagement.rules
polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.systemd1.manage-units") { if (action.lookup("unit") == "wpa_supplicant.service") { var verb = action.lookup("verb"); if (verb == "start" || verb == "stop" || verb == "restart") { return polkit.Result.YES; } } } });
另请参阅
- Polkit 手册页
- Polkit 身份验证框架 (openSUSE Leap 安全指南)