18 Polkit 身份验证框架 #
Polkit 是 Linux 图形桌面环境中使用的身份验证框架,用于对系统中的访问权限进行精细管理。一直以来,Linux 上的 root
用户(获得完全授权的管理员帐户)与系统中所有其他帐户和组之间存在严格的权限分离。这些非管理员帐户可能拥有某些额外的权限,例如通过 audio
组访问声音硬件。不过,这种权限是固定的,在特定的情况下或特定的时间内无法授予。
Polkit 不是完全切换到 root
用户(使用 sudo
之类的程序)来获取较高的特权,而是根据需要向用户或组授予特定的特权。此过程由配置文件控制,这些配置文件描述了需要在动态环境中授权的各个操作。
18.1 概念概述 #
Polkit 由多个组件构成。polkitd
是一个特权中心后台服务,根据现有的 Polkit 配置执行身份验证检查。支持 Polkit 的应用程序将特定身份验证请求转发到 polkitd
守护程序。在非特权用户环境中运行的 Polkit 身份验证代理负责代表 polkitd
守护程序显示身份验证请求,并提供用户以交互方式输入的身份凭证。
Polkit 操作表示受 Polkit 授权规则约束的单个活动。例如,重引导计算机的意图可以在 Polkit 中建模为单个操作。每个操作有一个唯一的标识符,对于重引导示例,该操作名为 org.freedesktop.login1.reboot
。
18.1.1 身份验证代理 #
当用户在功能齐全的桌面环境中启动图形会话时,身份验证代理通常会自动启动并在后台运行。当显示身份验证提示以响应请求授权执行特定操作的应用程序时,您会注意到这一点。无法轻松以文本模式或通过 SSH 使用 Polkit,因此本文档将重点介绍如何在图形会话环境中使用 Polkit。
18.1.2 Polkit 的配置 #
Polkit 的配置由操作和授权规则组成:
- 操作(文件扩展名为
*.policy
) 操作在
/usr/share/polkit-1/actions
下的 XML 文件中定义。每个文件可为特定的应用程序域定义一个或多个操作,而每个操作包含直观易懂的说明及其默认授权设置。尽管系统管理员可以编写自己的规则,但不能直接编辑这些默认策略文件。- 授权规则(文件扩展名为
*.rules
) 规则用 JavaScript 编程语言编写,位于两个位置:
/usr/share/polkit-1/rules.d
由系统软件包使用,/etc/polkit-1/rules.d
用于本地管理的配置。规则文件在默认操作授权设置的顶部包含较复杂的逻辑。例如,规则文件可以否决某个限制性操作,并允许特定的用户在未经授权的情况下使用该操作。
18.1.3 Polkit 实用程序 #
Polkit 提供了用于完成特定任务的实用程序(有关更多细节,另请参见这些实用程序的相应手册页):
pkaction
获取有关所定义操作的细节。有关更多信息,请参见第 18.3 节 “查询特权”。
pkcheck
检查某个进程是否有权执行特定的 Polkit 操作。
pkexec
允许程序根据 Polkit 授权设置以不同用户的身份执行。这与
su
或sudo
类似。pkttyagent
启动文本身份验证代理。如果桌面环境没有自己的身份验证代理,将使用此代理。
18.2 授权类型 #
每当支持 PolKit 的应用程序执行特权操作时,系统都会询问 PolKit 相应用户是否有权这样做。回答可以是 yes
、no
或 authentication needed
。对于后一种回答,系统会显示一个身份验证对话框,供用户输入所需的身份凭证。
18.2.1 隐式授权 #
如果给定的操作不存在专用的 Polkit JavaScript 规则,结果将取决于 Polkit 策略文件中为每个操作定义的隐式授权设置。授权分为三种类别:allow_active
、allow_inactive
和 allow_any
。allow_active
应用于活动会话中的用户。活动会话是文本模式控制台或图形用户环境中的本地登录。例如,当您切换到另一个控制台时(在这种情况下,相关的类别为 allow_inactive
),会话将变为非活动状态。allow_any
用于所有其他环境,例如,用于通过 SSH 或 VNC 登录的远程用户。为其中的每个类别分配了以下授权设置之一:
- no
永远不会为用户授予所需操作的授权。
- yes
始终为用户授予授权,且无需用户输入任何身份凭证。
- auth_self
用户需要输入自己的口令才能获得操作授权。
- auth_self_keep
与
auth_self
类似,但授权会缓存一定的时间,例如,如果同一个应用程序再次执行同一操作,则无需重新输入口令。- auth_admin
用户需要输入管理员 (
root
) 口令才能获得操作授权。- auth_admin_keep
与
auth_self_keep
类似,需要输入管理员 (root
) 口令。
18.2.2 SUSE 默认特权 #
到目前为止,所述 Polkit 策略文件中的隐式授权设置由相应应用程序的上游开发人员提供。我们将这些设置称为上游默认设置。这些上游默认设置不一定与 SUSE 系统上使用的默认值相同。SUSE Linux Enterprise Server 随附了一组可以覆盖上游默认设置的预定义特权。这些设置采用以下三种不同的模式(配置文件),每次只能有一种模式处于活动状态:
/etc/polkit-default-privs.easy
针对单用户桌面系统定制的授权设置,在此模式下,管理员也是有效的交互用户。此模式降低了安全性,但有利于改进用户体验。
/etc/polkit-default-privs.standard
适合大多数系统的平衡设置。
/etc/polkit-default-privs.restrictive
更保守的授权设置,可以减小可能的攻击面,但在某些方面会影响用户体验。
要切换处于活动状态的 Polkit 配置文件,请编辑 /etc/sysconfig/security
,并将 POLKIT_DEFAULT_PRIVS
的值调整为 easy
、standard
或 restrictive
。然后以 root
身份运行 set_polkit_default_privs
命令。
请不要修改上面列出的文件中的配置文件设置。要定义您自己的自定义 Polkit 设置,请使用 /etc/polkit-default-privs.local
。有关细节,请参见第 18.4.3 节 “修改 SUSE 默认特权”。
18.3 查询特权 #
要查询特权,请使用 Polkit 中包含的 pkaction
命令。
Polkit 随附了用于更改特权以及以另一用户身份执行命令的命令行工具(有关简要概览,请参见第 18.1.3 节 “Polkit 实用程序”)。每个现有策略都有一个唯一名称用于标识自身。使用 pkaction
命令可列出所有可用策略。有关更多信息,请参见man pkaction
。
要显示给定策略(例如 org.freedesktop.login1.reboot
)的所需授权,请如下所示使用 pkaction
:
>
pkaction -v --action-id=org.freedesktop.login1.reboot
org.freedesktop.login1.reboot: description: Reboot the system message: Authentication is required to allow rebooting the system vendor: The systemd Project vendor_url: http://www.freedesktop.org/wiki/Software/systemd icon: implicit any: auth_admin_keep implicit inactive: auth_admin_keep implicit active: yes
pkaction
限制
pkaction
仅考虑上游默认设置。它并不知道哪些 SUSE 默认特权会覆盖上游默认设置。因此,请谨慎解释此类输出。
18.4 修改 Polkit 配置 #
当您想要在不同的计算机上部署相同的策略集(例如,部署到特定团队的计算机)时,调整 Polkit 设置会很有用。自定义 Polkit 授权设置还可以强化特定操作的安全性,或通过减少在常用操作中提示输入口令的次数来改进用户体验。但是,不进行身份验证即授权执行某些 Polkit 操作可能会有安全隐患,因为这可能会为普通用户授予完全的 root
特权。仅当您确认降低 Polkit 身份验证要求不会破坏特定环境中的系统安全时,才可以这样做。
18.4.1 覆盖 Polkit 策略文件 #
可用的 Polkit 操作列表取决于您系统上安装的软件包。如需快速概览,请使用 pkaction
列出 Polkit 知道的所有操作。
对于本示例,我们将演示命令 gparted
(“GNOME 分区编辑器”)如何集成到 Polkit 中。
文件 /usr/share/polkit-1/actions/org.opensuse.policykit.gparted.policy
包含以下内容:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd"> <policyconfig> 1 <action id="org-opensuse-polkit-gparted"> 2 <message>Authentication is required to run the GParted Partition Editor</message> <icon_name>gparted</icon_name> <defaults> 3 <allow_any>auth_admin</allow_any> <allow_inactive>auth_admin</allow_inactive> < allow_active>auth_admin</allow_active> </defaults> <annotate 4 key="org.freedesktop.policykit.exec.path">/usr/sbin/gparted</annotate> <annotate 4 key="org.freedesktop.policykit.exec.allow_gui">true</annotate> </action> </policyconfig>
策略文件的根 XML 元素。 | |
此策略中唯一操作的定义的开头部分。 | |
在此处可以找到上述隐式授权设置。 | |
|
要添加您自己的策略,请创建采用上述结构的 .policy
文件,将相应的操作名称添加到 id
属性,并定义所需的覆盖隐式授权设置。
Polkit 授权框架以前称为 PolicyKit。在某些位置(例如上面的 XML 文档序言中),仍然使用了这个旧名称。
18.4.2 添加 JavaScript 授权规则 #
授权规则优先于隐式授权设置。要添加您自己的规则,请将您的文件存储在 /etc/polkit-1/rules.d/
下。
此目录中的文件名以两位数开头,后接短划线和描述性名称,并以 .rules
结尾。这些文件中的函数按照目录中文件名的字典顺序执行。例如,00-foo.rules
排序在 60-bar.rules
甚至 90-default-privs.rules
之前(因此会先执行)。
在规则文件中,脚本通常会检查要授权的操作 ID。例如,要允许 admin
组的任何成员执行 gparted
命令,请检查操作 ID org.opensuse.policykit.gparted
:
/* Allow users in admin group to run GParted without authentication */ polkit.addRule(function(action, subject) { if (action.id == "org.opensuse.policykit.gparted" && subject.isInGroup("admin")) { return polkit.Result.YES; } });
https://www.freedesktop.org/software/polkit/docs/latest/ref-api.html 上提供了 Polkit API 中各函数的所有类和方法的说明。
18.4.3 修改 SUSE 默认特权 #
如第 18.2.2 节 “SUSE 默认特权”中所述,SUSE 为上游开发人员定义的 Polkit 隐式授权设置随附了不同的覆盖配置文件。可以在 /etc/polkit-default-privs.local
中定义自定义特权。此处定义的特权始终优先于预定义的配置文件设置。要添加自定义特权设置,请执行以下操作:
编辑
/etc/polkit-default-privs.local
。要定义特权,请使用以下格式为每个操作添加一行:<action-id> <auth_any>:<auth_inactive>:<auth_active>
或者,如果所有三个类别接收相同的值,您也可以指定单个值:
<action-id> <auth_all>
例如:
org.freedesktop.color-manager.modify-profile auth_admin_keep
以
root
身份运行此工具,使更改生效:#
/sbin/set_polkit_default_privs
有关 SUSE Polkit 默认特权的完整文档,请参见 man polkit-default-privs
。
18.5 恢复 SUSE 默认特权 #
要恢复 SUSE 默认授权设置,请执行以下步骤:
按照第 18.2.2 节 “SUSE 默认特权”中所述选择所需的配置文件
从
/etc/polkit-default-privs.local
中去除所有覆盖项。运行
set_polkit_default_privs
以重新生成默认规则。