Sudo should not change $HOME

I recently bumped into trouble after starting to use common environment variables in post-install scripts. When I use sudo to execute a bash script, the sudo commands within that script translate $HOME to /home/root instead of the currently/single/default/admin logged in user.

I understand this is not how Ubuntu normally behaves, it is how Debian behaves.

This behaviour even caused all my docker container volumes to appear in the root home folder, creating all sorts of access denied and fatal exception issues. It took me a while to figure this out as the cause.

I first created a new environment variable using sudo nano /etc/environment but then that variable is only available to sudo and not to commands run without sudo.

Then I found this information:

Sudo has many compile-time configuration options. You can list the settings in your version with sudo -V . One of the differences between the configuration in Debian wheezy and in Ubuntu 12.04 is that the HOME environment variable is preserved in Ubuntu but not in Debian; both distributions erase all environment variables except for a few that are explicitly marked as safe to preserve. Thus sudo -s preserves HOME on Ubuntu, while on Debian HOME is erased and sudo then sets it to the home directory of the target user.

You can override this behavior in the sudoers file. Run visudo to edit the sudoers file. There are several relevant options:

  • env_keep determines which environment variables are preserved. Use Defaults env_keep += "HOME" to retain the caller’s HOME environment variable or Defaults env_keep -= "HOME" to erase it (and replace it by the home directory of the target user).
  • env_reset determines whether environment variables are reset at all. Resetting environment variables is often necessary for rules that allow running a specific command, but does not have a direct security benefit for rules that allow running arbitrary commands anyway.
  • always_set_home , if set, causes HOME to be overridden even if it was preserved due to env_reset being disabled or HOME being in the env_keep list. This option has no effect if HOME isn’t preserved anyway.
  • set_home is like always_set_home , but only applies to sudo -s , not when calling sudo with an explicit command.

These options can be set for a given source user, a given target user or a given command; see the sudoers manual for details.

You can always choose to override HOME for a given call to sudo by passing the option -H .

The shell will never override the value of HOME . (It would set HOME if it was unset, but sudo always sets HOME one way or another.)

If you run sudo -i , sudo simulates an initial login. This includes setting HOME to the home directory of the target user and invoking a login shell.

Now I ran sudo visudo and added this line:
Defaults env_keep += "HOME"

Now, whether I use sudo or not, $HOME always points to /home/user instead of /home/root.
Should this not be the default behaviour for UB as friendly operating system?

probably you should use sudo -i bashscript to inherit the environment you are running on.

Sorry I accidentally posted while still writing. My suggestion is to have that line added to visudo by default for the next version of Ubuntu Budgie.

Changing the default behaviour is fraught with dangers - there probably is hundreds and hundreds of scripts out there that is expecting the current behaviour and will probably break.

this does not work. sudo -i and then $HOME shows /root instead of /home/username.

As I am reading online, this is not normal Ubuntu behaviour…

for example: home/username/test.sh:

#!/bin/bash
mkdir $HOME/test

now run:
sudo -i bash $HOME/test.sh
the script saved in /home/username is executed ($HOME correctly translates to /home/username)

However the folder is created in:
/root/test

It seems 19.10 (version I am using) changed the behaviour, now always resetting the ENV:

The ugly solution is to edit visudo, which is not recommended. An alternative is using sudo --preserve-env=HOME command which definitely is not a nice solution.

I am now testing with sudo -E…
edit: sudo -E seems to be the solution!
Although I am afraid of unwanted side effects with docker and compose when running:
sudo -E docker-compose -f ~/docker/docker-compose.yml up -d

1 Like