在现代Linux上永久性地放弃Root权限

13

启动后,我想让我的Linux程序放弃root权限并切换到非特权帐户。我在网上找到了各种示例,但没有符合我要求的规范,具体要求如下:

  1. 这是一个永久性的变更
  2. (有效)用户ID和组ID都应切换为非root
  3. 仅支持Linux(内核> 2.6.32)
  4. 不需要补充组

我发现的最佳方法是:

uid_t new_uid = ...;
gid_t new_gid = ...;

gid_t rgid, egid, sgid;
if (setresgid(new_gid, new_gid, new_gid) < 0)
{
    perror("setresgid");
    exit(EXIT_FAILURE);
}
if (getresgid(&rgid, &egid, &sgid) < 0)
{
    perror("getresgid");
    exit(EXIT_FAILURE);
}
if (rgid != new_gid || egid != new_gid || sgid != new_gid)
{
    printf("unexpected gid");
    exit(EXIT_FAILURE);
}

if (setgroups(0, 0) != 0)
{
    perror("setgroups");
    exit(EXIT_FAILURE);
}

uid_t ruid, euid, suid;
if (setresuid(new_uid, new_uid, new_uid) < 0)
{
    perror("setresuid");
    exit(EXIT_FAILURE);
}
if (getresuid(&ruid, &euid, &suid) < 0)
{
    perror("getresuid");
    exit(EXIT_FAILURE);
}
if (ruid != new_uid || euid != new_uid || suid != new_uid)
{
    printf("unexpected uid");
    exit(EXIT_FAILURE);
}

我可以将这个程序打包成exe文件,并通过以下方式演示uid和gid正确:

ps -eO user,uid,ruid,suid,group,gid,rgid,sgid

程序无法绑定到特权端口或操作大多数属于root的文件,所以这很好。

我还发现了captest程序(包含在libcap-ng-utils中),它验证进程是否没有任何意外的capabilities(7)

然而,由于安全是一个问题,我希望更有信心地确认我已经正确地删除了所有非必要权限。我该如何确定呢?

谢谢。


你有没有看过setuidgid? 它是D.J. Bernstein的Daemon Tools软件包的一部分。查看该程序的源代码可能会有所帮助。 - j.w.r
你可以查看 sudosu 的源代码,以了解如何实现这一点。 - Kevin
1个回答

1

啊,很好。虽然我由于许可证的原因无法直接使用它,但我将继续接受这个答案。 - bfallik-bamboom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接