在现代Linux上永久删除根权限

在现代Linux上永久删除根权限,linux,security,root,Linux,Security,Root,启动后,我希望我的Linux程序放弃根权限并切换到非特权帐户。我在网上找到了各种各样的例子,但没有一个符合我的要求,特别是: 这是永久性的下降 (e)uid和(e)gid都应切换到非root 仅支持Linux(内核>2.6.32) 不需要补充组 我发现最好的方法是: uid_t new_uid = ...; gid_t new_gid = ...; gid_t rgid, egid, sgid; if (setresgid(new_gid, new_gid, new_gid) < 0)

启动后,我希望我的Linux程序放弃根权限并切换到非特权帐户。我在网上找到了各种各样的例子,但没有一个符合我的要求,特别是:

  • 这是永久性的下降
  • (e)uid和(e)gid都应切换到非root
  • 仅支持Linux(内核>2.6.32)
  • 不需要补充组
  • 我发现最好的方法是:

    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);
    }
    
    该程序不能绑定到特权端口或操作大多数root所有的文件,所以这一切都很好

    我还发现了一个程序(包含在libcap ng utils中),它可以验证进程没有任何意外的错误

    然而,由于安全性是一个问题,我想更确信我已经正确地放弃了所有非必要的特权。我怎么能确定

    谢谢。

    D.J.Bernstein在他的“setuidgid”代码中实现了“规范”方法,该代码最初用于他的QMail程序,现在包含在“daemontools”中


    GNU coreutils中使用的实际代码基于DJB对过程的描述,其代码在此处可见

    您签出了吗?这是我们的一部分。查看此程序的源代码可能会有所帮助。您可以查看
    sudo
    su
    源代码,了解如何实现此目的。啊,太酷了。我将继续接受这个答案,尽管由于许可证的原因我不能直接使用它。
    ps -eO user,uid,ruid,suid,group,gid,rgid,sgid