Sudo altera o PATH, mas executa o mesmo binário

7

Existem dois intérpretes do Python instalados:

[user@localhost ~]$ /usr/bin/python -V && /usr/local/bin/python -V
Python 2.4.3
Python 2.7.6

O Sudo altera o PATH quando executado:

[user@localhost ~]$ env | grep PATH && sudo env | grep PATH
PATH=/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/user/bin
PATH=/usr/bin:/bin

No entanto, o Python executado através do sudo é o mesmo que o executado diretamente:

[user@localhost ~]$ sudo python -V && python -V
Python 2.7.6
Python 2.7.6

Espero que sudo python execute /usr/bin/python , que é o único visível no PATH modificado. Por que ele executa /usr/local/bin/python ?

Eu perguntei esta questão na lista de usuários sudo mas podíamos encontre a razão para este comportamento em discussão com o mantenedor do sudo, Todd C. Miller.

Para referência:

[user@localhost ~]$ sudo -l
Matching Defaults entries for user on this host:
    requiretty, !visiblepw, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS
    LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE
    LINGUAS _XKB_CHARSET XAUTHORITY"

Runas and Command-specific defaults for user:


User user may run the following commands on this host:
    (ALL) NOPASSWD: ALL


[user@localhost ~]$ sudo sudo -V
Sudo version 1.7.2p1

Sudoers path: /etc/sudoers
nsswitch path: /etc/nsswitch.conf
ldap.conf path: /etc/ldap.conf
ldap.secret path: /etc/ldap.secret
Authentication methods: 'pam'
Syslog facility if syslog is being used for logging: authpriv
Syslog priority to use when user authenticates successfully: notice
Syslog priority to use when user authenticates unsuccessfully: alert
Ignore '.' in $PATH
Send mail if the user is not in sudoers
Use a separate timestamp for each user/tty combo
Lecture user the first time they run sudo
Require users to authenticate by default
Root may run sudo
Allow some information gathering to give useful error messages
Visudo will honor the EDITOR environment variable
Set the LOGNAME and USER environment variables
Length at which to wrap log file lines (0 for no wrap): 80
Authentication timestamp timeout: 5 minutes
Password prompt timeout: 5 minutes
Number of tries to enter a password: 3
Umask to use or 0777 to use user's: 022
Path to mail program: /usr/sbin/sendmail
Flags for mail program: -t
Address to send mail to: root
Subject line for mail messages: *** SECURITY information for %h ***
Incorrect password message: Sorry, try again.
Path to authentication timestamp dir: /var/run/sudo
Default password prompt: [sudo] password for %p: 
Default user to run commands as: root
Path to the editor for use by visudo: /bin/vi
When to require a password for 'list' pseudocommand: any
When to require a password for 'verify' pseudocommand: all
File containing dummy exec functions: /usr/libexec/sudo_noexec.so
File descriptors >= 3 will be closed before executing a command
Reset the environment to a default set of variables
Environment variables to check for sanity:
        TERM
        LINGUAS
        LC_*
        LANGUAGE
        LANG
        COLORTERM
Environment variables to remove:
        RUBYOPT
        RUBYLIB
        PYTHONINSPECT
        PYTHONPATH
        PYTHONHOME
        TMPPREFIX
        ZDOTDIR
        READNULLCMD
        NULLCMD
        FPATH
        PERL5DB
        PERL5OPT
        PERL5LIB
        PERLLIB
        PERLIO_DEBUG 
        JAVA_TOOL_OPTIONS
        SHELLOPTS
        GLOBIGNORE
        PS4
        BASH_ENV
        ENV
        TERMCAP
        TERMPATH
        TERMINFO_DIRS
        TERMINFO
        _RLD*
        LD_*
        PATH_LOCALE
        NLSPATH
        HOSTALIASES
        RES_OPTIONS
        LOCALDOMAIN
        CDPATH
        IFS
Environment variables to preserve:
        XAUTHORIZATION
        XAUTHORITY
        TZ
        PS2
        PS1
        PATH
        MAIL
        LS_COLORS
        KRB5CCNAME
        HOSTNAME
        HOME
        DISPLAY
        COLORS
Locale to use while parsing sudoers: C
Local IP address and netmask pairs:
        10.0.2.15 / 255.255.255.0
        fe80::a00:27ff:febb:56ce / ffff:ffff:ffff:ffff::


[user@localhost ~]$ sudo cat /etc/sudoers | grep -v -E '^#|^$'
Defaults    requiretty
Defaults   !visiblepw
Defaults    env_reset
Defaults    env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \
                        LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \
                        LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \
                        LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \
                        LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \
                        _XKB_CHARSET XAUTHORITY"
root    ALL=(ALL)       ALL
user    ALL=(ALL)       NOPASSWD: ALL


[user@localhost ~]$ which sudo && command -V sudo
/usr/bin/sudo
sudo is hashed (/usr/bin/sudo)

[user@localhost ~]$ cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 5.10 (Tikanga)
    
por Piotr Dobrogost 05.03.2014 / 22:33

2 respostas

6

Você está ficando confuso entre o PATH que está no ambiente de execução sudo real e o PATH que sudo define no ambiente do programa que ele executa. Do manual sudo :

When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process.

Com execve , você especifica o ambiente que deseja que o processo filho tenha, isto é, pode ser diferente do processo pai.

Frequentemente, secure_path será definido em /etc/sudoers :

secure_path

Path used for every command run from sudo. If you don't trust the people running sudo to have a sane PATH environment variable you may want to use this. Another use is if you want to have the “root path” be separate from the “user path”. Users in the group specified by the exempt_group option are not affected by secure_path. This option is not set by default.

Se isso estiver definido, sudo pesquisará o comando neste PATH e definirá isso no ambiente do comando executado. Ele também aparecerá na saída de sudo sudo -V com uma linha como:

Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

No entanto, no seu caso, isso não está definido, portanto, sudo usará o PATH em seu próprio ambiente de execução (que, nesse caso, é herdado do shell pai). Embora tenha sido configurado para ignorar o diretório atual, se isso foi colocado no PATH :

Ignore '.' in $PATH

Como env_reset é em /etc/sudoers (e PATH não está na string env_keep ), os conjuntos PATH that sudo no comando chamado serão ser definido por PAM ou por /etc/environment e, portanto, é diferente do PATH sudo usado para procurar sua localização:

By default, the env_reset option is enabled. This causes commands to be executed with a new, minimal environment. On AIX (and Linux systems without PAM), the environment is initialized with the contents of the /etc/environment file. The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables in addition to variables from the invoking process permitted by the env_check and env_keep options.

Para executar o python no PATH definido por sudo , você deve fazer algo assim:

sudo env python -V

Dessa forma, não é sudo que está procurando o comando, mas env terá o ambiente definido por sudo e env procurará o comando lá.

    
por 06.03.2014 / 00:04
0

A resposta de Graeme é bastante exaustiva, mas há duas coisas, que devem ser ditas explicitamente, mesmo que sejam Não responda à sua pergunta:

1. Se segurança e segurança são sua preocupação - que deve ser quando você usa

(ALL) NOPASSWD: ALL

(independentemente de quais usuários) - use secure_path . Caso contrário, um script mal-intencionado marcado como executável praticamente em qualquer lugar do sistema pode causar estragos (não apenas) na máquina local. E o script não precisa ser colocado diretamente no seu sistema - um sistema de arquivos de rede montado sem noexec também funcionaria.

2. Se segurança e segurança realmente são sua preocupação, não use

(ALL) NOPASSWD: ALL

em tudo. Não tenho muita certeza de quem surgiu com essa idéia totalmente estúpida (mais explícita) de usá-la como padrão primeiro, mas ela é muito permissiva e perigosa - até mesmo um pequeno erro de digitação pode arruinar (não apenas) o seu dia. Especifique alguns comandos que exijam privilégios de root (ou use setcap ) e permita o acesso a eles. Obviamente, qualquer coisa como um shell (e su para aqueles que estão acostumados a sudo su ) ou qualquer outro interpretador (Python, Perl, Ruby - o nome dele) está fora de questão. A propósito, C pode ser interpretado também . Pode ser um pouco mais intrincado configurar se você estiver usando programas mal projetados.

    
por 06.03.2014 / 19:21

Tags