Por que o sudo altera o PATH?


281

Esta é a PATHvariável sem sudo:

$ echo 'echo $PATH' | sh 
/opt/local/ruby/bin:/usr/bin:/bin

Esta é a PATHvariável com sudo:

$ echo 'echo $PATH' | sudo sh
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin

Tanto quanto eu posso dizer, sudodeve deixar PATHintocado. O que está acontecendo? Como eu mudo isso? (Isso é no Ubuntu 8.04).

ATUALIZAÇÃO: até onde posso ver, nenhum dos scripts foi iniciado como mudança de raiz de PATHforma alguma.

De man sudo:

Para impedir a falsificação de comandos, o sudo verifica ``. '' E `` '' (ambos indicando o diretório atual) por último ao procurar um comando no PATH do usuário (se um ou ambos estiverem no PATH). Observe, no entanto, que a variável de ambiente PATH real não é modificada e é passada inalterada para o programa que o sudo executa.


O root tem algo que define PATH em .bashrc? Isso pressupõe que, como você está no Linux, sh é realmente uma festa.
Greg Hewgill 03/11/08

Respostas:


241

Isto é uma função irritante uma característica do sudo em muitas distribuições.

Para contornar esse "problema" no ubuntu, faça o seguinte no meu ~ / .bashrc

alias sudo='sudo env PATH=$PATH'

Observe que o acima funcionará para comandos que não redefinem o $ PATH. No entanto, `su 'redefine seu $ PATH; portanto, você deve usar -p para dizer que não. IE:

sudo su -p

46
Essa "função irritante" impede que você seja trojanado. Eu digo que forçar um $ PATH específico é um recurso, não um bug - ele faz você escrever o caminho completo para um programa que está fora do $ PATH.
21119 Chris Jester-Young

29
Sim, mas é totalmente contra-intuitivo. Provavelmente engana os mocinhos mais do que os bandidos.
22711 Brian Armstrong

31
Não é apenas contra-intuitivo, está incorretamente documentado. Lendo as páginas de manual do sudo e comparando a configuração com uma caixa do Fedora, pensei que o caminho deveria ser preservado. De fato, "sudo -V" diz até "Variáveis ​​de ambiente a serem preservadas: PATH".
Jason R. Coombs

6
É irritante. período. se ele pudesse 'trojaned' por sudo, poderia trojaned o mesmo sem ele. concedido, mais difícil, mas se você estiver executando o código do lugar errado, mesmo com o usuário comum, as coisas já estarão ruins o suficiente.
gcb

7
Não alias sudo; veja a resposta de @Jacob sobre Padrões env_reset.
greg_1_anderson

121

Caso outra pessoa atravesse isso e queira apenas desativar todas as variáveis ​​de caminho alteradas para todos os usuários.
Acesse o arquivo sudoers usando o comando: visudo. Você deve ver a seguinte linha em algum lugar:

Padrões env_reset

que você deve adicionar o seguinte na próxima linha

Padrões! Secure_path

secure_path está ativado por padrão. Esta opção especifica o que fazer $ PATH ao sudoar. O ponto de exclamação desativa o recurso.


6
outra maneira:Defaults env_keep = "PATH"
gcb 13/03/2012

1
Padrões! Secure_path funcionou muito bem para mim em sistemas modernos; em uma antiga caixa do ubuntu 8.04, os padrões env_keep = "PATH" fizeram o truque.
Greg_1_anderson 19/08/2012

29
Em vez de desativar o secure_path, você pode adicionar a ele. Por exemplo, no meu caso, adicionei a linha "Defaults secure_path = / sbin: / bin: / usr / sbin: / usr / bin: / some / custom / directory" onde "some / custom / directory" é o caminho que eu precisava disponibilizar para o sudo.
Hector Correa

A solução @HectorCorrea é a melhor maneira de IMO.
chakrit

32

PATH é uma variável de ambiente e, como tal, é redefinida por padrão pelo sudo.

Você precisa de permissões especiais para poder fazer isso.

De man sudo

       -E A opção -E (preservar ambiente) substituirá o env_reset
           opção em sudoers (5)). Está disponível apenas quando o
           O comando SETENV possui a tag SETENV ou a opção setenv está definida em sudo-
           (5).
       As variáveis ​​de ambiente a serem definidas para o comando também podem ser transmitidas
       a linha de comando na forma de VAR = value, por exemplo,
        LD_LIBRARY_PATH = / usr / local / pkg / lib. Variáveis ​​transmitidas no comando
       linha estão sujeitos às mesmas restrições que as variações normais do ambiente.
       suporta uma exceção importante. Se a opção setenv estiver configurada em
       sudoers, o comando a ser executado possui a tag SETENV ou o comando
       correspondente é ALL, o usuário pode definir variáveis ​​que seriam
       solicitado. Veja sudoers (5) para mais informações.

Um exemplo de uso:

cat >> test.sh
env | grep "MYEXAMPLE" ;
^D
sh test.sh 
MYEXAMPLE=1 sh test.sh
# MYEXAMPLE=1
MYEXAMPLE=1 sudo sh test.sh 
MYEXAMPLE=1 sudo MYEXAMPLE=2 sh test.sh 
# MYEXAMPLE=2

atualizar

homem 5 sudoers: 

     env_reset Se definido, o sudo redefinirá o ambiente para conter apenas
                       LOGNAME, SHELL, USER, USERNAME e a variável SUDO_ *
                       capazes. Quaisquer variáveis ​​no ambiente do chamador que
                       coincidir com as listas env_keep e env_check são adicionadas.
                       O conteúdo padrão de env_keep e env_check
                       As listas são exibidas quando o sudo é executado pela raiz com o
                       Opção -V. Se o sudo foi compilado com o SECURE_PATH
                       opção, seu valor será usado para o ambiente PATH
                       variável. Esse sinalizador está ativado por padrão.

Portanto, pode ser necessário verificar se isso é / não está compilado.

É por padrão no Gentoo

# ( From the build Script )
....
ROOTPATH=$(cleanpath /bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/opt/bin${ROOTPATH:+:${ROOTPATH}})
....
econf --with-secure-path="${ROOTPATH}" 

17

Parece que esse bug existe há algum tempo! Aqui estão algumas referências de erros que você pode achar úteis (e podem se inscrever em / votar, dica, dica ...):


Bug Debian # 85123 ("sudo: SECURE_PATH ainda não pode ser substituído") (a partir de 2001!)

Parece que o Bug # 20996 ainda está presente nesta versão do sudo. O changelog diz que pode ser substituído em tempo de execução, mas ainda não descobri como.

Eles mencionam colocar algo assim no seu arquivo sudoers:

Defaults secure_path="/bin:/usr/bin:/usr/local/bin"

mas quando faço isso no Ubuntu 8.10, pelo menos, ele me dá este erro:

visudo: unknown defaults entry `secure_path' referenced near line 10

Bug no Ubuntu # 50797 ("o sudo construído com --with-secure-path é problemático")

Pior ainda, pelo que sei, é impossível respeitar novamente o secure_path no arquivo sudoers. Portanto, se, por exemplo, você deseja oferecer a seus usuários acesso fácil a algo sob / opt, você deve recompilar o sudo.


Sim. É necessário que haja uma maneira de substituir esse "recurso" sem precisar recompilar. Nada pior do que fanáticos de segurança dizendo o que é melhor para o seu ambiente e não dando a você uma maneira de desativá-lo.


Isso é realmente irritante. Pode ser prudente manter o comportamento atual por padrão por motivos de segurança, mas deve haver uma maneira de substituí-lo, além de recompilar a partir do código-fonte! Muitas pessoas precisam de herança PATH. Eu me pergunto por que nenhum mantenedor estuda, o que parece fácil de encontrar uma solução aceitável.


Eu trabalhei em torno disso assim:

mv /usr/bin/sudo /usr/bin/sudo.orig

em seguida, crie um arquivo / usr / bin / sudo contendo o seguinte:

#!/bin/bash
/usr/bin/sudo.orig env PATH=$PATH "$@"

então seu sudo regular funciona como o sudo de caminho não seguro


Bug no Ubuntu # 192651 ("o caminho do sudo é sempre redefinido")

Dado que uma duplicata desse bug foi originalmente arquivada em julho de 2006, não estou claro quanto tempo um env_keep ineficaz está em operação. Quaisquer que sejam os méritos de forçar os usuários a empregar truques como os listados acima, certamente as páginas de manual do sudo e sudoers devem refletir o fato de que as opções para modificar o PATH são efetivamente redundantes.

Modificar a documentação para refletir a execução real não é desestabilizador e é muito útil.


Bug no Ubuntu # 226595 ("impossível manter / especificar PATH")

Eu preciso ser capaz de executar o sudo com pastas binárias não-std adicionais no PATH. Depois de adicionar meus requisitos ao / etc / environment, fiquei surpreso quando recebi erros sobre a falta de comandos ao executá-los no sudo .....

Eu tentei o seguinte para corrigir isso sem sucesso:

  1. Usando a sudo -Eopção " " - não funcionou. Meu PATH existente ainda foi redefinido pelo sudo

  2. Alterar " Defaults env_reset" para " Defaults !env_reset" em / etc / sudoers - também não funcionou (mesmo quando combinado com sudo -E)

  3. Não comentar env_reset(por exemplo, " #Defaults env_reset") em / etc / sudoers - também não funcionou.

  4. Adicionar ' Defaults env_keep += "PATH"' a / etc / sudoers - também não funcionou.

Claramente - apesar da documentação do homem - o sudo é completamente codificado em relação ao PATH e não permite nenhuma flexibilidade em relação à retenção do PATH dos usuários. Muito irritante, pois não consigo executar software não padrão sob permissões de root usando o sudo.


13

Isso pareceu funcionar para mim

sudo -i 

que assume o não-sudo PATH


'sudo -i' não ajuda no Ubuntu (verifiquei o Ubuntu 14.04.3 LTS). $ PATH ainda é modificado pelo sudo.
Marcin Raczyński 26/02

11

Na verdade, é desejável que o sudo redefina o PATH: caso contrário, um invasor que comprometa sua conta de usuário pode colocar versões backdoored de todos os tipos de ferramentas no PATH dos usuários, e elas serão executadas ao usar o sudo.

(é claro que o sudo redefiniu o PATH não é uma solução completa para esses tipos de problemas, mas ajuda)

É de fato o que acontece quando você usa

Defaults env_reset

em / etc / sudoers sem usar exempt_groupou env_keep.

Isso também é conveniente porque você pode adicionar diretórios que são úteis apenas para raiz (como /sbine /usr/sbin) ao caminho do sudo sem adicioná-los aos caminhos dos usuários. Para especificar o caminho a ser usado pelo sudo:

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

um invasor que obtém acesso a uma conta sudoer pode fazer coisas ainda piores.
user508546

Um conselho decente. No ubuntu 12.04 Server, uma configuração semelhante é o padrão.
Tsutomu

7

Trabalha agora usando o sudo dos repositórios karmic. Detalhes da minha configuração:

root@sphinx:~# cat /etc/sudoers | grep -v -e '^$' -e '^#'
Defaults    env_reset
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/grub-1.96/sbin:/opt/grub-1.96/bin"
root    ALL=(ALL) ALL
%admin ALL=(ALL) ALL
root@sphinx:~# cat /etc/apt/sources.list
deb http://au.archive.ubuntu.com/ubuntu/ jaunty main restricted universe
deb-src http://au.archive.ubuntu.com/ubuntu/ jaunty main restricted universe

deb http://au.archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe
deb-src http://au.archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe

deb http://security.ubuntu.com/ubuntu jaunty-security main restricted universe
deb-src http://security.ubuntu.com/ubuntu jaunty-security main restricted universe

deb http://au.archive.ubuntu.com/ubuntu/ karmic main restricted universe
deb-src http://au.archive.ubuntu.com/ubuntu/ karmic main restricted universe

deb http://au.archive.ubuntu.com/ubuntu/ karmic-updates main restricted universe
deb-src http://au.archive.ubuntu.com/ubuntu/ karmic-updates main restricted universe

deb http://security.ubuntu.com/ubuntu karmic-security main restricted universe
deb-src http://security.ubuntu.com/ubuntu karmic-security main restricted universe
root@sphinx:~# 

root@sphinx:~# cat /etc/apt/preferences 
Package: sudo
Pin: release a=karmic-security
Pin-Priority: 990

Package: sudo
Pin: release a=karmic-updates
Pin-Priority: 960

Package: sudo
Pin: release a=karmic
Pin-Priority: 930

Package: *
Pin: release a=jaunty-security
Pin-Priority: 900

Package: *
Pin: release a=jaunty-updates
Pin-Priority: 700

Package: *
Pin: release a=jaunty
Pin-Priority: 500

Package: *
Pin: release a=karmic-security
Pin-Priority: 450

Package: *
Pin: release a=karmic-updates
Pin-Priority: 250

Package: *
Pin: release a=karmic
Pin-Priority: 50
root@sphinx:~# apt-cache policy sudo
sudo:
  Installed: 1.7.0-1ubuntu2
  Candidate: 1.7.0-1ubuntu2
  Package pin: 1.7.0-1ubuntu2
  Version table:
 *** 1.7.0-1ubuntu2 930
         50 http://au.archive.ubuntu.com karmic/main Packages
        100 /var/lib/dpkg/status
     1.6.9p17-1ubuntu3 930
        500 http://au.archive.ubuntu.com jaunty/main Packages
root@sphinx:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/grub-1.96/sbin:/opt/grub-1.96/bin
root@sphinx:~# exit
exit
abolte@sphinx:~$ echo $PATH
/home/abolte/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/grub-1.96/sbin:/opt/grub-1.96/bin:/opt/chromium-17593:/opt/grub-1.96/sbin:/opt/grub-1.96/bin:/opt/xpra-0.0.6/bin
abolte@sphinx:~$ 

É maravilhoso finalmente resolver isso sem usar um hack.


4
Talvez você considere reescrever isso para indicar como alguém com uma instalação limpa do Karmic pode atualizar sua configuração para resolver esse problema específico.
precisa

4
# cat .bash_profile | grep PATH
PATH=$HOME/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
export PATH

# cat /etc/sudoers | grep Defaults
Defaults    requiretty
Defaults    env_reset
Defaults    env_keep = "SOME_PARAM1 SOME_PARAM2 ... PATH"

3

Apenas comente "Padrões env_reset" em / etc / sudoers


3

Editar apenas env_keepem/etc/sudoers

Parece algo como isto:

Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASURE MENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL L ANGUAGE LINGUAS XDG_SESSION_COOKIE"

Basta acrescentar PATH no final, para que após a alteração fique assim:

Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASURE MENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL L ANGUAGE LINGUAS XDG_SESSION_COOKIE PATH"

Feche o terminal e abra novamente.


Aguarde PATH precisa de 2 **? Por que o PATH precisa **?
CMCDragonkai

@CMCDragonkai Foi formatado como negrito (no remarcado), mas alguém (o estouro da pilha não me permite apontar o dedo) o editou para marcá-lo como código.
1j01 12/12/15

2

Secure_path é seu amigo, mas se você deseja se eximir de secure_path, apenas

sudo visudo

E acrescentar

Padrões exempt_group = your_goup

Se você deseja isentar um monte de usuários, crie um grupo, adicione todos os usuários a ele e use-o como seu exempt_group. man 5 sudoers por mais.


1

a solução recomendada nos comentários da distribuição do OpenSUSE sugere mudar:

Defaults env_reset

para:

Defaults !env_reset

e, em seguida, presumivelmente para comentar a seguinte linha que não é necessária:

Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASURE    MENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL L    ANGUAGE LINGUAS XDG_SESSION_COOKIE"

1

comente "Env_reset padrão" e "caminho seguro seguro ..." no arquivo / etc / sudores funciona para mim


1

Você também pode mover seu arquivo em um diretório usado pelo sudoers:

    sudo mv $HOME/bash/script.sh /usr/sbin/ 

0

Er, não é realmente um teste se você não adicionar algo ao seu caminho:

bill @ bill-desktop: ~ $ ls -l / opt / pkg / bin
12 total
-rwxr-xr-x 1 raiz root 28 2009-01-22 18:58 foo
bill @ bill-desktop: ~ $ qual foo
/ opt / pkg / bin / foo
bill @ bill-desktop: ~ $ sudo su
root @ bill-desktop: / home / bill # qual foo
root @ bill-desktop: / home / bill # 

0

O PATH será redefinido ao usar su ou sudo pela definição de ENV_SUPATH e ENV_PATH definida em /etc/login.defs


0

$ PATH é uma variável de ambiente e significa que o valor de $ PATH pode ser diferente para outros usuários.

Quando você está fazendo login no seu sistema, a configuração do seu perfil decide o valor do $ PATH .

Agora, vamos dar uma olhada: -

User       |        Value of $PATH
--------------------------
root                /var/www
user1               /var/www/user1
user2               /var/www/html/private

Suponha que esses sejam os valores de $ PATH para diferentes usuários. Agora, quando você estiver executando qualquer comando com sudo, o usuário raiz, na realidade, executa esse comando.

Você pode confirmar executando estes comandos no terminal: -

user@localhost$ whoami
username
user@localhost$ sudo whoami
root
user@localhost$ 

Esta é a razão. Eu acho que está claro para você.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.