起因

  • 咱的 vps 上有一个时不时需要 root 权限执行特定命令的服务,但是咱又不想让这个服务以 root 权限运行。

Polkit 介绍

  • Polkit 是一套应用程序级别(application-level)的工具集,用来定义规则以及授权进程以其它用户的权限运行命令,分为操作(Actions)和认证规则(Authorization rules)两个部分。
  • 每个操作的政策由安装的软件包来设定,包含在一个 XML 格式的政策文件中,比如 /usr/share/polkit-1/actions/org.fedoraproject.FirewallD1.policy 就定义了 Firewalld 的默认政策(例如普通用户是否可以查询防火墙信息或者修改规则等)。注意对政策文件的修改可能会在包升级时被恢复或者覆盖,所以需要通过修改认证规则来达到自定义的效果。
  • 认证规则则放置在 /usr/share/polkit-1/rules.d 或者 /etc/polkit-1/rules.d,后缀名为 .rules,并使用 JavaScript 语法定义。
    这也是我们需要设置的地方也就是本文的重点。
  • 与 sudo 不同,polkit 并非赋予一个进程完整的 root 权限,而是通过一个策略系统(操作 + 认证规则)来进行更加精细的授权。
    比如当你运行 sudo hostnamectl set-hostname baka 时,系统会询问你密码,然后使用完整的 root 权限运行该命令。
    然而假如 hostnamectl 配置了相应的 polkit 政策,用户就可以直接运行 hostnamectl set-hostname baka,然后进程会读取相应的政策文件,并按照进程中被访问的操作来进行相应的处理,例如询问密码、直接拒绝,或者按照认证规则(Authorization rules)里的政策来根据用户名和用户组等信息进行判断。
  • 这里需要特别提一下 pkexec,它是 pokit 中包含的一条命令,与 sudo 一样,其作用也是以其它用户的权限执行命令,例如 pkexec --user root whoami。所以实际上,与 sudo 进行比较的应该是 pkexec 而不是 pokit,而 pokit 与 sudo 最主要的区别在于 pkexec 是通过 polkit 框架来实现的,也就是说可以通过配置与 pkexec 相关的认证规则来控制其行为。