Sudo ändert PATH, führt jedoch dieselbe Binärdatei aus

7

Es sind zwei Python-Interpreter installiert:

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

Sudo ändert PATH, wenn es ausgeführt wird:

[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

Der Python-Lauf durch sudo ist jedoch der gleiche wie der direkt durchgeführte:

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

Ich würde erwarten sudo pythonzu laufen, /usr/bin/pythonwas das einzige ist, das auf dem modifizierten sichtbar ist PATH. Warum läuft es /usr/local/bin/pythonstattdessen?

Ich habe diese Frage auf der Mailingliste der Sudo-Benutzer gestellt, aber wir konnten den Grund für dieses Verhalten in der Diskussion mit dem Sudo-Betreuer Todd C. Miller nicht finden.

Als Referenz:

[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)
Piotr Dobrogost
quelle
1
Environment variables to preserve: ... PATHklingt nach einer Erklärung.
Peterph
@peterph Warum zeigt env dann einen anderen Pfad an, wenn es mit sudo ausgeführt wird?
Piotr Dobrogost
Kannst du deine posten /etc/sudoers? Können Sie auch überprüfen, ob für sudo kein Alias ​​festgelegt ist, z alias='sudo -i'. Sie können das mit überprüfen which sudo.
Yoonix
In Ihrem PFAD steht / usr / local / bin vor / usr / bin. Ich denke, es wird erwartet, dass die Suche gestoppt und die ausführbare Datei ausgeführt wird, sobald sie gefunden wurde. Und der Ort, an dem es gefunden wird, ist beim ersten Mal / usr / local / bin. Es sei denn natürlich, Ihr Sudo wurde mit einem anderen Standardpfad kompiliert
MelBurslan
1
@ Mel_Burslan Und der Ort, an dem es gefunden wird, ist / usr / local / bin beim ersten Mal - ich bin mir nicht sicher, was du hier meinst. Laufen sudo env | grep PATHzeigt deutlich, was PATHbeim Betrieb mit sudo passiert. Die Frage ist, warum sudo pythonnicht danach handelt PATH?
Piotr Dobrogost

Antworten:

6

Sie werden verwirrt zwischen dem, PATHwas sich in der tatsächlichen sudoAusführungsumgebung befindet, und dem, PATHwas sich sudoin der Umgebung des Programms befindet, das es ausführt. Aus dem sudoHandbuch:

Wenn sudo einen Befehl ausführt, ruft es fork (2) auf, richtet die Ausführungsumgebung wie oben beschrieben ein und ruft den Systemaufruf execve im untergeordneten Prozess auf.

Wenn execveSie die Umgebung angeben, die der untergeordnete Prozess haben soll, kann sie sich vom übergeordneten Prozess unterscheiden.

Oft secure_pathwird gesetzt in /etc/sudoers:

sicherer_pfad

Pfad, der für jeden Befehl verwendet wird, der von sudo ausgeführt wird. Wenn Sie den Leuten, die sudo ausführen, nicht vertrauen, dass sie eine vernünftige PATH-Umgebungsvariable haben, können Sie diese verwenden. Eine andere Verwendung ist, wenn der "Stammpfad" vom "Benutzerpfad" getrennt werden soll. Benutzer in der durch die Optionempt_group angegebenen Gruppe sind von Secure_path nicht betroffen. Diese Option ist nicht standardmäßig eingestellt.

Wenn dies festgelegt ist, sudowird sowohl nach dem Befehl in diesem PATHals auch in der Umgebung des ausgeführten Befehls gesucht . Es wird auch in der Ausgabe von sudo sudo -Vmit einer Zeile wie folgt angezeigt:

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

In Ihrem Fall ist dies jedoch nicht festgelegt, sodass sudodie PATHeigene Ausführungsumgebung verwendet wird (die in diesem Fall von der übergeordneten Shell geerbt wird). Obwohl es so konfiguriert wurde, dass das aktuelle Verzeichnis ignoriert wird, wenn dies in Folgendes eingefügt wurde PATH:

Ignore '.' in $PATH

Da env_reset es sich in Ihrer /etc/sudoers(und PATHnicht in der env_keepZeichenfolge) befindet, wird das PATH, was sudoin dem von ihm aufgerufenen Befehl festgelegt wird, durch PAModer durch definiert /etc/environmentund unterscheidet sich daher von den PATH sudoVerwendungszwecken für die Suche nach seinem Speicherort:

Standardmäßig ist die Option env_reset aktiviert. Dies führt dazu, dass Befehle in einer neuen, minimalen Umgebung ausgeführt werden. Unter AIX (und Linux-Systemen ohne PAM) wird die Umgebung mit dem Inhalt der Datei / etc / environment initialisiert. Die neue Umgebung enthält zusätzlich zu den Variablen aus dem Aufrufprozess, die durch die Optionen env_check und env_keep zulässig sind, die Variablen TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME und SUDO_ *.

Um das pythonim PATHSet von auszuführen sudo, sollten Sie Folgendes tun:

sudo env python -V

Auf diese Weise sudosucht nicht selbst nach dem Befehl, sondern envdie Umgebung wird von festgelegt sudound envsucht dort nach dem Befehl.

Graeme
quelle
Wenn dies festgelegt ist, sudowird sowohl nach dem Befehl in diesem PATHals auch in der Umgebung des ausgeführten Befehls gesucht . - Dies ist viel klarer als kurz Path used for every command run from sudo.in der Sudoers Manpage.
Piotr Dobrogost
@Piotr, ja, die sudoersManpage ist hier wirklich nicht so klar. Wenn Sie nach allen genannten Orten suchen PATH, beginnen Sie, das Geschehen zusammenzusetzen.
Graeme
Ich habe ein Follow-up gepostet, an dem Sie interessiert sein könnten - Nichtübereinstimmung zwischen sys.executable und sys.version in Python
Piotr Dobrogost
0

Graemes Antwort ist ziemlich erschöpfend, aber es gibt zwei Dinge, die explizit gesagt werden sollten, obwohl sie Ihre Frage nicht beantworten:

1. Wenn Sicherheit Ihr Anliegen ist - was es sein sollte, wenn Sie verwenden

(ALL) NOPASSWD: ALL

(egal für welche Benutzer) - verwenden secure_path. Andernfalls kann ein bösartiges Skript, das praktisch überall auf Ihrem System als ausführbar markiert ist, (nicht nur) den lokalen Computer zerstören. Und das Skript muss nicht direkt auf Ihrem System platziert werden - ein Netzwerkdateisystem, das ohne bereitgestellt wird, noexecwürde dies ebenfalls tun.

2. Wenn Sicherheit wirklich Ihr Anliegen ist, verwenden Sie nicht

(ALL) NOPASSWD: ALL

überhaupt. Ich bin mir nicht ganz sicher, wer auf diese völlig dumme (explizitere, redigierte) Idee gekommen ist, sie zuerst als Standard zu verwenden, aber sie ist einfach viel zu freizügig und gefährlich - selbst ein kleiner Tippfehler kann (nicht nur) Ihren Tag ruinieren. Geben Sie einige Befehle an, für die Root-Rechte erforderlich sind (oder verwendet werden setcap), und ermöglichen Sie den Zugriff auf diese. Offensichtlich kommt alles wie eine Shell (und sufür diejenigen, die es gewohnt sind sudo su) oder einen anderen Interpreter (Python, Perl, Ruby - wie Sie es nennen) nicht in Frage. C kann übrigens auch interpretiert werden . Die Einrichtung kann jedoch etwas komplizierter sein, wenn Sie schlecht gestaltete Programme verwenden.

Peterph
quelle