Good day
背景:
我正在为 Linux 系统创建一个 OpenVPN 包装应用程序,该应用程序已接近完成。我遇到了一个小障碍。
OpenVPN 需要 root 访问权限才能修改路由表(添加和删除路由)。这就是事情变得有点模糊和混乱的地方。
希望通过扩展这个问题 https://stackoverflow.com/questions/5929220/get-root-privileges-to-my-qt-app,一些行业标准答案和解决方案可以分享。
文档:
因此,经过几个小时的搜索,我编制了一份获取 root 访问权限的可能方法列表,但似乎没有一个是官方的,也没有提供任何真正可靠的指导来获取此 SU 权限。
让我们考虑以下方法。
1. 使用 pkexec 和 polkits
请找官方freedesktop polkit 文档在这里 https://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html and here https://www.freedesktop.org/software/polkit/docs/latest/polkit-apps.html有关最佳实践的一些信息
网上找到了一些使用 pkexec 和 polkits 的教程
-here https://greyok.github.io/simple-polkit-tutorial.html,这帮助我创建了我的 polkit 文件。
-所以线程 https://stackoverflow.com/questions/5625870/how-to-launch-a-qprocess-with-root-rights- 还有一个可爱的小教程 https://q-a-assistant.info/life-arts/is-there-a-way-to-gain-superuser-access-from-a-qt-app/3365703对于 Qt 应用程序
简要解释一下(我的理解)pkexec
and polkits
:
polkit 由操作和规则组成(有关深入阅读和解释,请参阅文档)。它定义了应用程序的操作以及与其关联的规则。规则可以定义为属于特定组的用户,通过该操作查询规则,如果成功通过规则,则自动对用户进行身份验证(不会弹出密码提示),否则需要输入管理员权限密码
用于与 polkit 操作交互并对应用程序进行身份验证以获取 root 访问权限的应用程序。
这些需要添加一个动作/usr/share/polkit-1/actions/
and /usr/share/polkit-1/rules.d/
(除其他目录外,请参阅所有位置的文档)
这种方法似乎很好用(但需要更多的解释才能轻松理解,我认为)
注:有qt-polkit
可供使用的库,请参阅它们github 存储库 https://github.com/KDE/polkit-qt-1
对于简单的 TL;DR 版本,请参阅this https://askubuntu.com/a/525515/376524
我创建的 polkit 文件(请注意,这可能不正确,但它对我有用):
可以找到/添加它的位置(还有其他位置)
/usr/share/polkit-1/actions
策略工具包文件名:
com.myappname.something.policy //.policy
是必须的
Note:
com.myappname.something
被称为策略的命名空间(阅读文档,这个不会清楚)
政策工具包内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD polkit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/software/polkit/policyconfig-1.dtd">
<policyconfig>
<vendor>My App Name</vendor>
<vendor_url>http://myappurl.com/</vendor_url>
<action id="com.myappname.something.myaction-name">
<description>Run the polkit for My App which requires it for X usage</description>
<message>My App requires access to X, which requires root authentication, please let me have su access</message>
<icon_name>myappname</icon_name>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/myappname</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>
关于我的策略文件的注释(重要部分)
- 这只是一个示例,请参阅官方文档获取示例和说明:
-
<vendor>My App Name</vendor>
是应用程序名称,可以有空格
<action id="com.myappname.something.myaction-name">
此处任何操作名称。
笔记!
文件名->com.myappname.something.policy
和,
这action id
-> com.myappname.something.myaction-name
应该有相同的命名空间
图标名称应符合最新的 freedesktop 图标规范here https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html#example
TL;DR(或者不想):
图标位置是:
1. /home/yourusername/.icons (sometimes not there)
2. /home/yourusername/.local/share/icons
2. /usr/share/icons
只要它们符合尺寸并且是.png
,可以只传递文件名(省略格式)
打电话时pkexec <myappname>
,并且没有这些行(老实说,我不太确定他们的目的),会遇到类似这样的错误:
2017-12-19 12::58:24 Fatal: QXcbConnection: Could not connect to display ((null):0, (null))
Aborted (core dumped)
注意:保留key
相同,但是您可以并且可能应该更改exec.path
您的应用程序位置的关键。
政策工具包如何发挥作用?
简而言之,如果你回顾一下可爱的example https://greyok.github.io/simple-polkit-tutorial.html前面提到过(并跳过所有非常相似的文件名称),它就变得清晰了。
当一个人运行时:
pkexec <myappname>
这会调用本地身份验证代理以 root 身份运行应用程序(在我们的示例中)。
这是由actions
(上述政策套件)。此外,规则利用action id
执行附加查询等,可以在上面提供的示例中查看。
输入管理员密码后,根据输入默认值的“设置”(请参阅here https://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html), 我们有:
auth_admin_keep
与 auth_admin 类似,但授权会保留很短的一段时间(例如五分钟)。
因此,用户可以(在我的 OpenVPN 应用程序中)在接下来的 5 分钟内连接到 OpenVPN 连接,直到再次请求密码。
2. Sudo
(/etc/sudoers):
对于大多数需要 root 访问权限的用户来说,这似乎是首选方法,但不建议这样做:
例如在运行主应用程序之前通过调用 singleShot 检查 root 访问权限QProcess
带参数:
/bin/sh -c sudo -v
将导致退出代码为1
在各种 Linux 发行版中(因此导致我寻找替代方案)
3. setuid():
一个十分好的example https://forum.qt.io/post/153042可以在这里找到,不幸的是它似乎不适用于现代 Linux 发行版,因为它是一个很容易被利用的安全漏洞。
简而言之,这一过程需要:
chmod +x <executable>
并检查s
位在应用程序中使用设置getuid()
获取用户 ID 和getgid()
获取用户的组ID。
这些函数可以在 Linux 头文件中找到,定义如下:
<sys/types.h> // defines structs
<unistd.h> // defines methods
然而,这似乎不适用于现代 Linux 系统。这是使用 root 拥有的应用程序执行的输出s
位设置,以普通(非特权)用户身份运行:
2017-12-19 12::21:08 Fatal: FATAL: The application binary appears to be running setuid, this is a security hole. ((null):0, (null))
Aborted (core dumped)
告别,setuid()
4、其他方法:
如需进一步阅读,请参阅
对此有一个后续问题,请参阅这个QT论坛问题 https://forum.qt.io/topic/11729/admin-user-mode-adapt-gui-to-current-privileges
Problem:
以上可能仅包括获取root访问权限的可用方法的一小部分,但是考虑到某些应用程序在全球范围内使用,它们经常受到攻击或撬开甚至被破坏。
经过这项研究,它拓宽了我的知识面,但并没有给我一个推荐的万无一失的方法,而只是提示。
问题:
上述哪种方法在行业中是首选,即我什么时候应该使用其中一种而不是另一种(PAM、polkits 或简单 sudo),如果有其他方法可用,这些是首选方法吗?