polkit
來自 polkit 主頁:
- polkit 是一個應用程序級別的工具集,通過定義和審核權限規則,實現不同優先級進程間的通訊:控制決策集中在統一的框架之中,決定低優先級進程是否有權訪問高優先級進程。
Polkit 在系統層級進行權限控制,提供了一個低優先級進程和高優先級進程進行通訊的系統。和 sudo 等程序不同,Polkit 並沒有賦予進程完全的 root 權限,而是通過一個集中的策略系統進行更精細的授權。
Polkit 定義出一系列操作,例如運行 GParted, 並將用戶按照群組或用戶名進行劃分,例如 wheel 群組用戶。然後定義每個操作是否可以由某些用戶執行,執行操作前是否需要一些額外的確認,例如通過輸入密碼確認用戶是不是屬於某個群組。
安裝[編輯 | 編輯原始碼]
身份認證組件[編輯 | 編輯原始碼]
Polkit 的權限管理是基於用戶或群組進行配置,而身份認證組件的作用就是讓會話用戶證明自己是某個用戶或屬於某個群組。
圖形化環境Cinnamon、Deepin、GNOME、GNOME Flashback、KDE、LXDE、LXQt、MATE、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 中的可用操作是安裝的軟件包決定的。有些在多種桌面環境下都可以使用,文件命名為 (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_any、allow_inactive 和 allow_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; } });
跳過口令提示[編輯 | 編輯原始碼]
要模擬 sudo 的 NOPASSWD
選項,完全根據 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; } } } });
參閱[編輯 | 編輯原始碼]
- Polkit 手冊頁面
- 使用PolKit授權[失效鏈接 2021-11-15 ⓘ] (openSUSE Leap 15.2 安全指南)