自 19.10 以来,sudo 如何以不同的方式处理 $HOME?

自 19.10 以来,sudo 如何以不同的方式处理 $HOME?

在 Ubuntu 19.10 Eoan Ermine 之前的 Ubuntu 版本中,当我使用 运行命令时sudo,该命令会收到我的主目录$HOME环境变量中。这是我早就预料到的行为,警告其他人。如果我想sudo重置$HOME环境变量,以便它引用目标用户的主目录而不是我自己的主目录,我必须传递选项-H(或-i,尽管它做得更多)。

ek@Kip:~$ lsb_release -d
Description:    Ubuntu 18.04.3 LTS
ek@Kip:~$ sudo printenv HOME  # Shows ek's home, not root's.
/home/ek
ek@Kip:~$ sudo -u as printenv HOME  # Shows ek's home, not as's.
/home/ek
ek@Kip:~$ sudo -H printenv HOME  # Shows root's home.
/root
ek@Kip:~$ sudo -Hu as printenv HOME  # Shows as's home.
/home/as

当我第一次升级到 Ubuntu 19.10 时,我惊讶地发现sudo$HOME不管怎样似乎都会重置!现在 19.10 已经发布,我仍在继续观察这一点,并且我已经安装了更新 - 无论是在新安装的系统上还是在升级到 19.10 的系统上。

ek@Cord:~$ lsb_release -d
Description:    Ubuntu 19.10
ek@Cord:~$ sudo printenv HOME  # Shows root's home, even without -H or -i.
/root
ek@Cord:~$ sudo -u as printenv HOME  # Shows as's home, even without -H or -i.
/home/as
ek@Cord:~$ sudo -H printenv HOME  # Also shows root's home.
/root
ek@Cord:~$ sudo -Hu as printenv HOME  # Also shows as's home.
/home/as

我认为这可能是因为更新的配置文件。但我检查了一下,并always_set_home没有出现在Defaults我的19.10/etc/sudoers文件的任何一行中。

从 19.10 开始有何sudo不同?为什么要进行这样的更改?$HOMEsudo这样是否可以安全地在以前使用过的情况下使用普通版本sudo -H

答案1

多年来,Ubuntu发布了默认sudo保留的修补版本$HOME. 除了 Ubuntu 及其衍生产品之外,很少有其他操作系统(也许没有其他操作系统)这样做。 它一直认为这造成的问题比解决的问题还多, 和从 Ubuntu 19.10 开始$HOME不再是少数sudo保留的环境变量之一。

按照什么变化是什么以及它如何影响用户,关键点是:

  • 从 Ubuntu 19.10 开始,其功能与以前的版本相同。sudo commandsudo -H command确实可以使用在之前已经建议的情况下sudo -H,包括以 root 或其他用户身份运行 GUI 应用程序. 以 root 身份运行图形程序仍存在争议。但在 19.10 中,您可以运行sudo gedit与 完全相同的效果sudo -H gedit。在 19.10 中,类似命令sudo gedit不再创建恼人的文件所有权问题在你的主目录中。
  • 这适用甚至在从早期版本升级到 19.10 的系统上,即使升级不会更改您的/etc/sudoers文件。更改是在sudo程序本身的源代码中,而不是在其默认配置文件中。(它可以在文件中被覆盖sudoers,但如果您这样做了,您可能会知道。)
  • 它不适用于 19.10 之前的版本,也不会适用。在 19.10 之前,默认sudo保留,并且将来的更新不会改变这一点。例如,18.04 LTS 将始终保留旧行为,即使在未来的版本中也是如此。$HOMEsudo
  • sudo -H command仍然运行良好。如果您习惯使用它,那没问题。在 19.10 系统上,您不必这样做。
  • 最多您运行的命令sudo不会有不同的行为。在绝大多数情况下,你会不是已经过去了-H,你可以有。有些用户确实有依赖或以其他方式偏爱旧行为保存$HOME。但常常会产生意想不到的效果。因此,如果你依赖这个,你仍然可能不是想要覆盖sudoers文件中的更改。

也可以看看WinEunuuchs2Unix 的答案为什么用户永远不应该使用普通的 sudo 来启动图形应用程序?


为何改变

作为变更日志将其放在(在“sudo (1.8.27-1ubuntu2) eoan”下):

这将恢复 sudo 对 $HOME 的处理方式

“其他人”指的是上游 sudo项目 (托管于此)而且似乎全部其他包含的操作系统sudo,除源自 Ubuntu 的操作系统外。

不过,这还不算什么。这也被认为是为了修复一个安全漏洞,如Ubuntu 补丁将 HOME 添加到 env_keep 会导致自定义命令默认易受攻击. 历史简明扼要地总结在有这个评论经过史蒂夫·兰加塞克(谁你可能听说过),我将其全文引用如下:

这一变化最初是为了应对错误 #760140

sudo 中的上游变化从未伴随 CVE,并且行为变化从未应用于 Ubuntu 的早期版本,因此当时看起来并不涉及安全敏感问题。

我并不反对按照西蒙描述的方式进行改变,但我听从安全团队的意见。

托德·C·米勒,谁维护上游sudo项目(多年来一直非常积极)也被要求就这个问题提供意见。他解释原因 sudo重置(即不保留)$HOME

2019 年 5 月 16 日星期四 07:48:40 -0400,Dan Streetman 写道:

我已经抄送给 sudo-users,因此对上游 sudo 列表的问题可以总结为:
上游 sudo 默认将 HOME 添加到 env_keep 的可能性有多大?

极不可能。在 sudo 1.7.4 之前,HOME 和 MAIL 环境变量默认保留在环境中。这可能导致程序使用原始用户主目录中的配置文件,这会带来安全隐患,因此在 1.7.4 中更改了默认设置。

在过去,sudo 的作用只是更改 uid。如今,sudo 会尝试在与您以该用户身份登录时所获得的环境非常接近的环境中运行命令。事实证明,这更安全,因为它更接近其他程序所做的假设。

我们之所以提出这个问题,是因为 Ubuntu 带有一个补丁,该补丁将 HOME 添加到 env_keep,这与默认上游或任何其他 Linux/Unix 不同。我们正在考虑删除该补丁,以匹配上游默认设置,不是 包括 env_keep 中的 HOME。

我会支持这一点。我相信重置 HOME 是更安全的默认设置。

- 托德

(我改变了格式原始消息才能在此媒体上正确显示。

自 19.10 起,下游 sudoUbuntu 中的行为与上游sudo(以及sudo其他操作系统,包括 Debian)的行为一样。有关此更改的历史和之前的发展的更多详细信息,包括大量可供进一步阅读的链接,请参阅下面的“sudo$HOME:过去 20 年”部分。

嗯?sudo又名为什么它(有时)很重要$HOME

您运行的程序需要您的位置主目录经常检查$HOME 环境变量一个重要的情况是当程序尝试存储和访问配置文件在运行它的用户的主目录中。程序通常按 的值运行$HOME。有时,当您以替代用户身份(例如,以 root 帐户)运行程序时,让该程序使用你的设置。但这也可能变得混乱,表现在两个方面:

  1. 通常,当你以其他用户身份运行命令时,你希望它的工作方式与该用户运行它时大致相同。但如果该命令的行为可能会因以下事实而发生根本性改变:运行它——如果它的行为严重依赖于从名为的目录中找到的文件读取的数据而定制的话$HOME——那么这个目标就无法实现。

    当你被允许以任何用户身份(包括 root 用户,在 Ubuntu 中,root 是由组成员授予的)执行任何操作时sudo,问题大多是意外。但是,如果你是受限用户,并且被允许运行仅限特定命令使用sudo,那么能够操纵这些命令的作用将会带来严重的安全隐患。导致 19.10 版本更改的错误报告正是受该问题的启发(包括一个引人注目的例子)。

  2. 如果你以另一个用户身份运行命令,并且命令做出改变将其配置到 中指定的目录中$HOME,尝试将更改写入该位置的文件。当替代用户不是 root 用户时(如 ),这通常会失败并产生错误消息,这有点烦人,但并不严重。sudo -u username command

    但在替代用户是 root 的常见情况下,如,这将成功,但如果有任何sudo command新的文件被创建后,它们归 root 所有,并且您的用户帐户不再具有对其所有配置文件的完全访问权限。可以通过以下方法修复此问题:chown恢复文件,因此问题在图形应用程序的情况下最为严重,因为图形应用程序的复杂性可能会使它因此涉及更多地方的更多文件(以及它在哪里已经被报告了有时使登录变得困难, 尽管通常问题没有那么严重)。

有哪些变化,以及为什么所有 19.10 系统都有变化

默认情况下不会重置的环境变量的简短白名单本身是硬编码的sudo。在 Ubuntu 19.10 之前的版本中,Ubuntu 特定补丁添加$HOME到此白名单中。它被编译成 使用的二进制文件,因此升级到没有补丁sudo的 版本会将其从白名单中删除。sudo

该补丁已于 19.10 版本删除。因此,升级到 19.10 或更高版本将始终应用更改,即使没有配置文件与之关联的sudo被修改。

仍然可以配置任何版本的sudo以保留$HOME(见下文)。在极不寻常的情况下,如果您在 19.10 之前这样做(那时这样的配置不会产生任何影响),并且在升级过程中保留该配置,则$HOME仍会保留。但您大概会记得做过这件奇怪的事情。

如果你升级到 19.10(或更高版本)失败的sudo并为您提供了仅部分升级的系统,其版本为19.10 之前的版本,则sudo在该系统上仍$HOME默认保留。这几乎是唯一一种在您不知情的情况下在 19.10(或更高版本)中sudo保留的情况$HOME——尽管在发布升级期间您仍会被告知并非所有软件包都可以升级。

sudo最简单的方法是比较 Ubuntu 19.10源代码中是否存在补丁https://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches?h=ubuntu/disco-securityhttps://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches?h=ubuntu/eoan

不过,如果你不确定如何你的系统已经配置好了,你可以运行sudo printenv HOME一下看看。

$HOME在 Ubuntu 19.04 及更早版本中重置

虽然 Ubuntu 19.04 及更早版本中的更新sudo可能包括对文档sudo为了解释这种情况,这些版本中的处理方式$HOME没有被任何更新改变,也不会被任何更新改变。大多数用户不想费心手动更改sudo他们已经在使用且没有问题的系统上的运行方式。但是,如果您愿意,您可以重置sudo这些$HOME系统,甚至无需升级它们。

无论何时跑步sudo,您可以使用-H/--set-home选项来重置$HOME

sudo -H command

或者你可以使用-i。这比重置更多$HOME。表现得就像你以 root 身份登录,运行sudo -i commandcommand和 注销;sudo -i本身的行为就像您以 root 身份登录并将您置于交互式 root shell 中。这与 不同sudo -s,后者启动的不是登录 shell 的交互式 shell。在 Ubuntu 19.10 之前,sudo -s保留$HOME;也就是说,无论版本如何,该-s选项都不会影响 的处理方式。将和一起$HOME使用是有意义的。您还可以将、和中的任何一个与一起使用以成为-H-s-H-i-s-u useruser而不是 root。最后,sudo通过图形前端gksugksudo(在 16.04 LTS 中仍然可用,但您可能需要安装软件包gksu)使用重置$HOME

如果你想重新配置,sudo以便总是重置$HOME,您可以always_set_home在文件中启用该选项sudoers

Defaults    always_set_home

您可以将这一行添加到 中/etc/sudoers,或者更好的是,添加到 中的一个新文件中/etc/sudoers.d/。无论哪种方式,您都应该使用visudo来编辑文件,这样您就可以获得语法检查的好处。(任何sudoers文件中的语法错误都会导致sudo完全拒绝工作。不过,这很麻烦它可以修复

例如,在我的某些 19.10 之前的系统上,我通过运行以下命令创建和编辑:/etc/sudoers.d/always_set_home

sudo visudo -f /etc/sudoers.d/always_set_home

在文件中,我写了上面的Defaults行。文件名不需要是always_set_home--可以是任何你喜欢的,只要它不包含.或字符。行~上的单词Defaults当然,需要准确always_set_home

(选择创建新文件而不是/etc/sudoers.d/修改现有/etc/sudoers文件的一个原因是,如果将来有更新更改默认/etc/sudoers文件后,您可以接受新文件而不会丢失您的自定义设置。另一个原因是,您可以立即清楚地知道您更改了配置,以及可以在哪里找到您的更改。

如果您执行此操作,稍后希望运行sudo保留的单独命令$HOME,您可以按照在 19.10 中执行的操作进行操作(见下文)。

$HOME在 Ubuntu 19.10 及更高版本中保存

sudo处理方式的$HOME改变是有原因的。(请参阅上面的章节,以及下面的详细历史记录部分。)但如果您确实想sudo继续保留$HOME,即使在 19.10 及更高版本中,您也可以在文件中配置此行为sudoers

无论何时跑步sudo,你可以告诉它$HOME保存--preserve-env=HOME

sudo --preserve-env=HOME command

--preserve-env这是记录--preserve-env=list的形式手册sudo. 也可以使用--preserve-env不带列表操作数的 ; -E,它与保留全部环境变量。但这样做很少有充分的理由,特别是如果你的目标只是保留$HOME。如果你不喜欢输入--preserve-env=HOME,你可以定义一个 shell 别名或 shell 函数,或者编写一个脚本,让你运行一个更短的命令来执行它。更好的做法是很少保留$HOME(请参阅下面关于这样做的替代方法的部分)。

更一般地,您可以sudo保留任何特定的环境变量varname使用。 (您可能还会看到通过在命令运行中明确设置来有效保留的代码,例如使用。 这也有效。 它与 完全不同,后者不会阻止重置。)--preserve-env=varname$HOMEsudosudo HOME="$HOME" commandHOME="$HOME" sudo commandsudo$HOME

或者如果你真的想要sudo永远保留$HOME,您可以通过在文件中$HOME添加以下内容来实现:env_keepsudoers

Defaults    env_keep += "HOME"

这可以放入/etc/sudoers或 中的文件中/etc/sudoers.d/。尽管我强调我根本不建议这样做,但如果您决定这样做,那么我建议您通过运行以下命令创建和编辑(将文件命名为您喜欢的任何名称,只要名称不包含或):/etc/sudoers.d/keep-home.~

sudo visudo -f /etc/sudoers.d/keep-home

然后您可以将该Defaults行放入文件中。

之所以使用+=而不是仅仅使用=,是因为有许多其他环境变量,sudo它们本身是硬编码的,默认情况下会保留,而您可能希望保留它们。如果您使用了=,那么仅有的文件中明确列出的环境变量将被保留。在本例中,这将是只是 $HOME. 有关文件语法的更多信息,sudoers请参阅sudoers(5)

至于为什么我建议创建文件/etc/sudoers.d/而不是编辑/etc/sudoers- 以及为什么你绝对应该使用任何一种方式 - 请参阅上面“在 Ubuntu 19.04 及更早版本中visudo重置”部分中的我的评论。$HOME

保存的替代方案$HOME

大多数情况下,使用 时sudo,保留的最佳替代方案$HOME就是什么也不做。大多数sudo命令在没有保留的情况下具有相同的效果(有些效果略好)$HOME。但是,我知道两种保留的常见用例$HOME

使用您的文本编辑器配置和/或插件来编辑 root 或其他用户拥有的文件。 sudoedit或等效于sudo -e是此目的的理想替代方案。它以如下方式运行编辑器,您编辑该文件的临时副本,退出编辑器时该文件会更新。由于编辑器以您的身份运行,因此它会自动使用您的配置和插件,并且不会出现任何不透明和意外的失败风险,例如权限被拒绝错误或导致您无法访问主目录中的文件。要编辑file

sudoedit file

编辑fileeditor而不是默认编辑器:

SUDO_EDITOR=editor sudoedit file

例如,用SUDO_EDITOR=vim sudoedit /etc/apt/sources.list编辑。/etc/apt/sources.listvim

要决定使用什么编辑器,sudoedit请咨询环境变量 $SUDO_EDITOR;如果未设置,它会参考$VISUAL;如果未设置,它会参考$EDITOR;如果未设置,它会尝试从硬编码列表中使用编辑器命令,这在 Ubuntu 中实际上意味着它使用editor。通常,它会解析为/usr/bin/editor,这是一个符号链接。如果你想更改默认编辑器全系统范围然后您可以/usr/bin/editor通过运行来改变指向的内容sudo update-alternatives --config editor您还可以设置这三个环境变量之一,这是更改sudoedit单个用户编辑内容的好方法。

制作程序仅有的以 root 身份运行,使用特定的配置文件。如果您以 root 身份运行的程序查找$HOME其配置,那么您只需将该配置放入(或将该配置移动到)root 的主目录中/root

$HOME当你不知道正在使用哪个版本时进行重置

有时,您可能会编写命令,但不知道它将在哪个版本的 Ubuntu(或除 Ubuntu 之外的哪些操作系统)上运行。例如,您可能正在编写将在多台计算机上运行的脚本。

sudo继续接受该-H选项,其效果与以往相同。只是从 19.10 开始,sudowithout-H会执行与 相同的操作(除非您已将其配置为其他操作)sudo -H

要编写sudo重置的可移植命令$HOME,您可以继续使用:

sudo -H command

(同样和以前一样,如果脚本中执行的所有操作都需要以 root 身份完成,那么最好不要sudo在脚本中使用,而只需以 root 身份运行脚本sudo。)

sudo$HOME:过去 20 年

世纪之交, 这上游 sudo项目引入了env_reset选项,这使得sudo大多数环境变量被重置。除非在文件中明确禁用,否则此选项处于启用状态sudoers。(可以明确启用它,Defaults env_resetDebian 和 Ubuntu 的/etc/sudoers文件中就是这样做的,但实际上没有必要。)在sudohad之前env_reset,所有环境变量都保持不变。使用env_reset,只有少数变量被保留。这包括$HOME

2010年7月$HOME已从该小白名单中删除,因此不再默认保留。

2010年9月,有人提交了一份关于在 Debian 软件包中记录该问题的错误报告sudo。据我所知,Debian 开发人员对这一变化本身没有提出任何争议或反对。(但请参见下文。)

2011年2月,变化进一步下游从 Debian 到 Ubuntu 以及 Ubuntu 开发人员讨论是否可取。

2011年4月,该更改被报告为错误,并引用了该讨论。(由于更改导致的一些行为已被报告为错误至少在当时,这是经过考虑的成为一个回归(“Debian 维护者已经尝试修复过一次,但似乎修复不完整”)。我没有找到任何这样的 Debian 错误报告,但这并不意味着没有;此外,即使没有错误报告,也可以进行更改。不过,我怀疑它可能错误地提到了文档错误

第二天,Ubuntu 的开发版本已使用下游、仅限 Ubuntu 的补丁进行了更新,以重新添加$HOME到默认保留的环境变量列表中sudo。我相信这是快速完成的,以便将其纳入 Ubuntu 11.04 版本。结果是,sudo在 11.04 中,与之前的 Ubuntu 版本一样,$HOME默认保留。

2011年11月,有人报告了有关sudoUbuntu 中 said文档如何$HOME重置的错误。也就是说,Ubuntu 中的手册页正确描述了上游的行为sudo,但没有正确描述 Ubuntu 中已修补的行为。

2014年9月sudo,报告了一个错误,指出了默认情况下保留的一些问题$HOME,并认为使用正常模式运行图形程序的问题sudo并不在于它本身就很危险(经常被引用到此维基页面)但那sudo$HOMEUbuntu 中不寻常的处理这会造成危险,应视为错误。似乎有很多人(包括 Ubuntu 开发人员)对这个错误报告很感兴趣,尽管修复它还需要一段时间。

2016年3月,后来成为sudo保存问题的主要参考的错误$HOME被报告。最初,这个错误报告专门关注安全问题,即非管理员用户(即不能以 root 身份运行任意命令),但被允许运行具体的命令sudo可能会恶意改变某些程序的行为,在某些情况下甚至会完全控制系统。它建议进行一项狭义的更改,以尝试专门解决这种情况,同时仍保留$HOME组成员sudo以 root 或其他用户身份运行命令的时间。

2019年4月,有报告称即使在使用时,也存在默认sudo保留行为的错误。$HOMEsudo -s

当月晚些时候,讨论继续进行2016 年 3 月漏洞,朝着可能的解决方案完全删除 Ubuntu 特定的补丁。这扩大了该错误报告的关注范围,超出了它所描述的特定安全漏洞。从 Ubuntu 19.10 开始, sudoUbuntu 中的目标是以上游(和其他操作系统)对待它的$HOME方式对待它。sudosudo

2019年5月,有报告称使用 launchpadlib 的程序(包括非图形程序)由于sudo保留而遭受配置文件所有权问题$HOME

一个星期后,另一个关于“sudo 如何处理 $HOME”的邮件列表讨论开始了(另请参阅此存档页面sudo),展示了关于应该如何对待的一系列观点$HOME。一个没有争议的偏好是如果需要进行更改,但只能在 19.10 及更高版本上进行并且不会以任何方式先前版本的更新。 这问题出现了上游是否会在未来版本中sudo继续重置。$HOME

上游sudo维护者, 什么时候咨询过这个问题,明确表示没有计划进行此类上游变革sudo并支持Ubuntu 的下游版本也应$HOME默认重置的观点。该消息最初发布于在 sudo-users 邮件列表中, 曾是引用自评论2016 年 3 月错误报告

2019年6月之后,Ubuntu 开发人员计划删除该补丁,以保证sudoUbuntu 能够继续保留该补丁$HOME

大约一周后,此更改是在 Ubuntu 的存储库中进行的。此更改从 19.10 开始适用。sudo对早期版本所做的唯一更改是更新文档,以便清晰正确地描述sudo这些版本中的行为。

致谢

相关内容