放弃root权限

2024-04-28

我有一个以 root 身份启动的守护进程(因此它可以绑定到低端口)。出于安全原因,初始化后我非常希望它放弃 root 权限。

谁能指点我已知正确C 中的一段代码可以做到这一点?

我阅读了手册页,研究了不同应用程序中的各种实现,它们都是不同的,其中一些非常复杂。这是与安全相关的代码,我真的不想重复其他人所犯的相同错误。我正在寻找的是一个最佳实践,已知良好,可移植的库函数,我可以使用它,因为我知道它会得到正确的结果。这样的事情存在吗?

供参考:我以 root 身份开始;我需要更改为在不同的 uid 和 gid 下运行;我需要正确设置补充组;之后我不需要改回 root 权限。


为了删除所有权限(用户和组),您需要在用户之前删除组。鉴于userid and groupid包含您想要删除到的用户和组的 ID,并假设有效 ID 也是 root,这是通过调用来完成的setuid() http://linux.die.net/man/2/setuid and setgid() http://linux.die.net/man/2/setgid:

if (getuid() == 0) {
    /* process is running as root, drop privileges */
    if (setgid(groupid) != 0)
        fatal("setgid: Unable to drop group privileges: %s", strerror(errno));
    if (setuid(userid) != 0)
        fatal("setuid: Unable to drop user privileges: %S", strerror(errno));
}

如果你很偏执,你可以尝试恢复 root 权限,但这应该会失败。如果没有失败,您可以进行救助:

 if (setuid(0) != -1)
     fatal("ERROR: Managed to regain root privileges?");

另外,如果你仍然偏执,你可能想要seteuid() http://linux.die.net/man/2/seteuid and setegid() http://linux.die.net/man/2/setegid也是如此,但这不是必需的,因为如果进程由 root 拥有,setuid() 和 setgid() 已经设置了所有 ID。

补充组列表是一个问题,因为没有 POSIX 函数来设置补充组(有获取组() http://linux.die.net/man/2/getgroups,但没有 setgroups())。有 BSD 和 Linux 扩展设置组() http://linux.die.net/man/2/setgroups您可以使用它,这与您有关。

你也应该chdir("/") http://linux.die.net/man/2/chdir或任何其他目录,以便该进程不会保留在根拥有的目录中。

由于您的问题总体上是关于 Unix 的,因此这是非常通用的方法。请注意,在 Linux 中这不再是首选方法。在当前的 Linux 版本中,您应该设置CAP_NET_BIND_SERVICE能力 http://linux.die.net/man/7/capabilities可执行文件,并以普通用户身份运行它。不需要 root 访问权限。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

放弃root权限 的相关文章

随机推荐