'Nobody'用户的目的是什么?

在我阅读完列出所有人类用户后,我注意到我的Ubuntu系统中有一个名为'nobody'的用户账户。
此外,我还注意到我可以使用以下命令和我的密码从终端登录到这个账户:
sudo su nobody

su nobody

这完全不影响我,但我想知道这个用户的目的是什么?它是在新安装的Ubuntu上默认创建的,还是通过安装特定软件包而创建的?

11请注意,当您使用密码登录时,您是在进行sudo步骤时使用密码,而不是使用nobody账户的密码(而且之所以可以工作是因为超级用户可以su到任何人而无需输入他们的密码(尽管如下所述,我相信至少在RH衍生版本上,如果nobody的shell设置为/sbin/nologin,即使使用超级用户(也称为root)也无法登录)。 - Foon
2这是默认情况(18.04+?)。sudo su nobody 返回“此帐户当前无法使用”,因为用户“nobody”的shell已设置为/usr/sbin/nologingetent passwd nobody)。 - Pablo Bianchi
@sarnold - 请看一下我对你所提到的答案的评论。这个答案相当糟糕,因为它没有逻辑推理或引用来源。而且,它与我所了解的关于nobody账户和NFS工作原理的所有知识背道而驰:使用root_squash时,它会在远程系统上将root映射为nobody。这与这个答案所陈述的完全相反。 - vidarlo
发布文字图片会导致严重的无障碍问题,尤其是对于盲人而言。但也会影响其他人。 - ctrl-alt-delor
我刚刚遇到了一个用户使用案例:在控制我的计算机上的程序的网络界面上,我可以指定一个命令行来处理一些数据(通常是grepsed等)。我不希望这个功能成为一个太大的安全风险(比如将"文本处理"命令指定为rm *)... 以"nobody"用户身份运行grepsed可以消除这个风险。 - Martin Rosenau
6个回答

它负责运行不需要特殊权限的事务。通常保留给容易受攻击的服务(如httpd等),以便在它们被黑客攻击时,对系统的其他部分造成最小的损害。

与作为真实用户运行某个服务相比,如果该服务被攻陷(Web服务器有时会被利用来运行任意代码),它将作为该用户运行并具有该用户的所有访问权限。在大多数情况下,这和获得root权限一样糟糕。

您可以在Ubuntu维基上阅读更多关于nobody用户的信息:

回答你的后续问题:
为什么我不能用“su nobody”访问这个账户?
通过“sudo grep nobody /etc/shadow”,你会发现nobody没有密码,所以你不能在没有账户密码的情况下使用“su”。最干净的方式是使用“sudo su nobody”。这将使你进入一个相当荒凉的“sh” shell。
你能给出一个具体的例子来说明何时需要使用这个账户吗?
当程序的操作不需要权限时。这在没有任何磁盘活动的情况下尤为明显。
一个真实的例子是我的电脑和服务器上运行的memcached(一个键值内存缓存/数据库/其他东西),它在nobody账户下运行。为什么呢?因为它根本不需要任何权限,给它一个有写文件权限的账户只会增加不必要的风险。

如果你能解释清楚的话,还有两件事情:1)为什么我无法使用“su nobody”访问这个账户?2)你能给出一个具体的例子来说明何时需要使用这个账户吗? - Radu Rădeanu
@RaduRădeanu 1) 我猜这是因为它没有设置密码,当你作为普通用户使用su命令时,你必须输入目标用户的密码。尝试从root shell中使用sudo -i然后su nobody(这不需要密码)。 - user
2网络文件系统将root映射为nobody,因此本地的root无法像远程的root那样访问所有内容。 - Sylwester
@RaduRădeanu 我已经编辑好了,回答了你的问题。 - Oli
@Demizey, @Braiam, @Githlar 你们测试过这个命令了吗:sudo -u nobody -i - Radu Rădeanu
啊,糟糕,它在一些系统上可以工作,但是它是非标准的。旧的那个也不行,-i 需要用一个 shell 来替换。 - remmy
@Demizey 老的那个完美运作。看看原帖中的图片。 - Radu Rădeanu
@RaduRădeanu 对我和很多其他人都不起作用,因为通常没有人没有默认的shell。 - remmy
@Demizey 在Ubuntu中,因为我们在这里讨论的是Ubuntu,nobody用户有并且一直有一个默认的shell - 就是/bin/sh,正如Oli在他的回答中所说。 - Radu Rădeanu
@Oli 现在你在回答中自相矛盾:最干净的方法是使用 sudo -u nobody /bin/bash,这将使你进入一个相当荒凉的 sh shell。在我看来,如果使用 /bin/bash,那么你会进入一个 bash shell。此外,当我运行 sudo -u nobody /bin/bash 时,会出现错误 bash: /home/radu/.bash_aliases: Permission denied。所以,我认为这不是最干净的方式。 - Radu Rădeanu
1@RaduRădeanu 请注意编辑历史。当我测试原始命令(而不是现在的内容)时,最初我进入了一个破折号(/bin/sh)的shell,但现在无法复制这个情况。你的原始编辑是正确的。并不是我改变了它。 - Oli
@Oli 但是你已经接受了它 :D 如果你觉得有必要,你也可以清理掉所有这些无用的评论。 - Radu Rădeanu
重要提示:用户“nobody”绝不能拥有任何文件,也不能对任何文件具有写入权限。如果find / -user nobodyfind / -group nogroup返回任何文件,则表示您的系统存在漏洞。 - Born2Smile
@Born2Smile 为什么?而且容易受到什么伤害?怎么会这样呢? - Oli
@Oli,'nobody'-user的整个理念是从中运行易受攻击(或潜在易受攻击)的进程。因此,当这样的进程被黑客攻击时,黑客将以'nobody'的身份访问系统。如果此时'nobody'拥有任何文件或文件夹,黑客将被允许编辑这些文件和文件夹,从而危及依赖于这些文件的任何系统。一个可怕的例子是npm(node.js软件包管理器)。npm默认会将所有文件安装为'nobody',因此,以'nobody'身份访问您的计算机的人将对您的node.js服务器设置拥有完全的“管理员”权限。 - Born2Smile
@Born2Smile 我并不反对。你只是重新表述了这个答案的开头段落... 但是拥有文件的账户并不意味着系统容易受到攻击,而是意味着如果以nobody身份运行的服务被黑客攻击,那些文件就会容易受到攻击。这是一个非常大的区别。 - Oli
@Oli,在你的第一段中,确实提到了类似的内容,然而IME很少有人意识到,进程安全性的增加并不适用于由“nobody”拥有的文件。拥有由“nobody”所有的文件或文件夹会使您的系统变得__不安全__,而不是更安全。此外,您无需被黑客入侵,比如说您在机器上运行了一个匿名FTP服务器(用于供人们从您那里下载文件),这个服务器将以“nobody”身份运行,特别是为了防止人们获得过多的访问权限,但如果任何文件夹由“nobody”拥有,任何人也可以上传文件到这些文件夹中。 - Born2Smile
1我一直以为nobody主要是由NFS使用的,正如linuxstandardbase所述。 - dgonzalez
-1:nobody 用户仅适用于 NFS,不应被其他服务或者系统管理员使用。谢谢。 - sarnold
3Ubuntu的人声称:一些误导性的程序或指南建议使用该用户来执行不可信任的程序或处理不可信任的数据。这是错误的建议。 在QNAP NAS上,uid 65534是Guest用户,而没有nobody用户(也没有root用户,只有“admin”)。在QTV和其他在NAS上运行的Docker/容器中,属于Guest的文件被显示为属于nobody。在Samba上以Guest身份创建的文件将属于65534,即guest/nobody。关于这个uid似乎有些混淆。 - papo

用户 nobody 仅保留给 NFS 使用。

上述答案都相当错误,因为它们假设 nobody 是一个"通用"的匿名/访客风格的用户标识。

在 UNIX/Linux 访问控制模型中,不存在匿名/访客风格的用户标识,以下是错误的建议:

  • "常见的做法是将守护进程作为 nobody 运行,特别是服务器,以限制恶意用户获取守护进程控制权造成的破坏。",由于下面的原因,这种技术的有用性会降低:" "然而,如果多个守护进程以此方式运行,那么获得其中一个守护进程的控制权就能够控制所有守护进程。"
  • "一个现实世界的例子是我电脑和我的服务器上运行的 memcached(一种键值内存缓存/数据库/其他),使用 nobody 账户运行。为什么呢?因为它不需要任何权限,给它一个具有写访问文件权限的账户只会增加不必要的风险。"
创建并保留了用户ID为65534的“nobody”用户名,其目的是为了特定用途,并且应仅用于此目的:作为NFS树导出中未映射用户和用户ID的占位符。
也就是说,除非为NFS树导出设置了用户/ID映射,否则导出中的所有文件都将显示为由“nobody”拥有。这样做的目的是防止导入系统上的所有用户访问这些文件(除非它们具有“其他”权限),因为它们中没有任何人(除了“root”)可以成为“nobody”。
因此,将“nobody”用于任何其他目的都是非常糟糕的想法,因为它的目的是成为文件的用户名/用户ID,这些文件不得被任何人访问。
维基条目也是非常错误的。
UNIX/Linux的实践是为需要单独访问控制域的每个“应用程序”或应用程序区域创建一个新帐户,并且永远不要在NFS之外重复使用“nobody”

7这个回答没有引用任何来源,并且明确与其他一些引用了来源的回答相矛盾。当前的悬赏表明这个回答特别好,那么它应该引用一些来源或者至少有一些推理依据。 - vidarlo
6https://wiki.ubuntu.com/nobody,http://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/usernames.html - mook765
1@mook765 那部分没问题。然而,关于NFS的段落我不太理解。例如,使用root_squash选项时,root用户会被映射为nobody用户,因此拥有所有者为nobody的文件毫无意义。此外,文件由nobody所有意味着它们对任何人都是不可访问的这种说法也没有多大意义,因为在UNIX系统中,文件权限与所有权是分开的。我并不是说答案中的一切都是错的,只是其中的某些要素对我来说不太合理或没有意义 :) - vidarlo
2@vidarlo,这个回答并不是在建议你将文件设置为nobody所有。它告诉你的是,nobody是NFS在映射权限时使用的用户,这对我来说是最重要的一点。 NFS如何使用nobody并不那么重要,比起它确实使用nobody来说。谢谢。 - sarnold
@sarnold 在我看来,这个问题的答案仍然是完全错误的。如果用户阅读了这个答案和man exports,他可能会非常困惑。 - vidarlo
嗯,至少Solaris(NFS起源的系统!)曾经nobody用于多个目的,不仅仅是用于NFS - 例如用于运行Web服务器。 - raj

在许多Unix变种中,“nobody”是一个常用的用户名,该用户账户不拥有任何文件,不属于特权组,并且除了其他用户都具备的能力外,没有其他特殊权限。
通常情况下,特别是服务器,将守护进程以nobody身份运行,以限制恶意用户对其可能造成的损害。然而,如果有多个守护进程以此方式运行,这种技术的有效性就会降低,因为控制其中一个守护进程将提供对所有守护进程的控制。原因在于,由nobody所拥有的进程具有向彼此发送信号甚至调试彼此的能力,从而使它们能够读取甚至修改彼此的内存。
信息来源:http://en.wikipedia.org/wiki/Nobody_(username)

3-1:nobody 是专门为 NFS 设计的,不应该被其他服务使用,尤其是系统管理员。谢谢。 - sarnold
引用现在已经过时了。 - ricab

默认情况下,在新安装的系统上(在Ubuntu桌面版13.04上进行了验证),会创建一个名为nobody的用户。
在许多*nix变体中,"nobody"是一个常用的用户名,该用户账户不拥有任何文件,不属于特权组,并且除了其他用户都具备的能力外,没有其他特殊权限("nobody"用户和组在"/etc/sudoers"文件中没有任何条目)。
通常会将"nobody"作为"守护进程"的运行用户,尤其是服务器,以限制恶意用户获取对它们的控制所造成的损害。然而,如果有多个守护进程以此方式运行,这种技术的实用性就会降低,因为控制其中一个守护进程将提供对所有守护进程的控制。原因在于"nobody"所拥有的进程具有向彼此发送信号甚至调试彼此的能力,使它们能够读取甚至修改彼此的内存。
来源: Wikipedia - Nobody (username)

The nobody-owned processes are able to send signals to each others and even ptrace each other in Linux, meaning that a nobody-owned process can read and write the memory of another nobody-owned process.

This is a sample entry of the nobody user in the /etc/passwd file:

alaa@aa-lu:~$ grep nobody /etc/passwd
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh

As you may notice, the nobody user has /bin/sh as a login shell and /nonexistent as the home directory. As the name suggests, the /nonexistent directory does not exist, by default.

If you are paranoid, you can set nobody’s default shell as /usr/sbin/nologin and so, deny the ssh login for the nobody user.

Source: LinuxG.net - The Linux and Unix Nobody User


如果从维基百科中删除了错误的段落,这个回答将值得得到一个+1。谢谢。 - sarnold

没有人是一个特殊的用户和组账户。因为它是一个实际的用户名(和组名),可以被进程甚至用户使用,所以它并不是字面上的“nobody”。例如,一些Apache配置将nobody作为拥有网站文件和目录的用户/组。问题出现在多个进程可能使用nobody用户时,比如NFS目录和Web服务器。

对于“用户nobody仅用于NFS。”答案,有一个小修正。此时,nobody用户还用于具有绑定挂载的非特权容器。
这段话来自systemd-nspawn,具体是--bind挂载选项:

请注意,当此选项与--private-users结合使用时,生成的挂载点将由nobody用户拥有。这是因为挂载及其文件和目录仍然归相关主机用户和组所有,而这些在容器中不存在,并以通配符UID 65534(nobody)显示。如果创建此类绑定挂载,建议使用--bind-ro=将其设置为只读。

systemd-nspawn