1

尤其是在 Linux/POSIX 世界中,仅出于临时初始化目的(例如,读取 root 拥有的私钥文件,或打开一个小于 1024 的端口,或增加资源限制)需要一些 root 权限的守护进程,通常似乎遵循一种设计模式,他们使用setuid()/setresuid()setgid()/之类的函数调用来更改其凭据setresgid(),然后调用fork()以将实际程序作为其子程序运行。据说fork()-ing 是“以防万一”完成的,但是这样做的实际安全考虑是什么?

并且跟进这一点,当(除了setgroups(0, NULL),setresgid(GID_NOBODY, GID_NOBODY, GID_NOBODY)setresuid(UID_NOBODY, UID_NOBODY, UID_NOBODY))程序还主动限制Linux 功能时,这个原因是否仍然相关,通过在不再需要时立即删除所有功能,通过调用cap_set_proc()?

4

2 回答 2

1

安全方面的最佳实践建议有许多防线。

如果您确定您的守护进程没有缺陷,也没有它使用的库的任何功能,您可以让它以完全权限运行而没有任何风险。

但是,如果它只是由人类编写的,那么它很可能隐藏了一些可能的漏洞,这些漏洞可能允许攻击者让它执行任意代码。一个是在离今天不远的 SSL 库中发现的,不是说 Windows ......

这就是为什么您应该撤销处理外部输入不需要的所有特权的原因,因为这部分的风险更高。

这就是放弃特权的全部内容。fork 部分通常用于将守护进程拆分为一个高度特权的进程,该进程从不处理外部输出(安全...),并监视其他执行实际工作的低特权进程[es]。例如,它允许重新启动一个死亡或卡住的孩子,但外部输入数据永远不会被特权代码处理。

于 2016-02-26T08:57:18.033 回答
1

你有什么特别的例子吗?

通常,守护进程在“主”进程中分叉并保留 root 特权。这很有用,因为这意味着它可以重新加载配置并可能绑定到其他端口。分叉的孩子没有特权并处理实际的交通。

我的猜测是你看到了一个程序,它在父级中删除了 privs、分叉和退出。如果是这样,这是作为守护进程的一部分完成的。

于 2016-02-26T08:35:43.810 回答