Por que as variáveis ​​PATH são diferentes ao executar via sudo e su?

40

Na minha VM do fedora, ao executar com a minha conta de usuário, tenho /usr/local/binno meu caminho:

[justin@justin-fedora12 ~]$ env | grep PATH
 PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/justin/bin

E da mesma forma ao executar su:

[justin@justin-fedora12 ~]$ su -
Password: 
[root@justin-fedora12 justin]# env | grep PATH
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/justin/bin

No entanto, ao executar via sudo, este diretório não está no caminho:

[root@justin-fedora12 justin]# exit
[justin@justin-fedora12 ~]$ sudo bash
[root@justin-fedora12 ~]# env | grep PATH
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/sbin:/bin:/usr/sbin:/usr/bin

Por que o caminho seria diferente ao executar via sudo?

Justin Ethier
fonte
stackoverflow.com/questions/257616/sudo-changes-path-why
Ciro Santilli新疆改造中心法轮功六四事件

Respostas:

37

Dê uma olhada /etc/sudoers. O arquivo padrão no Fedora (assim como no RHEL, e também no Ubuntu e similares) inclui esta linha:

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

O que garante que seu caminho esteja limpo ao executar binários no sudo. Isso ajuda a proteger contra algumas das preocupações mencionadas nesta pergunta . Também é conveniente se você não tiver /sbine /usr/sbinem seu próprio caminho.

mattdm
fonte
Ah, eu vejo isso no meu arquivo. Então, não que eu queira, mas se eu adicionasse /usr/local/binessa diretiva, eu a veria no meu caminho ao executar via sudo, certo?
precisa
Eu apenas tentei e agora vejo /usr/local/bin. Muito obrigado por explicar isso!
precisa
Que tal adicionar o caminho de seus usuários para scripts e binários, para que você não precise escrever o caminho absoluto quando sudofor necessário, por exemplo, um script em seu ~/bin(ou qualquer outro caminho que você use)? Acabei de fazer a alteração - funciona, só pensei que poderia haver um outro lado?
Emanuel Berg
@mattdm Sim, o Ubuntu também, como me deparei com esse problema no Ubuntu Vivid ao jogar com VM. O mesmo para o Debian .
kenorb
9

O comando su -executará o perfil de usuários raiz e assumirá o ambiente do usuário, incluindo o caminho etc. sudo, não o faz.

Se você deseja sudose comportar assim su -, use a opção sudo -i [commandque executará o perfil do usuário

Se você gostaria de su -se comportar assim sudo, não use o hífen - basta usarsu [command]

Andrew Yochum
fonte
2

Você pode verificar o porquê (é diferente) executando sudo sudo -V.

Por exemplo, no Linux, execute:

$ sudo sudo -V | grep PATH
Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Nota: no MacOS / BSD, basta executar: sudo sudo -V.

A lista acima é restrita devido ao plug-in de diretiva de segurança padrão em algumas distribuições do Linux.


Isso é explicado em man sudoers:

Se a secure_pathopção estiver configurada, seu valor será usado para a PATHvariável de ambiente.

secure_path- Caminho usado para todos os comandos executados no sudo. Se você não confia que as pessoas que executam o sudo tenham uma PATHvariável de ambiente sã , convém usar isso.

Outro uso é se você deseja que o "caminho raiz" seja separado do "caminho do usuário". Os usuários do grupo especificado pela exempt_groupopção não são afetados por secure_path. Esta opção não está configurada por padrão.

Se for esse o caso, você pode alterar isso executando sudo visudoe editando o arquivo de configuração e modificando seu secure_path(adicionando caminho extra separado por :) ou adicione seu usuário exempt_group(para não ser afetado pelas secure_pathopções).

Ou, para passar PATHtemporariamente ao usuário , você pode executar:

sudo env PATH="$PATH" my_command

e você pode verificar isso:

sudo env PATH="$PATH" env | grep ^PATH

Veja também: Como fazer sudopreservar $PATH?


Outro motivo pelo qual o ambiente pode ser diferente sudoé porque você pode ter a env_resetopção ativada no seu sudoersarquivo. Isso faz com que os comandos sejam executados com um ambiente novo e mínimo.

Portanto, você pode usar a env_keepopção (não recomendada por razões de segurança ) para preservar as variáveis ​​de ambiente do usuário:

Defaults        env_reset
Defaults        env_keep += "PATH PYTHONPATH"
kenorb
fonte
1

Na maioria dos linuxes, você instala programas por meio do gerenciamento de pacotes e recebe atualizações regularmente. Se você instalar algo que contorna o gerenciamento de pacotes, ele será instalado em / usr / local / bin (por exemplo, ou ... / sbin ou / opt) e não receberá atualizações regulares.

Acho que, portanto, os programas não são considerados tão seguros e não são colocados no PATH por padrão.

Usuário desconhecido
fonte
+1 - Legal, eu queria saber por que não estava no caminho, e isso faz sentido. Pelo que vale a pena, eu estava construindo o node.js do zero para brincar com ele, por isso faz sentido o motivo de ter sido colocado lá e por sudoque excluir esse diretório por padrão.
precisa
@Justin Ethier: off topic, mas ver bugzilla.redhat.com/show_bug.cgi?id=634911
mattdm
1

Eu tentei isso sozinho e não vi o comportamento que você estava vendo - meu caminho permaneceu o mesmo, então talvez sua configuração do sudo seja diferente. Se você verificar, man sudoersverá que existe uma opção chamada secure_pathredefinição PATH- parece que essa opção pode ter sido ativada.

Richard Downer
fonte
Interessante. Este foi no Fedora 12, para o que vale a pena ...
Justin Ethier
1

Porque quando você usa sudo bash, bashnão age como um shell de login. Tente novamente com sudo bash -le você verá o mesmo resultado que su -.

Se isso estiver correto, então a diferença de PATHmentiras nos arquivos de configuração: /etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profilesão executados (nessa ordem) para um shell de login, enquanto ~/.bashrcé executada por um shell interativo não-login.

phunehehe
fonte
0

Uma pergunta antiga, eu sei, mas entrei aqui agora porque estava investigando exatamente esse problema.

Por alguma razão, /usr/local/binestava apenas no PATH ao se tornar root via sudo su -. Ao usá- sudo -ilo, não estava lá. É claro que agora sei que posso adicioná-lo ao / etc / sudoers, mas isso ainda não explica por que ele já está lá depois su -. De onde veio essa parte do PATH?

Depois de muito grepping e pesquisa, encontrei a resposta:

O caminho padrão que contém '/ usr / local / bin' é realmente codificado em su (1).

Portanto, nenhuma configuração de pam, perfil, bashrc ou qualquer outra coisa foi responsável por adicionar seletivamente esse elemento. Sempre estava lá quando suassumia o controle. E como sudonão chama su, mas usa sua própria configuração, estava faltando depoissudo -i

Eu achei isso verdade no RHEL6 e RHEL7. Não verifiquei nenhuma outra versão ou distribuição.

Oscar
fonte
Não me pergunte como verifiquei isso. Ok, se você insistir: editei uma cópia do subinário /usr/local/binem hexadecimal , mudei para outra coisa e invoquei a cópia. Meu PATH agora continha a string modificada ... É claro que crianças boas e administradores de sistemas não preguiçosos apenas baixam a fonte e fazem o check-in lá. ;-)
Oscar