Use sudo -E to pass environment variables through to brew.
brew uses environment variables to control many aspects of how it
operates. Using sudo with -E allows those variables to be used to
keep the build/setup consistent with the existing environment.
poke?
@zenspider are there specific env variables that need to be passed thru? Preserving the whole environment with sudo is a potential security risk. sudo --preserve-env=... would be safer.
For starters:
2532 % env | grep BREW
HOMEBREW_AUTO_UPDATE_SECS=86400000
BREW_CASK_OPTS=--appdir=~/Applications
HOMEBREW_NO_SANDBOX=1
HOMEBREW_NO_ANALYTICS=1
HOMEBREW_NO_AUTO_UPDATE=1
HOMEBREW_NO_GITHUB_API=1
HOMEBREW_NO_INSTALL_CLEANUP=1
HOMEBREW_NO_UPDATE_CLEANUP=1
and whatever other annoying thing they add in the future... 🤷♀️
The security policy can determine what is risky and what is not (at least in a black and white sense).
Maybe pass all env vars beginning with HOMEBREW_, since there are many and new ones like @zenspider points out?
Annual poke...
Please! It is super annoying when installing a new ruby version kicks off a 30 minute long brew upgrade of unrelated packages.
OK ok, I like @havenwood's idea of only allowing certain HOMEBREW_* env variables. We could use --preserve-env=list instead of -E to only pass in known HOMEBREW_ environment variables and avoid any potential issues with the user's entire env unintentionally leaking something into homebrew's env. I'm just very cautious about passing arbitrary environment variables through sudo, even if we're sudoing to a non-root user. I might be able to be convinced to just accept -E, but that seems like a potential risk.
It just occurred to me that using sudo -E or even sudo --preserve-env=HOMEBREW_*,... would not work if you invoked ruby-install with sudo initially. The initial sudo would filter out any HOMEBREW_* variables, before sudo -E/sudo --preserve-env=... could pass them to brew install. You would have to remember to do sudo -E ruby-install ... each and every time. Perhaps a better solution might be to configure /etc/sudoers to explicitly allow the HOMEBREW_* env variables?
Defaults env_keep += "HOMEBREW_NO_SANDBOX"
Defaults env_keep += "HOMEBREW_NO_ANALYTICS"
...
A better solution would be for homebrew to load this configuration from a configuration file in /etc/; I tried googling to verify whether homebrew supported a global configuration file, but couldn't find anything indicating that.
I am curious how most homebrew users set the HOMEBREW_* env variables? Is it explicitly with each command or is it set in ~/.bashrc/~/.zshrc/~/.profile? We could try executing the brew command with sudo -i (or sudo -s) which causes the command to be ran under that user's login shell, which should load the user's ~/.bashrc/~/.zshrc/~/.profile configuration.
Or, I dunno... 4 years later, you could merge it.
AFAIK, Homebrew no longer supports running commands with sudo. Here is what you get when you prefix a brew command with sudo:
Error: Running Homebrew as root is extremely dangerous and no longer supported.
As Homebrew does not drop privileges on installation you would be giving all
build scripts full access to your system.
What is the use case for running Homebrew commands with sudo?
@monfresh since ruby-install can be ran as a regular user or as root via sudo, we have to run homebrew under the user which installed homebrew. We should probably not be running homebrew as root. The logic in install_packages need to be refined. I will create a new issue specifically about that.
@zenspider I am very hesitant about merging anything which might introduce potential security issues, such as passing every environment variable from one user's session to another command (there's a reason why sudo does not preserve the caller's environment by default). I mentioned various problems with sudo -E and some alternative approaches, but nothing has changed with this PR. I will close this PR and open a new issue.
See issue #471. @monfresh I suspect a better solution specifically for homebrew being erroneously ran as root would be running the brew commands as the original non-root user (aka $SUDO_USER).