在Linux上为Qt应用程序获取root访问权的正确方法

KGC*_*beX 5 c++ linux qt sudo root

美好的一天

背景:

我正在为Linux系统创建一个OpenVPN包装器应用程序,该应用程序即将完成.我遇到了一些障碍.

OpenVPN需要root访问权来修改路由表(添加和删除路由).这是事情变得模糊和混乱的地方.

希望通过扩展这个问题,可以分享一些行业标准答案和解决方案.

文档:

因此,经过几个小时的搜索,我编制了一个获取root访问权限的可能方法列表,但是似乎没有一个是官方的,也没有任何真正可靠的指导来获得这个SU特权.

让我们考虑以下方法.


1.使用pkexec和polkits

在此处此处查找官方freedesktop polkit文档,以获取有关最佳实践的一些信息

使用pkexec和polkits在线发现了一些教程 - 这里,这有助于我创建我的polkit文件.- SO Thread - 和一个可爱的Qt应用程序小教程

简要解释(我的理解)关于pkexecpolkits:

  • polkits:

polkits由行动和规则组成(参见深入阅读和解释的文件).它定义了应用程序的操作以及与之关联的规则.规则可以定义为属于特定组的用户,其中操作查询规则,成功传递规则,用户自动进行身份验证(没有弹出密码提示),否则他们需要输入管理员密码

  • pkexec:

用于与polkit操作进行交互并对应用程序进行身份验证以获取root访问权限的应用程序.

这些需要在其中添加动作/usr/share/polkit-1/actions//usr/share/polkit-1/rules.d/(在其他目录中,请参阅所有位置的文档)

这种方法似乎很好用(但需要更多的解释才能轻松理解,imo)

注意:有qt-polkit可供使用的库,请参阅其 github存储库

对于简单的TL; DR版本,请参阅此内容

我创建的polkit文件(注意这可能不正确,但它对我有用):

可以找到/添加的位置(还有其他位置)

/usr/share/polkit-1/actions
Run Code Online (Sandbox Code Playgroud)

策略工具包文件名:com.myappname.something.policy // .policy是必需的

注意:

com.myappname.something
Run Code Online (Sandbox Code Playgroud)

被称为政策的命名空间(阅读文档,这将不清楚)

政策套件内容

<?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>
Run Code Online (Sandbox Code Playgroud)

关于我的政策文件的注释(重要的位)

  • 这只是一个示例,请参阅官方示例和说明的文档:
  • <vendor>My App Name</vendor> 是应用程序名称,它可以有空格
  • <action id="com.myappname.something.myaction-name"> 这里有任何动作名称.

  • 注意!文件名 - > com.myappname.something.policy和,action id- > com.myappname.something.myaction-name应该具有相同的命名空间

  • 图标名称应与此处的最新freedesktop图标规格一致

TL; DR(或不想):图标位置是:

 1. /home/yourusername/.icons (sometimes not there)
 2. /home/yourusername/.local/share/icons
 2. /usr/share/icons
Run Code Online (Sandbox Code Playgroud)

只要它们符合大小并且是a .png,你只能传递文件名(省略格式)

  • Very Important:

    <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/myappname</annotate>
    <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
    
    Run Code Online (Sandbox Code Playgroud)

在调用时pkexec <myappname>,并没有这些行(老实说,我不太确定它们的用途),会遇到类似这样的错误:

2017-12-19 12::58:24 Fatal: QXcbConnection: Could not connect to display  ((null):0, (null))

Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

注意:保持key不变,但是您可以并且可能应该将exec.path密钥更改为您的应用程序位置.

政策工具包如何运作?

简而言之,如果您查看前面提到的可爱示例(并跳过所有非常相似的文件名称),它就会变得清晰.

当一个人跑:

pkexec <myappname> 
Run Code Online (Sandbox Code Playgroud)

这会调用本地身份验证代理以root身份运行应用程序(在我们的示例中).

这由actions(上面提到的政策工具包)处理.此外,规则利用action id执行附加查询等,这些可以在上面提供的示例中查看.

输入管理员密码后,根据输入默认值的"设置"(参见此处),我们有:

auth_admin_keep
Run Code Online (Sandbox Code Playgroud)

与auth_admin一样,但授权保持一段时间(例如五分钟).

因此,用户可以(在我的OpenVPN应用程序中)在接下来的5分钟内连接到OpenVPN连接,直到再次请求密码.


2. Sudo(/ etc/sudoers):

这似乎是大多数需要root访问权限的用户的方法,但不建议:

例如,通过调用QProcess带参数的singleShot ,在运行主应用程序之前检查root访问权限:

/bin/sh -c sudo -v
Run Code Online (Sandbox Code Playgroud)

将导致1各种Linux发行版的退出代码(从而导致我搜索替代品)


3. setuid():

这里可以找到一个非常好的例子,不幸的是它似乎不适用于现代Linux发行版,因为它是一个很容易被利用的安全漏洞.

简而言之,该过程需要一个:

chmod +x <executable>
Run Code Online (Sandbox Code Playgroud)

并检查s在应用程序中设置的位getuid()用于获取用户ID并getgid()获取用户的组ID.

这些函数可以在以下定义的Linux头文件中找到:

<sys/types.h> // defines structs
<unistd.h>    // defines methods
Run Code Online (Sandbox Code Playgroud)

但是,这似乎不适用于现代Linux系统.以下是执行具有s位设置的root拥有的应用程序的输出,作为普通(非特权)用户运行:

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)
Run Code Online (Sandbox Code Playgroud)

永别了, setuid()


4.其他方法:

  • PAM

进一步阅读,见

关于此问题的后续问题,请参阅此QT论坛问题


问题:

上面可能只包括一小部分可用的方法来获取root访问权限,但考虑到某些应用程序是全局使用的,它们经常被攻击或撬开甚至受到攻击.

在做了这项研究之后,它扩大了我的知识,但没有给我一个推荐的确定方法,但只提示.

题:

上面哪种方法在工业上是首选的,即何时我应该使用另一种方法(PAM vs polkits vs simple sudo),如果有其他方法可用,这些首选吗?

小智 0

很好的研究。但想要添加新的情况:我认为更好的方法是创建新的 Unix 组并授予组成员对目标配置文件的写访问权限。您只需将用户添加到组中即可。并且只有用户才会改变路线。如果路线由特定程序定义。您可以只允许组成员运行该程序。