以普通用户身份运行 Python Portio 脚本,无需 root 访问权限

use*_*881 4 linux ubuntu hardware sudo gpio

我知道以普通用户身份运行 root 脚本存在风险,但在这种情况下,我别无选择,我正在做的事情与机器有关。我有一台带有 GPIO 端口的小型板式计算机,我需要使用其中一个输出通过切换关闭线来重置设备。该部分工作正常,设备会按原样重置。

我的问题是我编写了一个 python 脚本来重置设备并且它可以工作,但是我必须以 root 或“sudo 程序名称,输入密码”的身份运行它。但是我需要它作为没有root权限的普通用户工作。换句话说,我添加了一个普通用户,无论如何我都无法运行脚本。

我曾尝试将用户添加到 sudoer 文件中,但这不起作用并且被完全忽略了。我已经更改了权限,设置了 SUID 位以及我能想到的所有其他内容,但它仍然要求输入 root 密码。唯一有效的是当我打开用户和组并将用户添加到 Sudo 组时,但随后用户可以访问我希望它没有的程序,因为它就像我的默认管理员用户一样。那不是我想要的。我想以某种方式将用户可以访问的内容限制为单个脚本或程序。

我让其他人建议我需要编写一个驱动程序,但我真的不知道该怎么做,也不知道他们的确切含义,通常他们不想详细说明。虽然我使用过 Linux,但我不认为自己是这方面的专家。任何人有任何想法如何做到这一点?

小智 5

这里找到了解决方案。

您想要做的是用 C 编写一个受信任的 I/O 启用程序,该程序只允许访问所需的端口,然后使用execvp()在调用者的地址空间执行您的脚本。然后,您将 setuid root 设置为已编译的 I/O 启用程序。

以下是一些改编自上述来源的示例代码(请务必使用您不介意写入的地址块):

#include <stdio.h>
#include <stdlib.h>
#include <sys/io.h>

#define DESIRED_PORT    0x300
#define NUM_BYTES       8

int main(int argc, char*argv[])
{
    if (argc < 2) {
        printf("Error: no target program specified.\n");
        exit(1);
    }

    if (ioperm(DESIRED_PORT, NUM_BYTES, 1)) {
        printf("Error: couldn't set port permissions.\n");
        exit(1);
    }

    // Set uid to current user's id before executing the script
    setgid(getgid());
    setuid(getuid());

    if (execvp(argv[1], &argv[1]) < 0) {
        printf("Error: target program execution error.\n");
        exit(1);
    }
}
Run Code Online (Sandbox Code Playgroud)

我们称之为io_enable.c,然后编译并setuid root:

$ gcc io_enable.c -o io_enable
$ sudo chown root io_enable
$ sudo chmod u+s io_enable
Run Code Online (Sandbox Code Playgroud)

接下来,我们可以使用以下 python 脚本对其进行测试:

$ gcc io_enable.c -o io_enable
$ sudo chown root io_enable
$ sudo chmod u+s io_enable
Run Code Online (Sandbox Code Playgroud)

我称它为 io_test.py 然后像这样运行它:

$ ./io_enable python io_test.py
Run Code Online (Sandbox Code Playgroud)

看起来它有效:

$ cat /tmp/portio.log
Wrote 0, read 0.
Wrote 1, read 1.
Wrote 2, read 2.
Wrote 3, read 3.
Wrote 4, read 4.
Wrote 5, read 5.
Wrote 6, read 6.
Wrote 7, read 7.
Wrote 8, read 8.
Wrote 9, read 9.
Run Code Online (Sandbox Code Playgroud)