守护程序如何使用具有无效 shell 的用户帐户运行?

守护程序如何使用具有无效 shell 的用户帐户运行?

我一直在谷歌上搜索试图找到这个问题的答案,并试图在心里解析初始化脚本以找到它完成的位置,但无济于事。

我刚刚做了ps一个随机的例子。我有一个如下所示的过程:

polkitd 1230 1 0 May07 ? 00:00:00 /usr/lib/polkit-1/polkitd --no-debug

查看我的 /etc/passwd,我看到:

polkitd:x:87:87:PolicyKit daemon owner:/var/lib/polkit:/bin/false

作为测试,我以 root 身份运行一个命令: # su - polkitd -c whoami 正如预期的那样,它没有返回任何输出,因为它具有 /bin/false 作为 shell。此外,# su - polkitd不会将我切换到 polkitd。为了确保我正确地执行了此操作,我使用普通用户帐户测试了这两种方法,并且它们都按预期工作。

那么,当您似乎根本无法让它手动运行任何内容时,如何才能让专用帐户(例如我的示例中的 polkitd)来运行进程呢?

答案1

root可以polkitd通过适当的系统调用,例如seteuid(2)可以证明

$ cat becomepolkit.c 
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>

int main(void)
{
    // ID obtained via `id polkitd` on a Centos7 system
    // other systems may vary
    seteuid(999);

    printf("look for %d in process list\n", getpid());

    sleep(99999);

    return 0;
}
$ make becomepolkit
cc     becomepolkit.c   -o becomepolkit
$ sudo ./becomepolkit &
[1] 10914
$ look for 10915 in process list

$ ps auwwx | grep '1091[5]'
polkitd  10915  0.0  0.0   4160   340 pts/0    S    22:46   0:00 ./becomepolkit
$ 

通常root通过 init 系统(例如systemd)或cron将启动一个进程为root,然后更改该进程的用户;发生这种情况不需要 shell 访问。您可以通过在strace或其他一些跟踪工具下运行该进程来观察任意进程的情况:

sudo strace -o blah ./becomepolkit
look for 10968 in process list
^C$ grep 999 blah
setresuid(-1, 999, -1)                  = 0
nanosleep({99999, 0}, {99997, 670178798}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
$ 

所以这里Linux实际上使用的是setresuid(2)调用但相同的区别,进程将显示polkitd在进程表中。

答案2

用户的登录 shell 是大多数登录程序在用户经过身份验证(通常通过输入用户名和密码)时调用的程序。登录程序包括login(用于文本控制台登录)、sshd(用于通过网络登录)、su(用于从其他帐户登录)等。

登录程序可以选择运行它们选择的任何内容。事实上,它们中的大多数运行用户的登录 shell,这是一个管理决策,而不是技术限制。一类不遵循此约定的登录程序是显示管理器,即以图形模式登录用户的程序:这些程序通常执行/bin/sh诸如/etc/X11/Xsession.

系统服务通常根本不被登录程序调用。它们由以管理权限运行的守护程序启动器自动调用;启动系统服务不需要任何身份验证。 (对于用户来说要求启动系统服务通常需要身份验证才能成为 root。)因此根本不涉及登录 shell,因此没有理由涉及它。

守护进程启动器(我用于此答案的术语)包括系统,启动-停止-守护进程,运行用户, ETC。

相关内容