Como o sudo está configurado para não alterar o $ HOME no Ubuntu e como desabilitar esse comportamento?

31

No Ubuntu 12.04, quando eu sudo -s a variável $ HOME não é alterada, então se o meu usuário regular for regularuser , a situação será assim:

$ cd
$ pwd
/home/regularuser
$ sudo -s
# cd
# pwd
/home/regularuser

Eu abandonei o Ubuntu há muito tempo, então não posso ter certeza, mas acho que esse é o comportamento padrão. Então, minhas perguntas são:

Q1. Como isso é feito? Onde está a configuração?

Q2. Como faço para desativá-lo?

Editar: Obrigado pelas respostas, que esclareceram um pouco as coisas, mas acho que devo acrescentar algumas perguntas para obter a resposta que estou procurando.

Q3. No Debian sudo -s , altera a variável $ HOME para /root . Pelo que obtenho das respostas e man sudo o shell executado com sudo -s é o dado em /etc/passwd , certo?

Q4. No entanto, tanto no Ubuntu quanto no Debian, o shell fornecido em /etc/passwd para root é /bin/bash . Em qualquer dos sistemas também, não consigo encontrar onde a diferença nos arquivos .profile ou .bashrc é, no que diz respeito ao $ HOME, de modo que o comportamento de sudo -s seja diferente. Qualquer ajuda sobre isso?

    
por alxs 19.09.2013 / 12:03

5 respostas

41

O Sudo tem muitas opções de configuração em tempo de compilação. Você pode listar as configurações em sua versão com sudo -V . Uma das diferenças entre a configuração no Debian wheezy e no Ubuntu 12.04 é que a variável de ambiente HOME é preservada no Ubuntu, mas não no Debian; ambas as distribuições apagam todas as variáveis de ambiente, exceto algumas que são explicitamente marcadas como seguras para serem preservadas. Assim, sudo -s preserva HOME no Ubuntu, enquanto no Debian HOME é apagado e sudo então o configura para o diretório home do usuário alvo.

Você pode substituir esse comportamento no arquivo sudoers . Execute visudo para editar o arquivo sudoers . Existem várias opções relevantes:

  • env_keep determina quais variáveis de ambiente são preservadas. Use Defaults env_keep += "HOME" para manter a variável de ambiente HOME do chamador ou Defaults env_keep -= "HOME" para apagá-la (e substitua-a pelo diretório base do usuário de destino).
  • env_reset determina se as variáveis de ambiente são redefinidas. A reconfiguração de variáveis de ambiente geralmente é necessária para regras que permitem a execução de um comando específico, mas não tem um benefício de segurança direto para regras que permitem a execução de comandos arbitrários de qualquer maneira.
  • always_set_home , se definido, fará com que HOME seja substituído, mesmo que tenha sido preservado, pois env_reset está desativado ou HOME está na lista env_keep . Esta opção não tem efeito se HOME não for preservado de qualquer maneira.
  • set_home é como always_set_home , mas só se aplica a sudo -s , não ao chamar sudo com um comando explícito.

Essas opções podem ser definidas para um determinado usuário de origem, um determinado usuário de destino ou um determinado comando; veja o manual sudoers para detalhes.

Você sempre pode optar por substituir HOME de uma determinada chamada para sudo passando a opção -H .

O shell nunca substituirá o valor de HOME . (Ele definiria HOME se não fosse definido, mas sudo sempre definiria HOME de uma forma ou de outra.)

Se você executar sudo -i , sudo simulará um login inicial. Isso inclui a definição de HOME no diretório inicial do usuário de destino e a invocação de um shell de login .

    
por 20.09.2013 / 11:56
17

Use sudo -H -i em vez de sudo -s para obter um shell raiz de login interativo:

sudo -H -i
cd
pwd -P  #  /private/var/root  (on Mac OS X 10.6.8)

De man sudo :

-H      The -H (HOME) option sets the HOME environment variable to
        the homedir of the target user (root by default) as
        specified in passwd(5).  By default, sudo does not modify
        HOME (see set_home and always_set_home in sudoers(5)).
    
por 19.09.2013 / 12:36
6

Isso tem pouco a ver com o comportamento de sudo e muito a ver com a diferença entre um "shell de login" e um "shell de não-login". A solução rápida é

$ sudo -i

como pode ser visto em:

$ sudo -s
# id
uid=0(root) gid=0(root) groups=0(root)
# echo $HOME
/home/msw
# exit
$ sudo -i
# echo $HOME
/root
# pwd
/root

Como indicado no manual do sudo:

The -i (simulate initial login) option runs the shell specified by the password database entry of the target user as a login shell. This means that login-specific resource files such as .profile or .login will be read by the shell. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is specified, an interactive shell is executed.

    
por 19.09.2013 / 12:24
1

Uma maneira bastante popular de obter shell de root também está sendo usada:

 $ sudo su - 
 # id
 uid=0(root) gid=0(root) groups=0(root)
 # pwd
 /root
    
por 19.09.2013 / 12:54
0

Para se livrar do comportamento diferente de sudo -s no Ubuntu e no Debian, respectivamente, você pode usar um sudo wrapper (answer to Q4):

sudos() {
   local PATH="$(getconf PATH)" root_homedir
   root_homedir="$(sudo -H sh -c 'printf "%s" "$HOME"')"
   sudo sh -c 'export HOME="$0"; exec sh -i' "$root_homedir"
   return 0
}

sudo -k
sudos
{
logname
whoami
id -un
id -ur
echo "PATH: $PATH"
}
exit
echo "PATH: $PATH"
    
por 20.09.2013 / 09:52