polkit

出自 Arch Linux 中文维基

來自 polkit 主頁

polkit 是一個應用程式級別的工具集,通過定義和審核權限規則,實現不同優先級進程間的通訊:控制決策集中在統一的框架之中,決定低優先級進程是否有權訪問高優先級進程。

Polkit 在系統層級進行權限控制,提供了一個低優先級進程和高優先級進程進行通訊的系統。和 sudo 等程序不同,Polkit 並沒有賦予進程完全的 root 權限,而是通過一個集中的策略系統進行更精細的授權。

Polkit 定義出一系列操作,例如運行 GParted, 並將用户按照羣組或用户名進行劃分,例如 wheel 羣組用户。然後定義每個操作是否可以由某些用户執行,執行操作前是否需要一些額外的確認,例如通過輸入密碼確認用户是不是屬於某個羣組。

安裝[編輯 | 編輯原始碼]

安裝 polkit 包。

身份認證組件[編輯 | 編輯原始碼]

Polkit 的權限管理是基於用户或羣組進行配置,而身份認證組件的作用就是讓會話用户證明自己是某個用户或屬於某個羣組。

圖形化環境CinnamonDeepinGNOMEGNOME FlashbackKDELXDELXQtMATE、theShell 和 Xfce 各自都已有認證組件。請按照下列清單確認安裝了對應的身份認證組件,並且在登錄時 自動啟動 它。

其他桌面環境需要從下列實現中選用一種,polkit 軟件包提供了一個名為「pkttyagent」的基於文本方式的認證代理,作為後備方案。

  • lxqt-policykit,提供了 /usr/bin/lxqt-policykit-agent
  • lxsession,提供了 /usr/bin/lxpolkit
  • mate-polkit,提供了 /usr/lib/mate-polkit/polkit-mate-authentication-agent-1
  • polkit-efl-gitAUR,提供了 /usr/bin/polkit-efl-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-polkit-gitAUR,提供了 /usr/lib/xfce-polkit/xfce-polkit

配置[編輯 | 編輯原始碼]

警吿: 不要更改包文件的默認權限,因其可能在軟件包更新時被覆蓋。

Polkit 定義了兩種不同的內容:

  • 操作(Actions):在 /usr/share/polkit-1/actions 中定義,文件是 XML 格式,以 .policy 結尾。每個操作都有一個默認的權限集合(例如,你需要標識為管理員以使用 GParted 操作)。默認值是可以修改的,但是不應該通過修改操作文件實現。
  • 認證規則(Authorization rules):用 JavaScript 語法定義,文件以 .rules 結尾。有兩個目錄可放置規則文件:第三方的包將文件放置在 /usr/share/polkit-1/rules.d(儘管很少見),本地配置應該放置在 /etc/polkit-1/rules.d

Polkit 沒有取代系統已有的權限系統,而是在已有的羣組和管理員上進行管控。.rules 文件指定了一個用户的子集合,涉及到一個或多個操作文件中指定的操作,並規定這些用户可以執行哪些操作,需要滿足哪些限制。舉例來説,GParted 默認規則要求所有用户認證為管理員之後才能使用,可以用規則文件修改默認規則,規定某個用户不需要管理員身份認證就可以執行操作,也可以完全禁止某個用户使用 GParted。

注意: 如果用户不是通過 polkit 申請權限,比如通過命令行直接以 root 權限執行,這裏的禁止設定就無法起作用。所以應該用 polkit 給低權限用户更高的權限,而不應該用 polkit 限制高權限用户可以執行的操作。出於安全考慮,sudoers仍然是一種方法。

操作[編輯 | 編輯原始碼]

提示:要在圖形程序中顯示 Polikit 操作,可以安裝軟件包 polkit-explorer-gitAUR

polkit 中的可用操作是安裝的軟件包決定的。有些在多種桌面環境下都可以使用,文件命名為 (org.freedesktop.*),有些只能在特定桌面下使用,文件命名類似 (org.gnome.*),有些操作是單個程序特有的,命名類類似 (org.archlinux.pkexec.gparted.policy)pkaction 命令會顯示所有定義在 /usr/share/polkit-1/actions 操作。

通過下面幾個常用的操作類型,可以了解 polkit 到底能做什麼:

  • systemd-logind (org.freedesktop.login1.policy) 定義用户是否有權限進行關機、重啟、掛起、休眠等操作,即使有其它用户登錄時, polkit 也能管控某個用户的上述權限。
  • udisks (org.freedesktop.udisks2.policy) 定義文件系統掛載、加密磁盤打開等操作。
  • NetworkManager (org.freedesktop.NetworkManager.policy) 定義網絡打開和關閉, wifi 和流動網絡間的切換。

每個操作都定義在 .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_anyallow_inactiveallow_active。 Inactive 會話是遠程會話(例如 SSH、VNC 等。)active 會話是本地終端或圖形界面直接登錄機器的會話。allow_any 同時包含兩種會話。

對每個設置,都有如下選項:

  • no:不允許用户執行操作,不需要身份認證。
  • yes:用户可以不進行認證就執行操作。
  • auth_self:需要認證,但是用户可以只輸入自己的密碼,不需要屬於管理員。
  • auth_admin:需要用户認證為管理員。
  • auth_self_keep:和 auth_self 類似,認證狀態會保持一段時間。
  • auth_admin_keep:和 auth_admin 類似,認證狀態會保持一段時間。

這些設置是默認設置,只要沒有被配置規則覆蓋,適用於所有用户。

從上面的 Gparted 操作示例可以看出,不管用户是本地還是遠程,都需要先認證為管理員之後才能使用 GParted。

認證規則[編輯 | 編輯原始碼]

認證規則可以覆蓋默認的設置,個人使用的單個系統設置,應該放到 /etc/polkit-1/rules.d 目錄。

addRule() 方法可以增加一個函數,輸入操作和用户,只要進行權限檢查,這個函數就會被調用。所有函數會按添加順序依次調用,只要遇到第一個 return 返回。所以,要將規則放到其它規則前,需要將規則文件放到 /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.archlinux.pkexec.gparted" &&
        subject.isInGroup("admin")) {
        return polkit.Result.YES;
    }
});

上面函數檢查操作 ID (是否 org.archlinux.pkexec.gparted),再確認用户羣組(是否屬於 admin ),如果是,返回 "yes"。

管理員身份認證[編輯 | 編輯原始碼]

addAdminRule() 方法會添加一個在每個管理員認證時被執行的函數。此函數用來規定什麼用户可被視作系統管理員。函數的輸入是操作和用户,函數按順序依次執行,直到第一個 return。

系統默認的配置位於 50-default.rules,如果要修改這個值,需要把自定義的身份確認函數加到 50 之前,比如 40-default.rules

/etc/polkit-1/rules.d/50-default.rules
polkit.addAdminRule(function(action, subject) {
    return ["unix-group:wheel"];
});

需要配置的是 return 返回值:輸入誰的密碼之後就被認為是系統管理員。如果用户自己屬於管理員羣組,只需要輸入自己的密碼。如果只有 root 是管理員,需要輸入 root 密碼。

Arch 的默認設置中會將所有 wheel 羣組用户視作管理員,如果用下面的規則文件,那麼用户需要輸入 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"];
});

範例[編輯 | 編輯原始碼]

調試/輸出[編輯 | 編輯原始碼]

提示:需要先在配置文件/usr/lib/systemd/system/polkit.service中,刪除ExecStart命令中的--no-debug參數,polkit.log()才會生效。

下面的規則會輸出關於所請求的訪問的詳細信息。

/etc/polkit-1/rules.d/00-log-access.rules
polkit.addRule(function(action, subject) {
    polkit.log("action=" + action);
    polkit.log("subject=" + subject);
});

禁用掛起和休眠[編輯 | 編輯原始碼]

下面規則禁止所有用户通過 Polkit 進行掛起和休眠。

/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;
    }
});

跳過口令提示[編輯 | 編輯原始碼]

要模擬 sudoNOPASSWD 選項,完全根據 user/group 身份進行認證,可以在 /etc/polkit-1/rules.d/ 中創建規則進行設置。參考:示例.

全局規則[編輯 | 編輯原始碼]

創建下列文件:

/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 授權時,都不需要密碼。因此,請仔細選擇授權的羣組。

針對特定的動作設置[編輯 | 編輯原始碼]

創建文件:

/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.archlinux.pkexec.gparted" ||
	 action.id == "org.libvirt.unix.manage") &&
        subject.isInGroup("wheel"))
    {
        return polkit.Result.YES;
    }
});

示例中 action.id 選擇了 GParted 和 Libvirt,可以根據需要進行選擇。|| 操作符是「或」操作,&& 是「與」操作。

Udisks[編輯 | 編輯原始碼]

文件管理器在掛載磁盤時可能要求輸入密碼,或報吿 Not authorized 或類似錯誤,詳情請查看:Udisks#Configuration.

允許一般用户管理某個 systemd 單元[編輯 | 編輯原始碼]

通過檢查 polkit 策略中的某些值,可以指定某些用户和羣組管理 systemd 的權限。例如下面配置允許一般用户啟動和停止 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;
            }
        }
    }
});

參閱[編輯 | 編輯原始碼]