我有一个以root身份启动的守护进程(因此它可以绑定到低端口).在初始化之后,我非常希望出于安全原因让它删除root权限.
任何人都可以指出我在C中已知的正确代码片段会这样做吗?
我已经阅读了手册页,我已经在不同的应用程序中查看了它的各种实现,它们都是不同的,其中一些非常复杂.这是与安全相关的代码,我真的不想重新发明其他人犯的错误.我正在寻找的是一个最佳实践,已知良好的,可移植的库函数,我可以使用它知道它将正确.这样的事情存在吗?
供参考:我是从根本上开始的; 我需要改变以在不同的uid和gid下运行; 我需要正确设置补充组; 之后我不需要改回root权限.
Jul*_*ano 46
要删除所有权限(用户和组),您需要在用户之前删除该组.鉴于userid并groupid包含要删除的用户和组的ID,并假设有效ID也是root,这可以通过调用setuid()和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()和setegid(),但它不应该是必要的,因为如果进程由root拥有,setuid()和setgid()已经设置了所有ID.
补充组列表是一个问题,因为没有POSIX函数来设置补充组(有getgroups(),但没有setgroups()).您可以使用BSD和Linux扩展setgroups(),这会让您感到担忧.
您还应该chdir("/")或任何其他目录,以便该进程不会保留在根拥有的目录中.
由于你的问题一般是关于Unix的,所以这是非常通用的方法.请注意,在Linux中,这不再是首选方法.在当前的Linux版本中,您应该在可执行文件上设置CAP_NET_BIND_SERVICE功能,并以普通用户身份运行它.无需root访问权限.
| 归档时间: | 
 | 
| 查看次数: | 23197 次 | 
| 最近记录: |