Runsisi's Blog
不念过去 不畏将来
Polkit

接口定义 (Actions)

接口定义使用 XML 对操作进行了描述,并定义了默认的访问策略。

$ pkaction
com.mesonbuild.install.run
com.redhat.tuned.active_profile
com.redhat.tuned.auto_profile
org.freedesktop.NetworkManager.enable-disable-connectivity-check
org.freedesktop.NetworkManager.enable-disable-network
org.freedesktop.NetworkManager.enable-disable-statistics
org.freedesktop.NetworkManager.enable-disable-wifi
org.freedesktop.NetworkManager.enable-disable-wimax
org.freedesktop.NetworkManager.enable-disable-wwan
org.freedesktop.NetworkManager.network-control
org.freedesktop.NetworkManager.reload
org.freedesktop.NetworkManager.settings.modify.global-dns
org.freedesktop.NetworkManager.settings.modify.hostname
org.freedesktop.NetworkManager.settings.modify.own
org.freedesktop.NetworkManager.settings.modify.system
org.freedesktop.systemd1.manage-unit-files
org.freedesktop.systemd1.manage-units
org.freedesktop.systemd1.reload-daemon

$ pkaction -a org.freedesktop.systemd1.manage-units --verbose
org.freedesktop.systemd1.manage-units:
  description:       Manage system services or units
  message:           Authentication is required to manage system services or units.
  vendor:            The systemd Project
  vendor_url:        http://www.freedesktop.org/wiki/Software/systemd
  icon:
  implicit any:      auth_admin
  implicit inactive: auth_admin
  implicit active:   auth_admin_keep
$ sudo tree /usr/share/polkit-1/
/usr/share/polkit-1/
├── actions
│   ├── com.mesonbuild.install.policy
│   ├── com.redhat.tuned.policy
│   ├── org.fedoraproject.setroubleshootfixit.policy
│   ├── org.freedesktop.hostname1.policy
│   ├── org.freedesktop.import1.policy
│   ├── org.freedesktop.locale1.policy
│   ├── org.freedesktop.login1.policy
│   ├── org.freedesktop.machine1.policy
│   ├── org.freedesktop.NetworkManager.policy
│   ├── org.freedesktop.policykit.policy
│   ├── org.freedesktop.systemd1.policy
│   ├── org.freedesktop.timedate1.policy
│   ├── org.gnome.gconf.defaults.policy
│   └── org.x.xf86-video-intel.backlight-helper.policy
└── rules.d

策略 (Authorization rules)

策略定义了自定义的授权规则,即通过这些规则给普通用户开放原本需要特权用户权限才能访问的操作。

$ sudo tree /etc/polkit-1/
/etc/polkit-1/
├── localauthority
│   ├── 10-vendor.d
│   ├── 20-org.d
│   ├── 30-site.d
│   ├── 50-local.d
│   └── 90-mandatory.d
├── localauthority.conf.d
└── rules.d
    ├── 49-polkit-pkla-compat.rules
    └── 50-default.rules

需要注意的是,PolKit < 0.106 版本仅支持 .pkla KV 键值对形式的策略配置语法,而不支持新的基于 JavaScript 脚本的 .rules 策略配置语法。

但即使是 Ubuntu 20.04 仍然使用的是非常老的版本(即 Polkit 改名前的版本 PolicyKit):

$ pkexec --version
pkexec version 0.105

在 CentOS 上,polkit-pkla-compat 会兼容处理 .pkla 策略:

$ rpm -qi polkit-pkla-compat-0.1-4.el7.x86_64
Name        : polkit-pkla-compat
Version     : 0.1
Release     : 4.el7
Architecture: x86_64
Install Date: Sat 09 Jan 2016 09:20:42 PM CST
Group       : Unspecified
Size        : 82409
License     : LGPLv2+
Signature   : RSA/SHA256, Fri 04 Jul 2014 12:32:08 PM CST, Key ID 24c6a8a7f4a80eb5
Source RPM  : polkit-pkla-compat-0.1-4.el7.src.rpm
Build Date  : Tue 10 Jun 2014 06:08:34 AM CST
Build Host  : worker1.bsys.centos.org
Relocations : (not relocatable)
Packager    : CentOS BuildSystem <http://bugs.centos.org>
Vendor      : CentOS
URL         : https://fedorahosted.org/polkit-pkla-compat/
Summary     : Rules for polkit to add compatibility with pklocalauthority
Description :
A polkit JavaScript rule and associated helpers that mostly provide
compatibility with the .pkla file format supported in polkit <= 0.105 for users
of later polkit releases.

.pkla 策略的语法可以参考 pkla-check-authorization 命令的 man 手册页,而 .rules 策略实际上就是 js 代码:

$ sudo cat /etc/polkit-1/rules.d/10-units.rules
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.isInGroup("runsisi"))
    {
        polkit.log(action);
        polkit.log(subject);
        return polkit.Result.YES;
    }
})

在 CentOS 下,polkit.log 记录的日志在如下位置:

$ sudo cat /var/log/secure
polkitd[7470]: /etc/polkit-1/rules.d/10-units.rules:6: [Action id='org.freedesktop.systemd1.manage-units']
polkitd[7470]: /etc/polkit-1/rules.d/10-units.rules:7: [Subject pid=3474460 user='runsisi' groups=runsisi seat='' session='1260' local=false active=true]

需要注意的是,配置操作 systemd service 的策略时,仅 systemd v226+ 版本支持访问 unitverb 属性:

$ sudo cat /etc/polkit-1/rules.d/10-units.rules
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.user == "runsisi" &&
        subject.isInGroup("runsisi")) {
        if (action.lookup("unit") == "chronyd.service") {
            var verb = action.lookup("verb");
            if (verb == "start" || verb == "stop" || verb == "restart") {
                return polkit.Result.YES;
            }
        }
    }
})

参考资料

polkit Reference Manual

https://www.freedesktop.org/software/polkit/docs/latest/

PolicyKit Library Reference Manual

http://www.manpagez.com/html/PolicyKit/PolicyKit-0.9/model-theory-of-operation.php

Polkit

https://wiki.archlinux.org/index.php/Polkit

Authorization with PolKit

https://documentation.suse.com/sled/15-SP1/html/SLED-all/cha-security-policykit.html

Using PolicyKit to allow non-root users to start and stop a service

https://stackoverflow.com/questions/61480914/using-policykit-to-allow-non-root-users-to-start-and-stop-a-service

PolicyKit rules never come into effect

https://askubuntu.com/questions/536591/policykit-rules-never-come-into-effect

Polkit

https://lauri.xn--vsandi-pxa.com/cfgmgmt/polkit.html

Provide unit name and operation in manage-units polkit checks (v2)

https://github.com/systemd/systemd/pull/1159


最后修改于 2020-12-20