在 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
没有出现在我的 19.10文件的任何Defaults
行中。/etc/sudoers
从 19.10 开始,是什么让sudo
待遇$HOME
有所不同,为什么会做出这种改变?sudo
在我以前使用过的情况下,这是否可以安全地使用 plain sudo -H
?
多年来,Ubuntu 已经发布了一个默认保留的补丁版本
sudo
$HOME
。除了 Ubuntu 及其衍生产品之外,很少有其他操作系统(也许没有其他操作系统)这样做。已经确定这导致的问题多于解决的问题,并且从 Ubuntu 19.10 开始,$HOME
不再是sudo
保留的少数环境变量之一。就变化是什么以及它如何影响用户而言,关键点是:
sudo command
sudo -H command
它确实可以用于以前建议的情况sudo -H
,包括以 root 或其他用户身份运行 GUI 应用程序。以 root 身份运行图形程序仍然存在争议。但是在 19.10 中,您可以运行sudo gedit
与sudo -H gedit
. 在 19.10 中,诸如此类的命令sudo gedit
不再在您的主目录中产生烦人的文件所有权问题。/etc/sudoers
文件。更改是在sudo
程序本身的源代码中,而不是在其默认配置文件中。(它可以在sudoers
文件中被覆盖,但如果你这样做了,你可能会知道。)sudo
保留$HOME
,未来的更新sudo
不会改变这一点。例如,18.04 LTS 将始终具有旧行为,即使在未来的单点版本中也是如此。sudo -H command
仍然可以正常工作。如果你有使用它的习惯,那没问题。在 19.10 系统上,您不必这样做。sudo
命令的行为不会有所不同。在绝大多数你不会通过-H
,你可以通过。一些用户确实依赖或更喜欢保存$HOME
. 但这往往会产生意想不到的影响。因此,如果您依赖于此,您可能仍然不想覆盖sudoers
文件中的更改。另请参阅WinEunuuchs2Unix对为什么用户永远不应该使用普通 sudo 来启动图形应用程序的回答?
为什么改变
正如更改日志所说(在“sudo (1.8.27-1ubuntu2) eoan”下):
“其他人”指的是上游
sudo
项目(托管在这里)以及看似所有其他包含 的操作系统sudo
,除了那些从 Ubuntu 派生的操作系统。不过,还有更多。这也被认为可以修复安全漏洞,如Ubuntu patch to add HOME to env_keep 中所述,默认情况下自定义命令易受攻击。Steve Langasek(你可能听说过)在这篇评论中简明扼要地总结了这段历史,我全文引用:
维护上游
sudo
项目的Todd C. Miller (非常积极,并且已经工作了很多年)也被要求就这个问题提供意见。他解释了sudo
重置的原因(即不保留)$HOME
:(我已更改原始消息的格式以在此媒体中正确显示。)
从 19.10 开始, Ubuntu下游
sudo
的行为与上游sudo
(以及sudo
其他操作系统,包括 Debian)多年来的行为相同。有关此更改的历史和之前的发展的更多详细信息,包括许多供进一步阅读的链接,请参阅下面的“sudo
和$HOME
:过去 20 年”部分。嗯?又名为什么它(有时)很
sudo
重要$HOME
您运行的需要主目录位置的程序通常会检查
$HOME
环境变量的值。一个重要的情况是当程序试图在运行它的用户的主目录中存储和访问配置文件时。程序通常按$HOME
. 有时,当您以替代用户身份运行程序时(例如,作为 root 帐户),让该程序使用您的设置是很有吸引力的。但这也可能会变得混乱,有两种方式:通常,当您以另一个用户身份运行命令时,您希望它的工作方式与该用户运行它的方式大致相同。但是,如果它是一个命令,它的行为可以通过你运行它的事实而彻底改变——如果它的行为是通过从目录中找到的文件中读取的数据大量定制的,那么就会发生这种情况——那么
$HOME
这个目标就没有实现。当您被允许以任何用户的身份执行您选择的任何操作时,包括 root(在 Ubuntu 中由
sudo
组中的成员授予),问题主要是偶然的。但是,如果您是受限用户,并且您只被允许使用 运行特定命令,sudo
那么能够操纵这些命令的功能会产生严重的安全隐患。导致 19.10 发生更改的错误报告是由该问题引起的(并包括一个令人信服的示例)。如果您以另一个用户身份运行命令,并且该命令在名为 in 的目录中更改
$HOME
了其配置,则会尝试将更改写入该位置的文件。当替代用户不是 root 时,例如在 中,这通常会失败并产生错误消息,这有点烦人但并不严重。sudo -u username command
但是在替代用户是 root 的常见情况下,如 中,这会成功,但是如果创建了任何新文件,它们将归 root 所有,并且您的用户帐户不再具有对其所有配置文件的完全访问权限。这可以通过恢复文件来解决,因此问题在图形应用程序的情况下最为严重,其复杂性可能使其涉及更多文件,在更多地方(据报道有时会导致登录困难) ,尽管通常问题没有那么严重)。
sudo command
chown
发生了什么变化,以及为什么所有 19.10 系统都有变化
默认情况下未重置的环境变量的简短白名单
sudo
本身是硬编码的。在 19.10 之前的 Ubuntu 版本中,特定于 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 -安全到https://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches?h=ubuntu/eoan。不过,如果你不确定你的系统是如何配置的,你可以跑去
sudo printenv HOME
看看。$HOME
在 Ubuntu 19.04 及更早版本中重置尽管
sudo
Ubuntu 19.04 及更早版本中的更新可能包括对文档的更改以解释情况,但这些版本中的sudo
处理方式$HOME
没有也不会因任何更新而改变。大多数用户不想打扰手动更改sudo
他们已经在使用它而没有问题的系统上的工作方式。但是,如果您愿意,您可以在这些系统上进行sudo
重置$HOME
,即使不升级它们。在您运行的任何特定时间
sudo
,您都可以使用-H
/--set-home
选项来重置$HOME
:或者你可以使用
-i
. 这不仅仅是 reset$HOME
。表现得就像您以 root 身份登录、运行和注销一样;它本身的行为就像您以 root 身份登录并将您置于交互式 root shell 中一样。这与 不同,后者启动一个不是登录 shell 的交互式 shell。在 Ubuntu 19.10 之前,保留; 也就是说,无论版本如何,该选项都不带有任何影响如何处理的行为。用和在一起是有意义的。您也可以使用 、 和 with 中的任何一个来成为而不是root。最后,通过图形前端或sudo -i command
command
sudo -i
sudo -s
sudo -s
$HOME
-s
$HOME
-H
-s
-H
-i
-s
-u user
user
sudo
gksu
gksudo
(在 16.04 LTS 中仍然可用,但您可能需要安装该gksu
软件包$HOME
)如果要重新配置
sudo
以使其始终重置$HOME
,可以always_set_home
在文件中启用该选项sudoers
:您可以将该行添加到
/etc/sudoers
或更好地添加到/etc/sudoers.d/
. 无论哪种方式,您都应该使用visudo
来编辑文件,因此您可以获得语法检查的好处。(任何sudoers
文件中的语法错误都会导致sudo
根本拒绝工作。这很麻烦,尽管可以修复。)例如,在我的一些 19.10 之前的系统上,我通过运行创建和编辑:
/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
继续保存,即使在 19.10 及更高版本中,你也可以在文件$HOME
中配置此行为。sudoers
sudo
$HOME
在您运行的任何特定时间,您都可以告诉它保留--preserve-env=HOME
:这是manpage中
--preserve-env
记录--preserve-env=list
的形式。也可以不使用列表操作数,与 ; 相同。保留所有环境变量。但很少有这样做的充分理由,特别是如果您的目标只是保留. 如果你不喜欢打字,你可以定义一个 shell 别名或 shell 函数,或者编写一个脚本,让你运行一个更短的命令来完成它。更好的是很少保留(请参阅下面有关这样做的替代方案的部分)。sudo
--preserve-env
-E
$HOME
--preserve-env=HOME
$HOME
更一般地,您
sudo
可以varname
使用. (您可能还会看到通过在命令运行中显式设置它来有效保留的代码,例如 with 。这也有效。它与 完全不同,不会阻止重置。)--preserve-env=varname
$HOME
sudo
sudo HOME="$HOME" command
HOME="$HOME" sudo command
sudo
$HOME
或者,如果您真的想
sudo
始终保留$HOME
,您可以通过在文件中添加$HOME
to来做到这一点:env_keep
sudoers
那可以进入
/etc/sudoers
或在/etc/sudoers.d/
. 尽管我强调我根本不建议这样做,但如果您决定这样做,那么我建议您通过运行创建和编辑(只要名称不包含or ,就可以随意调用文件):/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
:要
file
使用editor
而不是默认编辑器进行编辑:例如,
SUDO_EDITOR=vim sudoedit /etc/apt/sources.list
使用./etc/apt/sources.list
vim
要决定使用什么编辑器,
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 开始,sudo
没有-H
和sudo -H
.要编写
sudo
reset 的可移植命令$HOME
,您可以继续使用:(和以前一样,如果您的脚本中执行的所有操作都需要以 root 身份完成,最好不要
sudo
在您的脚本中使用,而只需使用 . 作为 root 运行脚本sudo
。)sudo
和$HOME
:过去的 20 年在世纪之交,上游
sudo
项目引入了该env_reset
选项,这使得sudo
重置大多数环境变量。sudoers
除非在文件中明确禁用,否则启用此选项。(可以显式启用它,这Defaults env_reset
在 Debian 和 Ubuntu 的/etc/sudoers
文件中会这样做,但这实际上不是必需的。)在sudo
had之前env_reset
,所有环境变量都保持不变。使用env_reset
时,只保留了少数变量。这包括$HOME
.2010 年 7 月,
$HOME
从那个小白名单中删除,因此默认情况下不再保留。2010 年 9 月
sudo
,提交了一份关于在 Debian 的软件包中记录该内容的错误报告。据我所知,Debian 开发人员对更改本身没有争议或反对。(但见下文。)2011 年 2 月,从 Debian 到 Ubuntu 的变化进一步向下游发展,Ubuntu 开发人员讨论了它是否可取。
2011 年 4 月,该更改被报告为错误,引用了该讨论。(由于更改导致的一些行为在前一天被报告为错误。)至少在当时,这被认为是一种回归(“Debian 维护者已经尝试过修复这个问题,但似乎修复不完整”)。我没有找到任何这样的 Debian 错误报告,但这并不意味着没有;此外,没有人也可以做出改变。不过,我怀疑它可能是对该文档错误的错误引用。
第二天,Ubuntu 的开发版本更新了一个下游的、仅限 Ubuntu 的补丁,以重新添加到默认保留
$HOME
的环境变量列表中。sudo
我相信这很快就完成了,以使其成为 Ubuntu 11.04 的发行版。效果是sudo
在 11.04 中,与以前的 Ubuntu 版本一样,默认保留$HOME
。2011 年 11 月,报告了一个关于
sudo
Ubuntu中的文档如何$HOME
重置的错误。也就是说,Ubuntu 中的手册页正确描述了上游的行为,sudo
但没有描述 Ubuntu 中的修补行为。2014 年 9 月,报告了一个错误,指出了默认情况下
sudo
保存$HOME
的一些问题,并认为以正常方式运行图形程序的问题sudo
不是它本质上是危险的(经常被此 wiki 页面引用),而是sudo
不寻常$HOME
在 Ubuntu中处理会使其变得危险,应该被视为一个错误。似乎对这个错误报告很感兴趣,包括来自 Ubuntu 开发人员的,尽管它需要一段时间才能得到修复。2016 年 3 月,报告了后来成为
sudo
保存问题的主要参考的错误$HOME
。最初,此错误报告专门针对非管理员用户(即不能以 root 身份运行任意命令)但已被允许使用 运行特定命令的sudo
用户可以恶意更改某些程序的行为的安全问题,并且在在某些情况下,甚至可以完全控制系统。它建议进行一个狭窄的更改,以尝试专门解决这种情况,同时在组成员以 root 或其他用户身份运行命令时仍然$HOME
保留。sudo
2019 年 4 月,报告了一个错误,该错误反对默认情况下
sudo
保留的行为$HOME
,即使sudo -s
使用时也是如此。当月晚些时候,关于 2016 年3 月错误的讨论继续进行,以寻求完全删除特定于 Ubuntu 的补丁的可能解决方案。这扩大了该错误报告的重点,超出了它所描述的特定安全漏洞。从 Ubuntu 19.10 开始,让
sudo
Ubuntu$HOME
以相同的方式对待上游sudo
(和sudo
其他操作系统)的目标已经明确。2019 年 5 月,报告了一个关于使用 launchpadlib 的程序(包括非图形程序)如何因
sudo
保留$HOME
.一周后,关于“sudo 如何处理 $HOME”的另一个邮件列表讨论发生了(另请参阅此存档页面
sudo
),展示了关于如何处理的一系列观点$HOME
。一个没有争议的偏好是,如果要进行更改,它应该只针对 19.10 和更高版本,而不是在以前版本的任何更新中进行。问题是上游是否会在未来的版本中继续sudo
重置。$HOME
上游
sudo
维护者在咨询此事时明确表示没有计划进行此类上游更改,并支持 Ubuntu 中的下游版本也应默认sudo
重置的观点。$HOME
该消息最初发布在 sudo-users 邮件列表中,在 2016年3 月错误报告的评论中被引用。2019 年 6 月,Ubuntu 开发人员计划删除
sudo
在 Ubuntu 中保留的补丁$HOME
。大约一周后,在 Ubuntu 的存储库中进行了更改。此更改从 19.10 开始适用。将
sudo
在早期版本中进行的唯一更改是更新文档,以便清楚准确地描述sudo
这些版本中的行为。致谢
sudo
19.10 中的变化,这是在此问答之前,并且(据我所知)是发布到 Ask Ubuntu 的有关更改的第一个信息。