特别是在Linux / POSIX世界中,需要一些root功能的守护程序仅用于临时初始化目的(例如,读取root拥有的私钥文件,或打开端口< 1024,或增加资源限制),通常似乎遵循设计模式,他们通过setuid()
/ setresuid()
和setgid()
/ setresgid()
等函数调用更改其凭据,然后调用fork()
将实际程序作为其子程序运行。据说fork()
已完成“以防万一”,但这样做的实际安全考虑是什么?
为了跟进这一点,这个原因在(除了setgroups(0, NULL)
,setresgid(GID_NOBODY, GID_NOBODY, GID_NOBODY)
和setresuid(UID_NOBODY, UID_NOBODY, UID_NOBODY)
)之外仍然是相关的,该程序还会主动限制 Linux功能,通过调用cap_set_proc()
,在不再需要时立即删除所有功能?
答案 0 :(得分:1)
你有什么特别的例子吗?
通常,守护程序在“主”进程中分叉并保留root权限。这很有用,因为这意味着它可以例如重新加载配置并可能绑定到其他端口。分叉的孩子没有特权,处理实际的交通。
我的猜测是你看到一个程序在父母中删除了私人,分叉和退出。如果是这样,这是作为守护进程的一部分完成的。
答案 1 :(得分:1)
安全方面的最佳做法建议使用许多防线。
如果您确定您的守护程序没有任何缺陷,也没有它使用的库的任何功能,您可以让它以完全权限运行而不会有任何风险。
但如果它只是由一个人写的,那么很可能隐藏了一些可能让攻击者让它执行任意代码的漏洞。一个是在SSL库中发现的,而不是今天,而不是Windows ...
这就是为什么你应该撤销处理外部输入所不需要的所有权限的原因,因为该部分的风险更高。
这就是删除特权的全部。 fork部分通常用于将守护程序拆分为一个高权限进程,该进程从不处理外部输出(安全性...)并监视执行实际工作的其他低权限进程[es]。例如,它允许重新启动死亡或卡住的子项,但外部输入数据永远不会被特权代码处理。