So verhindern Sie, dass die Shell des Anrufers in sudo verwendet wird

8

Ich verwende sudo-1.8.6 unter CentOS 6.5. Meine Frage ist sehr einfach: Wie verhindere ich, dass SHELL von einer Benutzerumgebung in eine Sudo-Umgebung übertragen wird?

Normalerweise gehen die Leute in die andere Richtung - sie möchten eine Umgebungsvariable beibehalten. Ich habe jedoch ein Problem, bei dem mein Benutzer "zabbix", dessen Shell /sbin/nologinversucht, einen Befehl über sudo auszuführen. Sudo /sbin/nologinbehält das bei, damit root keine Subshells ausführen kann. (Update: Dieser Teil ist wahr, aber es ist nicht die Umgebungsvariable SHELL. Es ist der Shell-Wert, der aus / etc / passwd abgerufen wird, der das Problem darstellt.)

Ich füge einen Test hinzu, der das Problem veranschaulicht. Dies ist nicht mein realer Anwendungsfall, sondern zeigt lediglich, dass die SHELL des anrufenden Benutzers erhalten bleibt. Ich habe ein Programm, das als Benutzer ausgeführt wird zabbix. Es wird aufgerufen /usr/bin/sudo -u root /tmp/doit(die Programmierung zabbixwird als Daemon ausgeführt, sodass die /sbin/nologinShell in der Kennwortdatei dies nicht verhindert). /tmp/doitist ein Shell-Skript, das einfach hat:

#!/bin/sh
env > /tmp/outfile

(sein Modus ist offensichtlich 755). In outfileich sehen kann , dass SHELList /sbin/nologin. Zu diesem Zeitpunkt wird das Skript jedoch über sudo als root ausgeführt, sodass es nicht die Umgebungsvariablen des vorherigen Benutzers enthalten sollte, oder?

Hier sind meine / etc / sudoers:

Standardeinstellungen erforderlich
Standardeinstellungen! Visiblepw

Standardmäßig always_set_home
Standardmäßig env_reset
Defaults env_keep = "FARBENANZEIGE HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Standardeinstellungen env_keep + = "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Standardwert env_keep + = "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Standardwerte env_keep + = "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Standardeinstellungen env_keep + = "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Standardmäßig ist secure_path = / sbin: / bin: / usr / sbin: / usr / bin: / usr / local / bin: / usr / local / sbin

## Erlaube root, Befehle überall auszuführen 
root ALL = (ALL) ALL

#includedir /etc/sudoers.d

Und hier ist mein /etc/sudoers.d/zabbix:

Standardeinstellungen: zabbix! Requiretty

zabbix ALL = (root) NOPASSWD: / tmp / doit

Edit: Ein bisschen mehr Information:

Der Prozess, auf dem der sudo ausgeführt wird zabbix_agentd, stammt von der Zabbix-Überwachungssoftware. Die /etc/zabbix/zabbix_agentd.d/userparameter_disk.confDatei enthält einen Eintrag, der wie folgt aussieht:

UserParameter = example.disk.discovery, / usr / local / bin / zabbix_raid_discovery

/usr/local/bin/zabbix_raid_discoveryist ein Python-Skript. Ich habe es geändert, um dies einfach zu tun:

print subprocess.check_output (['/ usr / bin / sudo', '-u', 'root', '/ tmp / doit'])

/tmp/doit macht einfach das:

#! / bin / sh
env >> / tmp / outfile

Ich führe auf meinem Zabbix-Server Folgendes aus, um das /usr/local/bin/zabbix_raid_discoverySkript auszuführen :

zabbix_get -s client_hostname -k 'example.disk.discovery'

Dann überprüfe ich das /tmp/outfileund sehe:

SHELL = / sbin / nologin
TERM = Linux
USER = root
SUDO_USER = zabbix
SUDO_UID = 497
USERNAME = root
PATH = / sbin: / bin: / usr / sbin: / usr / bin: / usr / local / bin: / usr / local / sbin
MAIL = / var / mail / root
PWD = /
LANG = en_US.UTF-8
SHLVL = 1
SUDO_COMMAND = / tmp / doit
HOME = / root
LOGNAME = root
SUDO_GID = 497
_ = / bin / env

Diese SHELLLinie nervt mich wirklich. Die Datei gehört root, daher weiß ich, dass sie vom Root-Benutzer erstellt wird, aber die Shell stammt vom aufrufenden Benutzer ( zabbix).

Mike S.
quelle
Gibt sudo env SHELL=/bin/sh shes eine Eingabeaufforderung mit / bin / sh als SHELL-Variable in Ihrem System?
@adonis - Siehe meine aktualisierte Frage. Übrigens, du bist sehr hübsch.
Mike S
@BinaryZebra - Ja, ich weiß Bescheid env_delete, aber ich stimme zu, dass der Kern des Problems darin besteht, dass das Standardverhalten von env_reset ...causes commands to be executed with a new, minimal environment.ein Linux-System mit PAM ist The new environment contains the ... SHELL ... (variable). Wie Sie aus meiner /etc/sudoersDatei oben sehen können, erlauben wir nicht SHELLin der env_keep. Sollte also SHELLnicht erhalten bleiben; Wir sollten die Root-Benutzer haben SHELL.
Mike S
@BinaryZebra - Ich habe zabbix ALL=(root) NOPASSWD: /bin/env SHELL=/bin/sh /tmp/doit *meiner /etc/sudoers/zabbixDatei hinzugefügt , und sie hat eine richtige Shell. Danke, ich habe jetzt eine Problemumgehung. Die Frage ist, warum musste ich es aufnehmen? Es scheint gefährlich (und kaputt) zu sein, die SHELL des Anrufers zu übergeben, aber ich kann keinen Ort finden, an dem sudo eingestellt ist, um sie zu ändern. Ich bin gelaufen find /etc/sudoers /etc/sysconfig -type f -exec grep env_ {} \;und finde keine roten Fahnen; /etc/sudoersenthält die einzige env_Zeichenfolge. Ich glaube also nicht, dass eine Sudoers-Flagge stört ...
Mike S
Mike: Auf einer ersten Ebene: Ein einfaches sudo bashsollte eine Bash-Shell als root starten und die Variable SHELL muss auf den Wert von / etc / password gesetzt sein. Sie melden, dass SHELL auf gesetzt (oder beibehalten) wird /sbin/nologin. Dies ist ein Sicherheitsproblem. Die von root gestartete Shell darf nicht von einer von einem Benutzer festgelegten Umgebungsvariablen gesteuert werden. Das müssen Sie untersuchen.

Antworten:

5

Dann ist die Antwort, dass sudoes einen Fehler gibt. Zunächst die Problemumgehung: Ich habe dies in meine /etc/sudoers.d/zabbix file:

zabbix ALL = (root) NOPASSWD: / bin / env SHELL = / bin / sh / usr / local / bin / zabbix_raid_discovery

und jetzt Unterbefehle von der zabbix_raid_discoveryArbeit aufgerufen .

Ein Patch, um dies zu beheben, wird in sudo 1.8.15 sein. Vom Betreuer Todd Miller:

Dies ist nur ein Fall von "es war schon immer so". Das gibt es nicht
wirklich ein guter Grund dafür. Der Unterschied unten sollte das Verhalten machen
stimmen mit der Dokumentation überein.

 - Todd

diff -r adb927ad5e86 plugins / sudoers / env.c.
--- a / plugins / sudoers / env.c Di Okt 06 06 09:33:27 2015 -0600
+++ b / plugins / sudoers / env.c Di 06 Okt 10:04:03 2015 -0600
@ -939,8 +939,6 @@
            CHECK_SETENV2 ("USERNAME", runas_pw-> pw_name,
                ISSET (didvar, DID_USERNAME), true);
        } else {
- if (! ISSET (didvar, DID_SHELL))
- CHECK_SETENV2 ("SHELL", sudo_user.pw-> pw_shell, false, true);
            / * Wir werden LOGNAME später im Fall def_set_logname setzen. * /
            if (! def_set_logname) {
                if (! ISSET (didvar, DID_LOGNAME))
@@ -984,6 +982,8 @@
            if (! env_should_delete (* ep)) {
                if (strncmp (* ep, "SUDO_PS1 =", 9) == 0)
                    ps1 = * ep + 5;
+ else if (strncmp (* ep, "SHELL =", 6) == 0)
+ SET (didvar, DID_SHELL);
                sonst wenn (strncmp (* ep, "PATH =", 5) == 0)
                    SET (didvar, DID_PATH);
                sonst wenn (strncmp (* ep, "TERM =", 5) == 0)
-1039,7 +1039,9 @@
     if (reset_home)
        CHECK_SETENV2 ("HOME", runas_pw-> pw_dir, true, true);

- / * Geben Sie Standardwerte für $ TERM und $ PATH an, wenn diese nicht festgelegt sind. * /
+ / * Geben Sie Standardwerte für $ SHELL, $ TERM und $ PATH an, wenn diese nicht festgelegt sind. * /
+ if (! ISSET (didvar, DID_SHELL))
+ CHECK_SETENV2 ("SHELL", runas_pw-> pw_shell, false, false);
     if (! ISSET (didvar, DID_TERM))
        CHECK_PUTENV ("TERM = unbekannt", false, false);
     if (! ISSET (didvar, DID_PATH))
Mike S.
quelle
Ausgezeichneter Mike! Danke für die Detektivarbeit.
Mike, ist es möglich, dass Sie einen Link zum (zukünftigen?) Patch setzen.
@BinaryZebra Diff ist hier: sudo.ws/repos/sudo/rev/b77adbc08c91 Ich sehe noch keinen Patch.
Mike S
Mike: Ich glaube, dass Sie zum falschen Baum bellen. Der entscheidende Punkt hier Provide default values for $SHELL, $TERM and $PATH if not set.ist : ... if not set.. Jeder eingestellte Wert wird von sudo beibehalten. Wer setzt SHELL?
@BinaryZebra - So habe ich es nicht gelesen. SHELL ist nicht gesetzt (standardmäßig von env_reset). Da es nicht gesetzt ist, sagt der alte Code, dass der pw-Eintrag von sudo_user verwendet werden soll. Der neue Code besagt, dass der pw-Eintrag des Runas-Benutzers verwendet werden soll.
Mike S
4

Die Frage war, wo ich dachte, dass das Problem liegt, aber es stellt sich heraus, dass das Problem nicht darin besteht, was mit der SHELL-Variablen passiert, sondern was sudo tatsächlich tut. Zum Beispiel:

-bash-4.1 $ whoami
Testdude
-bash-4.1 $ grep testdude / etc / passwd
Testdude: x: 1001: 10: Testdude: / tmp: / bin / bash
-bash-4.1 $ sudo env
[sudo] Passwort für Testdude: 
...
SHELL = / bin / bash
...

So weit, ist es gut. ... aber das Problem ist, dass sudo im Gegensatz zu den Dokumenten die Shell des Anrufers anstelle des Angerufenen verwendet. Wenn ich meine Shell durch Bearbeiten von / etc / passwd ändere, können Sie sehen, dass sudo der Shell des Aufrufers folgt und nicht SHELL:

-bash-4.1 $ grep root / etc / passwd
root: x: 0: 0: root: / root: / bin / bash
-bash-4.1 $ sudo sed -i -e '/ testdude / s / bash / sh /' / etc / passwd
-bash-4.1 $ grep testdude / etc / passwd
Testdude: x: 1001: 10: Testdude: / tmp: / bin / sh
-bash-4.1 $ sudo env
...
SHELL = / bin / sh
...
-bash-4.1 $ export SHELL = / vollständig / bedeutungslos / Pfad
-bash-4.1 $ sudo env
...
SHELL = / bin / sh
...

Ich kann nicht verwenden, sudo -ida ich keine erste Anmeldung simulieren möchte. sudo -swird funktionieren, solange ich den richtigen Befehl in der sudoers-Datei habe. Das erwartete Verhalten (wie in der Manpage angegeben: " The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables") ist jedoch, dass die Shell der Angerufene ist. Wenn Sie auf der Suche PATH, HOME, LOGNAME, und USERVariablen für sudo env werden Sie root Sachen sehen. SHELLsollte auch die Wurzelschale sein.

Mike S.
quelle