我怎样才能放弃权限并清理 /var/run 中的 pid 文件?

我怎样才能放弃权限并清理 /var/run 中的 pid 文件?

我有一个名为 的守护进程foo。我的 init 脚本/etc/init.d/foo启动foo守护进程并将其 pidfile 存储在 中/var/run/foo.pid,这似乎是标准位置。因为/etc/init.d/foo必须以 root 身份运行,所以它可以毫无问题地在 中创建和删除 pidfile /var/run

守护进程foo实际上是/usr/sbin/foo由 init 脚本以 root 身份调用但随后立即将其权限放弃给非特权foo用户的程序。但是,我还希望此/usr/sbin/foo程序在因严重错误而退出时删除其 pidfile。但由于它已经放弃其权限,因此它不再具有从目录中删除文件的能力/var/run

我目前的方法是使用seteuid而不是setuid来放弃我的权限,然后在退出前立即重新提升权限,以便我可以正确地从 中删除 pidfile /var/run。但是,我遇到了很多问题,各种库和外部程序在使用不同的 euid 而不是 uid 调用时都会出现问题。

还有其他方法可以实现这一点吗?我想另一种选择是将我的 pidfile 放在 root 和foo用户都可以写入的目录中。但是我们所有其他 pidfile 都在 中,包括以非特权用户身份运行的其他程序的 pidfile,所以我也/var/run想将文件放在那里。foo.pid

除了使用之外还有其他方法可以做到这一点吗seteuid

答案1

不要将 PID 文件放入/var/run/foo.pid,而是将其放入/var/run/foo/foo.pid并归用户和组/var/run/foo所有。这样,您可以在退出之前删除 pid 文件,而不必提升您的权限级别。foofoo

但请注意,这是一种不良的安全做法,因为允许非特权应用程序破坏其文件将打开一个安全漏洞:想象一下您的应用程序被劫持(毕竟,如果不预料到应用程序可能会受到攻击,放弃特权的意义何在?)——现在,攻击者更新 pid 文件并将 sshd 的 pid 编号放在那里。现在,当系统范围的脚本(以 root 身份运行)尝试使用该 pid 文件停止您的应用程序时,它们将关闭 sshd。这只是一个例子,还有更多方法可以滥用您的系统。总之,应该创建 pid 文件删除权限和清理 pid 文件应该由系统范围的脚本执行。——Dmitry D. Khlebnikov

更好的想法是切换到不需要 PID 文件来管理服务的 init 系统(如 systemd 或 Upstart)。

答案2

您可以在运行守护进程之前派生一个新进程。父进程仍具有特权用户root。子进程将其权限放弃给foo用户。此进程执行真正的守护进程工作。

父进程将在分叉子进程后创建 PID 文件,并在子进程终止时将其删除。

答案3

查看我的 Ubuntu 系统时,我发现一些已安装的软件在 /var/run 下创建了由非 root 用户拥有的目录,正如 jcollie 所建议的那样。

另一个选择是让非 root 用户拥有 pidfile,并将该文件清零而不是删除它。

相关内容