In Ubuntu releases prior to Ubuntu 19.10 Eoan Ermine, when I run a command with sudo
, that command receives my home directory in the $HOME
environment variable. This is the behavior I have long expected and warned other people about. If I want sudo
to reset the $HOME
environment variable, so that it refers to the target user's home directory instead of my own, I have to pass the -H
option (or -i
, though that does more).
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
When I first upgraded to Ubuntu 19.10, I was surprised to discover that sudo
seems to reset $HOME
no matter what! I continue to observe this now that 19.10 is released and I've installed updates--both on newly installed systems and one I upgraded to 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
I thought this might be due to updated configuration files. But I checked, and always_set_home
does not appear in any Defaults
line in my 19.10 /etc/sudoers
file.
What makes sudo
treat $HOME
differently starting in 19.10, and why was this change made? Does this make it safe to use plain sudo
in cases where I would previously have used sudo -H
?
For years, Ubuntu has shipped a patched version of
sudo
that preserves$HOME
by default. Besides Ubuntu and its derivatives, very few other operating systems (perhaps no others) do this. It has been decided that this causes more problems than it solves, and starting in Ubuntu 19.10,$HOME
is no longer one of the few environment variablessudo
preserves.In terms of what the change is and how it affects users, the key points are:
sudo command
does whatsudo -H command
does in previous releases. It can indeed be used in cases that would have previously advisedsudo -H
, including to run GUI applications as root or another user. Running graphical programs as root at all remains controversial. But in 19.10 you can runsudo gedit
with the exact same effect assudo -H gedit
. In 19.10, commands likesudo gedit
no longer create annoying file ownership problems in your home directory./etc/sudoers
file. The change is in the source code of thesudo
program itself, not in its default configuration files. (It can be overridden in asudoers
file, but you'd probably know if you did this.)sudo
preserves$HOME
by default, and future updates tosudo
won't change that. For example, 18.04 LTS will always have the old behavior, even in future point releases.sudo -H command
still works fine. If you're in the habit of using that, no problem. You just don't have to, on a 19.10 system.sudo
won't behave differently. In the overwhelming majority of situations where you would not have passed-H
, you could have. Some users do rely on or otherwise prefer the old behavior of preserving$HOME
. But that often had unintended effects. So if you were relying on this, you still might not want to override the change in asudoers
file.See also WinEunuuchs2Unix's answer to Why should users never use normal sudo to start graphical applications?
Why The Change
As the changelog puts it (under "sudo (1.8.27-1ubuntu2) eoan"):
"Everyone else" refers to the upstream
sudo
project (hosted here) and also seemingly all other operating systems that containsudo
, except those that derive from Ubuntu.There's more to it, though. This is also considered to fix a security bug, as described in Ubuntu patch to add HOME to env_keep makes custom commands vulnerable by default. The history was concisely summarized in this comment there by Steve Langasek (whom you may have heard of), which I quote in full:
Todd C. Miller, who maintains the upstream
sudo
project (very actively, and for many years now), was also asked for input on the issue. He explained the reasonsudo
resets (i.e., does not preserve)$HOME
:(I have altered the formatting from the original message to display properly in this medium.)
As of 19.10, the downstream
sudo
in Ubuntu behaves as the upstreamsudo
(andsudo
in other operating systems, including Debian) have behaved for many years. For more detailed information on the history of this change and the developments that preceded it, including numerous links for further reading, see the "sudo
and$HOME
: The Last 20 Years" section below.Huh? a.k.a. Why it (sometimes) matters what
sudo
does with$HOME
Programs you run that need the location of your home directory often examine the value of the
$HOME
environment variable. One important case is when a program tries to store and access configuration files in the home directory of the user running it. Programs typically go by the value of$HOME
. Sometimes when you run a program as a substitute user--for example, as the root account--it is appealing to have that program use your settings. But this can also get messy, in two ways:Usually when you run a command as another user, you want it to work mostly the same way as if that user had run it. But if it is a command whose behavior can be radically altered by the fact that you ran it--which happens if its behavior is heavily customized by data read from files found inside the directory named in
$HOME
--then this goal is not achieved.When you're permitted to perform any action you choose as any user including root (which in Ubuntu is conferred by membership in the
sudo
group), the issue is mostly one of accident. However, if you are a limited user and you have been permitted to run only specific commands withsudo
, then being able to manipulate what those commands do has serious security implications. The bug report that led to the change in 19.10 was specifically motivated by that problem (and includes a compelling example of it).If you run a command as another user and the command makes changes to its configuration in the directory named in
$HOME
, an attempt is made to write the changes to files in that location. When the substitute user is not root, as insudo -u username command
, this typically fails and produces error messages, which is mildly annoying but not serious.But in the common case that the substitute user is root, as in
sudo command
, this succeeds, but if any new files are created, they are owned by root, and your user account no longer has full access to all its own configuration files. This can be fixed bychown
ing the files back, so the problem is most severe in the case of graphical applications, whose complexity can make it so more files, in more places, are involved (and where it has been reported to sometimes make login difficult, though usually the problem is less severe than that).What changed, and why all 19.10 systems have the change
A short whitelist of environment variables that are not reset by default is hard-coded in
sudo
itself. In Ubuntu releases prior to 19.10, an Ubuntu-specific patch adds$HOME
to this whitelist. It is compiled into a binary file used bysudo
, so upgrading to a version ofsudo
that does not have the patch removes it from the whitelist.The patch was removed in 19.10. So upgrading to 19.10 or higher will always apply the change, even when no configuration files associated with
sudo
are modified.It is still possible to configure any version of
sudo
to preserve$HOME
(see below). In the extremely unusual case that you did this before 19.10--when such a configuration would have made no difference--and kept that configuration across an upgrade,$HOME
would still be preserved. But you would presumably remember having done this strange thing.If your upgrade to 19.10 (or later) failed and gave you an only partially upgraded system with a version of
sudo
from before 19.10, thensudo
on that system still preserves$HOME
by default. This is almost the only case wheresudo
would preserve$HOME
in 19.10 (or later) without you knowing about it--though you would still have been informed, during the release upgrade, that not all packages could be upgraded.The easiest way to see directly that the patch is gone in the source code of
sudo
in Ubuntu 19.10 is to compare https://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches?h=ubuntu/disco-security to https://git.launchpad.net/ubuntu/+source/sudo/tree/debian/patches?h=ubuntu/eoan.Still, if you are not sure how your system is configured, you can run
sudo printenv HOME
to find out.Resetting
$HOME
in Ubuntu 19.04 and earlierAlthough updates to
sudo
in Ubuntu 19.04 and earlier may include changes to the documentation to explain the situation, the waysudo
treats$HOME
in those releases has not been and will not be changed by any updates. Most users will not want to bother manually changing howsudo
works on systems where they are already using it without problems. However, if you like, you can makesudo
reset$HOME
on those systems, even without upgrading them.Any particular time you run
sudo
, you can use the-H
/--set-home
option to reset$HOME
:Or you can use
-i
. This does more than reset$HOME
.sudo -i command
behaves as if you logged in as root, rancommand
, and logged out;sudo -i
by itself behaves as if you logged in as root and places you in an interactive root shell. This differs fromsudo -s
, which starts an interactive shell that is not a login shell. Before Ubuntu 19.10,sudo -s
preserves$HOME
; that is, regardless of version, the-s
option does not carry any behavior that affects how$HOME
is treated. It is meaningful to use-H
and-s
together. You can also use any of-H
,-i
, and-s
with-u user
to becomeuser
rather than root. Finally, usingsudo
via the graphical frontendsgksu
orgksudo
(still available in 16.04 LTS, though you may need to install thegksu
package) resets$HOME
.If you want to reconfigure
sudo
so that it always resets$HOME
, you can enable thealways_set_home
option in asudoers
file:You would add that line to
/etc/sudoers
or, better, to a new file in/etc/sudoers.d/
. Either way, you should usevisudo
to edit the file, so you get the benefit of syntax checking. (A syntax error in anysudoers
file causessudo
to refuse to work at all. This is a hassle, though it can be fixed.)For example, on some of my pre-19.10 systems, I created and edited
/etc/sudoers.d/always_set_home
by running:In the file, I wrote the above
Defaults
line. The filename need not bealways_set_home
--it can be whatever you like, so long as it contains no.
or~
character. The word on theDefaults
line does, of course, need to be exactlyalways_set_home
.(One reason to prefer making a new file in
/etc/sudoers.d/
to modifying the existing/etc/sudoers
file is that, if a future update ever does change the default/etc/sudoers
file, you can accept the new file without losing your customizations. Another reason is that it is immediately clear that you have changed the configuration, and where your changes may be found.)If you do this and later wish to run an individual
sudo
command that preserves$HOME
, you can do that the same way you would do it in 19.10 (see below).Preserving
$HOME
in Ubuntu 19.10 and laterThe way
sudo
treats$HOME
has been changed for a reason. (See the above sections, as well as the detailed history section below.) But if you really want to makesudo
continue to preserve$HOME
, even in 19.10 and later, you can configure this behavior in asudoers
file.Any particular time you run
sudo
, you can tell it to preserve$HOME
with--preserve-env=HOME
:This is the form of
--preserve-env
that is documented as--preserve-env=list
in thesudo
manpage. It is also possible to use--preserve-env
with no list operand, which is the same as-E
; that preserves all environment variables. But there's rarely a good reason to do that, especially if your goal is just to preserve$HOME
. If you don't like typing--preserve-env=HOME
, you could define a shell alias or shell function or write a script that lets you run a shorter command to do it. Even better would be to seldom preserve$HOME
(see the section below on alternatives to doing so).More generally, you can make
sudo
preserve any particular environment variablevarname
with--preserve-env=varname
. (You may also see code that effectively preserves$HOME
by setting it explicitly in the commandsudo
runs, such as withsudo HOME="$HOME" command
. This also works. It is quite different fromHOME="$HOME" sudo command
, which would not keepsudo
from resetting$HOME
.)Or if you really want to make
sudo
always preserve$HOME
, you can do this by adding$HOME
toenv_keep
in asudoers
file:That can go in
/etc/sudoers
or a file in/etc/sudoers.d/
. Although I stress I don't recommend doing this at all, if you decide to do it then I'd suggest creating and editing/etc/sudoers.d/keep-home
(call the file what you like, so long as the name doesn't contain.
or~
) by running:Then you can put that
Defaults
line in the file.The reason to use
+=
instead of merely=
is that there are a handful of other environment variables, hard-coded intosudo
itself, that are preserved by default, and that you probably want preserved. If you used=
, then only the environment variables you listed explicitly in the file would be preserved. In this case, that would be just$HOME
. More information about the grammar ofsudoers
files is available in sudoers(5).As for why I suggest making a file in
/etc/sudoers.d/
instead of editing/etc/sudoers
--and why you should definitely usevisudo
either way--see my comments in the "Resetting$HOME
in Ubuntu 19.04 and earlier" section above.Alternatives to Preserving
$HOME
Most of the time you use
sudo
, the best alternative to preserving$HOME
is to do nothing. Mostsudo
commands have the same effect (and some work slightly better) without$HOME
preserved. However, I am aware of two popular use cases for preserving$HOME
.Using your text editor configuration and/or plugins to edit files owned by root or another user.
sudoedit
, or equivalentlysudo -e
, is an ideal alternative for this. It runs the editor as you, you edit a temporary copy of the file, and the file is updated when you quit the editor. Since the editor runs as you, it uses your configuration and plugins automatically, and does so without any risk of failing in opaque and unexpected ways with permission denied errors or making files in your home directory inaccessible to you. To editfile
:To edit
file
witheditor
instead of the default editor:For example,
SUDO_EDITOR=vim sudoedit /etc/apt/sources.list
edits/etc/apt/sources.list
withvim
.To decide what editor to use,
sudoedit
consults the environment variable$SUDO_EDITOR
; if that's unset, it consults$VISUAL
; if that's unset, it consults$EDITOR
; if that's unset, it tries editor commands from a hard-coded list, which in practice in Ubuntu means it useseditor
. Typically that resolves to/usr/bin/editor
, which is a symlink. If you want to change the default editor systemwide then you can change what/usr/bin/editor
points to by runningsudo update-alternatives --config editor
. You can also set one of those three environment variables, which is a good way to change whatsudoedit
edits with for just one user.Making programs you only run as root use specific configuration files. If a program you run as root looks in
$HOME
for its configuration, then you can just put that configuration in (or move that configuration to) root's home directory,/root
.Resetting
$HOME
when you don't know what release you're usingYou may sometimes write a command and not know what release of Ubuntu (or what operating systems besides Ubuntu) it will run on. For example, you may be writing a script that you will run on multiple machines.
sudo
continues to accept the-H
option, with the same effect it always had. It just happens that, starting on 19.10,sudo
without-H
does the same thing (unless you have configured it to do otherwise) assudo -H
.To write portable
sudo
commands that reset$HOME
, you can continue using:(Also as before, if all the actions performed in your script need to be done as root, it's probably better not to use
sudo
in your script and just run the script as root withsudo
.)sudo
and$HOME
: The Last 20 YearsAround the turn of the century, the upstream
sudo
project introduced theenv_reset
option, which makessudo
reset most environment variables. This option is enabled unless disabled explicitly in asudoers
file. (It is possible to enable it explicitly, whichDefaults env_reset
in Debian and Ubuntu's/etc/sudoers
file does, but this is not actually necessary.) Beforesudo
hadenv_reset
, all environment variables were preserved unchanged. Withenv_reset
, only a handful of variables were preserved. This included$HOME
.In July of 2010,
$HOME
was removed from that small whitelist and thus no longer preserved by default.In September of 2010, a bug report about documenting that in the
sudo
package in Debian was filed. As far as I can tell, there was no controversy about, or objection to, the change itself, from Debian developers. (But see below.)In February of 2011, the change had come further downstream from Debian to Ubuntu and Ubuntu developers discussed whether or not it was desirable.
In April of 2011, the change was reported as a bug, referencing that discussion. (Some behavior resulting from the change had been reported as a bug the day before that.) At least at the time, this was considered to be a regression ("the Debian maintainer already tried to fix this once but it appears the fix was incomplete"). I haven't found any such Debian bug report, but that doesn't mean there wasn't one; furthermore, a change could have been made without one. I suspect, though, that it may have been an erroneous reference to that documentation bug.
The next day, the development release of Ubuntu was updated with a downstream, Ubuntu-only patch, to re-add
$HOME
to the list of environment variablessudo
preserved by default. I believe this was done quickly so as to make it into the release of Ubuntu 11.04. The effect was thatsudo
in 11.04, as in previous Ubuntu releases, preserved$HOME
by default.In November of 2011, a bug was reported about how the documentation for
sudo
in Ubuntu said$HOME
was reset. That is, the manpage in Ubuntu correctly described the behavior of upstreamsudo
but not the patched behavior in Ubuntu.In September of 2014, a bug was reported pointing out some of the problems with having
sudo
preserve$HOME
by default and arguing that the problem with running graphical programs with normalsudo
is not that it's inherently dangerous (often cited to this wiki page) but thatsudo
's unusual handling of$HOME
in Ubuntu makes it dangerous and should be considered a bug. It appears there was significant interest in this bug report, including from Ubuntu developers, even though it would be some time before it would be fixed.In March of 2016, the bug that would later become the main reference for the problems with
sudo
preserving$HOME
was reported. Initially, this bug report focused specifically on the security problem that users who are not administrators (i.e., cannot run arbitrary commands as root), but who have been permitted to run specific commands withsudo
, can maliciously alter the behavior of some programs, and in some cases even gain full control of the system. It recommended a narrow change that would attempt to address that case specifically, while still having$HOME
preserved when members of thesudo
group run commands as root or another user.In April of 2019, a bug was reported objecting to the behavior of
sudo
preserving$HOME
by default, even whensudo -s
is used.Later that month, discussion resumed on the March 2016 bug, toward the possible resolution of removing the Ubuntu-specific patch altogether. This broadened the focus of that bug report beyond the specific security vulnerability it described. The goal of making
sudo
in Ubuntu treat$HOME
the same way upstreamsudo
(andsudo
in other operating systems) treats it, starting in Ubuntu 19.10, was articulated.In May of 2019, a bug was reported about how programs (including non-graphical programs) that use launchpadlib suffer configuration file ownership problems because
sudo
preserves$HOME
.A week later, another mailing list discussion on "how sudo handles $HOME" took place (see also this archive page), showcasing a range of views on how
sudo
ought to treat$HOME
. One preference that was uncontroversial was that if a change were to be made, it should only be to 19.10 and later, and not be made in any updates for previous releases. The question arose of whether upstreamsudo
would continue resetting$HOME
in future versions.The upstream
sudo
maintainer, when consulted about this, made clear that no such upstream change is planned and supported the view that the downstream version ofsudo
in Ubuntu should also reset$HOME
by default. That message, posted originally on the sudo-users mailing list, was quoted in a comment on the March 2016 bug report.In June 2019, Ubuntu developers made plans to remove the patch that makes
sudo
in Ubuntu preserve$HOME
.About a week later, the change was made in Ubuntu's repositories. This change applies starting in 19.10. The only change that will be made to
sudo
in earlier releases is to update the documentation so it clearly and correctly describes the behavior ofsudo
in those releases.Acknowledgements
sudo
changed in 19.10, which preceded this Q&A and (as far as I know) was the first information about the change posted to Ask Ubuntu.